1
0
mirror of https://github.com/golang/go synced 2024-11-14 08:10:22 -07:00

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
This commit is contained in:
Russ Cox 2010-04-27 22:40:26 -07:00
parent f9d33ee6cb
commit 000ab98df6
16 changed files with 235 additions and 59 deletions

View File

@ -184,6 +184,7 @@ enum {
ElfStrText, ElfStrText,
ElfStrData, ElfStrData,
ElfStrBss, ElfStrBss,
ElfStrGosymcounts,
ElfStrGosymtab, ElfStrGosymtab,
ElfStrGopclntab, ElfStrGopclntab,
ElfStrShstrtab, ElfStrShstrtab,
@ -225,6 +226,7 @@ doelf(void)
elfstr[ElfStrData] = addstring(shstrtab, ".data"); elfstr[ElfStrData] = addstring(shstrtab, ".data");
elfstr[ElfStrBss] = addstring(shstrtab, ".bss"); elfstr[ElfStrBss] = addstring(shstrtab, ".bss");
if(!debug['s']) { if(!debug['s']) {
elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts");
elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab"); elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab");
elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab"); elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab");
} }
@ -243,36 +245,45 @@ doelf(void)
/* interpreter string */ /* interpreter string */
s = lookup(".interp", 0); s = lookup(".interp", 0);
s->reachable = 1; s->reachable = 1;
s->type = SDATA; // TODO: rodata s->type = SELFDATA; // TODO: rodata
/* dynamic symbol table - first entry all zeros */ /* dynamic symbol table - first entry all zeros */
s = lookup(".dynsym", 0); s = lookup(".dynsym", 0);
s->type = SDATA; s->type = SELFDATA;
s->reachable = 1; s->reachable = 1;
s->value += ELF32SYMSIZE; s->value += ELF32SYMSIZE;
/* dynamic string table */ /* dynamic string table */
s = lookup(".dynstr", 0); s = lookup(".dynstr", 0);
s->type = SELFDATA;
s->reachable = 1;
addstring(s, ""); addstring(s, "");
dynstr = s; dynstr = s;
/* relocation table */ /* relocation table */
s = lookup(".rel", 0); s = lookup(".rel", 0);
s->reachable = 1; s->reachable = 1;
s->type = SDATA; s->type = SELFDATA;
/* global offset table */ /* global offset table */
s = lookup(".got", 0); s = lookup(".got", 0);
s->reachable = 1; s->reachable = 1;
s->type = SDATA; s->type = SELFDATA;
/* got.plt - ??? */ /* got.plt - ??? */
s = lookup(".got.plt", 0); s = lookup(".got.plt", 0);
s->reachable = 1; s->reachable = 1;
s->type = SDATA; s->type = SELFDATA;
/* hash */
s = lookup(".hash", 0);
s->reachable = 1;
s->type = SELFDATA;
/* define dynamic elf table */ /* define dynamic elf table */
s = lookup(".dynamic", 0); s = lookup(".dynamic", 0);
s->reachable = 1;
s->type = SELFDATA;
dynamic = s; dynamic = s;
/* /*
@ -664,7 +675,7 @@ asmb(void)
if(!debug['s']) { if(!debug['s']) {
ph = newElfPhdr(); ph = newElfPhdr();
ph->type = PT_LOAD; ph->type = PT_LOAD;
ph->flags = PF_W+PF_R; ph->flags = PF_R;
ph->off = symo; ph->off = symo;
ph->vaddr = symdatva; ph->vaddr = symdatva;
ph->paddr = symdatva; ph->paddr = symdatva;
@ -757,13 +768,19 @@ asmb(void)
va = startva + fo; va = startva + fo;
w = textsize; 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 = newElfShdr(elfstr[ElfStrText]);
sh->type = SHT_PROGBITS; sh->type = SHT_PROGBITS;
sh->flags = SHF_ALLOC+SHF_EXECINSTR; sh->flags = SHF_ALLOC+SHF_EXECINSTR;
sh->addr = va; sh->addr = va;
sh->off = fo; sh->off = fo;
sh->size = w; sh->size = w;
sh->addralign = 4; sh->addralign = ELFRESERVE;
fo = rnd(fo+w, INITRND); fo = rnd(fo+w, INITRND);
va = rnd(va+w, INITRND); va = rnd(va+w, INITRND);
@ -772,10 +789,10 @@ asmb(void)
sh = newElfShdr(elfstr[ElfStrData]); sh = newElfShdr(elfstr[ElfStrData]);
sh->type = SHT_PROGBITS; sh->type = SHT_PROGBITS;
sh->flags = SHF_WRITE+SHF_ALLOC; sh->flags = SHF_WRITE+SHF_ALLOC;
sh->addr = va; sh->addr = va + elfdatsize;
sh->off = fo; sh->off = fo + elfdatsize;
sh->size = w; sh->size = w - elfdatsize;
sh->addralign = 4; sh->addralign = INITRND;
fo += w; fo += w;
va += w; va += w;
@ -790,23 +807,38 @@ asmb(void)
sh->addralign = 4; sh->addralign = 4;
if (!debug['s']) { 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; w = symsize;
sh = newElfShdr(elfstr[ElfStrGosymtab]); sh = newElfShdr(elfstr[ElfStrGosymtab]);
sh->type = SHT_PROGBITS; sh->type = SHT_PROGBITS;
sh->flags = SHF_ALLOC;
sh->off = fo; sh->off = fo;
sh->size = w; sh->size = w;
sh->addralign = 1; sh->addralign = 1;
sh->addr = symdatva + 8;
fo += w; fo += w;
w = lcsize; w = lcsize;
sh = newElfShdr(elfstr[ElfStrGopclntab]); sh = newElfShdr(elfstr[ElfStrGopclntab]);
sh->type = SHT_PROGBITS; sh->type = SHT_PROGBITS;
sh->flags = SHF_ALLOC;
sh->off = fo; sh->off = fo;
sh->size = w; sh->size = w;
sh->addralign = 1; sh->addralign = 1;
sh->addr = symdatva + 8 + lcsize;
} }
sh = newElfShstrtab(elfstr[ElfStrShstrtab]); sh = newElfShstrtab(elfstr[ElfStrShstrtab]);
@ -987,6 +1019,7 @@ asmsym(void)
continue; continue;
case SDATA: case SDATA:
case SELFDATA:
putsymb(s->name, 'D', s->value+INITDAT, s->version); putsymb(s->name, 'D', s->value+INITDAT, s->version);
continue; continue;
@ -994,6 +1027,10 @@ asmsym(void)
putsymb(s->name, 'B', s->value+INITDAT, s->version); putsymb(s->name, 'B', s->value+INITDAT, s->version);
continue; continue;
case SFIXED:
putsymb(s->name, 'B', s->value, s->version);
continue;
case SSTRING: case SSTRING:
putsymb(s->name, 'T', s->value, s->version); putsymb(s->name, 'T', s->value, s->version);
continue; continue;

View File

@ -200,6 +200,9 @@ enum
SIMPORT, SIMPORT,
SEXPORT, SEXPORT,
SFIXED,
SELFDATA,
LFROM = 1<<0, LFROM = 1<<0,
LTO = 1<<1, LTO = 1<<1,
LPOOL = 1<<2, LPOOL = 1<<2,
@ -317,6 +320,7 @@ EXTERN Prog* curp;
EXTERN Prog* curtext; EXTERN Prog* curtext;
EXTERN Prog* datap; EXTERN Prog* datap;
EXTERN int32 datsize; EXTERN int32 datsize;
EXTERN int32 elfdatsize;
EXTERN char debug[128]; EXTERN char debug[128];
EXTERN Prog* edatap; EXTERN Prog* edatap;
EXTERN Prog* etextp; EXTERN Prog* etextp;

View File

@ -48,7 +48,7 @@ dodata(void)
s->value = dtype; s->value = dtype;
if(s->type == SBSS) if(s->type == SBSS)
s->type = SDATA; s->type = SDATA;
if(s->type != SDATA) if(s->type != SDATA && s->type != SELFDATA)
diag("initialize non-data (%d): %s\n%P", diag("initialize non-data (%d): %s\n%P",
s->type, s->name, p); s->type, s->name, p);
v = p->from.offset + p->reg; v = p->from.offset + p->reg;
@ -73,13 +73,30 @@ dodata(void)
} }
} }
/*
* pass 0
* assign elf data - must be segregated from real data
*/
orig = 0;
for(i=0; i<NHASH; i++)
for(s = hash[i]; s != S; s = s->link) {
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 * pass 1
* assign 'small' variables to data segment * assign 'small' variables to data segment
* (rational is that data segment is more easily * (rational is that data segment is more easily
* addressed through offset on R12) * addressed through offset on R12)
*/ */
orig = 0;
for(i=0; i<NHASH; i++) for(i=0; i<NHASH; i++)
for(s = hash[i]; s != S; s = s->link) { for(s = hash[i]; s != S; s = s->link) {
t = s->type; t = s->type;
@ -146,6 +163,11 @@ dodata(void)
xdefine("edata", SDATA, datsize); xdefine("edata", SDATA, datsize);
xdefine("end", SBSS, datsize+bsssize); xdefine("end", SBSS, datsize+bsssize);
xdefine("etext", STEXT, 0L); xdefine("etext", STEXT, 0L);
if(debug['s'])
xdefine("symdat", SFIXED, 0);
else
xdefine("symdat", SFIXED, SYMDATVA);
} }
void void

View File

@ -708,6 +708,10 @@ aclass(Adr *a)
s->name, TNAME); s->name, TNAME);
s->type = SDATA; s->type = SDATA;
} }
if(s->type == SFIXED) {
instoffset = s->value + a->offset;
return C_LCON;
}
instoffset = s->value + a->offset + INITDAT; instoffset = s->value + a->offset + INITDAT;
if(s->type == STEXT || s->type == SLEAF || s->type == SUNDEF) { if(s->type == STEXT || s->type == SLEAF || s->type == SUNDEF) {
instoffset = s->value + a->offset; instoffset = s->value + a->offset;
@ -756,6 +760,9 @@ aclass(Adr *a)
s->name, TNAME); s->name, TNAME);
s->type = SDATA; s->type = SDATA;
break; break;
case SFIXED:
instoffset = s->value + a->offset;
return C_LCON;
case SUNDEF: case SUNDEF:
case STEXT: case STEXT:
case SSTRING: case SSTRING:

View File

@ -254,6 +254,7 @@ enum {
ElfStrText, ElfStrText,
ElfStrData, ElfStrData,
ElfStrBss, ElfStrBss,
ElfStrGosymcounts,
ElfStrGosymtab, ElfStrGosymtab,
ElfStrGopclntab, ElfStrGopclntab,
ElfStrShstrtab, ElfStrShstrtab,
@ -296,6 +297,7 @@ doelf(void)
elfstr[ElfStrData] = addstring(shstrtab, ".data"); elfstr[ElfStrData] = addstring(shstrtab, ".data");
elfstr[ElfStrBss] = addstring(shstrtab, ".bss"); elfstr[ElfStrBss] = addstring(shstrtab, ".bss");
if(!debug['s']) { if(!debug['s']) {
elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts");
elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab"); elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab");
elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab"); elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab");
if(debug['e']) { if(debug['e']) {
@ -317,32 +319,42 @@ doelf(void)
/* dynamic symbol table - first entry all zeros */ /* dynamic symbol table - first entry all zeros */
s = lookup(".dynsym", 0); s = lookup(".dynsym", 0);
s->type = SDATA; s->type = SELFDATA;
s->reachable = 1; s->reachable = 1;
s->value += ELF64SYMSIZE; s->value += ELF64SYMSIZE;
/* dynamic string table */ /* dynamic string table */
s = lookup(".dynstr", 0); s = lookup(".dynstr", 0);
s->type = SELFDATA;
s->reachable = 1;
s->value += ELF64SYMSIZE;
addstring(s, ""); addstring(s, "");
dynstr = s; dynstr = s;
/* relocation table */ /* relocation table */
s = lookup(".rela", 0); s = lookup(".rela", 0);
s->reachable = 1; s->reachable = 1;
s->type = SDATA; s->type = SELFDATA;
/* global offset table */ /* global offset table */
s = lookup(".got", 0); s = lookup(".got", 0);
s->reachable = 1; s->reachable = 1;
s->type = SDATA; s->type = SELFDATA;
/* got.plt - ??? */ /* got.plt - ??? */
s = lookup(".got.plt", 0); s = lookup(".got.plt", 0);
s->reachable = 1; s->reachable = 1;
s->type = SDATA; s->type = SELFDATA;
/* hash */
s = lookup(".hash", 0);
s->reachable = 1;
s->type = SELFDATA;
/* define dynamic elf table */ /* define dynamic elf table */
s = lookup(".dynamic", 0); s = lookup(".dynamic", 0);
s->reachable = 1;
s->type = SELFDATA;
dynamic = s; dynamic = s;
/* /*
@ -737,7 +749,7 @@ asmb(void)
if(!debug['s']) { if(!debug['s']) {
ph = newElfPhdr(); ph = newElfPhdr();
ph->type = PT_LOAD; ph->type = PT_LOAD;
ph->flags = PF_W+PF_R; ph->flags = PF_R;
ph->off = symo; ph->off = symo;
ph->vaddr = symdatva; ph->vaddr = symdatva;
ph->paddr = symdatva; ph->paddr = symdatva;
@ -835,9 +847,9 @@ asmb(void)
sh = newElfShdr(elfstr[ElfStrData]); sh = newElfShdr(elfstr[ElfStrData]);
sh->type = SHT_PROGBITS; sh->type = SHT_PROGBITS;
sh->flags = SHF_WRITE+SHF_ALLOC; sh->flags = SHF_WRITE+SHF_ALLOC;
sh->addr = va; sh->addr = va + elfdatsize;
sh->off = fo; sh->off = fo + elfdatsize;
sh->size = w; sh->size = w - elfdatsize;
sh->addralign = 8; sh->addralign = 8;
fo += w; fo += w;
@ -853,23 +865,38 @@ asmb(void)
sh->addralign = 8; sh->addralign = 8;
if (!debug['s']) { 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; w = symsize;
sh = newElfShdr(elfstr[ElfStrGosymtab]); sh = newElfShdr(elfstr[ElfStrGosymtab]);
sh->type = SHT_PROGBITS; sh->type = SHT_PROGBITS;
sh->flags = SHF_ALLOC;
sh->off = fo; sh->off = fo;
sh->size = w; sh->size = w;
sh->addralign = 1; sh->addralign = 1;
sh->addr = symdatva + 8;
fo += w; fo += w;
w = lcsize; w = lcsize;
sh = newElfShdr(elfstr[ElfStrGopclntab]); sh = newElfShdr(elfstr[ElfStrGopclntab]);
sh->type = SHT_PROGBITS; sh->type = SHT_PROGBITS;
sh->flags = SHF_ALLOC;
sh->off = fo; sh->off = fo;
sh->size = w; sh->size = w;
sh->addralign = 1; sh->addralign = 1;
sh->addr = symdatva + 8 + symsize;
if(debug['e']) { if(debug['e']) {
sh = newElfShdr(elfstr[ElfStrSymtab]); sh = newElfShdr(elfstr[ElfStrSymtab]);
@ -1102,7 +1129,7 @@ datblk(int32 s, int32 n)
for(j=l+(c-i)-1; j>=l; j--) for(j=l+(c-i)-1; j>=l; j--)
if(buf.dbuf[j]) { if(buf.dbuf[j]) {
print("%P\n", p); print("%P\n", p);
diag("multiple initialization"); diag("multiple initialization for %d %d", s, j);
break; break;
} }
} }

View File

@ -167,6 +167,8 @@ enum
SEXPORT, SEXPORT,
SMACHO, SMACHO,
SFIXED,
SELFDATA,
NHASH = 10007, NHASH = 10007,
NHUNK = 100000, NHUNK = 100000,
@ -314,6 +316,7 @@ EXTERN Prog* curtext;
EXTERN Prog* datap; EXTERN Prog* datap;
EXTERN Prog* edatap; EXTERN Prog* edatap;
EXTERN vlong datsize; EXTERN vlong datsize;
EXTERN vlong elfdatsize;
EXTERN char debug[128]; EXTERN char debug[128];
EXTERN char literal[32]; EXTERN char literal[32];
EXTERN Prog* etextp; EXTERN Prog* etextp;

View File

@ -56,7 +56,7 @@ dodata(void)
s->value = dtype; s->value = dtype;
if(s->type == SBSS) if(s->type == SBSS)
s->type = SDATA; s->type = SDATA;
if(s->type != SDATA) if(s->type != SDATA && s->type != SELFDATA)
diag("initialize non-data (%d): %s\n%P", diag("initialize non-data (%d): %s\n%P",
s->type, s->name, p); s->type, s->name, p);
t = p->from.offset + p->width; t = p->from.offset + p->width;
@ -64,9 +64,24 @@ dodata(void)
diag("initialize bounds (%lld): %s\n%P", diag("initialize bounds (%lld): %s\n%P",
s->value, s->name, p); s->value, s->name, p);
} }
/* allocate small guys */
/* allocate elf guys - must be segregated from real data */
datsize = 0; datsize = 0;
for(i=0; i<NHASH; i++) for(i=0; i<NHASH; i++)
for(s = hash[i]; s != S; s = s->link) {
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; i<NHASH; i++)
for(s = hash[i]; s != S; s = s->link) { for(s = hash[i]; s != S; s = s->link) {
if(!s->reachable) if(!s->reachable)
continue; continue;
@ -167,6 +182,11 @@ dobss(void)
xdefine("data", SBSS, 0); xdefine("data", SBSS, 0);
xdefine("edata", SBSS, datsize); xdefine("edata", SBSS, datsize);
xdefine("end", SBSS, dynptrsize + bsssize + datsize); xdefine("end", SBSS, dynptrsize + bsssize + datsize);
if(debug['s'])
xdefine("symdat", SFIXED, 0);
else
xdefine("symdat", SFIXED, SYMDATVA);
} }
Prog* Prog*

View File

@ -234,6 +234,7 @@ genasmsym(void (*put)(char*, int, vlong, vlong, int, Sym*))
continue; continue;
case SDATA: case SDATA:
case SELFDATA:
if(!s->reachable) if(!s->reachable)
continue; continue;
put(s->name, 'D', s->value+INITDAT, s->size, s->version, s->gotype); 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); put(s->name, 'B', s->value+INITDAT, s->size, s->version, s->gotype);
continue; continue;
case SFIXED:
put(s->name, 'B', s->value, s->size, s->version, s->gotype);
continue;
case SFILE: case SFILE:
put(s->name, 'f', s->value, 0, s->version, 0); put(s->name, 'f', s->value, 0, s->version, 0);
continue; continue;
@ -792,6 +797,9 @@ vaddr(Adr *a)
v += INITTEXT; /* TO DO */ v += INITTEXT; /* TO DO */
v += s->value; v += s->value;
break; break;
case SFIXED:
v += s->value;
break;
case SMACHO: case SMACHO:
if(!s->reachable) if(!s->reachable)
sysfatal("unreachable symbol in vaddr - %s", s->name); sysfatal("unreachable symbol in vaddr - %s", s->name);

View File

@ -38,7 +38,7 @@
char linuxdynld[] = "/lib/ld-linux.so.2"; char linuxdynld[] = "/lib/ld-linux.so.2";
char freebsddynld[] = "/usr/libexec/ld-elf.so.1"; char freebsddynld[] = "/usr/libexec/ld-elf.so.1";
uint32 symdatva = 0x99<<24; uint32 symdatva = SYMDATVA;
int32 int32
entryvalue(void) entryvalue(void)
@ -248,6 +248,7 @@ enum {
ElfStrText, ElfStrText,
ElfStrData, ElfStrData,
ElfStrBss, ElfStrBss,
ElfStrGosymcounts,
ElfStrGosymtab, ElfStrGosymtab,
ElfStrGopclntab, ElfStrGopclntab,
ElfStrShstrtab, ElfStrShstrtab,
@ -289,6 +290,7 @@ doelf(void)
elfstr[ElfStrData] = addstring(shstrtab, ".data"); elfstr[ElfStrData] = addstring(shstrtab, ".data");
elfstr[ElfStrBss] = addstring(shstrtab, ".bss"); elfstr[ElfStrBss] = addstring(shstrtab, ".bss");
if(!debug['s']) { if(!debug['s']) {
elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts");
elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab"); elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab");
elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab"); elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab");
} }
@ -307,36 +309,40 @@ doelf(void)
/* interpreter string */ /* interpreter string */
s = lookup(".interp", 0); s = lookup(".interp", 0);
s->reachable = 1; s->reachable = 1;
s->type = SDATA; // TODO: rodata s->type = SELFDATA;
/* dynamic symbol table - first entry all zeros */ /* dynamic symbol table - first entry all zeros */
s = lookup(".dynsym", 0); s = lookup(".dynsym", 0);
s->type = SDATA; s->type = SELFDATA;
s->reachable = 1; s->reachable = 1;
s->value += ELF32SYMSIZE; s->value += ELF32SYMSIZE;
/* dynamic string table */ /* dynamic string table */
s = lookup(".dynstr", 0); s = lookup(".dynstr", 0);
s->reachable = 1;
s->type = SELFDATA;
addstring(s, ""); addstring(s, "");
dynstr = s; dynstr = s;
/* relocation table */ /* relocation table */
s = lookup(".rel", 0); s = lookup(".rel", 0);
s->reachable = 1; s->reachable = 1;
s->type = SDATA; s->type = SELFDATA;
/* global offset table */ /* global offset table */
s = lookup(".got", 0); s = lookup(".got", 0);
s->reachable = 1; s->reachable = 1;
s->type = SDATA; s->type = SELFDATA;
/* got.plt - ??? */ /* got.plt - ??? */
s = lookup(".got.plt", 0); s = lookup(".got.plt", 0);
s->reachable = 1; s->reachable = 1;
s->type = SDATA; s->type = SELFDATA;
/* define dynamic elf table */ /* define dynamic elf table */
s = lookup(".dynamic", 0); s = lookup(".dynamic", 0);
s->reachable = 1;
s->type = SELFDATA;
dynamic = s; dynamic = s;
/* /*
@ -874,7 +880,7 @@ asmb(void)
if(!debug['s'] && HEADTYPE != 8 && HEADTYPE != 11) { if(!debug['s'] && HEADTYPE != 8 && HEADTYPE != 11) {
ph = newElfPhdr(); ph = newElfPhdr();
ph->type = PT_LOAD; ph->type = PT_LOAD;
ph->flags = PF_W+PF_R; ph->flags = PF_R;
ph->off = symo; ph->off = symo;
ph->vaddr = symdatva; ph->vaddr = symdatva;
ph->paddr = symdatva; ph->paddr = symdatva;
@ -986,9 +992,9 @@ asmb(void)
sh = newElfShdr(elfstr[ElfStrData]); sh = newElfShdr(elfstr[ElfStrData]);
sh->type = SHT_PROGBITS; sh->type = SHT_PROGBITS;
sh->flags = SHF_WRITE+SHF_ALLOC; sh->flags = SHF_WRITE+SHF_ALLOC;
sh->addr = va; sh->addr = va + elfdatsize;
sh->off = fo; sh->off = fo + elfdatsize;
sh->size = w; sh->size = w - elfdatsize;
sh->addralign = 4; sh->addralign = 4;
fo += w; fo += w;
@ -1004,23 +1010,38 @@ asmb(void)
sh->addralign = 4; sh->addralign = 4;
if (!debug['s']) { 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; w = symsize;
sh = newElfShdr(elfstr[ElfStrGosymtab]); sh = newElfShdr(elfstr[ElfStrGosymtab]);
sh->type = SHT_PROGBITS; sh->type = SHT_PROGBITS;
sh->flags = SHF_ALLOC;
sh->off = fo; sh->off = fo;
sh->size = w; sh->size = w;
sh->addralign = 1; sh->addralign = 1;
sh->addr = symdatva + 8;
fo += w; fo += w;
w = lcsize; w = lcsize;
sh = newElfShdr(elfstr[ElfStrGopclntab]); sh = newElfShdr(elfstr[ElfStrGopclntab]);
sh->type = SHT_PROGBITS; sh->type = SHT_PROGBITS;
sh->flags = SHF_ALLOC;
sh->off = fo; sh->off = fo;
sh->size = w; sh->size = w;
sh->addralign = 1; sh->addralign = 1;
sh->addr = symdatva + 8 + symsize;
} }
sh = newElfShstrtab(elfstr[ElfStrShstrtab]); sh = newElfShstrtab(elfstr[ElfStrShstrtab]);

View File

@ -161,6 +161,9 @@ enum
SMACHO, /* pointer to mach-o imported symbol */ SMACHO, /* pointer to mach-o imported symbol */
SFIXED,
SELFDATA,
NHASH = 10007, NHASH = 10007,
NHUNK = 100000, NHUNK = 100000,
MINSIZ = 4, MINSIZ = 4,
@ -280,6 +283,7 @@ EXTERN Prog* curtext;
EXTERN Prog* datap; EXTERN Prog* datap;
EXTERN Prog* edatap; EXTERN Prog* edatap;
EXTERN int32 datsize; EXTERN int32 datsize;
EXTERN int32 elfdatsize;
EXTERN int32 dynptrsize; EXTERN int32 dynptrsize;
EXTERN char debug[128]; EXTERN char debug[128];
EXTERN char literal[32]; EXTERN char literal[32];

View File

@ -55,7 +55,7 @@ dodata(void)
s->value = dtype; s->value = dtype;
if(s->type == SBSS) if(s->type == SBSS)
s->type = SDATA; s->type = SDATA;
if(s->type != SDATA) if(s->type != SDATA && s->type != SELFDATA)
diag("initialize non-data (%d): %s\n%P", diag("initialize non-data (%d): %s\n%P",
s->type, s->name, p); s->type, s->name, p);
t = p->from.offset + p->width; t = p->from.offset + p->width;
@ -63,9 +63,24 @@ dodata(void)
diag("initialize bounds (%ld): %s\n%P", diag("initialize bounds (%ld): %s\n%P",
s->value, s->name, p); s->value, s->name, p);
} }
/* allocate small guys */
/* allocate elf guys - must be segregated from real data */
datsize = 0; datsize = 0;
for(i=0; i<NHASH; i++) for(i=0; i<NHASH; i++)
for(s = hash[i]; s != S; s = s->link) {
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; i<NHASH; i++)
for(s = hash[i]; s != S; s = s->link) { for(s = hash[i]; s != S; s = s->link) {
if(!s->reachable) if(!s->reachable)
continue; continue;
@ -148,6 +163,11 @@ dodata(void)
xdefine("data", SBSS, 0); xdefine("data", SBSS, 0);
xdefine("edata", SBSS, datsize); xdefine("edata", SBSS, datsize);
xdefine("end", SBSS, dynptrsize + bsssize + datsize); xdefine("end", SBSS, dynptrsize + bsssize + datsize);
if(debug['s'])
xdefine("symdat", SFIXED, 0);
else
xdefine("symdat", SFIXED, SYMDATVA);
} }
Prog* Prog*

View File

@ -214,6 +214,7 @@ asmsym(void)
continue; continue;
case SDATA: case SDATA:
case SELFDATA:
if(!s->reachable) if(!s->reachable)
continue; continue;
putsymb(s->name, 'D', s->value+INITDAT, s->version, s->gotype); 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); putsymb(s->name, 'B', s->value+INITDAT, s->version, s->gotype);
continue; continue;
case SFIXED:
putsymb(s->name, 'B', s->value, s->version, s->gotype);
continue;
case SFILE: case SFILE:
putsymb(s->name, 'f', s->value, s->version, 0); putsymb(s->name, 'f', s->value, s->version, 0);
continue; continue;
@ -622,6 +627,9 @@ vaddr(Adr *a)
sysfatal("unreachable symbol in vaddr - %s", s->name); sysfatal("unreachable symbol in vaddr - %s", s->name);
v += INITDAT + datsize + s->value; v += INITDAT + datsize + s->value;
break; break;
case SFIXED:
v += s->value;
break;
default: default:
if(!s->reachable) if(!s->reachable)
sysfatal("unreachable symbol in vaddr - %s", s->name); sysfatal("unreachable symbol in vaddr - %s", s->name);

View File

@ -320,7 +320,7 @@ elfdynhash(int nsym)
uint32 *chain, *buckets; uint32 *chain, *buckets;
s = lookup(".hash", 0); s = lookup(".hash", 0);
s->type = SDATA; // TODO: rodata s->type = SELFDATA; // TODO: rodata
s->reachable = 1; s->reachable = 1;
i = nsym; i = nsym;

View File

@ -406,6 +406,10 @@ ldobj(Biobuf *f, char *pkg, int64 len, char *pn)
if(n != strlen(thestring) || strncmp(line, thestring, n) != 0) { if(n != strlen(thestring) || strncmp(line, thestring, n) != 0) {
if(line) if(line)
line[n] = '\0'; 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); diag("file not %s [%s]\n", thestring, line);
return; return;
} }

View File

@ -28,7 +28,7 @@
// 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.
// 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 #define SYMDATVA 0x99LL<<24
typedef struct Library Library; typedef struct Library Library;

View File

@ -17,10 +17,7 @@
#include "os.h" #include "os.h"
#include "arch.h" #include "arch.h"
// TODO(rsc): Move this *under* the text segment. extern int32 symdat[];
// 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)
typedef struct Sym Sym; typedef struct Sym Sym;
struct Sym struct Sym
@ -39,18 +36,15 @@ walksymtab(void (*fn)(Sym*))
byte *p, *ep, *q; byte *p, *ep, *q;
Sym s; Sym s;
// TODO(rsc): Remove once TODO at top of file is done. if(symdat == nil)
if(goos != nil && strcmp((uint8*)goos, (uint8*)"nacl") == 0)
return;
if(goos != nil && strcmp((uint8*)goos, (uint8*)"pchw") == 0)
return; return;
#ifdef __MINGW__ #ifdef __MINGW__
v = get_symdat_addr(); v = get_symdat_addr();
p = (byte*)v+8; p = (byte*)v+8;
#else #else
v = SYMCOUNTS; v = symdat;
p = SYMDATA; p = (byte*)(symdat+2);
#endif #endif
ep = p + v[0]; ep = p + v[0];
while(p < ep) { while(p < ep) {
@ -258,10 +252,7 @@ splitpcln(void)
break; break;
} }
// TODO(rsc): Remove once TODO at top of file is done. if(symdat == nil)
if(goos != nil && strcmp((uint8*)goos, (uint8*)"nacl") == 0)
return;
if(goos != nil && strcmp((uint8*)goos, (uint8*)"pchw") == 0)
return; return;
// pc/ln table bounds // pc/ln table bounds
@ -269,8 +260,8 @@ splitpcln(void)
v = get_symdat_addr(); v = get_symdat_addr();
p = (byte*)v+8; p = (byte*)v+8;
#else #else
v = SYMCOUNTS; v = symdat;
p = SYMDATA; p = (byte*)(symdat+2);
#endif #endif
p += v[0]; p += v[0];
ep = p+v[1]; ep = p+v[1];