Commit 67addd4e authored by Russ Cox's avatar Russ Cox

symbol table changes

	* add gotype string to symbol table
	* fill in gotype in 6l for known funcs/vars
	* print gotype with nm -t

	* load symbol and pc/ln tables into memory at magic address 0x99<<32.
	* add sys.symdat() to retrieve raw bytes of symbol table
	  and pc/ln table.

most of this should be considered experimental
and subject to change.

R=r
DELTA=157  (128 added, 0 deleted, 29 changed)
OCL=19746
CL=19750
parent ec913c42
...@@ -84,6 +84,7 @@ struct Sym ...@@ -84,6 +84,7 @@ struct Sym
uint sig; uint sig;
char type; char type;
char *name; char *name;
char *gotype;
}; };
/* /*
* End of Plan 9 a.out.h * End of Plan 9 a.out.h
......
...@@ -121,10 +121,11 @@ asmb(void) ...@@ -121,10 +121,11 @@ asmb(void)
{ {
Prog *p; Prog *p;
int32 v, magic; int32 v, magic;
int a; int a, np;
uchar *op1; uchar *op1;
vlong vl, va, fo, w; vlong vl, va, fo, w, symo;
int strtabsize; int strtabsize;
vlong symdatva = 0x99LL<<32;
strtabsize = 0; strtabsize = 0;
...@@ -221,6 +222,7 @@ asmb(void) ...@@ -221,6 +222,7 @@ asmb(void)
symsize = 0; symsize = 0;
spsize = 0; spsize = 0;
lcsize = 0; lcsize = 0;
symo = 0;
if(!debug['s']) { if(!debug['s']) {
if(debug['v']) if(debug['v'])
Bprint(&bso, "%5.2f sym\n", cputime()); Bprint(&bso, "%5.2f sym\n", cputime());
...@@ -230,15 +232,17 @@ asmb(void) ...@@ -230,15 +232,17 @@ asmb(void)
case 2: case 2:
case 5: case 5:
debug['s'] = 1; debug['s'] = 1;
seek(cout, HEADR+textsize+datsize, 0); symo = HEADR+textsize+datsize;
break; break;
case 6: case 6:
seek(cout, rnd(HEADR+textsize, INITRND)+rnd(datsize, INITRND), 0); symo = rnd(HEADR+textsize, INITRND)+rnd(datsize, INITRND);
break; break;
case 7: case 7:
seek(cout, rnd(HEADR+textsize, INITRND)+datsize+strtabsize, 0); symo = rnd(HEADR+textsize, INITRND)+datsize+strtabsize;
symo = rnd(symo, INITRND);
break; break;
} }
seek(cout, symo+8, 0);
if(!debug['s']) if(!debug['s'])
asmsym(); asmsym();
if(debug['v']) if(debug['v'])
...@@ -252,6 +256,10 @@ asmb(void) ...@@ -252,6 +256,10 @@ asmb(void)
if(dlm) if(dlm)
asmdyn(); asmdyn();
cflush(); cflush();
seek(cout, symo, 0);
lputl(symsize);
lputl(lcsize);
cflush();
} else } else
if(dlm){ if(dlm){
seek(cout, HEADR+textsize+datsize, 0); seek(cout, HEADR+textsize+datsize, 0);
...@@ -352,7 +360,7 @@ asmb(void) ...@@ -352,7 +360,7 @@ asmb(void)
if (debug['s']) if (debug['s'])
lputl(4); /* number of loads */ lputl(4); /* number of loads */
else else
lputl(6); /* number of loads */ lputl(7); /* number of loads */
lputl(machheadr()-32); /* size of loads */ lputl(machheadr()-32); /* size of loads */
lputl(1); /* flags - no undefines */ lputl(1); /* flags - no undefines */
lputl(0); /* reserved */ lputl(0); /* reserved */
...@@ -394,6 +402,13 @@ asmb(void) ...@@ -394,6 +402,13 @@ asmb(void)
machstack(va+HEADR); machstack(va+HEADR);
if (!debug['s']) { if (!debug['s']) {
machseg("__SYMDAT",
symdatva, /* vaddr */
8+symsize+lcsize, /* vsize */
symo, 8+symsize+lcsize, /* fileoffset filesize */
7, 5, /* protects */
0, 0); /* sections flags */
v += rnd(datsize, INITRND); v += rnd(datsize, INITRND);
machsymseg(v,symsize); /* fileoffset,filesize */ machsymseg(v,symsize); /* fileoffset,filesize */
v += symsize; v += symsize;
...@@ -413,11 +428,14 @@ asmb(void) ...@@ -413,11 +428,14 @@ asmb(void)
lputl(1L); /* version = CURRENT */ lputl(1L); /* version = CURRENT */
llputl(entryvalue()); /* entry vaddr */ llputl(entryvalue()); /* entry vaddr */
llputl(64L); /* offset to first phdr */ llputl(64L); /* offset to first phdr */
llputl(64L+56*3); /* offset to first shdr */ np = 3;
if(!debug['s'])
np++;
llputl(64L+56*np); /* offset to first shdr */
lputl(0L); /* processor specific flags */ lputl(0L); /* processor specific flags */
wputl(64); /* Ehdr size */ wputl(64); /* Ehdr size */
wputl(56); /* Phdr size */ wputl(56); /* Phdr size */
wputl(3); /* # of Phdrs */ wputl(np); /* # of Phdrs */
wputl(64); /* Shdr size */ wputl(64); /* Shdr size */
if (!debug['s']) if (!debug['s'])
wputl(7); /* # of Shdrs */ wputl(7); /* # of Shdrs */
...@@ -451,6 +469,17 @@ asmb(void) ...@@ -451,6 +469,17 @@ asmb(void)
w+bsssize, /* memory size */ w+bsssize, /* memory size */
INITRND); /* alignment */ INITRND); /* alignment */
if(!debug['s']) {
linuxphdr(1, /* data - type = PT_LOAD */
2L+4L, /* data - flags = PF_W+PF_R */
symo, /* file offset */
symdatva, /* vaddr */
symdatva, /* paddr */
8+symsize+lcsize, /* file size */
8+symsize+lcsize, /* memory size */
INITRND); /* alignment */
}
linuxphdr(0x6474e551, /* gok - type = gok */ linuxphdr(0x6474e551, /* gok - type = gok */
1L+2L+4L, /* gok - flags = PF_X+PF_W+PF_R */ 1L+2L+4L, /* gok - flags = PF_X+PF_W+PF_R */
0, /* file offset */ 0, /* file offset */
...@@ -533,7 +562,7 @@ asmb(void) ...@@ -533,7 +562,7 @@ asmb(void)
if (debug['s']) if (debug['s'])
break; break;
fo += w; fo = symo+8;
w = symsize; w = symsize;
linuxshdr(".gosymtab", /* name */ linuxshdr(".gosymtab", /* name */
...@@ -829,6 +858,7 @@ machheadr(void) ...@@ -829,6 +858,7 @@ machheadr(void)
a += 20; /* bss sect */ a += 20; /* bss sect */
a += 46; /* stack sect */ a += 46; /* stack sect */
if (!debug['s']) { if (!debug['s']) {
a += 18; /* symdat seg */
a += 4; /* symtab seg */ a += 4; /* symtab seg */
a += 4; /* lctab seg */ a += 4; /* lctab seg */
} }
...@@ -853,6 +883,7 @@ linuxheadr(void) ...@@ -853,6 +883,7 @@ linuxheadr(void)
a += 64; /* .bss sect */ a += 64; /* .bss sect */
a += 64; /* .shstrtab sect - strings for headers */ a += 64; /* .shstrtab sect - strings for headers */
if (!debug['s']) { if (!debug['s']) {
a += 56; /* symdat seg */
a += 64; /* .gosymtab sect */ a += 64; /* .gosymtab sect */
a += 64; /* .gopclntab sect */ a += 64; /* .gopclntab sect */
} }
......
...@@ -70,6 +70,27 @@ ilookup(char *name) ...@@ -70,6 +70,27 @@ ilookup(char *name)
return x; return x;
} }
char*
gotypefor(char *name)
{
Import *x;
char *s, *p;
s = strdup(name);
p = utfrune(s, 0xB7); // center dot
if(p == nil)
return nil;
*p++ = '.';
memmove(p, p+1, strlen(p));
x = ilookup(s);
free(s);
if(x == nil || x->prefix == nil)
return nil;
if(strcmp(x->prefix, "var") != 0 && strcmp(x->prefix, "func") != 0)
return nil;
return x->def;
}
static void loadpkgdata(char*, char*, int); static void loadpkgdata(char*, char*, int);
static int parsemethod(char**, char*, char**); static int parsemethod(char**, char*, char**);
static int parsepkgdata(char*, char**, char*, int*, char**, char**, char**); static int parsepkgdata(char*, char**, char*, int*, char**, char**, char**);
......
...@@ -397,6 +397,8 @@ int find2(int32, int); ...@@ -397,6 +397,8 @@ int find2(int32, int);
void follow(void); void follow(void);
void addstachmark(void); void addstachmark(void);
void gethunk(void); void gethunk(void);
void gotypestrings(void);
char* gotypefor(char*);
void histtoauto(void); void histtoauto(void);
double ieeedtod(Ieee*); double ieeedtod(Ieee*);
int32 ieeedtof(Ieee*); int32 ieeedtof(Ieee*);
......
...@@ -150,9 +150,9 @@ xdefine(char *p, int t, vlong v) ...@@ -150,9 +150,9 @@ xdefine(char *p, int t, vlong v)
} }
void void
putsymb(char *s, int t, vlong v, int ver) putsymb(char *s, int t, vlong v, int ver, char *go)
{ {
int i, f, l; int i, j, f, l;
if(t == 'f') if(t == 'f')
s++; s++;
...@@ -181,7 +181,13 @@ putsymb(char *s, int t, vlong v, int ver) ...@@ -181,7 +181,13 @@ putsymb(char *s, int t, vlong v, int ver)
cput(s[i]); cput(s[i]);
cput(0); cput(0);
} }
symsize += l + 1 + i + 1; j = 0;
if(go) {
for(j=0; go[j]; j++)
cput(go[j]);
}
cput(0);
symsize += l + 1 + i + 1 + j + 1;
if(debug['n']) { if(debug['n']) {
if(t == 'z' || t == 'Z') { if(t == 'z' || t == 'Z') {
...@@ -194,9 +200,9 @@ putsymb(char *s, int t, vlong v, int ver) ...@@ -194,9 +200,9 @@ putsymb(char *s, int t, vlong v, int ver)
return; return;
} }
if(ver) if(ver)
Bprint(&bso, "%c %.8llux %s<%d>\n", t, v, s, ver); Bprint(&bso, "%c %.8llux %s<%d> %s\n", t, v, s, ver, go);
else else
Bprint(&bso, "%c %.8llux %s\n", t, v, s); Bprint(&bso, "%c %.8llux %s %s\n", t, v, s, go);
} }
} }
...@@ -210,25 +216,25 @@ asmsym(void) ...@@ -210,25 +216,25 @@ asmsym(void)
s = lookup("etext", 0); s = lookup("etext", 0);
if(s->type == STEXT) if(s->type == STEXT)
putsymb(s->name, 'T', s->value, s->version); putsymb(s->name, 'T', s->value, s->version, nil);
for(h=0; h<NHASH; h++) for(h=0; h<NHASH; h++)
for(s=hash[h]; s!=S; s=s->link) for(s=hash[h]; s!=S; s=s->link)
switch(s->type) { switch(s->type) {
case SCONST: case SCONST:
putsymb(s->name, 'D', s->value, s->version); putsymb(s->name, 'D', s->value, s->version, gotypefor(s->name));
continue; continue;
case SDATA: case SDATA:
putsymb(s->name, 'D', s->value+INITDAT, s->version); putsymb(s->name, 'D', s->value+INITDAT, s->version, gotypefor(s->name));
continue; continue;
case SBSS: case SBSS:
putsymb(s->name, 'B', s->value+INITDAT, s->version); putsymb(s->name, 'B', s->value+INITDAT, s->version, gotypefor(s->name));
continue; continue;
case SFILE: case SFILE:
putsymb(s->name, 'f', s->value, s->version); putsymb(s->name, 'f', s->value, s->version, nil);
continue; continue;
} }
...@@ -240,22 +246,23 @@ asmsym(void) ...@@ -240,22 +246,23 @@ asmsym(void)
/* filenames first */ /* filenames first */
for(a=p->to.autom; a; a=a->link) for(a=p->to.autom; a; a=a->link)
if(a->type == D_FILE) if(a->type == D_FILE)
putsymb(a->asym->name, 'z', a->aoffset, 0); putsymb(a->asym->name, 'z', a->aoffset, 0, nil);
else else
if(a->type == D_FILE1) if(a->type == D_FILE1)
putsymb(a->asym->name, 'Z', a->aoffset, 0); putsymb(a->asym->name, 'Z', a->aoffset, 0, nil);
putsymb(s->name, 'T', s->value, s->version); putsymb(s->name, 'T', s->value, s->version, gotypefor(s->name));
/* frame, auto and param after */ /* frame, auto and param after */
putsymb(".frame", 'm', p->to.offset+8, 0); putsymb(".frame", 'm', p->to.offset+8, 0, nil);
/* TODO(rsc): Add types for D_AUTO and D_PARAM */
for(a=p->to.autom; a; a=a->link) for(a=p->to.autom; a; a=a->link)
if(a->type == D_AUTO) if(a->type == D_AUTO)
putsymb(a->asym->name, 'a', -a->aoffset, 0); putsymb(a->asym->name, 'a', -a->aoffset, 0, nil);
else else
if(a->type == D_PARAM) if(a->type == D_PARAM)
putsymb(a->asym->name, 'p', a->aoffset, 0); putsymb(a->asym->name, 'p', a->aoffset, 0, nil);
} }
if(debug['v'] || debug['n']) if(debug['v'] || debug['n'])
Bprint(&bso, "symsize = %lud\n", symsize); Bprint(&bso, "symsize = %lud\n", symsize);
......
...@@ -89,3 +89,6 @@ export func bytestorune(*byte, int, int) (int, int); // convert bytes to runes ...@@ -89,3 +89,6 @@ export func bytestorune(*byte, int, int) (int, int); // convert bytes to runes
export func stringtorune(string, int) (int, int); // convert bytes to runes export func stringtorune(string, int) (int, int); // convert bytes to runes
export func exit(int); export func exit(int);
export func symdat() (symtab *[]byte, pclntab *[]byte);
char *sysimport = char *sysimport =
"package sys\n" "package sys\n"
"export func sys.mal (? int32) (? *any)\n" "export func sys.mal (? int32) (? *any)\n"
"export func sys.breakpoint ()\n" "export func sys.breakpoint ()\n"
...@@ -70,5 +70,6 @@ char *sysimport = ...@@ -70,5 +70,6 @@ char *sysimport =
"export func sys.bytestorune (? *uint8, ? int, ? int) (? int, ? int)\n" "export func sys.bytestorune (? *uint8, ? int, ? int) (? int, ? int)\n"
"export func sys.stringtorune (? string, ? int) (? int, ? int)\n" "export func sys.stringtorune (? string, ? int) (? int, ? int)\n"
"export func sys.exit (? int)\n" "export func sys.exit (? int)\n"
"export func sys.symdat () (symtab *[]uint8, pclntab *[]uint8)\n"
"\n" "\n"
"$$\n"; "$$\n";
...@@ -52,6 +52,7 @@ int nflag; ...@@ -52,6 +52,7 @@ int nflag;
int sflag; int sflag;
int uflag; int uflag;
int Tflag; int Tflag;
int tflag;
Sym **fnames; /* file path translation table */ Sym **fnames; /* file path translation table */
Sym **symptr; Sym **symptr;
...@@ -90,6 +91,7 @@ main(int argc, char *argv[]) ...@@ -90,6 +91,7 @@ main(int argc, char *argv[])
case 'n': nflag = 1; break; case 'n': nflag = 1; break;
case 's': sflag = 1; break; case 's': sflag = 1; break;
case 'u': uflag = 1; break; case 'u': uflag = 1; break;
case 't': tflag = 1; break;
case 'T': Tflag = 1; break; case 'T': Tflag = 1; break;
} ARGEND } ARGEND
if (argc == 0) if (argc == 0)
...@@ -298,7 +300,7 @@ printsyms(Sym **symptr, long nsym) ...@@ -298,7 +300,7 @@ printsyms(Sym **symptr, long nsym)
if(!sflag) if(!sflag)
qsort(symptr, nsym, sizeof(*symptr), (void*)cmp); qsort(symptr, nsym, sizeof(*symptr), (void*)cmp);
wid = 0; wid = 0;
for (i=0; i<nsym; i++) { for (i=0; i<nsym; i++) {
s = symptr[i]; s = symptr[i];
...@@ -306,7 +308,7 @@ printsyms(Sym **symptr, long nsym) ...@@ -306,7 +308,7 @@ printsyms(Sym **symptr, long nsym)
wid = 8; wid = 8;
else if (s->value >= 0x100000000LL && wid == 8) else if (s->value >= 0x100000000LL && wid == 8)
wid = 16; wid = 16;
} }
for (i=0; i<nsym; i++) { for (i=0; i<nsym; i++) {
s = symptr[i]; s = symptr[i];
if (multifile && !hflag) if (multifile && !hflag)
...@@ -322,7 +324,10 @@ printsyms(Sym **symptr, long nsym) ...@@ -322,7 +324,10 @@ printsyms(Sym **symptr, long nsym)
Bprint(&bout, "%*llux ", wid, s->value); Bprint(&bout, "%*llux ", wid, s->value);
else else
Bprint(&bout, "%*s ", wid, ""); Bprint(&bout, "%*s ", wid, "");
Bprint(&bout, "%c %s\n", s->type, cp); Bprint(&bout, "%c %s", s->type, cp);
if(tflag && s->gotype && s->gotype[0])
Bprint(&bout, " %s", s->gotype);
Bprint(&bout, "\n");
} }
} }
......
...@@ -87,6 +87,7 @@ static uvlong firstinstr; /* as found from symtab; needed for amd64 */ ...@@ -87,6 +87,7 @@ static uvlong firstinstr; /* as found from symtab; needed for amd64 */
static void cleansyms(void); static void cleansyms(void);
static int32 decodename(Biobuf*, Sym*); static int32 decodename(Biobuf*, Sym*);
static int32 decodegotype(Biobuf*, Sym*);
static short *encfname(char*); static short *encfname(char*);
static int fline(char*, int, int32, Hist*, Hist**); static int fline(char*, int, int32, Hist*, Hist**);
static void fillsym(Sym*, Symbol*); static void fillsym(Sym*, Symbol*);
...@@ -151,6 +152,10 @@ syminit(int fd, Fhdr *fp) ...@@ -151,6 +152,10 @@ syminit(int fd, Fhdr *fp)
if(i < 0) if(i < 0)
return -1; return -1;
size += i+svalsz+sizeof(p->type); size += i+svalsz+sizeof(p->type);
i = decodegotype(&b, p);
if(i < 0)
return -1;
size += i;
/* count global & auto vars, text symbols, and file names */ /* count global & auto vars, text symbols, and file names */
switch (p->type) { switch (p->type) {
...@@ -293,6 +298,27 @@ decodename(Biobuf *bp, Sym *p) ...@@ -293,6 +298,27 @@ decodename(Biobuf *bp, Sym *p)
return n; return n;
} }
static int32
decodegotype(Biobuf *bp, Sym *p)
{
char *cp;
int32 n;
cp = Brdline(bp, '\0');
if(cp == 0) {
werrstr("can't read go type");
return -1;
}
n = Blinelen(bp);
p->gotype = malloc(n);
if(p->gotype == 0) {
werrstr("can't malloc %ld bytes", n);
return -1;
}
strcpy(p->gotype, cp);
return n;
}
/* /*
* free any previously loaded symbol tables * free any previously loaded symbol tables
*/ */
......
...@@ -743,3 +743,34 @@ algarray[3] = ...@@ -743,3 +743,34 @@ algarray[3] =
// { pointerhash, pointerequal, pointerprint, pointercopy }, // 2 // { pointerhash, pointerequal, pointerprint, pointercopy }, // 2
{ 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);
}
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