Skip to content

Commit

Permalink
cmd/ld: remove Plan 9 symbol table
Browse files Browse the repository at this point in the history
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
  • Loading branch information
rsc committed Feb 19, 2014
1 parent cce25c8 commit 964f6d3
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 170 deletions.
170 changes: 0 additions & 170 deletions src/cmd/ld/symtab.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
}
3 changes: 3 additions & 0 deletions src/pkg/debug/elf/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
27 changes: 27 additions & 0 deletions src/pkg/debug/gosym/pclntab.go
Original file line number Diff line number Diff line change
Expand Up @@ -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):]) {
Expand Down
7 changes: 7 additions & 0 deletions src/pkg/debug/gosym/symtab.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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:]
}
Expand Down
6 changes: 6 additions & 0 deletions src/pkg/debug/macho/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down Expand Up @@ -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
}

Expand Down
3 changes: 3 additions & 0 deletions src/pkg/debug/pe/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down

0 comments on commit 964f6d3

Please sign in to comment.