]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/ld: remove Plan 9 symbol table
authorRuss Cox <rsc@golang.org>
Wed, 19 Feb 2014 04:41:15 +0000 (23:41 -0500)
committerRuss Cox <rsc@golang.org>
Wed, 19 Feb 2014 04:41:15 +0000 (23:41 -0500)
Update #6853

Nothing reads the Plan 9 symbol table anymore.
The last holdout was 'go tool nm', but since being rewritten in Go
it uses the standard symbol table for the binary format
(ELF, Mach-O, PE) instead.

Removing the Plan 9 symbol table saves ~15% disk space
on most binaries.

Two supporting changes included in this CL:

debug/gosym: use Go 1.2 pclntab to synthesize func-only
symbol table when there is no Plan 9 symbol table

debug/elf, debug/macho, debug/pe: ignore final EOF from ReadAt

LGTM=r
R=r, bradfitz
CC=golang-codereviews
https://golang.org/cl/65740045

src/cmd/ld/symtab.c
src/pkg/debug/elf/file.go
src/pkg/debug/gosym/pclntab.go
src/pkg/debug/gosym/symtab.go
src/pkg/debug/macho/file.go
src/pkg/debug/pe/file.go

index 0789c8a3eb4f9b96783839fc6bd37612b0fe2205..bd14d9be7a02b93d7dcb509b4037f862acd17655 100644 (file)
@@ -270,47 +270,6 @@ asmplan9sym(void)
 
 static LSym *symt;
 
-static void
-scput(int b)
-{
-       uchar *p;
-
-       symgrow(ctxt, symt, symt->size+1);
-       p = symt->p + symt->size;
-       *p = b;
-       symt->size++;
-}
-
-static void
-slputb(int32 v)
-{
-       uchar *p;
-
-       symgrow(ctxt, symt, symt->size+4);
-       p = symt->p + symt->size;
-       *p++ = v>>24;
-       *p++ = v>>16;
-       *p++ = v>>8;
-       *p = v;
-       symt->size += 4;
-}
-
-static void
-slputl(int32 v)
-{
-       uchar *p;
-
-       symgrow(ctxt, symt, symt->size+4);
-       p = symt->p + symt->size;
-       *p++ = v;
-       *p++ = v>>8;
-       *p++ = v>>16;
-       *p = v>>24;
-       symt->size += 4;
-}
-
-static void (*slput)(int32);
-
 void
 wputl(ushort w)
 {
@@ -357,108 +316,6 @@ vputl(uint64 v)
        lputl(v >> 32);
 }
 
-// Emit symbol table entry.
-// The table format is described at the top of ../../pkg/runtime/symtab.c.
-void
-putsymb(LSym *s, char *name, int t, vlong v, vlong size, int ver, LSym *typ)
-{
-       int i, f, c;
-       vlong v1;
-       Reloc *rel;
-
-       USED(size);
-
-       // type byte
-       if('A' <= t && t <= 'Z')
-               c = t - 'A' + (ver ? 26 : 0);
-       else if('a' <= t && t <= 'z')
-               c = t - 'a' + 26;
-       else {
-               diag("invalid symbol table type %c", t);
-               errorexit();
-               return;
-       }
-       
-       if(s != nil)
-               c |= 0x40; // wide value
-       if(typ != nil)
-               c |= 0x80; // has go type
-       scput(c);
-
-       // value
-       if(s != nil) {
-               // full width
-               rel = addrel(symt);
-               rel->siz = PtrSize;
-               rel->sym = s;
-               rel->type = D_ADDR;
-               rel->off = symt->size;
-               if(PtrSize == 8)
-                       slput(0);
-               slput(0);
-       } else {
-               // varint
-               if(v < 0) {
-                       diag("negative value in symbol table: %s %lld", name, v);
-                       errorexit();
-               }
-               v1 = v;
-               while(v1 >= 0x80) {
-                       scput(v1 | 0x80);
-                       v1 >>= 7;
-               }
-               scput(v1);
-       }
-
-       // go type if present
-       if(typ != nil) {
-               if(!typ->reachable)
-                       diag("unreachable type %s", typ->name);
-               rel = addrel(symt);
-               rel->siz = PtrSize;
-               rel->sym = typ;
-               rel->type = D_ADDR;
-               rel->off = symt->size;
-               if(PtrSize == 8)
-                       slput(0);
-               slput(0);
-       }
-       
-       // name 
-       if(t == 'f')
-               name++;
-
-       if(t == 'Z' || t == 'z') {
-               scput(name[0]);
-               for(i=1; name[i] != 0 || name[i+1] != 0; i += 2) {
-                       scput(name[i]);
-                       scput(name[i+1]);
-               }
-               scput(0);
-               scput(0);
-       } else {
-               for(i=0; name[i]; i++)
-                       scput(name[i]);
-               scput(0);
-       }
-
-       if(debug['n']) {
-               if(t == 'z' || t == 'Z') {
-                       Bprint(&bso, "%c %.8llux ", t, v);
-                       for(i=1; name[i] != 0 || name[i+1] != 0; i+=2) {
-                               f = ((name[i]&0xff) << 8) | (name[i+1]&0xff);
-                               Bprint(&bso, "/%x", f);
-                       }
-                       Bprint(&bso, "\n");
-                       return;
-               }
-               if(ver)
-                       Bprint(&bso, "%c %.8llux %s<%d> %s\n", t, v, name, ver, typ ? typ->name : "");
-               else
-                       Bprint(&bso, "%c %.8llux %s %s\n", t, v, name, typ ? typ->name : "");
-       }
-}
-
 void
 symtab(void)
 {
@@ -553,31 +410,4 @@ symtab(void)
                        s->outer = symgofunc;
                }
        }
-
-       if(debug['s'])
-               return;
-
-       switch(thechar) {
-       default:
-               diag("unknown architecture %c", thechar);
-               errorexit();
-       case '5':
-       case '6':
-       case '8':
-               // little-endian symbol table
-               slput = slputl;
-               break;
-       case 'v':
-               // big-endian symbol table
-               slput = slputb;
-               break;
-       }
-       // new symbol table header.
-       slput(0xfffffffd);
-       scput(0);
-       scput(0);
-       scput(0);
-       scput(PtrSize);
-
-       genasmsym(putsymb);
 }
index a406170996884ad933d6c1498a0e4664aa8ff73c..2840f07674a3678d63cee68b8bcd155b577565a0 100644 (file)
@@ -76,6 +76,9 @@ type Section struct {
 func (s *Section) Data() ([]byte, error) {
        dat := make([]byte, s.sr.Size())
        n, err := s.sr.ReadAt(dat, 0)
+       if n == len(dat) {
+               err = nil
+       }
        return dat[0:n], err
 }
 
index 3e6a8046b3e35e45beb591b747532ba92a6673d8..6620aefb053ceab0bb20b4a8cd5900adab4e091c 100644 (file)
@@ -196,6 +196,33 @@ func (t *LineTable) go12Init() {
        t.go12 = 1 // so far so good
 }
 
+// go12Funcs returns a slice of Funcs derived from the Go 1.2 pcln table.
+func (t *LineTable) go12Funcs() []Func {
+       // Assume it is malformed and return nil on error.
+       defer func() {
+               recover()
+       }()
+
+       n := len(t.functab) / int(t.ptrsize) / 2
+       funcs := make([]Func, n)
+       for i := range funcs {
+               f := &funcs[i]
+               f.Entry = uint64(t.uintptr(t.functab[2*i*int(t.ptrsize):]))
+               f.End = uint64(t.uintptr(t.functab[(2*i+2)*int(t.ptrsize):]))
+               info := t.Data[t.uintptr(t.functab[(2*i+1)*int(t.ptrsize):]):]
+               f.LineTable = t
+               f.FrameSize = int(t.binary.Uint32(info[t.ptrsize+2*4:]))
+               f.Sym = &Sym{
+                       Value:  f.Entry,
+                       Type:   'T',
+                       Name:   t.string(t.binary.Uint32(info[t.ptrsize:])),
+                       GoType: 0,
+                       Func:   f,
+               }
+       }
+       return funcs
+}
+
 // findFunc returns the func corresponding to the given program counter.
 func (t *LineTable) findFunc(pc uint64) []byte {
        if pc < t.uintptr(t.functab) || pc >= t.uintptr(t.functab[len(t.functab)-int(t.ptrsize):]) {
index 9ab05bac2f70af17e9edb7417956eb56e196f8df..3864e3cb4fa8ff81060e470a5bf4fb11af067f65 100644 (file)
@@ -129,6 +129,9 @@ var (
 )
 
 func walksymtab(data []byte, fn func(sym) error) error {
+       if len(data) == 0 { // missing symtab is okay
+               return nil
+       }
        var order binary.ByteOrder = binary.BigEndian
        newTable := false
        switch {
@@ -455,6 +458,10 @@ func NewTable(symtab []byte, pcln *LineTable) (*Table, error) {
                        i = end - 1 // loop will i++
                }
        }
+
+       if t.go12line != nil && nf == 0 {
+               t.Funcs = t.go12line.go12Funcs()
+       }
        if obj != nil {
                obj.Funcs = t.Funcs[lastf:]
        }
index c799fa49df3f8d9611e4763b0165546e0d694aa6..2b19f7f658fcf617fc95f784c42628c8e86b43b9 100644 (file)
@@ -74,6 +74,9 @@ type Segment struct {
 func (s *Segment) Data() ([]byte, error) {
        dat := make([]byte, s.sr.Size())
        n, err := s.sr.ReadAt(dat, 0)
+       if n == len(dat) {
+               err = nil
+       }
        return dat[0:n], err
 }
 
@@ -109,6 +112,9 @@ type Section struct {
 func (s *Section) Data() ([]byte, error) {
        dat := make([]byte, s.sr.Size())
        n, err := s.sr.ReadAt(dat, 0)
+       if n == len(dat) {
+               err = nil
+       }
        return dat[0:n], err
 }
 
index a2859bf370372a7d6dc9ae639584c5ef8838da77..d0005bacf383ee9e6ff4107092ba07e3827eb184 100644 (file)
@@ -72,6 +72,9 @@ type ImportDirectory struct {
 func (s *Section) Data() ([]byte, error) {
        dat := make([]byte, s.sr.Size())
        n, err := s.sr.ReadAt(dat, 0)
+       if n == len(dat) {
+               err = nil
+       }
        return dat[0:n], err
 }