]> Cypherpunks repositories - gostls13.git/commitdiff
delete stack mark strings
authorRuss Cox <rsc@golang.org>
Mon, 24 Nov 2008 01:08:55 +0000 (17:08 -0800)
committerRuss Cox <rsc@golang.org>
Mon, 24 Nov 2008 01:08:55 +0000 (17:08 -0800)
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

src/cmd/6l/6.out.h
src/cmd/6l/obj.c
src/cmd/6l/pass.c
src/runtime/Makefile
src/runtime/iface.c
src/runtime/print.c
src/runtime/rt2_amd64.c
src/runtime/runtime.c
src/runtime/runtime.h
src/runtime/string.c
src/runtime/symtab.c [new file with mode: 0644]

index 4abbbf057f9fb068af6bcf6b07fced5a41e1ede3..0c22944fa933891011e872e32c40e3edd8804807 100644 (file)
@@ -33,7 +33,6 @@
 #define NOPROF (1<<0)
 #define DUPOK  (1<<1)
 #define NOSPLIT        (1<<2)
-#define SOFmark        "\xa7\xf1\xd9\x2a\x82\xc8\xd8\xfe"
 
 /*
  *     amd64
index 9777cdf42aaf04ef4d337868593b238f8445c598..8ecb035b40b92a2da860520379e1bc5e21896e74 100644 (file)
@@ -402,7 +402,6 @@ main(int argc, char *argv[])
                        doprof1();
                else
                        doprof2();
-       addstackmark();
        span();
        doinit();
        asmb();
index 9f765e836f9fd321333e5cb54d21fa213ca1cbc0..3ddc1e93708888a5d397b2be487b97813ee64855 100644 (file)
@@ -293,100 +293,6 @@ byteq(int v)
        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
 relinv(int a)
 {
index df33b5801518e9bbe171c97aab3ec2eca7a7cee0..cd1cf28212ece15a04acbe7010cf36e27504bb80 100644 (file)
@@ -26,6 +26,7 @@ LIBOFILES=\
        rune.$O\
        proc.$O\
        string.$O\
+       symtab.$O\
        sys_file.$O\
 
 OFILES=$(RT0OFILES) $(LIBOFILES)
@@ -61,3 +62,4 @@ sys_file.$O:  sys_file.c sys_types.h $(OS_H)
 
 runtime.acid: runtime.h proc.c
        $(CC) -a proc.c >runtime.acid
+
index 07bd325843a7739b0adb1603285785c3a615fd64..5062075c34c4986bac03c9e168ae8b4ae6e48a0f 100644 (file)
@@ -420,21 +420,12 @@ sys·printinter(Map *im, void *it)
 void
 sys·reflect(Map *im, void *it, uint64 retit, string rettype)
 {
-       string s;
-       int32 n;
-       byte *type;
-
        if(im == nil) {
                retit = 0;
                rettype = nil;
        } else {
                retit = (uint64)it;
-               type = im->sigt->name;
-               n = findnull((int8*)type);
-               s = mal(sizeof *s + n + 1);
-               s->len = n;
-               mcpy(s->str, type, n);
-               rettype = s;
+               rettype = gostring(im->sigt->name);
        }
        FLUSH(&retit);
        FLUSH(&rettype);
index 26d59a7390d12db968525011f9afd344dcb792f1..6266d1658f547ad8747ef2ac57acc2238a5eb5be 100644 (file)
@@ -25,7 +25,7 @@ dump(byte *p, int32 n)
 void
 prints(int8 *s)
 {
-       sys·write(1, s, findnull(s));
+       sys·write(1, s, findnull((byte*)s));
 }
 
 void
index 38eeddb495ce5260e15d60df6eb990cf9bfd9bad..5a388bfe0262a53a268aa4213b30028e82a2027b 100644 (file)
@@ -6,8 +6,6 @@
 
 extern int32   debug;
 
-static int8 spmark[] = "\xa7\xf1\xd9\x2a\x82\xc8\xd8\xfe";
-
 extern uint8 end;
 
 void
@@ -18,7 +16,8 @@ traceback(uint8 *pc, uint8 *sp, void* r15)
        uint8* callpc;
        int32 counter;
        int32 i;
-       int8* name;
+       string name;
+       Func *f;
        G g;
        Stktop *stktop;
 
@@ -33,7 +32,7 @@ traceback(uint8 *pc, uint8 *sp, void* r15)
        }
 
        counter = 0;
-       name = "panic";
+       name = gostring((byte*)"panic");
        for(;;){
                callpc = pc;
                if((uint8*)retfromnewstack == pc) {
@@ -46,21 +45,11 @@ traceback(uint8 *pc, uint8 *sp, void* r15)
                        sp += 16;  // two irrelevant calls on stack - morestack, plus the call morestack made
                        continue;
                }
-               /* find SP offset by stepping back through instructions to SP offset marker */
-               while(pc > (uint8*)0x1000+sizeof spmark-1) {
-                       if(pc >= &end)
-                               return;
-                       for(spp = spmark; *spp != '\0' && *pc++ == (uint8)*spp++; )
-                               ;
-                       if(*spp == '\0'){
-                               spoff = *pc++;
-                               spoff += *pc++ << 8;
-                               spoff += *pc++ << 16;
-                               name = (int8*)pc;
-                               sp += spoff + 8;
-                               break;
-                       }
-               }
+               f = findfunc((uint64)callpc);
+               if(f == nil)
+                       return;
+               name = f->name;
+               sp += f->frame;
                if(counter++ > 100){
                        prints("stack trace terminated\n");
                        break;
@@ -73,7 +62,7 @@ traceback(uint8 *pc, uint8 *sp, void* r15)
                sys·printpointer(callpc  - 1); // -1 to get to CALL instr.
                prints("?zi\n");
                prints("\t");
-               prints(name);
+               sys·printstring(name);
                prints("(");
                for(i = 0; i < 3; i++){
                        if(i != 0)
@@ -82,7 +71,7 @@ traceback(uint8 *pc, uint8 *sp, void* r15)
                }
                prints(", ...)\n");
                prints("\t");
-               prints(name);
+               sys·printstring(name);
                prints("(");
                for(i = 0; i < 3; i++){
                        if(i != 0)
index 13f9cacef4d68ec8777bfaba5edea376f8672280..33f2abcea48c6e2ea172ba5d1ca987ac269eec0b 100644 (file)
@@ -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
 rnd(uint32 n, uint32 m)
 {
@@ -464,7 +473,7 @@ getenv(int8 *s)
        byte *v, *bs;
 
        bs = (byte*)s;
-       len = findnull(s);
+       len = findnull(bs);
        for(i=0; i<envc; i++){
                v = envv[i];
                for(j=0; j<len; j++)
@@ -509,21 +518,10 @@ sys·envc(int32 v)
 void
 sys·argv(int32 i, string s)
 {
-       uint8* str;
-       int32 l;
-
-       if(i < 0 || i >= argc) {
+       if(i >= 0 && i < argc)
+               s = gostring(argv[i]);
+       else
                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);
 }
 
@@ -531,21 +529,10 @@ out:
 void
 sys·envv(int32 i, string s)
 {
-       uint8* str;
-       int32 l;
-
-       if(i < 0 || i >= envc) {
+       if(i >= 0 && i < envc)
+               s = gostring(envv[i]);
+       else
                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);
 }
 
@@ -742,33 +729,3 @@ algarray[3] =
        {       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);
-}
index 842ac8ed2b207b6262f8dc954172059661b71521..7ec9c7d9bb46faf04f2489e89b0f02d06be448f9 100644 (file)
@@ -19,32 +19,35 @@ typedef     uint64          uintptr;
 
 /*
  * get rid of C types
+ * the / / / forces a syntax error immediately,
+ * which will show "last name: XXunsigned".
  */
-#define        unsigned                XXunsigned
-#define        signed                  XXsigned
-#define        char                    XXchar
-#define        short                   XXshort
-#define        int                     XXint
-#define        long                    XXlong
-#define        float                   XXfloat
-#define        double                  XXdouble
+#define        unsigned                XXunsigned / / /
+#define        signed                  XXsigned / / /
+#define        char                    XXchar / / /
+#define        short                   XXshort / / /
+#define        int                     XXint / / /
+#define        long                    XXlong / / /
+#define        float                   XXfloat / / /
+#define        double                  XXdouble / / /
 
 /*
  * defined types
  */
 typedef        uint8                   bool;
 typedef        uint8                   byte;
-typedef        struct  String          *string;
+typedef        struct  Alg             Alg;
 typedef        struct  Array           Array;
-typedef        struct  Gobuf           Gobuf;
+typedef        struct  Func            Func;
 typedef        struct  G               G;
-typedef        struct  M               M;
-typedef        struct  Stktop          Stktop;
-typedef        struct  Alg             Alg;
+typedef        struct  Gobuf           Gobuf;
 typedef        struct  Lock            Lock;
-typedef        union   Note    Note;
+typedef        struct  M               M;
 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
@@ -179,6 +182,18 @@ struct     SigTab
        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
  *    you need super-goru privilege
@@ -202,7 +217,7 @@ extern      int32   maxround;
  * common functions and data
  */
 int32  strcmp(byte*, byte*);
-int32  findnull(int8*);
+int32  findnull(byte*);
 void   dump(byte*, int32);
 int32  runetochar(byte*, int32);
 int32  chartorune(uint32*, byte*);
@@ -220,10 +235,12 @@ void*     getu(void);
 void   throw(int8*);
 uint32 rnd(uint32, uint32);
 void   prints(int8*);
+byte*  mchr(byte*, byte, byte*);
 void   mcpy(byte*, byte*, uint32);
 void   mmov(byte*, byte*, uint32);
 void*  mal(uint32);
 uint32 cmpstring(string, string);
+string gostring(byte*);
 void   initsig(void);
 int32  gotraceback(void);
 void   traceback(uint8 *pc, uint8 *sp, G* gp);
@@ -243,6 +260,7 @@ void        sigaltstack(void*, void*);
 void   signalstack(byte*, int32);
 G*     malg(int32);
 void   minit(void);
+Func*  findfunc(uint64);
 
 /*
  * mutual exclusion locks.  in the uncontended case,
index fec66f8a82a9bc2630ee75f6e70df5738157719b..4dba5ad7e5d4a754b06fb650cb8490a53a345b06 100644 (file)
@@ -8,7 +8,7 @@ static  int32   empty           = 0;
 string emptystring     = (string)&empty;
 
 int32
-findnull(int8 *s)
+findnull(byte *s)
 {
        int32 l;
 
@@ -17,6 +17,19 @@ findnull(int8 *s)
        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
 sys·catstring(string s1, string s2, string s3)
 {
diff --git a/src/runtime/symtab.c b/src/runtime/symtab.c
new file mode 100644 (file)
index 0000000..734f391
--- /dev/null
@@ -0,0 +1,190 @@
+// 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;
+}