mirror of
https://github.com/golang/go
synced 2024-11-12 07:00:21 -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:
parent
f9d33ee6cb
commit
000ab98df6
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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; 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
|
||||
@ -79,7 +97,6 @@ dodata(void)
|
||||
* (rational is that data segment is more easily
|
||||
* addressed through offset on R12)
|
||||
*/
|
||||
orig = 0;
|
||||
for(i=0; i<NHASH; i++)
|
||||
for(s = hash[i]; s != S; s = s->link) {
|
||||
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
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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; 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) {
|
||||
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*
|
||||
|
@ -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);
|
||||
|
@ -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]);
|
||||
|
@ -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];
|
||||
|
@ -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; 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) {
|
||||
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*
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
|
Loading…
Reference in New Issue
Block a user