summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-02-18 23:41:15 -0500
committerRuss Cox <rsc@golang.org>2014-02-18 23:41:15 -0500
commit72d7979c6f00dbe37b2d2049a35c8913e337ee13 (patch)
tree05124829aab829635266f3a488c71dad40038341
parent812d3df2323c3c5b1e2389ea954587793799e932 (diff)
downloadgo-72d7979c6f00dbe37b2d2049a35c8913e337ee13.tar.gz
cmd/ld: remove Plan 9 symbol table
Update issue 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://codereview.appspot.com/65740045
-rw-r--r--src/cmd/ld/symtab.c170
-rw-r--r--src/pkg/debug/elf/file.go3
-rw-r--r--src/pkg/debug/gosym/pclntab.go27
-rw-r--r--src/pkg/debug/gosym/symtab.go7
-rw-r--r--src/pkg/debug/macho/file.go6
-rw-r--r--src/pkg/debug/pe/file.go3
6 files changed, 46 insertions, 170 deletions
diff --git a/src/cmd/ld/symtab.c b/src/cmd/ld/symtab.c
index 0789c8a3e..bd14d9be7 100644
--- a/src/cmd/ld/symtab.c
+++ b/src/cmd/ld/symtab.c
@@ -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);
}
diff --git a/src/pkg/debug/elf/file.go b/src/pkg/debug/elf/file.go
index a40617099..2840f0767 100644
--- a/src/pkg/debug/elf/file.go
+++ b/src/pkg/debug/elf/file.go
@@ -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
}
diff --git a/src/pkg/debug/gosym/pclntab.go b/src/pkg/debug/gosym/pclntab.go
index 3e6a8046b..6620aefb0 100644
--- a/src/pkg/debug/gosym/pclntab.go
+++ b/src/pkg/debug/gosym/pclntab.go
@@ -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):]) {
diff --git a/src/pkg/debug/gosym/symtab.go b/src/pkg/debug/gosym/symtab.go
index 9ab05bac2..3864e3cb4 100644
--- a/src/pkg/debug/gosym/symtab.go
+++ b/src/pkg/debug/gosym/symtab.go
@@ -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:]
}
diff --git a/src/pkg/debug/macho/file.go b/src/pkg/debug/macho/file.go
index c799fa49d..2b19f7f65 100644
--- a/src/pkg/debug/macho/file.go
+++ b/src/pkg/debug/macho/file.go
@@ -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
}
diff --git a/src/pkg/debug/pe/file.go b/src/pkg/debug/pe/file.go
index a2859bf37..d0005bacf 100644
--- a/src/pkg/debug/pe/file.go
+++ b/src/pkg/debug/pe/file.go
@@ -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
}