uint sig;
char type;
char *name;
+ char *gotype;
};
/*
* End of Plan 9 a.out.h
{
Prog *p;
int32 v, magic;
- int a;
+ int a, np;
uchar *op1;
- vlong vl, va, fo, w;
+ vlong vl, va, fo, w, symo;
int strtabsize;
+ vlong symdatva = 0x99LL<<32;
strtabsize = 0;
symsize = 0;
spsize = 0;
lcsize = 0;
+ symo = 0;
if(!debug['s']) {
if(debug['v'])
Bprint(&bso, "%5.2f sym\n", cputime());
case 2:
case 5:
debug['s'] = 1;
- seek(cout, HEADR+textsize+datsize, 0);
+ symo = HEADR+textsize+datsize;
break;
case 6:
- seek(cout, rnd(HEADR+textsize, INITRND)+rnd(datsize, INITRND), 0);
+ symo = rnd(HEADR+textsize, INITRND)+rnd(datsize, INITRND);
break;
case 7:
- seek(cout, rnd(HEADR+textsize, INITRND)+datsize+strtabsize, 0);
+ symo = rnd(HEADR+textsize, INITRND)+datsize+strtabsize;
+ symo = rnd(symo, INITRND);
break;
}
+ seek(cout, symo+8, 0);
if(!debug['s'])
asmsym();
if(debug['v'])
if(dlm)
asmdyn();
cflush();
+ seek(cout, symo, 0);
+ lputl(symsize);
+ lputl(lcsize);
+ cflush();
} else
if(dlm){
seek(cout, HEADR+textsize+datsize, 0);
if (debug['s'])
lputl(4); /* number of loads */
else
- lputl(6); /* number of loads */
+ lputl(7); /* number of loads */
lputl(machheadr()-32); /* size of loads */
lputl(1); /* flags - no undefines */
lputl(0); /* reserved */
machstack(va+HEADR);
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);
machsymseg(v,symsize); /* fileoffset,filesize */
v += symsize;
lputl(1L); /* version = CURRENT */
llputl(entryvalue()); /* entry vaddr */
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 */
wputl(64); /* Ehdr size */
wputl(56); /* Phdr size */
- wputl(3); /* # of Phdrs */
+ wputl(np); /* # of Phdrs */
wputl(64); /* Shdr size */
if (!debug['s'])
wputl(7); /* # of Shdrs */
w+bsssize, /* memory size */
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 */
1L+2L+4L, /* gok - flags = PF_X+PF_W+PF_R */
0, /* file offset */
if (debug['s'])
break;
- fo += w;
+ fo = symo+8;
w = symsize;
linuxshdr(".gosymtab", /* name */
a += 20; /* bss sect */
a += 46; /* stack sect */
if (!debug['s']) {
+ a += 18; /* symdat seg */
a += 4; /* symtab seg */
a += 4; /* lctab seg */
}
a += 64; /* .bss sect */
a += 64; /* .shstrtab sect - strings for headers */
if (!debug['s']) {
+ a += 56; /* symdat seg */
a += 64; /* .gosymtab sect */
a += 64; /* .gopclntab sect */
}
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 int parsemethod(char**, char*, char**);
static int parsepkgdata(char*, char**, char*, int*, char**, char**, char**);
void follow(void);
void addstachmark(void);
void gethunk(void);
+void gotypestrings(void);
+char* gotypefor(char*);
void histtoauto(void);
double ieeedtod(Ieee*);
int32 ieeedtof(Ieee*);
}
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')
s++;
cput(s[i]);
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(t == 'z' || t == 'Z') {
return;
}
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
- Bprint(&bso, "%c %.8llux %s\n", t, v, s);
+ Bprint(&bso, "%c %.8llux %s %s\n", t, v, s, go);
}
}
s = lookup("etext", 0);
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(s=hash[h]; s!=S; s=s->link)
switch(s->type) {
case SCONST:
- putsymb(s->name, 'D', s->value, s->version);
+ putsymb(s->name, 'D', s->value, s->version, gotypefor(s->name));
continue;
case SDATA:
- putsymb(s->name, 'D', s->value+INITDAT, s->version);
+ putsymb(s->name, 'D', s->value+INITDAT, s->version, gotypefor(s->name));
continue;
case SBSS:
- putsymb(s->name, 'B', s->value+INITDAT, s->version);
+ putsymb(s->name, 'B', s->value+INITDAT, s->version, gotypefor(s->name));
continue;
case SFILE:
- putsymb(s->name, 'f', s->value, s->version);
+ putsymb(s->name, 'f', s->value, s->version, nil);
continue;
}
/* filenames first */
for(a=p->to.autom; a; a=a->link)
if(a->type == D_FILE)
- putsymb(a->asym->name, 'z', a->aoffset, 0);
+ putsymb(a->asym->name, 'z', a->aoffset, 0, nil);
else
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 */
- 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)
if(a->type == D_AUTO)
- putsymb(a->asym->name, 'a', -a->aoffset, 0);
+ putsymb(a->asym->name, 'a', -a->aoffset, 0, nil);
else
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'])
Bprint(&bso, "symsize = %lud\n", symsize);
export func stringtorune(string, int) (int, int); // convert bytes to runes
export func exit(int);
+
+export func symdat() (symtab *[]byte, pclntab *[]byte);
+
-char *sysimport =
+char *sysimport =
"package sys\n"
"export func sys.mal (? int32) (? *any)\n"
"export func sys.breakpoint ()\n"
"export func sys.bytestorune (? *uint8, ? int, ? int) (? int, ? int)\n"
"export func sys.stringtorune (? string, ? int) (? int, ? int)\n"
"export func sys.exit (? int)\n"
+ "export func sys.symdat () (symtab *[]uint8, pclntab *[]uint8)\n"
"\n"
"$$\n";
int sflag;
int uflag;
int Tflag;
+int tflag;
Sym **fnames; /* file path translation table */
Sym **symptr;
case 'n': nflag = 1; break;
case 's': sflag = 1; break;
case 'u': uflag = 1; break;
+ case 't': tflag = 1; break;
case 'T': Tflag = 1; break;
} ARGEND
if (argc == 0)
if(!sflag)
qsort(symptr, nsym, sizeof(*symptr), (void*)cmp);
-
+
wid = 0;
for (i=0; i<nsym; i++) {
s = symptr[i];
wid = 8;
else if (s->value >= 0x100000000LL && wid == 8)
wid = 16;
- }
+ }
for (i=0; i<nsym; i++) {
s = symptr[i];
if (multifile && !hflag)
Bprint(&bout, "%*llux ", wid, s->value);
else
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");
}
}
static void cleansyms(void);
static int32 decodename(Biobuf*, Sym*);
+static int32 decodegotype(Biobuf*, Sym*);
static short *encfname(char*);
static int fline(char*, int, int32, Hist*, Hist**);
static void fillsym(Sym*, Symbol*);
if(i < 0)
return -1;
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 */
switch (p->type) {
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
*/
// { pointerhash, pointerequal, pointerprint, pointercopy }, // 2
{ 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);
+}