1
0
mirror of https://github.com/golang/go synced 2024-11-22 07:34:40 -07:00

5l, 6l, 8l: omit symbols for type, string, go.string

Much of the bulk of Go binaries is the symbol tables,
which give a name to every C string, Go string,
and reflection type symbol.  These names are not worth
much other than seeing what's where in a binary.

This CL deletes all those names from the symbol table,
instead aggregating the symbols into contiguous blocks
and giving them the names "string.*", "go.string.*", and "type.*".

Before:
$ 6nm $(which godoc.old) | sort | grep ' string\.' | tail -10
  59eda4 D string."aa87ca22be8b05378eb1c71...
  59ee08 D string."b3312fa7e23ee7e4988e056...
  59ee6c D string."func(*token.FileSet, st...
  59eed0 D string."func(io.Writer, []uint8...
  59ef34 D string."func(*tls.Config, *tls....
  59ef98 D string."func(*bool, **template....
  59effc D string."method(p *printer.print...
  59f060 D string."method(S *scanner.Scann...
  59f12c D string."func(*struct { begin in...
  59f194 D string."method(ka *tls.ecdheRSA...
$

After:
$ 6nm $(which godoc) | sort | grep ' string\.' | tail -10
  5e6a30 D string.*
$

Those names in the "Before" are truncated for the CL.
In the real binary they are the complete string, up to
a certain length, or else a unique identifier.
The same applies to the type and go.string symbols.

Removing the names cuts godoc by more than half:

-rwxr-xr-x 1 rsc rsc 9153405 2011-03-07 23:19 godoc.old
-rwxr-xr-x 1 rsc rsc 4290071 2011-03-07 23:19 godoc

For what it's worth, only 80% of what's left gets loaded
into memory; the other 20% is dwarf debugging information
only ever accessed by gdb:

-rwxr-xr-x 1 rsc rsc 3397787 2011-03-07 23:19 godoc.nodwarf

R=r, cw
CC=golang-dev
https://golang.org/cl/4245072
This commit is contained in:
Russ Cox 2011-03-08 14:14:28 -05:00
parent 9267b0ddf1
commit 7a09a88274
11 changed files with 87 additions and 66 deletions

View File

@ -1978,6 +1978,8 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
for(h=0; h<NHASH; h++) { for(h=0; h<NHASH; h++) {
for(s=hash[h]; s!=S; s=s->hash) { for(s=hash[h]; s!=S; s=s->hash) {
if(s->hide)
continue;
switch(s->type) { switch(s->type) {
case SCONST: case SCONST:
case SRODATA: case SRODATA:

View File

@ -136,6 +136,7 @@ struct Sym
uchar dynexport; uchar dynexport;
uchar leaf; uchar leaf;
uchar stkcheck; uchar stkcheck;
uchar hide;
int32 dynid; int32 dynid;
int32 plt; int32 plt;
int32 got; int32 got;
@ -202,22 +203,6 @@ struct Count
enum enum
{ {
Sxxx,
/* order here is order in output file */
STEXT = 1,
SRODATA,
SELFDATA,
SDATA,
SBSS,
SXREF,
SFILE,
SCONST,
SDYNIMPORT,
SSUB = 1<<8,
LFROM = 1<<0, LFROM = 1<<0,
LTO = 1<<1, LTO = 1<<1,
LPOOL = 1<<2, LPOOL = 1<<2,

View File

@ -1105,12 +1105,17 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
for(h=0; h<NHASH; h++) { for(h=0; h<NHASH; h++) {
for(s=hash[h]; s!=S; s=s->hash) { for(s=hash[h]; s!=S; s=s->hash) {
if(s->hide)
continue;
switch(s->type&~SSUB) { switch(s->type&~SSUB) {
case SCONST: case SCONST:
case SRODATA: case SRODATA:
case SDATA: case SDATA:
case SELFDATA: case SELFDATA:
case SMACHOGOT: case SMACHOGOT:
case STYPE:
case SSTRING:
case SGOSTRING:
case SWINDOWS: case SWINDOWS:
if(!s->reachable) if(!s->reachable)
continue; continue;

View File

@ -132,6 +132,7 @@ struct Sym
uchar dynexport; uchar dynexport;
uchar special; uchar special;
uchar stkcheck; uchar stkcheck;
uchar hide;
int32 dynid; int32 dynid;
int32 sig; int32 sig;
int32 plt; int32 plt;
@ -177,28 +178,6 @@ struct Movtab
enum enum
{ {
Sxxx,
/* order here is order in output file */
STEXT = 1,
SELFDATA,
SMACHOPLT,
SRODATA,
SDATA,
SMACHOGOT,
SWINDOWS,
SBSS,
SXREF,
SMACHODYNSTR,
SMACHODYNSYM,
SMACHOINDIRECTPLT,
SMACHOINDIRECTGOT,
SFILE,
SCONST,
SDYNIMPORT,
SSUB = 1<<8,
NHASH = 10007, NHASH = 10007,
MINSIZ = 8, MINSIZ = 8,
STRINGSZ = 200, STRINGSZ = 200,

View File

@ -1158,6 +1158,8 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
for(h=0; h<NHASH; h++) { for(h=0; h<NHASH; h++) {
for(s=hash[h]; s!=S; s=s->hash) { for(s=hash[h]; s!=S; s=s->hash) {
if(s->hide)
continue;
switch(s->type&~SSUB) { switch(s->type&~SSUB) {
case SCONST: case SCONST:
case SRODATA: case SRODATA:

View File

@ -131,6 +131,7 @@ struct Sym
uchar dynexport; uchar dynexport;
uchar special; uchar special;
uchar stkcheck; uchar stkcheck;
uchar hide;
int32 value; int32 value;
int32 size; int32 size;
int32 sig; int32 sig;
@ -168,30 +169,6 @@ struct Optab
enum enum
{ {
Sxxx,
/* order here is order in output file */
STEXT,
SELFDATA,
SMACHOPLT,
SRODATA,
SDATA,
SMACHO, /* Mach-O __nl_symbol_ptr */
SMACHOGOT,
SWINDOWS,
SBSS,
SXREF,
SMACHODYNSTR,
SMACHODYNSYM,
SMACHOINDIRECTPLT,
SMACHOINDIRECTGOT,
SFILE,
SCONST,
SDYNIMPORT,
SSUB = 1<<8, /* sub-symbol, linked from parent via ->sub list */
NHASH = 10007, NHASH = 10007,
MINSIZ = 4, MINSIZ = 4,
STRINGSZ = 200, STRINGSZ = 200,

View File

@ -732,6 +732,7 @@ dodata(void)
last = nil; last = nil;
datap = nil; datap = nil;
for(h=0; h<NHASH; h++) { for(h=0; h<NHASH; h++) {
for(s=hash[h]; s!=S; s=s->hash){ for(s=hash[h]; s!=S; s=s->hash){
if(!s->reachable || s->special) if(!s->reachable || s->special)
@ -786,7 +787,7 @@ dodata(void)
s = datap; s = datap;
for(; s != nil && s->type < SDATA; s = s->next) { for(; s != nil && s->type < SDATA; s = s->next) {
s->type = SRODATA; s->type = SRODATA;
t = rnd(s->size, 4); t = rnd(s->size, PtrSize);
s->size = t; s->size = t;
s->value = datsize; s->value = datsize;
datsize += t; datsize += t;

View File

@ -1467,7 +1467,7 @@ defdwsymb(Sym* sym, char *s, int t, vlong v, vlong size, int ver, Sym *gotype)
if (strncmp(s, "type._.", 7) == 0) if (strncmp(s, "type._.", 7) == 0)
return; return;
if (strncmp(s, "type.", 5) == 0) { if (strncmp(s, "type.", 5) == 0 && strcmp(s, "type.*") != 0) {
defgotype(sym); defgotype(sym);
return; return;
} }

View File

@ -662,6 +662,7 @@ deadcode(void)
if(strncmp(s->name, "weak.", 5) == 0) { if(strncmp(s->name, "weak.", 5) == 0) {
s->special = 1; // do not lay out in data segment s->special = 1; // do not lay out in data segment
s->reachable = 1; s->reachable = 1;
s->hide = 1;
} }
} }

View File

@ -28,8 +28,35 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
// Where symbol table data gets mapped into memory. enum
#define SYMDATVA 0x99LL<<24 {
Sxxx,
/* order here is order in output file */
STEXT,
SELFDATA,
SMACHOPLT,
STYPE,
SSTRING,
SGOSTRING,
SRODATA,
SDATA,
SMACHO, /* Mach-O __nl_symbol_ptr */
SMACHOGOT,
SWINDOWS,
SBSS,
SXREF,
SMACHODYNSTR,
SMACHODYNSYM,
SMACHOINDIRECTPLT,
SMACHOINDIRECTGOT,
SFILE,
SCONST,
SDYNIMPORT,
SSUB = 1<<8, /* sub-symbol, linked from parent via ->sub list */
};
typedef struct Library Library; typedef struct Library Library;
struct Library struct Library

View File

@ -340,6 +340,9 @@ putsymb(Sym *s, char *name, int t, vlong v, vlong size, int ver, Sym *typ)
void void
symtab(void) symtab(void)
{ {
int32 h;
Sym *s;
// Define these so that they'll get put into the symbol table. // Define these so that they'll get put into the symbol table.
// data.c:/^address will provide the actual values. // data.c:/^address will provide the actual values.
xdefine("text", STEXT, 0); xdefine("text", STEXT, 0);
@ -352,10 +355,49 @@ symtab(void)
xdefine("epclntab", SRODATA, 0); xdefine("epclntab", SRODATA, 0);
xdefine("esymtab", SRODATA, 0); xdefine("esymtab", SRODATA, 0);
// pseudo-symbols to mark locations of type, string, and go string data.
s = lookup("type.*", 0);
s->type = STYPE;
s->size = 0;
s->reachable = 1;
s = lookup("string.*", 0);
s->type = SSTRING;
s->size = 0;
s->reachable = 1;
s = lookup("go.string.*", 0);
s->type = SGOSTRING;
s->size = 0;
s->reachable = 1;
symt = lookup("symtab", 0); symt = lookup("symtab", 0);
symt->type = SRODATA; symt->type = SRODATA;
symt->size = 0; symt->size = 0;
symt->reachable = 1; symt->reachable = 1;
// assign specific types so that they sort together.
// within a type they sort by size, so the .* symbols
// just defined above will be first.
// hide the specific symbols.
for(h=0; h<NHASH; h++) {
for(s=hash[h]; s!=S; s=s->hash){
if(!s->reachable || s->special || s->type != SRODATA)
continue;
if(strncmp(s->name, "type.", 5) == 0) {
s->type = STYPE;
s->hide = 1;
}
if(strncmp(s->name, "string.", 7) == 0) {
s->type = SSTRING;
s->hide = 1;
}
if(strncmp(s->name, "go.string.", 10) == 0) {
s->type = SGOSTRING;
s->hide = 1;
}
}
}
genasmsym(putsymb); genasmsym(putsymb);
} }