From 000ab98df684adfb030ce4a4f55869571001c406 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 27 Apr 2010 22:40:26 -0700 Subject: [PATCH] 5l, 6l, 8l, runtime: make -s binaries work 5l, 6l, 8l: change ELF header so that strip doesn't destroy binary Fixes #261. R=iant, r CC=golang-dev https://golang.org/cl/994044 --- src/cmd/5l/asm.c | 63 +++++++++++++++++++++++++++++++--------- src/cmd/5l/l.h | 4 +++ src/cmd/5l/pass.c | 26 +++++++++++++++-- src/cmd/5l/span.c | 7 +++++ src/cmd/6l/asm.c | 47 +++++++++++++++++++++++------- src/cmd/6l/l.h | 3 ++ src/cmd/6l/pass.c | 24 +++++++++++++-- src/cmd/6l/span.c | 8 +++++ src/cmd/8l/asm.c | 43 ++++++++++++++++++++------- src/cmd/8l/l.h | 4 +++ src/cmd/8l/pass.c | 24 +++++++++++++-- src/cmd/8l/span.c | 8 +++++ src/cmd/ld/elf.c | 2 +- src/cmd/ld/lib.c | 4 +++ src/cmd/ld/lib.h | 2 +- src/pkg/runtime/symtab.c | 25 +++++----------- 16 files changed, 235 insertions(+), 59 deletions(-) diff --git a/src/cmd/5l/asm.c b/src/cmd/5l/asm.c index 79050a9d02..62c2a07ad8 100644 --- a/src/cmd/5l/asm.c +++ b/src/cmd/5l/asm.c @@ -184,6 +184,7 @@ enum { ElfStrText, ElfStrData, ElfStrBss, + ElfStrGosymcounts, ElfStrGosymtab, ElfStrGopclntab, ElfStrShstrtab, @@ -224,7 +225,8 @@ doelf(void) elfstr[ElfStrText] = addstring(shstrtab, ".text"); elfstr[ElfStrData] = addstring(shstrtab, ".data"); elfstr[ElfStrBss] = addstring(shstrtab, ".bss"); - if(!debug['s']) { + if(!debug['s']) { + elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts"); elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab"); elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab"); } @@ -243,36 +245,45 @@ doelf(void) /* interpreter string */ s = lookup(".interp", 0); s->reachable = 1; - s->type = SDATA; // TODO: rodata + s->type = SELFDATA; // TODO: rodata /* dynamic symbol table - first entry all zeros */ s = lookup(".dynsym", 0); - s->type = SDATA; + s->type = SELFDATA; s->reachable = 1; s->value += ELF32SYMSIZE; /* dynamic string table */ s = lookup(".dynstr", 0); + s->type = SELFDATA; + s->reachable = 1; addstring(s, ""); dynstr = s; /* relocation table */ s = lookup(".rel", 0); s->reachable = 1; - s->type = SDATA; + s->type = SELFDATA; /* global offset table */ s = lookup(".got", 0); s->reachable = 1; - s->type = SDATA; + s->type = SELFDATA; /* got.plt - ??? */ s = lookup(".got.plt", 0); s->reachable = 1; - s->type = SDATA; + s->type = SELFDATA; + + /* hash */ + s = lookup(".hash", 0); + s->reachable = 1; + s->type = SELFDATA; /* define dynamic elf table */ s = lookup(".dynamic", 0); + s->reachable = 1; + s->type = SELFDATA; dynamic = s; /* @@ -664,7 +675,7 @@ asmb(void) if(!debug['s']) { ph = newElfPhdr(); ph->type = PT_LOAD; - ph->flags = PF_W+PF_R; + ph->flags = PF_R; ph->off = symo; ph->vaddr = symdatva; ph->paddr = symdatva; @@ -757,13 +768,19 @@ asmb(void) va = startva + fo; w = textsize; + /* + * The alignments are bigger than they really need + * to be here, but they are necessary to keep the + * arm strip from moving everything around. + */ + sh = newElfShdr(elfstr[ElfStrText]); sh->type = SHT_PROGBITS; sh->flags = SHF_ALLOC+SHF_EXECINSTR; sh->addr = va; sh->off = fo; sh->size = w; - sh->addralign = 4; + sh->addralign = ELFRESERVE; fo = rnd(fo+w, INITRND); va = rnd(va+w, INITRND); @@ -772,10 +789,10 @@ asmb(void) sh = newElfShdr(elfstr[ElfStrData]); sh->type = SHT_PROGBITS; sh->flags = SHF_WRITE+SHF_ALLOC; - sh->addr = va; - sh->off = fo; - sh->size = w; - sh->addralign = 4; + sh->addr = va + elfdatsize; + sh->off = fo + elfdatsize; + sh->size = w - elfdatsize; + sh->addralign = INITRND; fo += w; va += w; @@ -790,23 +807,38 @@ asmb(void) sh->addralign = 4; if (!debug['s']) { - fo = symo+8; + fo = symo; + w = 8; + + sh = newElfShdr(elfstr[ElfStrGosymtab]); + sh->type = SHT_PROGBITS; + sh->flags = SHF_ALLOC; + sh->off = fo; + sh->size = w; + sh->addralign = INITRND; + sh->addr = symdatva; + + fo += w; w = symsize; sh = newElfShdr(elfstr[ElfStrGosymtab]); sh->type = SHT_PROGBITS; + sh->flags = SHF_ALLOC; sh->off = fo; sh->size = w; sh->addralign = 1; + sh->addr = symdatva + 8; fo += w; w = lcsize; sh = newElfShdr(elfstr[ElfStrGopclntab]); sh->type = SHT_PROGBITS; + sh->flags = SHF_ALLOC; sh->off = fo; sh->size = w; sh->addralign = 1; + sh->addr = symdatva + 8 + lcsize; } sh = newElfShstrtab(elfstr[ElfStrShstrtab]); @@ -987,6 +1019,7 @@ asmsym(void) continue; case SDATA: + case SELFDATA: putsymb(s->name, 'D', s->value+INITDAT, s->version); continue; @@ -994,6 +1027,10 @@ asmsym(void) putsymb(s->name, 'B', s->value+INITDAT, s->version); continue; + case SFIXED: + putsymb(s->name, 'B', s->value, s->version); + continue; + case SSTRING: putsymb(s->name, 'T', s->value, s->version); continue; diff --git a/src/cmd/5l/l.h b/src/cmd/5l/l.h index 44bd923a9c..c6659cfab3 100644 --- a/src/cmd/5l/l.h +++ b/src/cmd/5l/l.h @@ -199,6 +199,9 @@ enum SIMPORT, SEXPORT, + + SFIXED, + SELFDATA, LFROM = 1<<0, LTO = 1<<1, @@ -317,6 +320,7 @@ EXTERN Prog* curp; EXTERN Prog* curtext; EXTERN Prog* datap; EXTERN int32 datsize; +EXTERN int32 elfdatsize; EXTERN char debug[128]; EXTERN Prog* edatap; EXTERN Prog* etextp; diff --git a/src/cmd/5l/pass.c b/src/cmd/5l/pass.c index fcdee69449..06b1792b4d 100644 --- a/src/cmd/5l/pass.c +++ b/src/cmd/5l/pass.c @@ -48,7 +48,7 @@ dodata(void) s->value = dtype; if(s->type == SBSS) s->type = SDATA; - if(s->type != SDATA) + if(s->type != SDATA && s->type != SELFDATA) diag("initialize non-data (%d): %s\n%P", s->type, s->name, p); v = p->from.offset + p->reg; @@ -72,6 +72,24 @@ dodata(void) s->type = SSTRING; } } + + /* + * pass 0 + * assign elf data - must be segregated from real data + */ + orig = 0; + for(i=0; ilink) { + if(!s->reachable || s->type != SELFDATA) + continue; + v = s->value; + while(v & 3) + v++; + s->size = v; + s->value = orig; + orig += v; + } + elfdatsize = orig; /* * pass 1 @@ -79,7 +97,6 @@ dodata(void) * (rational is that data segment is more easily * addressed through offset on R12) */ - orig = 0; for(i=0; ilink) { t = s->type; @@ -146,6 +163,11 @@ dodata(void) xdefine("edata", SDATA, datsize); xdefine("end", SBSS, datsize+bsssize); xdefine("etext", STEXT, 0L); + + if(debug['s']) + xdefine("symdat", SFIXED, 0); + else + xdefine("symdat", SFIXED, SYMDATVA); } void diff --git a/src/cmd/5l/span.c b/src/cmd/5l/span.c index 1272b05ecc..a97af07f93 100644 --- a/src/cmd/5l/span.c +++ b/src/cmd/5l/span.c @@ -708,6 +708,10 @@ aclass(Adr *a) s->name, TNAME); s->type = SDATA; } + if(s->type == SFIXED) { + instoffset = s->value + a->offset; + return C_LCON; + } instoffset = s->value + a->offset + INITDAT; if(s->type == STEXT || s->type == SLEAF || s->type == SUNDEF) { instoffset = s->value + a->offset; @@ -756,6 +760,9 @@ aclass(Adr *a) s->name, TNAME); s->type = SDATA; break; + case SFIXED: + instoffset = s->value + a->offset; + return C_LCON; case SUNDEF: case STEXT: case SSTRING: diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c index b83cec68fb..c104d23d4b 100644 --- a/src/cmd/6l/asm.c +++ b/src/cmd/6l/asm.c @@ -254,6 +254,7 @@ enum { ElfStrText, ElfStrData, ElfStrBss, + ElfStrGosymcounts, ElfStrGosymtab, ElfStrGopclntab, ElfStrShstrtab, @@ -296,6 +297,7 @@ doelf(void) elfstr[ElfStrData] = addstring(shstrtab, ".data"); elfstr[ElfStrBss] = addstring(shstrtab, ".bss"); if(!debug['s']) { + elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts"); elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab"); elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab"); if(debug['e']) { @@ -317,32 +319,42 @@ doelf(void) /* dynamic symbol table - first entry all zeros */ s = lookup(".dynsym", 0); - s->type = SDATA; + s->type = SELFDATA; s->reachable = 1; s->value += ELF64SYMSIZE; /* dynamic string table */ s = lookup(".dynstr", 0); + s->type = SELFDATA; + s->reachable = 1; + s->value += ELF64SYMSIZE; addstring(s, ""); dynstr = s; /* relocation table */ s = lookup(".rela", 0); s->reachable = 1; - s->type = SDATA; + s->type = SELFDATA; /* global offset table */ s = lookup(".got", 0); s->reachable = 1; - s->type = SDATA; + s->type = SELFDATA; /* got.plt - ??? */ s = lookup(".got.plt", 0); s->reachable = 1; - s->type = SDATA; + s->type = SELFDATA; + + /* hash */ + s = lookup(".hash", 0); + s->reachable = 1; + s->type = SELFDATA; /* define dynamic elf table */ s = lookup(".dynamic", 0); + s->reachable = 1; + s->type = SELFDATA; dynamic = s; /* @@ -737,7 +749,7 @@ asmb(void) if(!debug['s']) { ph = newElfPhdr(); ph->type = PT_LOAD; - ph->flags = PF_W+PF_R; + ph->flags = PF_R; ph->off = symo; ph->vaddr = symdatva; ph->paddr = symdatva; @@ -835,9 +847,9 @@ asmb(void) sh = newElfShdr(elfstr[ElfStrData]); sh->type = SHT_PROGBITS; sh->flags = SHF_WRITE+SHF_ALLOC; - sh->addr = va; - sh->off = fo; - sh->size = w; + sh->addr = va + elfdatsize; + sh->off = fo + elfdatsize; + sh->size = w - elfdatsize; sh->addralign = 8; fo += w; @@ -853,23 +865,38 @@ asmb(void) sh->addralign = 8; if (!debug['s']) { - fo = symo+8; + fo = symo; + w = 8; + + sh = newElfShdr(elfstr[ElfStrGosymcounts]); + sh->type = SHT_PROGBITS; + sh->flags = SHF_ALLOC; + sh->off = fo; + sh->size = w; + sh->addralign = 1; + sh->addr = symdatva; + + fo += w; w = symsize; sh = newElfShdr(elfstr[ElfStrGosymtab]); sh->type = SHT_PROGBITS; + sh->flags = SHF_ALLOC; sh->off = fo; sh->size = w; sh->addralign = 1; + sh->addr = symdatva + 8; fo += w; w = lcsize; sh = newElfShdr(elfstr[ElfStrGopclntab]); sh->type = SHT_PROGBITS; + sh->flags = SHF_ALLOC; sh->off = fo; sh->size = w; sh->addralign = 1; + sh->addr = symdatva + 8 + symsize; if(debug['e']) { sh = newElfShdr(elfstr[ElfStrSymtab]); @@ -1102,7 +1129,7 @@ datblk(int32 s, int32 n) for(j=l+(c-i)-1; j>=l; j--) if(buf.dbuf[j]) { print("%P\n", p); - diag("multiple initialization"); + diag("multiple initialization for %d %d", s, j); break; } } diff --git a/src/cmd/6l/l.h b/src/cmd/6l/l.h index 5f99e9a512..3db0b450ad 100644 --- a/src/cmd/6l/l.h +++ b/src/cmd/6l/l.h @@ -167,6 +167,8 @@ enum SEXPORT, SMACHO, + SFIXED, + SELFDATA, NHASH = 10007, NHUNK = 100000, @@ -314,6 +316,7 @@ EXTERN Prog* curtext; EXTERN Prog* datap; EXTERN Prog* edatap; EXTERN vlong datsize; +EXTERN vlong elfdatsize; EXTERN char debug[128]; EXTERN char literal[32]; EXTERN Prog* etextp; diff --git a/src/cmd/6l/pass.c b/src/cmd/6l/pass.c index 44dcb07100..f869429261 100644 --- a/src/cmd/6l/pass.c +++ b/src/cmd/6l/pass.c @@ -56,7 +56,7 @@ dodata(void) s->value = dtype; if(s->type == SBSS) s->type = SDATA; - if(s->type != SDATA) + if(s->type != SDATA && s->type != SELFDATA) diag("initialize non-data (%d): %s\n%P", s->type, s->name, p); t = p->from.offset + p->width; @@ -64,9 +64,24 @@ dodata(void) diag("initialize bounds (%lld): %s\n%P", s->value, s->name, p); } - /* allocate small guys */ + + /* allocate elf guys - must be segregated from real data */ datsize = 0; for(i=0; ilink) { + if(!s->reachable) + continue; + if(s->type != SELFDATA) + continue; + t = rnd(s->value, 8); + s->size = t; + s->value = datsize; + datsize += t; + } + elfdatsize = datsize; + + /* allocate small guys */ + for(i=0; ilink) { if(!s->reachable) continue; @@ -167,6 +182,11 @@ dobss(void) xdefine("data", SBSS, 0); xdefine("edata", SBSS, datsize); xdefine("end", SBSS, dynptrsize + bsssize + datsize); + + if(debug['s']) + xdefine("symdat", SFIXED, 0); + else + xdefine("symdat", SFIXED, SYMDATVA); } Prog* diff --git a/src/cmd/6l/span.c b/src/cmd/6l/span.c index 237a81fffd..15f931bcb1 100644 --- a/src/cmd/6l/span.c +++ b/src/cmd/6l/span.c @@ -234,6 +234,7 @@ genasmsym(void (*put)(char*, int, vlong, vlong, int, Sym*)) continue; case SDATA: + case SELFDATA: if(!s->reachable) continue; put(s->name, 'D', s->value+INITDAT, s->size, s->version, s->gotype); @@ -251,6 +252,10 @@ genasmsym(void (*put)(char*, int, vlong, vlong, int, Sym*)) put(s->name, 'B', s->value+INITDAT, s->size, s->version, s->gotype); continue; + case SFIXED: + put(s->name, 'B', s->value, s->size, s->version, s->gotype); + continue; + case SFILE: put(s->name, 'f', s->value, 0, s->version, 0); continue; @@ -792,6 +797,9 @@ vaddr(Adr *a) v += INITTEXT; /* TO DO */ v += s->value; break; + case SFIXED: + v += s->value; + break; case SMACHO: if(!s->reachable) sysfatal("unreachable symbol in vaddr - %s", s->name); diff --git a/src/cmd/8l/asm.c b/src/cmd/8l/asm.c index 0fca6fa0f8..797209169d 100644 --- a/src/cmd/8l/asm.c +++ b/src/cmd/8l/asm.c @@ -38,7 +38,7 @@ char linuxdynld[] = "/lib/ld-linux.so.2"; char freebsddynld[] = "/usr/libexec/ld-elf.so.1"; -uint32 symdatva = 0x99<<24; +uint32 symdatva = SYMDATVA; int32 entryvalue(void) @@ -248,6 +248,7 @@ enum { ElfStrText, ElfStrData, ElfStrBss, + ElfStrGosymcounts, ElfStrGosymtab, ElfStrGopclntab, ElfStrShstrtab, @@ -289,6 +290,7 @@ doelf(void) elfstr[ElfStrData] = addstring(shstrtab, ".data"); elfstr[ElfStrBss] = addstring(shstrtab, ".bss"); if(!debug['s']) { + elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts"); elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab"); elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab"); } @@ -307,36 +309,40 @@ doelf(void) /* interpreter string */ s = lookup(".interp", 0); s->reachable = 1; - s->type = SDATA; // TODO: rodata + s->type = SELFDATA; /* dynamic symbol table - first entry all zeros */ s = lookup(".dynsym", 0); - s->type = SDATA; + s->type = SELFDATA; s->reachable = 1; s->value += ELF32SYMSIZE; /* dynamic string table */ s = lookup(".dynstr", 0); + s->reachable = 1; + s->type = SELFDATA; addstring(s, ""); dynstr = s; /* relocation table */ s = lookup(".rel", 0); s->reachable = 1; - s->type = SDATA; + s->type = SELFDATA; /* global offset table */ s = lookup(".got", 0); s->reachable = 1; - s->type = SDATA; + s->type = SELFDATA; /* got.plt - ??? */ s = lookup(".got.plt", 0); s->reachable = 1; - s->type = SDATA; + s->type = SELFDATA; /* define dynamic elf table */ s = lookup(".dynamic", 0); + s->reachable = 1; + s->type = SELFDATA; dynamic = s; /* @@ -874,7 +880,7 @@ asmb(void) if(!debug['s'] && HEADTYPE != 8 && HEADTYPE != 11) { ph = newElfPhdr(); ph->type = PT_LOAD; - ph->flags = PF_W+PF_R; + ph->flags = PF_R; ph->off = symo; ph->vaddr = symdatva; ph->paddr = symdatva; @@ -986,9 +992,9 @@ asmb(void) sh = newElfShdr(elfstr[ElfStrData]); sh->type = SHT_PROGBITS; sh->flags = SHF_WRITE+SHF_ALLOC; - sh->addr = va; - sh->off = fo; - sh->size = w; + sh->addr = va + elfdatsize; + sh->off = fo + elfdatsize; + sh->size = w - elfdatsize; sh->addralign = 4; fo += w; @@ -1004,23 +1010,38 @@ asmb(void) sh->addralign = 4; if (!debug['s']) { - fo = symo+8; + fo = symo; + w = 8; + + sh = newElfShdr(elfstr[ElfStrGosymcounts]); + sh->type = SHT_PROGBITS; + sh->flags = SHF_ALLOC; + sh->off = fo; + sh->size = w; + sh->addralign = 1; + sh->addr = symdatva; + + fo += w; w = symsize; sh = newElfShdr(elfstr[ElfStrGosymtab]); sh->type = SHT_PROGBITS; + sh->flags = SHF_ALLOC; sh->off = fo; sh->size = w; sh->addralign = 1; + sh->addr = symdatva + 8; fo += w; w = lcsize; sh = newElfShdr(elfstr[ElfStrGopclntab]); sh->type = SHT_PROGBITS; + sh->flags = SHF_ALLOC; sh->off = fo; sh->size = w; sh->addralign = 1; + sh->addr = symdatva + 8 + symsize; } sh = newElfShstrtab(elfstr[ElfStrShstrtab]); diff --git a/src/cmd/8l/l.h b/src/cmd/8l/l.h index 5b0f307233..495c40d644 100644 --- a/src/cmd/8l/l.h +++ b/src/cmd/8l/l.h @@ -161,6 +161,9 @@ enum SMACHO, /* pointer to mach-o imported symbol */ + SFIXED, + SELFDATA, + NHASH = 10007, NHUNK = 100000, MINSIZ = 4, @@ -280,6 +283,7 @@ EXTERN Prog* curtext; EXTERN Prog* datap; EXTERN Prog* edatap; EXTERN int32 datsize; +EXTERN int32 elfdatsize; EXTERN int32 dynptrsize; EXTERN char debug[128]; EXTERN char literal[32]; diff --git a/src/cmd/8l/pass.c b/src/cmd/8l/pass.c index 9c42c3ded8..e8fda9b735 100644 --- a/src/cmd/8l/pass.c +++ b/src/cmd/8l/pass.c @@ -55,7 +55,7 @@ dodata(void) s->value = dtype; if(s->type == SBSS) s->type = SDATA; - if(s->type != SDATA) + if(s->type != SDATA && s->type != SELFDATA) diag("initialize non-data (%d): %s\n%P", s->type, s->name, p); t = p->from.offset + p->width; @@ -63,9 +63,24 @@ dodata(void) diag("initialize bounds (%ld): %s\n%P", s->value, s->name, p); } - /* allocate small guys */ + + /* allocate elf guys - must be segregated from real data */ datsize = 0; for(i=0; ilink) { + if(!s->reachable) + continue; + if(s->type != SELFDATA) + continue; + t = rnd(s->value, 4); + s->size = t; + s->value = datsize; + datsize += t; + } + elfdatsize = datsize; + + /* allocate small guys */ + for(i=0; ilink) { if(!s->reachable) continue; @@ -148,6 +163,11 @@ dodata(void) xdefine("data", SBSS, 0); xdefine("edata", SBSS, datsize); xdefine("end", SBSS, dynptrsize + bsssize + datsize); + + if(debug['s']) + xdefine("symdat", SFIXED, 0); + else + xdefine("symdat", SFIXED, SYMDATVA); } Prog* diff --git a/src/cmd/8l/span.c b/src/cmd/8l/span.c index 0245d72b9b..99ba279da0 100644 --- a/src/cmd/8l/span.c +++ b/src/cmd/8l/span.c @@ -214,6 +214,7 @@ asmsym(void) continue; case SDATA: + case SELFDATA: if(!s->reachable) continue; putsymb(s->name, 'D', s->value+INITDAT, s->version, s->gotype); @@ -231,6 +232,10 @@ asmsym(void) putsymb(s->name, 'B', s->value+INITDAT, s->version, s->gotype); continue; + case SFIXED: + putsymb(s->name, 'B', s->value, s->version, s->gotype); + continue; + case SFILE: putsymb(s->name, 'f', s->value, s->version, 0); continue; @@ -622,6 +627,9 @@ vaddr(Adr *a) sysfatal("unreachable symbol in vaddr - %s", s->name); v += INITDAT + datsize + s->value; break; + case SFIXED: + v += s->value; + break; default: if(!s->reachable) sysfatal("unreachable symbol in vaddr - %s", s->name); diff --git a/src/cmd/ld/elf.c b/src/cmd/ld/elf.c index a0bcba35a6..c5d58576dc 100644 --- a/src/cmd/ld/elf.c +++ b/src/cmd/ld/elf.c @@ -320,7 +320,7 @@ elfdynhash(int nsym) uint32 *chain, *buckets; s = lookup(".hash", 0); - s->type = SDATA; // TODO: rodata + s->type = SELFDATA; // TODO: rodata s->reachable = 1; i = nsym; diff --git a/src/cmd/ld/lib.c b/src/cmd/ld/lib.c index 3524bd1c4a..18c4255161 100644 --- a/src/cmd/ld/lib.c +++ b/src/cmd/ld/lib.c @@ -406,6 +406,10 @@ ldobj(Biobuf *f, char *pkg, int64 len, char *pn) if(n != strlen(thestring) || strncmp(line, thestring, n) != 0) { if(line) line[n] = '\0'; + if(strlen(pn) > 3 && strcmp(pn+strlen(pn)-3, ".go") == 0) { + print("%cl: input %s is not .%c file (use %cg to compile .go files)\n", thechar, pn, thechar, thechar); + errorexit(); + } diag("file not %s [%s]\n", thestring, line); return; } diff --git a/src/cmd/ld/lib.h b/src/cmd/ld/lib.h index c89322e38d..4307d2d41e 100644 --- a/src/cmd/ld/lib.h +++ b/src/cmd/ld/lib.h @@ -28,7 +28,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -// This magic number also defined in src/pkg/runtime/symtab.c in SYMCOUNTS +// Where symbol table data gets mapped into memory. #define SYMDATVA 0x99LL<<24 typedef struct Library Library; diff --git a/src/pkg/runtime/symtab.c b/src/pkg/runtime/symtab.c index b571d21eca..4707b1537b 100644 --- a/src/pkg/runtime/symtab.c +++ b/src/pkg/runtime/symtab.c @@ -17,10 +17,7 @@ #include "os.h" #include "arch.h" -// TODO(rsc): Move this *under* the text segment. -// Then define names for these addresses instead of hard-coding magic ones. -#define SYMCOUNTS ((int32*)(0x99LL<<24)) // known to 6l, 8l; see src/cmd/ld/lib.h -#define SYMDATA ((byte*)(0x99LL<<24) + 8) +extern int32 symdat[]; typedef struct Sym Sym; struct Sym @@ -39,18 +36,15 @@ walksymtab(void (*fn)(Sym*)) byte *p, *ep, *q; Sym s; - // TODO(rsc): Remove once TODO at top of file is done. - if(goos != nil && strcmp((uint8*)goos, (uint8*)"nacl") == 0) - return; - if(goos != nil && strcmp((uint8*)goos, (uint8*)"pchw") == 0) + if(symdat == nil) return; #ifdef __MINGW__ v = get_symdat_addr(); p = (byte*)v+8; #else - v = SYMCOUNTS; - p = SYMDATA; + v = symdat; + p = (byte*)(symdat+2); #endif ep = p + v[0]; while(p < ep) { @@ -248,7 +242,7 @@ splitpcln(void) Func *f, *ef; int32 *v; int32 pcquant; - + switch(thechar) { case '5': pcquant = 4; @@ -258,10 +252,7 @@ splitpcln(void) break; } - // TODO(rsc): Remove once TODO at top of file is done. - if(goos != nil && strcmp((uint8*)goos, (uint8*)"nacl") == 0) - return; - if(goos != nil && strcmp((uint8*)goos, (uint8*)"pchw") == 0) + if(symdat == nil) return; // pc/ln table bounds @@ -269,8 +260,8 @@ splitpcln(void) v = get_symdat_addr(); p = (byte*)v+8; #else - v = SYMCOUNTS; - p = SYMDATA; + v = symdat; + p = (byte*)(symdat+2); #endif p += v[0]; ep = p+v[1]; -- 2.50.0