]> Cypherpunks repositories - gostls13.git/commitdiff
5l, 6l, 8l, runtime: make -s binaries work
authorRuss Cox <rsc@golang.org>
Wed, 28 Apr 2010 05:40:26 +0000 (22:40 -0700)
committerRuss Cox <rsc@golang.org>
Wed, 28 Apr 2010 05:40:26 +0000 (22:40 -0700)
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

16 files changed:
src/cmd/5l/asm.c
src/cmd/5l/l.h
src/cmd/5l/pass.c
src/cmd/5l/span.c
src/cmd/6l/asm.c
src/cmd/6l/l.h
src/cmd/6l/pass.c
src/cmd/6l/span.c
src/cmd/8l/asm.c
src/cmd/8l/l.h
src/cmd/8l/pass.c
src/cmd/8l/span.c
src/cmd/ld/elf.c
src/cmd/ld/lib.c
src/cmd/ld/lib.h
src/pkg/runtime/symtab.c

index 79050a9d02856e06a65caf9184af106fbaeda30a..62c2a07ad8b9c6e0033305bc2243a306e3342200 100644 (file)
@@ -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;
index 44bd923a9c34fc412c7d60038ad2f048f5d17ee9..c6659cfab3f4df522a0a617d1ff829f8256046a4 100644 (file)
@@ -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;
index fcdee69449051076f3d15d0ca3de2a22d5112bf3..06b1792b4dcc10ed33d4a5712daea8efb8382c39 100644 (file)
@@ -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
index 1272b05eccb7acee1ddc1cd1ae8d6c4d30cf899e..a97af07f933830c1e60538bb2ba85af1c5832911 100644 (file)
@@ -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:
index b83cec68fbd2eee590649975fd7f36f32f1dddf7..c104d23d4b5b184de3db5f41e540ab30b3242dff 100644 (file)
@@ -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;
                                }
                }
index 5f99e9a51220f2687cb2ccc24633446ff5784401..3db0b450ad57199af80eaf44f3a030e9ef7a585b 100644 (file)
@@ -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;
index 44dcb07100bdb8a8924452b9b2bd91cea4203d83..f8694292610f4bf08c2dd62bcb50998a1869c438 100644 (file)
@@ -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*
index 237a81fffdb558d5fc6358f2cbca34af1f671716..15f931bcb10f3ff9d6ea802c70fb7b9569fd9c2f 100644 (file)
@@ -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);
index 0fca6fa0f87f65688ea8fd358796d27f0f68a9ee..797209169dfab9c8271efe9c5a61f628ad6b047b 100644 (file)
@@ -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]);
index 5b0f307233eb826447cbca42fc8d9532c9ec30f7..495c40d6445fa50078b2758f0aef3615cf7264bf 100644 (file)
@@ -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];
index 9c42c3ded86045bb569e1200045563732d5faea4..e8fda9b7353602510d553d586f4c13a7b5aea1df 100644 (file)
@@ -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*
index 0245d72b9bf0504d7ddd8d3f696d4a20efb795bd..99ba279da0f6a34e52acb0505a210027cf1d3cdb 100644 (file)
@@ -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);
index a0bcba35a66de2673a0d22f23bbbbbb0151afa8f..c5d58576dcf59d84e181693d3031336fd36fdb9e 100644 (file)
@@ -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;
index 3524bd1c4aa6e93ba96f78a5d64bb555830b6d27..18c4255161613a4f9c316f18800c9f82bc2ba15a 100644 (file)
@@ -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;
        }
index c89322e38d578af93c080ae147a1fdafd6fe6815..4307d2d41e62814467268d289b0b13f6248c5f54 100644 (file)
@@ -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;
index b571d21eca405fddafea3c82360be2310ffbc7a4..4707b1537b9e83662f5f6cc8642d07f9bf111bfb 100644 (file)
 #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];