]> Cypherpunks repositories - gostls13.git/commitdiff
symbol table changes
authorRuss Cox <rsc@golang.org>
Fri, 21 Nov 2008 01:32:18 +0000 (17:32 -0800)
committerRuss Cox <rsc@golang.org>
Fri, 21 Nov 2008 01:32:18 +0000 (17:32 -0800)
* 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

include/mach_amd64.h
src/cmd/6l/asm.c
src/cmd/6l/go.c
src/cmd/6l/l.h
src/cmd/6l/span.c
src/cmd/gc/sys.go
src/cmd/gc/sysimport.c
src/cmd/nm/nm.c
src/libmach_amd64/sym.c
src/runtime/runtime.c

index 1ffa44033c703f8d282237e9f523ce55c8696cb6..140240993e8bceecee06f1e7ca44c0ef8f06b6bd 100644 (file)
@@ -84,6 +84,7 @@ struct        Sym
        uint    sig;
        char    type;
        char    *name;
+       char *gotype;
 };
 /*
  * End of Plan 9 a.out.h
index 0c4c15fbf3dad07d21efdcb4327c74485abf170f..901c988509013a3b474a500d580ed0df42c9b2f2 100644 (file)
@@ -121,10 +121,11 @@ asmb(void)
 {
        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;
 
@@ -221,6 +222,7 @@ asmb(void)
        symsize = 0;
        spsize = 0;
        lcsize = 0;
+       symo = 0;
        if(!debug['s']) {
                if(debug['v'])
                        Bprint(&bso, "%5.2f sym\n", cputime());
@@ -230,15 +232,17 @@ asmb(void)
                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'])
@@ -252,6 +256,10 @@ asmb(void)
                if(dlm)
                        asmdyn();
                cflush();
+               seek(cout, symo, 0);
+               lputl(symsize);
+               lputl(lcsize);
+               cflush();
        } else
        if(dlm){
                seek(cout, HEADR+textsize+datsize, 0);
@@ -352,7 +360,7 @@ asmb(void)
                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 */
@@ -394,6 +402,13 @@ asmb(void)
                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;
@@ -413,11 +428,14 @@ asmb(void)
                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 */
@@ -451,6 +469,17 @@ asmb(void)
                        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 */
@@ -533,7 +562,7 @@ asmb(void)
                if (debug['s'])
                        break;
 
-               fo += w;
+               fo = symo+8;
                w = symsize;
 
                linuxshdr(".gosymtab",          /* name */
@@ -829,6 +858,7 @@ machheadr(void)
        a += 20;        /* bss sect */
        a += 46;        /* stack sect */
        if (!debug['s']) {
+               a += 18;        /* symdat seg */
                a += 4; /* symtab seg */
                a += 4; /* lctab seg */
        }
@@ -853,6 +883,7 @@ linuxheadr(void)
        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 */
        }
index e073959ded3da97e41474c9d79681a531a8f34ca..5128c51fa9f9f828d4c94fff6c27f965f1db4af1 100644 (file)
@@ -70,6 +70,27 @@ ilookup(char *name)
        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**);
index b9e8dd37a3c2367609ddfb6996577f7865d6daab..ce3ff8eaf6ae9792aa5c4654d46bc7cd8dab2ea4 100644 (file)
@@ -397,6 +397,8 @@ int find2(int32, int);
 void   follow(void);
 void   addstachmark(void);
 void   gethunk(void);
+void   gotypestrings(void);
+char*  gotypefor(char*);
 void   histtoauto(void);
 double ieeedtod(Ieee*);
 int32  ieeedtof(Ieee*);
index acb8f071d4f99e80c741e35f3446f60d068d713c..8ac0543a88ebb037bc40d13aa1bee873f12f99c7 100644 (file)
@@ -150,9 +150,9 @@ xdefine(char *p, int t, vlong v)
 }
 
 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++;
@@ -181,7 +181,13 @@ putsymb(char *s, int t, vlong v, int ver)
                        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') {
@@ -194,9 +200,9 @@ putsymb(char *s, int t, vlong v, int ver)
                        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);
        }
 }
 
@@ -210,25 +216,25 @@ asmsym(void)
 
        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;
                        }
 
@@ -240,22 +246,23 @@ asmsym(void)
                /* 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);
index 910bbd8c6219e424756819f4856586a11e369029..1f34e0cd6cfd3fb4d2012e3c4606cdf929360adb 100644 (file)
@@ -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    exit(int);
+
+export func    symdat() (symtab *[]byte, pclntab *[]byte);
+
index 64dd1a98d19a3d9f462040bdc41732278ba99c5a..ba09bb970eb6ff2cd520386cefdcddc14f905bcf 100644 (file)
@@ -1,4 +1,4 @@
-char *sysimport = 
+char *sysimport =
        "package sys\n"
        "export func sys.mal (? int32) (? *any)\n"
        "export func sys.breakpoint ()\n"
@@ -70,5 +70,6 @@ char *sysimport =
        "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";
index 7c77f66c618fc50ce15b017697c0d219e38b89a9..63c77bd921453c7f1964899696190cabedc06cbf 100644 (file)
@@ -52,6 +52,7 @@ int   nflag;
 int    sflag;
 int    uflag;
 int    Tflag;
+int    tflag;
 
 Sym    **fnames;               /* file path translation table */
 Sym    **symptr;
@@ -90,6 +91,7 @@ main(int argc, char *argv[])
        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)
@@ -298,7 +300,7 @@ printsyms(Sym **symptr, long nsym)
 
        if(!sflag)
                qsort(symptr, nsym, sizeof(*symptr), (void*)cmp);
-       
+
        wid = 0;
        for (i=0; i<nsym; i++) {
                s = symptr[i];
@@ -306,7 +308,7 @@ printsyms(Sym **symptr, long nsym)
                        wid = 8;
                else if (s->value >= 0x100000000LL && wid == 8)
                        wid = 16;
-       }       
+       }
        for (i=0; i<nsym; i++) {
                s = symptr[i];
                if (multifile && !hflag)
@@ -322,7 +324,10 @@ printsyms(Sym **symptr, long nsym)
                        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");
        }
 }
 
index aedd2afde10fb0eb151d717a951a068ce8457fbe..7faf5cd2f4ed17f66977f00b26d55f96ac9926be 100644 (file)
@@ -87,6 +87,7 @@ static        uvlong  firstinstr;             /* as found from symtab; needed for amd64 */
 
 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*);
@@ -151,6 +152,10 @@ syminit(int fd, Fhdr *fp)
                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) {
@@ -293,6 +298,27 @@ decodename(Biobuf *bp, Sym *p)
        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
  */
index 5dd4336e794b478d840e39d542c768aad1e804bc..0a72b146baf4adb7bdfc324b91825f40e4c36939 100644 (file)
@@ -743,3 +743,34 @@ algarray[3] =
 //     {       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);
+}