summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2010-04-27 22:40:26 -0700
committerRuss Cox <rsc@golang.org>2010-04-27 22:40:26 -0700
commit9febb2629da0a0104979998947689ff2722ed743 (patch)
tree7db5ba59a0995dd0eb21073fa33d25b800ea844e
parentd73000e8e65eff91259019ccbde72998c1df3551 (diff)
downloadgolang-9febb2629da0a0104979998947689ff2722ed743.tar.gz
5l, 6l, 8l, runtime: make -s binaries work
5l, 6l, 8l: change ELF header so that strip doesn't destroy binary Fixes issue 261. R=iant, r CC=golang-dev http://codereview.appspot.com/994044
-rw-r--r--src/cmd/5l/asm.c63
-rw-r--r--src/cmd/5l/l.h4
-rw-r--r--src/cmd/5l/pass.c26
-rw-r--r--src/cmd/5l/span.c7
-rw-r--r--src/cmd/6l/asm.c47
-rw-r--r--src/cmd/6l/l.h3
-rw-r--r--src/cmd/6l/pass.c24
-rw-r--r--src/cmd/6l/span.c8
-rw-r--r--src/cmd/8l/asm.c43
-rw-r--r--src/cmd/8l/l.h4
-rw-r--r--src/cmd/8l/pass.c24
-rw-r--r--src/cmd/8l/span.c8
-rw-r--r--src/cmd/ld/elf.c2
-rw-r--r--src/cmd/ld/lib.c4
-rw-r--r--src/cmd/ld/lib.h2
-rw-r--r--src/pkg/runtime/symtab.c25
16 files changed, 235 insertions, 59 deletions
diff --git a/src/cmd/5l/asm.c b/src/cmd/5l/asm.c
index 79050a9d0..62c2a07ad 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 44bd923a9..c6659cfab 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 fcdee6944..06b1792b4 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; 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
diff --git a/src/cmd/5l/span.c b/src/cmd/5l/span.c
index 1272b05ec..a97af07f9 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 b83cec68f..c104d23d4 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 5f99e9a51..3db0b450a 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 44dcb0710..f86942926 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,12 +64,27 @@ 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;
if(s->type != SDATA)
if(s->type != SBSS)
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 237a81fff..15f931bcb 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 0fca6fa0f..797209169 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 5b0f30723..495c40d64 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 9c42c3ded..e8fda9b73 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,12 +63,27 @@ 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;
if(s->type != SDATA)
if(s->type != SBSS)
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 0245d72b9..99ba279da 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 a0bcba35a..c5d58576d 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 3524bd1c4..18c425516 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 c89322e38..4307d2d41 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 b571d21ec..4707b1537 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];