Commit 3aa063d7 authored by Russ Cox's avatar Russ Cox

delete stack mark strings

in favor of using in-memory copy of symbol table.

$ ls -l pretty pretty.big
-rwxr-xr-x  1 rsc  eng  439516 Nov 21 16:43 pretty
-rwxr-xr-x  1 rsc  eng  580984 Nov 21 16:20 pretty.big
$

R=r
DELTA=446  (238 added, 178 deleted, 30 changed)
OCL=19851
CL=19884
parent ffafad19
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#define NOPROF (1<<0) #define NOPROF (1<<0)
#define DUPOK (1<<1) #define DUPOK (1<<1)
#define NOSPLIT (1<<2) #define NOSPLIT (1<<2)
#define SOFmark "\xa7\xf1\xd9\x2a\x82\xc8\xd8\xfe"
/* /*
* amd64 * amd64
......
...@@ -402,7 +402,6 @@ main(int argc, char *argv[]) ...@@ -402,7 +402,6 @@ main(int argc, char *argv[])
doprof1(); doprof1();
else else
doprof2(); doprof2();
addstackmark();
span(); span();
doinit(); doinit();
asmb(); asmb();
......
...@@ -293,100 +293,6 @@ byteq(int v) ...@@ -293,100 +293,6 @@ byteq(int v)
return p; return p;
} }
void
markstk(Prog *l)
{
Prog *p0, *p, *q, *r;
int32 i, n, line;
Sym *s;
version++;
s = lookup(l->from.sym->name, version);
s->type = STEXT;
line = l->line;
// start with fake copy of ATEXT
p0 = prg();
p = p0;
*p = *l; // note this gets p->pcond and p->line
p->from.type = D_STATIC;
p->from.sym = s;
p->to.offset = 0;
// put out magic sequence
n = strlen(SOFmark);
for(i=0; i<n; i++) {
q = byteq(SOFmark[i]);
q->line = line;
p->link = q;
p = q;
}
// put out stack offset
n = l->to.offset;
if(n < 0)
n = 0;
for(i=0; i<3; i++) {
q = byteq(n);
q->line = line;
p->link = q;
p = q;
n = n>>8;
}
// put out null terminated name
for(i=0;; i++) {
n = s->name[i];
q = byteq(n);
q->line = line;
p->link = q;
p = q;
if(n == 0)
break;
}
// put out return instruction
q = prg();
q->as = ARET;
q->line = line;
p->link = q;
p = q;
r = l->pcond;
l->pcond = p0;
p->link = r;
p0->pcond = r;
// hard part is linking end of
// the text body to my fake ATEXT
for(p=l;; p=q) {
q = p->link;
if(q == r) {
p->link = p0;
return;
}
}
}
void
addstackmark(void)
{
Prog *p;
if(debug['v'])
Bprint(&bso, "%5.2f stkmark\n", cputime());
Bflush(&bso);
for(p=textp; p!=P; p=p->pcond) {
markstk(p); // splice in new body
p = p->pcond; // skip the one we just put in
}
// for(p=textp; p!=P; p=p->pcond)
// print("%P\n", p);
}
int int
relinv(int a) relinv(int a)
{ {
......
...@@ -26,6 +26,7 @@ LIBOFILES=\ ...@@ -26,6 +26,7 @@ LIBOFILES=\
rune.$O\ rune.$O\
proc.$O\ proc.$O\
string.$O\ string.$O\
symtab.$O\
sys_file.$O\ sys_file.$O\
OFILES=$(RT0OFILES) $(LIBOFILES) OFILES=$(RT0OFILES) $(LIBOFILES)
...@@ -61,3 +62,4 @@ sys_file.$O: sys_file.c sys_types.h $(OS_H) ...@@ -61,3 +62,4 @@ sys_file.$O: sys_file.c sys_types.h $(OS_H)
runtime.acid: runtime.h proc.c runtime.acid: runtime.h proc.c
$(CC) -a proc.c >runtime.acid $(CC) -a proc.c >runtime.acid
...@@ -420,21 +420,12 @@ sys·printinter(Map *im, void *it) ...@@ -420,21 +420,12 @@ sys·printinter(Map *im, void *it)
void void
sys·reflect(Map *im, void *it, uint64 retit, string rettype) sys·reflect(Map *im, void *it, uint64 retit, string rettype)
{ {
string s;
int32 n;
byte *type;
if(im == nil) { if(im == nil) {
retit = 0; retit = 0;
rettype = nil; rettype = nil;
} else { } else {
retit = (uint64)it; retit = (uint64)it;
type = im->sigt->name; rettype = gostring(im->sigt->name);
n = findnull((int8*)type);
s = mal(sizeof *s + n + 1);
s->len = n;
mcpy(s->str, type, n);
rettype = s;
} }
FLUSH(&retit); FLUSH(&retit);
FLUSH(&rettype); FLUSH(&rettype);
......
...@@ -25,7 +25,7 @@ dump(byte *p, int32 n) ...@@ -25,7 +25,7 @@ dump(byte *p, int32 n)
void void
prints(int8 *s) prints(int8 *s)
{ {
sys·write(1, s, findnull(s)); sys·write(1, s, findnull((byte*)s));
} }
void void
......
...@@ -6,8 +6,6 @@ ...@@ -6,8 +6,6 @@
extern int32 debug; extern int32 debug;
static int8 spmark[] = "\xa7\xf1\xd9\x2a\x82\xc8\xd8\xfe";
extern uint8 end; extern uint8 end;
void void
...@@ -18,7 +16,8 @@ traceback(uint8 *pc, uint8 *sp, void* r15) ...@@ -18,7 +16,8 @@ traceback(uint8 *pc, uint8 *sp, void* r15)
uint8* callpc; uint8* callpc;
int32 counter; int32 counter;
int32 i; int32 i;
int8* name; string name;
Func *f;
G g; G g;
Stktop *stktop; Stktop *stktop;
...@@ -33,7 +32,7 @@ traceback(uint8 *pc, uint8 *sp, void* r15) ...@@ -33,7 +32,7 @@ traceback(uint8 *pc, uint8 *sp, void* r15)
} }
counter = 0; counter = 0;
name = "panic"; name = gostring((byte*)"panic");
for(;;){ for(;;){
callpc = pc; callpc = pc;
if((uint8*)retfromnewstack == pc) { if((uint8*)retfromnewstack == pc) {
...@@ -46,21 +45,11 @@ traceback(uint8 *pc, uint8 *sp, void* r15) ...@@ -46,21 +45,11 @@ traceback(uint8 *pc, uint8 *sp, void* r15)
sp += 16; // two irrelevant calls on stack - morestack, plus the call morestack made sp += 16; // two irrelevant calls on stack - morestack, plus the call morestack made
continue; continue;
} }
/* find SP offset by stepping back through instructions to SP offset marker */ f = findfunc((uint64)callpc);
while(pc > (uint8*)0x1000+sizeof spmark-1) { if(f == nil)
if(pc >= &end) return;
return; name = f->name;
for(spp = spmark; *spp != '\0' && *pc++ == (uint8)*spp++; ) sp += f->frame;
;
if(*spp == '\0'){
spoff = *pc++;
spoff += *pc++ << 8;
spoff += *pc++ << 16;
name = (int8*)pc;
sp += spoff + 8;
break;
}
}
if(counter++ > 100){ if(counter++ > 100){
prints("stack trace terminated\n"); prints("stack trace terminated\n");
break; break;
...@@ -73,7 +62,7 @@ traceback(uint8 *pc, uint8 *sp, void* r15) ...@@ -73,7 +62,7 @@ traceback(uint8 *pc, uint8 *sp, void* r15)
sys·printpointer(callpc - 1); // -1 to get to CALL instr. sys·printpointer(callpc - 1); // -1 to get to CALL instr.
prints("?zi\n"); prints("?zi\n");
prints("\t"); prints("\t");
prints(name); sys·printstring(name);
prints("("); prints("(");
for(i = 0; i < 3; i++){ for(i = 0; i < 3; i++){
if(i != 0) if(i != 0)
...@@ -82,7 +71,7 @@ traceback(uint8 *pc, uint8 *sp, void* r15) ...@@ -82,7 +71,7 @@ traceback(uint8 *pc, uint8 *sp, void* r15)
} }
prints(", ...)\n"); prints(", ...)\n");
prints("\t"); prints("\t");
prints(name); sys·printstring(name);
prints("("); prints("(");
for(i = 0; i < 3; i++){ for(i = 0; i < 3; i++){
if(i != 0) if(i != 0)
......
...@@ -107,6 +107,15 @@ mmov(byte *t, byte *f, uint32 n) ...@@ -107,6 +107,15 @@ mmov(byte *t, byte *f, uint32 n)
} }
} }
byte*
mchr(byte *p, byte c, byte *ep)
{
for(; p < ep; p++)
if(*p == c)
return p;
return nil;
}
uint32 uint32
rnd(uint32 n, uint32 m) rnd(uint32 n, uint32 m)
{ {
...@@ -464,7 +473,7 @@ getenv(int8 *s) ...@@ -464,7 +473,7 @@ getenv(int8 *s)
byte *v, *bs; byte *v, *bs;
bs = (byte*)s; bs = (byte*)s;
len = findnull(s); len = findnull(bs);
for(i=0; i<envc; i++){ for(i=0; i<envc; i++){
v = envv[i]; v = envv[i];
for(j=0; j<len; j++) for(j=0; j<len; j++)
...@@ -509,21 +518,10 @@ sys·envc(int32 v) ...@@ -509,21 +518,10 @@ sys·envc(int32 v)
void void
sys·argv(int32 i, string s) sys·argv(int32 i, string s)
{ {
uint8* str; if(i >= 0 && i < argc)
int32 l; s = gostring(argv[i]);
else
if(i < 0 || i >= argc) {
s = emptystring; s = emptystring;
goto out;
}
str = argv[i];
l = findnull((int8*)str);
s = mal(sizeof(s->len)+l);
s->len = l;
mcpy(s->str, str, l);
out:
FLUSH(&s); FLUSH(&s);
} }
...@@ -531,21 +529,10 @@ out: ...@@ -531,21 +529,10 @@ out:
void void
sys·envv(int32 i, string s) sys·envv(int32 i, string s)
{ {
uint8* str; if(i >= 0 && i < envc)
int32 l; s = gostring(envv[i]);
else
if(i < 0 || i >= envc) {
s = emptystring; s = emptystring;
goto out;
}
str = envv[i];
l = findnull((int8*)str);
s = mal(sizeof(s->len)+l);
s->len = l;
mcpy(s->str, str, l);
out:
FLUSH(&s); FLUSH(&s);
} }
...@@ -742,33 +729,3 @@ algarray[3] = ...@@ -742,33 +729,3 @@ algarray[3] =
{ memhash, memequal, memprint, memcopy }, // 2 - treat pointers as ints { memhash, memequal, memprint, memcopy }, // 2 - treat pointers as ints
}; };
// Return a pointer to a byte array containing the symbol table segment.
//
// NOTE(rsc): I expect that we will clean up both the method of getting
// at the symbol table and the exact format of the symbol table at some
// point in the future. It probably needs to be better integrated with
// the type strings table too. This is just a quick way to get started
// and figure out what we want from/can do with it.
void
sys·symdat(Array *symtab, Array *pclntab)
{
Array *a;
int32 *v;
v = (int32*)(0x99LL<<32); /* known to 6l */
a = mal(sizeof *a);
a->nel = v[0];
a->cap = a->nel;
a->array = (byte*)&v[2];
symtab = a;
FLUSH(&symtab);
a = mal(sizeof *a);
a->nel = v[1];
a->cap = a->nel;
a->array = (byte*)&v[2] + v[0];
pclntab = a;
FLUSH(&pclntab);
}
...@@ -19,32 +19,35 @@ typedef uint64 uintptr; ...@@ -19,32 +19,35 @@ typedef uint64 uintptr;
/* /*
* get rid of C types * get rid of C types
* the / / / forces a syntax error immediately,
* which will show "last name: XXunsigned".
*/ */
#define unsigned XXunsigned #define unsigned XXunsigned / / /
#define signed XXsigned #define signed XXsigned / / /
#define char XXchar #define char XXchar / / /
#define short XXshort #define short XXshort / / /
#define int XXint #define int XXint / / /
#define long XXlong #define long XXlong / / /
#define float XXfloat #define float XXfloat / / /
#define double XXdouble #define double XXdouble / / /
/* /*
* defined types * defined types
*/ */
typedef uint8 bool; typedef uint8 bool;
typedef uint8 byte; typedef uint8 byte;
typedef struct String *string; typedef struct Alg Alg;
typedef struct Array Array; typedef struct Array Array;
typedef struct Gobuf Gobuf; typedef struct Func Func;
typedef struct G G; typedef struct G G;
typedef struct M M; typedef struct Gobuf Gobuf;
typedef struct Stktop Stktop;
typedef struct Alg Alg;
typedef struct Lock Lock; typedef struct Lock Lock;
typedef union Note Note; typedef struct M M;
typedef struct Mem Mem; typedef struct Mem Mem;
typedef struct Usema Usema; typedef union Note Note;
typedef struct Stktop Stktop;
typedef struct String *string;
typedef struct Usema Usema;
/* /*
* per cpu declaration * per cpu declaration
...@@ -179,6 +182,18 @@ struct SigTab ...@@ -179,6 +182,18 @@ struct SigTab
int8 *name; int8 *name;
}; };
// (will be) shared with go; edit ../cmd/6g/sys.go too.
// should move out of sys.go eventually.
// also eventually, the loaded symbol table should
// be closer to this form.
struct Func
{
string name;
string type;
uint64 entry;
int64 frame;
};
/* /*
* defined macros * defined macros
* you need super-goru privilege * you need super-goru privilege
...@@ -202,7 +217,7 @@ extern int32 maxround; ...@@ -202,7 +217,7 @@ extern int32 maxround;
* common functions and data * common functions and data
*/ */
int32 strcmp(byte*, byte*); int32 strcmp(byte*, byte*);
int32 findnull(int8*); int32 findnull(byte*);
void dump(byte*, int32); void dump(byte*, int32);
int32 runetochar(byte*, int32); int32 runetochar(byte*, int32);
int32 chartorune(uint32*, byte*); int32 chartorune(uint32*, byte*);
...@@ -220,10 +235,12 @@ void* getu(void); ...@@ -220,10 +235,12 @@ void* getu(void);
void throw(int8*); void throw(int8*);
uint32 rnd(uint32, uint32); uint32 rnd(uint32, uint32);
void prints(int8*); void prints(int8*);
byte* mchr(byte*, byte, byte*);
void mcpy(byte*, byte*, uint32); void mcpy(byte*, byte*, uint32);
void mmov(byte*, byte*, uint32); void mmov(byte*, byte*, uint32);
void* mal(uint32); void* mal(uint32);
uint32 cmpstring(string, string); uint32 cmpstring(string, string);
string gostring(byte*);
void initsig(void); void initsig(void);
int32 gotraceback(void); int32 gotraceback(void);
void traceback(uint8 *pc, uint8 *sp, G* gp); void traceback(uint8 *pc, uint8 *sp, G* gp);
...@@ -243,6 +260,7 @@ void sigaltstack(void*, void*); ...@@ -243,6 +260,7 @@ void sigaltstack(void*, void*);
void signalstack(byte*, int32); void signalstack(byte*, int32);
G* malg(int32); G* malg(int32);
void minit(void); void minit(void);
Func* findfunc(uint64);
/* /*
* mutual exclusion locks. in the uncontended case, * mutual exclusion locks. in the uncontended case,
......
...@@ -8,7 +8,7 @@ static int32 empty = 0; ...@@ -8,7 +8,7 @@ static int32 empty = 0;
string emptystring = (string)&empty; string emptystring = (string)&empty;
int32 int32
findnull(int8 *s) findnull(byte *s)
{ {
int32 l; int32 l;
...@@ -17,6 +17,19 @@ findnull(int8 *s) ...@@ -17,6 +17,19 @@ findnull(int8 *s)
return l; return l;
} }
string
gostring(byte *str)
{
int32 l;
string s;
l = findnull(str);
s = mal(sizeof(s->len)+l+1);
s->len = l;
mcpy(s->str, str, l+1);
return s;
}
void void
sys·catstring(string s1, string s2, string s3) sys·catstring(string s1, string s2, string s3)
{ {
......
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "runtime.h"
// Runtime symbol table access.
// Very much a work in progress.
#define SYMCOUNTS ((int32*)(0x99LL<<32)) // known to 6l
#define SYMDATA ((byte*)(0x99LL<<32) + 8)
// Return a pointer to a byte array containing the symbol table segment.
//
// NOTE(rsc): I expect that we will clean up both the method of getting
// at the symbol table and the exact format of the symbol table at some
// point in the future. It probably needs to be better integrated with
// the type strings table too. This is just a quick way to get started
// and figure out what we want from/can do with it.
void
sys·symdat(Array *symtab, Array *pclntab)
{
Array *a;
int32 *v;
v = SYMCOUNTS;
a = mal(sizeof *a);
a->nel = v[0];
a->cap = a->nel;
a->array = SYMDATA;
symtab = a;
FLUSH(&symtab);
a = mal(sizeof *a);
a->nel = v[1];
a->cap = a->nel;
a->array = SYMDATA + v[0];
pclntab = a;
FLUSH(&pclntab);
}
typedef struct Sym Sym;
struct Sym
{
uint64 value;
byte symtype;
byte *name;
byte *gotype;
};
// Walk over symtab, calling fn(&s) for each symbol.
void
walksymtab(void (*fn)(Sym*))
{
int32 *v;
byte *p, *ep, *q;
Sym s;
v = SYMCOUNTS;
p = SYMDATA;
ep = p + v[0];
while(p < ep) {
if(p + 7 > ep)
break;
s.value = ((uint32)p[0]<<24) | ((uint32)p[1]<<16) | ((uint32)p[2]<<8) | ((uint32)p[3]);
if(!(p[4]&0x80))
break;
s.symtype = p[4] & ~0x80;
p += 5;
if(s.symtype == 'z' || s.symtype == 'Z') {
// path reference string - skip first byte,
// then 2-byte pairs ending at two zeros.
// for now, just skip over it and ignore it.
q = p+1;
for(;;) {
if(q+2 > ep)
return;
if(q[0] == '\0' && q[1] == '\0')
break;
q += 2;
}
p = q+2;
s.name = nil;
}else{
q = mchr(p, '\0', ep);
if(q == nil)
break;
s.name = p;
p = q+1;
}
q = mchr(p, '\0', ep);
if(q == nil)
break;
s.gotype = p;
p = q+1;
fn(&s);
}
}
// Symtab walker; accumulates info about functions.
Func *func;
int32 nfunc;
static void
dofunc(Sym *sym)
{
static byte *lastfuncname;
static Func *lastfunc;
Func *f;
if(lastfunc && sym->symtype == 'm') {
lastfunc->frame = sym->value;
return;
}
if(sym->symtype != 'T' && sym->symtype != 't')
return;
if(strcmp(sym->name, (byte*)"etext") == 0)
return;
if(func == nil) {
nfunc++;
return;
}
f = &func[nfunc++];
f->name = gostring(sym->name);
f->entry = sym->value;
lastfunc = f;
}
static void
buildfuncs(void)
{
extern byte etext[];
if(func != nil)
return;
nfunc = 0;
walksymtab(dofunc);
func = mal((nfunc+1)*sizeof func[0]);
nfunc = 0;
walksymtab(dofunc);
func[nfunc].entry = (uint64)etext;
}
Func*
findfunc(uint64 addr)
{
Func *f;
int32 i, nf, n;
if(func == nil)
buildfuncs();
if(nfunc == 0)
return nil;
if(addr < func[0].entry || addr >= func[nfunc].entry)
return nil;
// linear search, for debugging
if(0) {
for(i=0; i<nfunc; i++) {
if(func[i].entry <= addr && addr < func[i+1].entry)
return &func[i];
}
return nil;
}
// binary search to find func with entry <= addr.
f = func;
nf = nfunc;
while(nf > 0) {
n = nf/2;
if(f[n].entry <= addr && addr < f[n+1].entry)
return &f[n];
else if(addr < f[n].entry)
nf = n;
else {
f += n+1;
nf -= n+1;
}
}
// can't get here -- we already checked above
// that the address was in the table bounds.
// this can only happen if the table isn't sorted
// by address or if the binary search above is buggy.
prints("findfunc unreachable\n");
return nil;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment