]> Cypherpunks repositories - gostls13.git/commitdiff
5l, 6l, 8l: accumulate data image during import
authorRuss Cox <rsc@golang.org>
Fri, 15 Oct 2010 03:48:40 +0000 (23:48 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 15 Oct 2010 03:48:40 +0000 (23:48 -0400)
Using explicit relocations internally, we can
represent the data for a particular symbol as
an initialized block of memory instead of a
linked list of ADATA instructions.  The real
goal here is to be able to hand off some of the
relocations to the dynamic linker when interacting
with system libraries, but a pleasant side effect is
that the memory image is much more compact
than the ADATA list, so the linkers use less memory.

R=ken2
CC=golang-dev
https://golang.org/cl/2512041

30 files changed:
src/cmd/5l/Makefile
src/cmd/5l/asm.c
src/cmd/5l/l.h
src/cmd/5l/list.c
src/cmd/5l/noop.c
src/cmd/5l/obj.c
src/cmd/5l/pass.c
src/cmd/5l/span.c
src/cmd/5l/symtab.c
src/cmd/5l/thumb.c
src/cmd/6l/Makefile
src/cmd/6l/asm.c
src/cmd/6l/l.h
src/cmd/6l/obj.c
src/cmd/6l/pass.c
src/cmd/6l/span.c
src/cmd/6l/symtab.c
src/cmd/8l/Makefile
src/cmd/8l/asm.c
src/cmd/8l/l.h
src/cmd/8l/obj.c
src/cmd/8l/pass.c
src/cmd/8l/span.c
src/cmd/8l/symtab.c
src/cmd/ld/data.c [new file with mode: 0644]
src/cmd/ld/go.c
src/cmd/ld/lib.c
src/cmd/ld/lib.h
src/cmd/ld/macho.c
src/cmd/ld/pe.c

index c68ef42da98c381b0a6e5e7782fd435a1d5b14d1..e05682c4b2ab55b24dd7dba09f692a943aa8984f 100644 (file)
@@ -9,6 +9,7 @@ TARG=5l
 
 OFILES=\
        asm.$O\
+       data.$O\
        elf.$O\
        enam.$O\
        lib.$O\
index a033898c001a2cff5fae99c6da012da41d3d8b2c..4d9264c91405d0eb96b8c71566c00ac82a258099 100644 (file)
@@ -52,125 +52,11 @@ entryvalue(void)
        s = lookup(a, 0);
        if(s->type == 0)
                return INITTEXT;
-       switch(s->type) {
-       case STEXT:
-       case SLEAF:
-               break;
-       case SDATA:
-       default:
+       if(s->type != STEXT)
                diag("entry not text: %s", s->name);
-       }
        return s->value;
 }
 
-vlong
-addstring(Sym *s, char *str)
-{
-       int n, m;
-       vlong r;
-       Prog *p;
-
-       if(s->type == 0)
-               s->type = SDATA;
-       s->reachable = 1;
-       r = s->value;
-       n = strlen(str)+1;
-       while(n > 0) {
-               m = n;
-               if(m > NSNAME)
-                       m = NSNAME;
-               p = newdata(s, s->value, m, D_EXTERN);
-               p->to.type = D_SCONST;
-               p->to.sval = mal(NSNAME);
-               memmove(p->to.sval, str, m);
-               s->value += m;
-               str += m;
-               n -= m;
-       }
-       return r;
-}
-
-vlong
-adduintxx(Sym *s, uint64 v, int wid)
-{
-       vlong r;
-       Prog *p;
-
-       if(s->type == 0)
-               s->type = SDATA;
-       s->reachable = 1;
-       r = s->value;
-       p = newdata(s, s->value, wid, D_EXTERN);
-       s->value += wid;
-       p->to.type = D_CONST;
-       p->to.offset = v;
-       return r;
-}
-
-vlong
-adduint8(Sym *s, uint8 v)
-{
-       return adduintxx(s, v, 1);
-}
-
-vlong
-adduint16(Sym *s, uint16 v)
-{
-       return adduintxx(s, v, 2);
-}
-
-vlong
-adduint32(Sym *s, uint32 v)
-{
-       return adduintxx(s, v, 4);
-}
-
-vlong
-adduint64(Sym *s, uint64 v)
-{
-       return adduintxx(s, v, 8);
-}
-
-vlong
-addaddr(Sym *s, Sym *t)
-{
-       vlong r;
-       Prog *p;
-       enum { Ptrsize = 4 };
-
-       if(s->type == 0)
-               s->type = SDATA;
-       s->reachable = 1;
-       r = s->value;
-       p = newdata(s, s->value, Ptrsize, D_EXTERN);
-       s->value += Ptrsize;
-       p->to.type = D_ADDR;
-       p->to.index = D_EXTERN;
-       p->to.offset = 0;
-       p->to.sym = t;
-       return r;
-}
-
-vlong
-addsize(Sym *s, Sym *t)
-{
-       vlong r;
-       Prog *p;
-       enum { Ptrsize = 4 };
-
-       if(s->type == 0)
-               s->type = SDATA;
-       s->reachable = 1;
-       r = s->value;
-       p = newdata(s, s->value, Ptrsize, D_EXTERN);
-       s->value += Ptrsize;
-       p->to.type = D_SIZE;
-       p->to.index = D_EXTERN;
-       p->to.offset = 0;
-       p->to.sym = t;
-       return r;
-}
-
 enum {
        ElfStrEmpty,
        ElfStrInterp,
@@ -220,10 +106,13 @@ doelf(void)
 
        /* predefine strings we need for section headers */
        shstrtab = lookup(".shstrtab", 0);
+       shstrtab->type = SELFDATA;
        shstrtab->reachable = 1;
+
        elfstr[ElfStrEmpty] = addstring(shstrtab, "");
        elfstr[ElfStrText] = addstring(shstrtab, ".text");
        elfstr[ElfStrData] = addstring(shstrtab, ".data");
+       addstring(shstrtab, ".rodata");
        elfstr[ElfStrBss] = addstring(shstrtab, ".bss");
        if(!debug['s']) {       
                elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts");
@@ -372,16 +261,18 @@ doelf(void)
 vlong
 datoff(vlong addr)
 {
-       if(addr >= INITDAT)
-               return addr - INITDAT + rnd(HEADR+textsize, INITRND);
-       diag("datoff %#llx", addr);
+       if(addr >= segdata.vaddr)
+               return addr - segdata.vaddr + segdata.fileoff;
+       if(addr >= segtext.vaddr)
+               return addr - segtext.vaddr + segtext.fileoff;
+       diag("datoff %#x", addr);
        return 0;
 }
 
 void
 shsym(Elf64_Shdr *sh, Sym *s)
 {
-       sh->addr = s->value + INITDAT;
+       sh->addr = symaddr(s);
        sh->off = datoff(sh->addr);
        sh->size = s->size;
 }
@@ -401,7 +292,7 @@ void
 asmb(void)
 {
        Prog *p;
-       int32 t, etext;
+       int32 t;
        int a, dynsym;
        uint32 va, fo, w, symo, startva;
        uint32 symdatva = SYMDATVA;
@@ -410,6 +301,7 @@ asmb(void)
        ElfEhdr *eh;
        ElfPhdr *ph, *pph;
        ElfShdr *sh;
+       Section *sect;
 
        strtabsize = 0;
        symo = 0;
@@ -441,26 +333,16 @@ asmb(void)
                        pc += o->size;
                }
        }
-       while(pc-INITTEXT < textsize) {
-               cput(0);
-               pc++;
-       }
-
-       if(debug['a'])
-               Bprint(&bso, "\n");
-       Bflush(&bso);
        cflush();
+       if(seek(cout, 0, 1) != pc - segtext.vaddr + segtext.fileoff)
+               diag("text phase error");
 
-       /* output strings in text segment */
-       etext = INITTEXT + textsize;
-       for(t = pc; t < etext; t += sizeof(buf)-100) {
-               if(etext-t > sizeof(buf)-100)
-                       datblk(t, sizeof(buf)-100, 1);
-               else
-                       datblk(t, etext-t, 1);
-       }
+       /* output read-only data in text segment */
+       sect = segtext.sect->next;
+       seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
+       datblk(sect->vaddr, sect->len);
 
-       /* output section header strings */
+       /* output data segment */
        cursym = nil;
        switch(HEADTYPE) {
        case 0:
@@ -475,17 +357,12 @@ asmb(void)
                seek(cout, OFFSET, 0);
                break;
        case 6:
-               OFFSET = rnd(HEADR+textsize, INITRND);
+               OFFSET = rnd(segtext.fileoff+segtext.filelen, INITRND);
                seek(cout, OFFSET, 0);
                break;
        }
-       for(t = 0; t < datsize; t += sizeof(buf)-100) {
-               if(datsize-t > sizeof(buf)-100)
-                       datblk(t, sizeof(buf)-100, 0);
-               else
-                       datblk(t, datsize-t, 0);
-       }
-       cflush();
+       segdata.fileoff = seek(cout, 0, 1);
+       datblk(INITDAT, segdata.filelen);
 
        /* output symbol table */
        symsize = 0;
@@ -502,16 +379,16 @@ asmb(void)
                        debug['s'] = 1;
                        break;
                case 2:
-                       OFFSET = HEADR+textsize+datsize;
+                       OFFSET = HEADR+textsize+segdata.filelen;
                        seek(cout, OFFSET, 0);
                        break;
                case 3:
-                       OFFSET += rnd(datsize, 4096);
+                       OFFSET += rnd(segdata.filelen, 4096);
                        seek(cout, OFFSET, 0);
                        break;
                case 6:
-                       symo = rnd(HEADR+textsize, INITRND)+datsize+strtabsize;
-                       symo = rnd(symo, INITRND);
+                       OFFSET += segdata.filelen;
+                       symo = rnd(OFFSET, INITRND);
                        seek(cout, symo + 8, 0);
                        break;
                }
@@ -555,10 +432,10 @@ asmb(void)
 
                lputl(0xef000011);              /* SWI - exit code */
                lputl(textsize+HEADR);          /* text size */
-               lputl(datsize);                 /* data size */
+               lputl(segdata.filelen);                 /* data size */
                lputl(0);                       /* sym size */
 
-               lputl(bsssize);                 /* bss size */
+               lputl(segdata.len - segdata.filelen);                   /* bss size */
                lputl(0);                       /* sym type */
                lputl(INITTEXT-HEADR);          /* text addr */
                lputl(0);                       /* workspace - ignored */
@@ -575,8 +452,8 @@ asmb(void)
        case 2: /* plan 9 */
                lput(0x647);                    /* magic */
                lput(textsize);                 /* sizes */
-               lput(datsize);
-               lput(bsssize);
+               lput(segdata.filelen);
+               lput(segdata.len - segdata.filelen);
                lput(symsize);                  /* nsyms */
                lput(entryvalue());             /* va of entry */
                lput(0L);
@@ -585,8 +462,8 @@ asmb(void)
        case 3: /* boot for NetBSD */
                lput((143<<16)|0413);           /* magic */
                lputl(rnd(HEADR+textsize, 4096));
-               lputl(rnd(datsize, 4096));
-               lputl(bsssize);
+               lputl(rnd(segdata.filelen, 4096));
+               lputl(segdata.len - segdata.filelen);
                lputl(symsize);                 /* nsyms */
                lputl(entryvalue());            /* va of entry */
                lputl(0L);
@@ -634,40 +511,16 @@ asmb(void)
                        phsh(ph, sh);
                }
 
-               ph = newElfPhdr();
-               ph->type = PT_LOAD;
-               ph->flags = PF_X+PF_R;
-               ph->vaddr = va;
-               ph->paddr = va;
-               ph->off = fo;
-               ph->filesz = w;
-               ph->memsz = w;
-               ph->align = INITRND;
-
-               fo = rnd(fo+w, INITRND);
-               va = rnd(va+w, INITRND);
-               w = datsize;
-
-               ph = newElfPhdr();
-               ph->type = PT_LOAD;
-               ph->flags = PF_W+PF_R;
-               ph->off = fo;
-               ph->vaddr = va;
-               ph->paddr = va;
-               ph->filesz = w;
-               ph->memsz = w+bsssize;
-               ph->align = INITRND;
+               elfphload(&segtext);
+               elfphload(&segdata);
 
                if(!debug['s']) {
-                       ph = newElfPhdr();
-                       ph->type = PT_LOAD;
-                       ph->flags = PF_R;
-                       ph->off = symo;
-                       ph->vaddr = symdatva;
-                       ph->paddr = symdatva;
-                       ph->filesz = rnd(8+symsize+lcsize, INITRND);
-                       ph->memsz = rnd(8+symsize+lcsize, INITRND);
-                       ph->align = INITRND;
+                       segsym.rwx = 04;
+                       segsym.vaddr = symdatva;
+                       segsym.len = rnd(8+symsize+lcsize, INITRND);
+                       segsym.fileoff = symo;
+                       segsym.filelen = segsym.len;
+                       elfphload(&segsym);
                }
 
                /* Dynamic linking sections */
@@ -750,47 +603,12 @@ asmb(void)
                ph->flags = PF_W+PF_R;
                ph->align = 4;
 
-               fo = ELFRESERVE;
-               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 = ELFRESERVE;
-
-               fo = rnd(fo+w, INITRND);
-               va = rnd(va+w, INITRND);
-               w = datsize;
-
-               sh = newElfShdr(elfstr[ElfStrData]);
-               sh->type = SHT_PROGBITS;
-               sh->flags = SHF_WRITE+SHF_ALLOC;
-               sh->addr = va + elfdatsize;
-               sh->off = fo + elfdatsize;
-               sh->size = w - elfdatsize;
-               sh->addralign = INITRND;
-
-               fo += w;
-               va += w;
-               w = bsssize;
-
-               sh = newElfShdr(elfstr[ElfStrBss]);
-               sh->type = SHT_NOBITS;
-               sh->flags = SHF_WRITE+SHF_ALLOC;
-               sh->addr = va;
-               sh->off = fo;
-               sh->size = w;
-               sh->addralign = 4;
+               for(sect=segtext.sect; sect!=nil; sect=sect->next)
+                       elfshbits(sect);
+               for(sect=segrodata.sect; sect!=nil; sect=sect->next)
+                       elfshbits(sect);
+               for(sect=segdata.sect; sect!=nil; sect=sect->next)
+                       elfshbits(sect);
 
                if (!debug['s']) {
                        fo = symo;
@@ -864,25 +682,14 @@ asmb(void)
        cflush();
        if(debug['c']){
                print("textsize=%d\n", textsize);
-               print("datsize=%d\n", datsize);
-               print("bsssize=%d\n", bsssize);
+               print("datsize=%d\n", segdata.filelen);
+               print("bsssize=%d\n", segdata.len - segdata.filelen);
                print("symsize=%d\n", symsize);
                print("lcsize=%d\n", lcsize);
-               print("total=%d\n", textsize+datsize+bsssize+symsize+lcsize);
+               print("total=%d\n", textsize+segdata.len+symsize+lcsize);
        }
 }
 
-void
-strnput(char *s, int n)
-{
-       for(; *s; s++){
-               cput(*s);
-               n--;
-       }
-       for(; n > 0; n--)
-               cput(0);
-}
-
 void
 cput(int c)
 {
@@ -1038,140 +845,6 @@ asmthumbmap(void)
                outt(lastt, pc+1);
 }
 
-void
-datblk(int32 s, int32 n, int str)
-{
-       Sym *v;
-       Prog *p;
-       char *cast;
-       int32 a, l, fl, j, d;
-       int i, c;
-
-       memset(buf.dbuf, 0, n+100);
-       for(p = datap; p != P; p = p->link) {
-               if(str != (p->from.sym->type == SSTRING))
-                       continue;
-               curp = p;
-               a = p->from.sym->value + p->from.offset;
-               l = a - s;
-               c = p->reg;
-               i = 0;
-               if(l < 0) {
-                       if(l+c <= 0)
-                               continue;
-                       while(l < 0) {
-                               l++;
-                               i++;
-                       }
-               }
-               if(l >= n)
-                       continue;
-               for(j=l+(c-i)-1; j>=l; j--)
-                       if(buf.dbuf[j]) {
-                               print("%P\n", p);
-                               diag("multiple initialization");
-                               break;
-                       }
-               switch(p->to.type) {
-               default:
-                       diag("unknown mode in initialization%P", p);
-                       break;
-
-               case D_FCONST:
-                       switch(c) {
-                       default:
-                       case 4:
-                               fl = ieeedtof(p->to.ieee);
-                               cast = (char*)&fl;
-                               for(; i<c; i++) {
-                                       buf.dbuf[l] = cast[fnuxi4[i]];
-                                       l++;
-                               }
-                               break;
-                       case 8:
-                               cast = (char*)p->to.ieee;
-                               for(; i<c; i++) {
-                                       buf.dbuf[l] = cast[fnuxi8[i]];
-                                       l++;
-                               }
-                               break;
-                       }
-                       break;
-
-               case D_SCONST:
-                       for(; i<c; i++) {
-                               buf.dbuf[l] = p->to.sval[i];
-                               l++;
-                       }
-                       break;
-
-               case D_CONST:
-                       d = p->to.offset;
-                       v = p->to.sym;
-                       if(v) {
-                               switch(v->type) {
-                               case STEXT:
-                               case SLEAF:
-                                       d += v->value;
-#ifdef CALLEEBX
-                                       d += fnpinc(v);
-#else
-                                       if(v->thumb)
-                                               d++;            // T bit
-#endif
-                                       break;
-                               case SSTRING:
-                                       d += v->value;
-                                       break;
-                               case SDATA:
-                               case SBSS:
-                                       if(p->to.type == D_SIZE)
-                                               d += v->size;
-                                       else
-                                               d += v->value + INITDAT;
-                                       break;
-                               }
-                       }
-                       cast = (char*)&d;
-                       switch(c) {
-                       default:
-                               diag("bad nuxi %d %d%P", c, i, curp);
-                               break;
-                       case 1:
-                               for(; i<c; i++) {
-                                       buf.dbuf[l] = cast[inuxi1[i]];
-                                       l++;
-                               }
-                               break;
-                       case 2:
-                               for(; i<c; i++) {
-                                       buf.dbuf[l] = cast[inuxi2[i]];
-                                       l++;
-                               }
-                               break;
-                       case 4:
-                               for(; i<c; i++) {
-                                       buf.dbuf[l] = cast[inuxi4[i]];
-                                       l++;
-                               }
-                               break;
-                       }
-                       break;
-
-               case D_SBIG:
-                       if(debug['a'] && i == 0) {
-                               Bprint(&bso, "\t%P\n", curp);
-                       }
-                       for(; i<c; i++) {
-                               buf.dbuf[l] = p->to.sbig[i];
-                               l++;
-                       }
-                       break;
-               }
-       }
-       ewrite(cout, buf.dbuf, n);
-}
-
 void
 asmout(Prog *p, Optab *o)
 {
@@ -1644,7 +1317,7 @@ if(debug['G']) print("%ux: %s: arm %d %d %d %d\n", (uint32)(p->pc), p->from.sym-
        case 54:        /* floating point arith */
                o1 = oprrr(p->as, p->scond);
                if(p->from.type == D_FCONST) {
-                       rf = chipfloat(p->from.ieee);
+                       rf = chipfloat(&p->from.ieee);
                        if(rf < 0){
                                diag("invalid floating-point immediate\n%P", p);
                                rf = 0;
index 5b1f46af013c78ac781f5d8b7a1d3eeeecc63b09..6414b023ac6a228d0c658fd23da670bc597d59f2 100644 (file)
@@ -49,6 +49,7 @@ typedef       struct  Adr     Adr;
 typedef        struct  Sym     Sym;
 typedef        struct  Autom   Auto;
 typedef        struct  Prog    Prog;
+typedef        struct  Reloc   Reloc;
 typedef        struct  Optab   Optab;
 typedef        struct  Oprang  Oprang;
 typedef        uchar   Opcross[32][2][32];
@@ -66,7 +67,7 @@ struct        Adr
        {
                int32   u0offset;
                char*   u0sval;
-               Ieee*   u0ieee;
+               Ieee    u0ieee;
                char*   u0sbig;
        } u0;
        Sym*    sym;
@@ -81,9 +82,19 @@ struct       Adr
 
 #define        offset  u0.u0offset
 #define        sval    u0.u0sval
+#define        scon    sval
 #define        ieee    u0.u0ieee
 #define        sbig    u0.u0sbig
 
+struct Reloc
+{
+       int32   off;
+       uchar   siz;
+       uchar   type;
+       int32   add;
+       Sym*    sym;
+};
+
 struct Prog
 {
        Adr     from;
@@ -105,8 +116,10 @@ struct     Prog
        uchar   reg;
        uchar   align;
 };
+
 #define        regused u0.u0regused
 #define        forwd   u0.u0forwd
+#define        datasize        reg
 
 struct Sym
 {
@@ -116,6 +129,7 @@ struct      Sym
        uchar   dupok;
        uchar   reachable;
        uchar   dynexport;
+       uchar   leaf;
        int32   value;
        int32   sig;
        int32   size;
@@ -136,7 +150,12 @@ struct     Sym
        Prog*   text;
        
        // SDATA, SBSS
-       Prog*   data;
+       uchar*  p;
+       int32   np;
+       int32   maxp;
+       Reloc*  r;
+       int32   nr;
+       int32   maxr;
 };
 
 #define SIGNINTERN     (1729*325*1729)
@@ -180,20 +199,18 @@ struct    Use
 enum
 {
        Sxxx,
-
+       
+       /* order here is order in output file */
        STEXT           = 1,
+       SRODATA,
+       SELFDATA,
        SDATA,
        SBSS,
-       SDATA1,
+
        SXREF,
-       SLEAF,
        SFILE,
        SCONST,
-       SSTRING,
-       SREMOVED,
-       
        SFIXED,
-       SELFDATA,
 
        LFROM           = 1<<0,
        LTO             = 1<<1,
@@ -300,7 +317,6 @@ EXTERN      int32   INITTEXT;               /* text location */
 EXTERN char*   INITENTRY;              /* entry point */
 EXTERN int32   autosize;
 EXTERN Biobuf  bso;
-EXTERN int32   bsssize;
 EXTERN int     cbc;
 EXTERN uchar*  cbp;
 EXTERN int     cout;
@@ -308,11 +324,9 @@ EXTERN     Auto*   curauto;
 EXTERN Auto*   curhist;
 EXTERN Prog*   curp;
 EXTERN Sym*    cursym;
-EXTERN Prog*   datap;
-EXTERN int32   datsize;
+EXTERN Sym*    datap;
 EXTERN int32   elfdatsize;
 EXTERN char    debug[128];
-EXTERN Prog*   edatap;
 EXTERN Sym*    etextp;
 EXTERN char*   noname;
 EXTERN int     xrefresolv;
@@ -388,7 +402,6 @@ int chipfloat(Ieee*);
 int    cmp(int, int);
 int    compound(Prog*);
 double cputime(void);
-void   datblk(int32, int32, int);
 void   diag(char*, ...);
 void   divsig(void);
 void   dodata(void);
@@ -407,7 +420,6 @@ void        lput(int32);
 void   lputl(int32);
 void*  mysbrk(uint32);
 void   names(void);
-Prog*  newdata(Sym *s, int o, int w, int t);
 void   nocache(Prog*);
 int    ocmp(const void*, const void*);
 int32  opirr(int);
@@ -435,6 +447,7 @@ int32       rnd(int32, int32);
 void   softfloat(void);
 void   span(void);
 void   strnput(char*, int);
+int32  symaddr(Sym*);
 void   undef(void);
 void   wput(int32);
 void    wputl(ushort w);
index 666b03fde0a9059f94ba9fea74d87f0754e7c5cf..582e79aadcc00f77499b7633dc07884d9ff0a594 100644 (file)
@@ -274,7 +274,7 @@ Dconv(Fmt *fp)
                break;
 
        case D_FCONST:
-               snprint(str, sizeof str, "$%e", ieeedtod(a->ieee));
+               snprint(str, sizeof str, "$%e", ieeedtod(&a->ieee));
                break;
 
        case D_SCONST:
index 5b456c9e5c042eed22a8ee96a022747b19e8e3b5..a3a0ae29b25b3afe462d3970debad882d54e093e 100644 (file)
@@ -234,7 +234,7 @@ noops(void)
                                }
 #endif
                                if(cursym->text->mark & LEAF) {
-                                       cursym->type = SLEAF;
+                                       cursym->leaf = 1;
                                        if(!autosize)
                                                break;
                                }
index 8232e29625fcb67a04b1fd747c5e204bf512608b..b811a609fd3f3b9189d5b30774ed6506f977f34b 100644 (file)
@@ -226,9 +226,6 @@ main(int argc, char *argv[])
        buildop();
        thumbbuildop(); // could build on demand
        histgen = 0;
-       textp = nil;
-       datap = P;
-       edatap = P;
        pc = 0;
        dtype = 4;
        nuxiinit();
@@ -245,6 +242,10 @@ main(int argc, char *argv[])
        for(i=0; i<nelem(linkername); i++)
                mark(lookup(linkername[i], 0));
        deadcode();
+       if(textp == nil) {
+               diag("no code");
+               errorexit();
+       }
 
        patch();
        if(debug['p'])
@@ -254,16 +255,13 @@ main(int argc, char *argv[])
                        doprof2();
        doelf();
        dodata();
-       if(seenthumb && debug['f'])
-               fnptrs();
        follow();
-       if(textp == nil) {
-               diag("no code");
-               errorexit();
-       }
        softfloat();
        noops();
+       xdefine("setR12", SFIXED, 0);
        span();
+       xdefine("setR12", SFIXED, INITDAT+BIG);
+       reloc();
        asmb();
        undef();
 
@@ -308,7 +306,7 @@ zaddr(Biobuf *f, Adr *a, Sym *h[])
        if(a->type == D_CONST || a->type == D_OCONST) {
                if(a->name == D_EXTERN || a->name == D_STATIC) {
                        s = a->sym;
-                       if(s != S && (s->type == STEXT || s->type == SLEAF || s->type == SCONST || s->type == SXREF)) {
+                       if(s != S && (s->type == STEXT || s->type == SCONST || s->type == SXREF)) {
                                if(0 && !s->fnptr && s->name[0] != '.')
                                        print("%s used as function pointer\n", s->name);
                                s->fnptr = 1;   // over the top cos of SXREF
@@ -351,9 +349,8 @@ zaddr(Biobuf *f, Adr *a, Sym *h[])
                break;
 
        case D_FCONST:
-               a->ieee = mal(sizeof(Ieee));
-               a->ieee->l = Bget4(f);
-               a->ieee->h = Bget4(f);
+               a->ieee.l = Bget4(f);
+               a->ieee.h = Bget4(f);
                break;
        }
        s = a->sym;
@@ -394,7 +391,7 @@ void
 ldobj1(Biobuf *f, char *pkg, int64 len, char *pn)
 {
        int32 ipc;
-       Prog *p, *t;
+       Prog *p;
        Sym *h[NSYM], *s, *di;
        int v, o, r, skip;
        uint32 sig;
@@ -492,8 +489,8 @@ loop:
        zaddr(f, &p->from, h);
        zaddr(f, &p->to, h);
 
-       if(p->reg > NREG)
-               diag("register out of range %d", p->reg);
+       if(p->as != ATEXT && p->as != AGLOBL && p->reg > NREG)
+               diag("register out of range %A %d", p->as, p->reg);
 
        p->link = P;
        p->cond = P;
@@ -541,8 +538,8 @@ loop:
                        s->type = SBSS;
                        s->value = 0;
                }
-               if(p->to.offset > s->value)
-                       s->value = p->to.offset;
+               if(p->to.offset > s->size)
+                       s->size = p->to.offset;
                if(p->reg & DUPOK)
                        s->dupok = 1;
                break;
@@ -553,26 +550,19 @@ loop:
                // ignore any more ADATA we see, which must be
                // redefinitions.
                s = p->from.sym;
-               if(s != S && s->dupok) {
+               if(s->dupok) {
                        if(debug['v'])
                                Bprint(&bso, "skipping %s in %s: dupok\n", s->name, pn);
                        goto loop;
                }
-               if(s != S) {
-                       p->dlink = s->data;
-                       s->data = p;
-                       if(s->file == nil)
-                               s->file = pn;
-                       else if(s->file != pn) {
-                               diag("multiple initialization for %s: in both %s and %s", s->name, s->file, pn);
-                               errorexit();
-                       }                       
+               if(s->file == nil)
+                       s->file = pn;
+               else if(s->file != pn) {
+                       diag("multiple initialization for %s: in both %s and %s", s->name, s->file, pn);
+                       errorexit();
                }
-               if(edatap == P)
-                       datap = p;
-               else
-                       edatap->link = p;
-               edatap = p;
+               savedata(s, p);
+               unmal(p, sizeof *p);
                break;
 
        case AGOK:
@@ -673,27 +663,14 @@ loop:
                if(skip)
                        goto casedef;
 
-               if(p->from.type == D_FCONST && chipfloat(p->from.ieee) < 0) {
+               if(p->from.type == D_FCONST && chipfloat(&p->from.ieee) < 0) {
                        /* size sb 9 max */
-                       sprint(literal, "$%ux", ieeedtof(p->from.ieee));
+                       sprint(literal, "$%ux", ieeedtof(&p->from.ieee));
                        s = lookup(literal, 0);
                        if(s->type == 0) {
                                s->type = SBSS;
-                               s->value = 4;
-                               t = prg();
-                               t->as = ADATA;
-                               t->line = p->line;
-                               t->from.type = D_OREG;
-                               t->from.sym = s;
-                               t->from.name = D_EXTERN;
-                               t->reg = 4;
-                               t->to = p->from;
-                               if(edatap == P)
-                                       datap = t;
-                               else
-                                       edatap->link = t;
-                               edatap = t;
-                               t->link = P;
+                               adduint32(s, ieeedtof(&p->from.ieee));
+                               s->reachable = 0;
                        }
                        p->from.type = D_OREG;
                        p->from.sym = s;
@@ -708,28 +685,16 @@ loop:
                if(skip)
                        goto casedef;
 
-               if(p->from.type == D_FCONST && chipfloat(p->from.ieee) < 0) {
+               if(p->from.type == D_FCONST && chipfloat(&p->from.ieee) < 0) {
                        /* size sb 18 max */
                        sprint(literal, "$%ux.%ux",
-                               p->from.ieee->l, p->from.ieee->h);
+                               p->from.ieee.l, p->from.ieee.h);
                        s = lookup(literal, 0);
                        if(s->type == 0) {
                                s->type = SBSS;
-                               s->value = 8;
-                               t = prg();
-                               t->as = ADATA;
-                               t->line = p->line;
-                               t->from.type = D_OREG;
-                               t->from.sym = s;
-                               t->from.name = D_EXTERN;
-                               t->reg = 8;
-                               t->to = p->from;
-                               if(edatap == P)
-                                       datap = t;
-                               else
-                                       edatap->link = t;
-                               edatap = t;
-                               t->link = P;
+                               adduint32(s, p->from.ieee.l);
+                               adduint32(s, p->from.ieee.h);
+                               s->reachable = 0;
                        }
                        p->from.type = D_OREG;
                        p->from.sym = s;
index 8225a43fc77040dfcffd5823606fcc674bafc511..e16b34171be85301496d2ee041be6c751dc59539 100644 (file)
 
 static void xfol(Prog*, Prog**);
 
-void
-dodata(void)
-{
-       int i, t;
-       Sym *s;
-       Prog *p;
-       int32 orig, v;
-
-       if(debug['v'])
-               Bprint(&bso, "%5.2f dodata\n", cputime());
-       Bflush(&bso);
-       for(p = datap; p != P; p = p->link) {
-               s = p->from.sym;
-               if(s->type == SBSS)
-                       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;
-               if(v > s->value)
-                       diag("initialize bounds (%d/%d): %s\n%P",
-                               v, s->value, s->name, p);
-               if((s->type == SBSS || s->type == SDATA) && (p->to.type == D_CONST || p->to.type == D_OCONST) && (p->to.name == D_EXTERN || p->to.name == D_STATIC)){
-                       s = p->to.sym;
-                       if(s != S && (s->type == STEXT || s->type == SLEAF || s->type == SCONST || s->type == SXREF))
-                               s->fnptr = 1;
-               }
-       }
-
-       if(debug['t']) {
-               /*
-                * pull out string constants
-                */
-               for(p = datap; p != P; p = p->link) {
-                       s = p->from.sym;
-                       if(p->to.type == D_SCONST)
-                               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->hash) {
-               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
-        *      assign 'small' variables to data segment
-        *      (rational is that data segment is more easily
-        *       addressed through offset on R12)
-        */
-       for(i=0; i<NHASH; i++)
-       for(s = hash[i]; s != S; s = s->hash) {
-               t = s->type;
-               if(t != SDATA && t != SBSS)
-                       continue;
-               v = s->value;
-               if(v == 0) {
-                       diag("%s: no size", s->name);
-                       v = 1;
-               }
-               while(v & 3)
-                       v++;
-               s->size = v;
-               s->value = v;
-               if(v > MINSIZ)
-                       continue;
-               s->value = orig;
-               orig += v;
-               s->type = SDATA1;
-       }
-
-       /*
-        * pass 2
-        *      assign large 'data' variables to data segment
-        */
-       for(i=0; i<NHASH; i++)
-       for(s = hash[i]; s != S; s = s->hash) {
-               t = s->type;
-               if(t != SDATA) {
-                       if(t == SDATA1)
-                               s->type = SDATA;
-                       continue;
-               }
-               v = s->value;
-               s->size = v;
-               s->value = orig;
-               orig += v;
-       }
-
-       while(orig & 7)
-               orig++;
-       datsize = orig;
-
-       /*
-        * pass 3
-        *      everything else to bss segment
-        */
-       for(i=0; i<NHASH; i++)
-       for(s = hash[i]; s != S; s = s->hash) {
-               if(s->type != SBSS)
-                       continue;
-               v = s->value;
-               s->size = v;
-               s->value = orig;
-               orig += v;
-       }
-       while(orig & 7)
-               orig++;
-       bsssize = orig-datsize;
-
-       xdefine("setR12", SDATA, 0L+BIG);
-       xdefine("bdata", SDATA, 0L);
-       xdefine("data", SBSS, 0);
-       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
 undef(void)
 {
@@ -500,205 +363,3 @@ rnd(int32 v, int32 r)
        v -= c;
        return v;
 }
-
-static void
-fused(Adr *a, Prog *p, Prog *ct)
-{
-       Sym *s = a->sym;
-       Use *u;
-
-       if(s == S)
-               return;
-       if(a->type == D_OREG || a->type == D_OCONST || a->type == D_CONST){
-               if(a->name == D_EXTERN || a->name == D_STATIC){
-                       u = malloc(sizeof(Use));
-                       u->p = p;
-                       u->ct = ct;
-                       u->link = s->use;
-                       s->use = u;
-               }
-       }
-       else if(a->type == D_BRANCH){
-               u = malloc(sizeof(Use));
-               u->p = p;
-               u->ct = ct;
-               u->link = s->use;
-               s->use = u;
-       }
-}
-
-static int
-ckfpuse(Prog *p, Prog *ct, Sym *fp, Sym *r)
-{
-       int reg;
-
-       USED(fp);
-       USED(ct);
-       if(p->from.sym == r && p->as == AMOVW && (p->from.type == D_CONST || p->from.type == D_OREG) && p->reg == NREG && p->to.type == D_REG){
-               reg = p->to.reg;
-               for(p = p->link; p != P && p->as != ATEXT; p = p->link){
-                       if((p->as == ABL || p->as == ABX) && p->to.type == D_OREG && p->to.reg == reg)
-                               return 1;
-                       if(!debug['F'] && (isbranch(p) || p->as == ARET)){
-                               // print("%s: branch %P in %s\n", fp->name, p, ct->from.sym->name);
-                               return 0;
-                       }
-                       if((p->from.type == D_REG || p->from.type == D_OREG) && p->from.reg == reg){
-                               if(!debug['F'] && p->to.type != D_REG){
-                                       // print("%s: store %P in %s\n", fp->name, p, ct->from.sym->name);
-                                       return 0;
-                               }
-                               reg = p->to.reg;
-                       }
-               }
-       }
-       // print("%s: no MOVW O(R), R\n", fp->name);
-       return debug['F'];
-}
-
-static void
-setfpuse(Prog *p, Sym *fp, Sym *r)
-{
-       int reg;
-
-       if(p->from.sym == r && p->as == AMOVW && (p->from.type == D_CONST || p->from.type == D_OREG) && p->reg == NREG && p->to.type == D_REG){
-               reg = p->to.reg;
-               for(p = p->link; p != P && p->as != ATEXT; p = p->link){
-                       if((p->as == ABL || p->as == ABX) && p->to.type == D_OREG && p->to.reg == reg){
-                               fp->fnptr = 0;
-                               p->as = ABL;    // safe to do so
-// print("simplified %s call\n", fp->name);
-                               break;
-                       }
-                       if(!debug['F'] && (isbranch(p) || p->as == ARET))
-                               diag("bad setfpuse call");
-                       if((p->from.type == D_REG || p->from.type == D_OREG) && p->from.reg == reg){
-                               if(!debug['F'] && p->to.type != D_REG)
-                                       diag("bad setfpuse call");
-                               reg = p->to.reg;
-                       }
-               }
-       }
-}
-
-static int
-cksymuse(Sym *s, int t)
-{
-       Prog *p;
-
-       for(p = datap; p != P; p = p->link){
-               if(p->from.sym == s && p->to.sym != nil && strcmp(p->to.sym->name, ".string") != 0 && p->to.sym->thumb != t){
-                       // print("%s %s %d %d ", p->from.sym->name, p->to.sym->name, p->to.sym->thumb, t);
-                       return 0;
-               }
-       }
-       return 1;
-}
-
-/* check the use of s at the given point */
-static int
-ckuse(Sym *s, Sym *s0, Use *u)
-{
-       Sym *s1;
-
-       s1 = u->p->from.sym;
-// print("ckuse %s %s %s\n", s->name, s0->name, s1 ? s1->name : "nil");
-       if(u->ct == nil){       /* in data area */
-               if(s0 == s && !cksymuse(s1, s0->thumb)){
-                       // print("%s: cksymuse fails\n", s0->name);
-                       return 0;
-               }
-               for(u = s1->use; u != U; u = u->link)
-                       if(!ckuse(s1, s0, u))
-                               return 0;
-       }
-       else{           /* in text area */
-               if(u->ct->from.sym->thumb != s0->thumb){
-                       // print("%s(%d): foreign call %s(%d)\n", s0->name, s0->thumb, u->ct->from.sym->name, u->ct->from.sym->thumb);
-                       return 0;
-               }
-               return ckfpuse(u->p, u->ct, s0, s);
-       }
-       return 1;
-}
-
-static void
-setuse(Sym *s, Sym *s0, Use *u)
-{
-       Sym *s1;
-
-       s1 = u->p->from.sym;
-       if(u->ct == nil){       /* in data area */
-               for(u = s1->use; u != U; u = u->link)
-                       setuse(s1, s0, u);
-       }
-       else{           /* in text area */
-               setfpuse(u->p, s0, s);
-       }
-}
-
-/* detect BX O(R) which can be done as BL O(R) */
-void
-fnptrs(void)
-{
-       int i;
-       Sym *s;
-       Prog *p;
-       Use *u;
-
-       for(i=0; i<NHASH; i++){
-               for(s = hash[i]; s != S; s = s->hash){
-                       if(s->fnptr && (s->type == STEXT || s->type == SLEAF || s->type == SCONST)){
-                               // print("%s : fnptr %d %d\n", s->name, s->thumb, s->foreign);
-                       }
-               }
-       }
-       /* record use of syms */
-       for(cursym = textp; cursym != nil; cursym = cursym->next)
-       for(p = cursym->text; p != P; p = p->link) {
-               if(p->as != ATEXT) {
-                       fused(&p->from, p, cursym->text);
-                       fused(&p->to, p, cursym->text);
-               }
-       }
-       for(p = datap; p != P; p = p->link)
-               fused(&p->to, p, nil);
-
-       /* now look for fn ptrs */
-       for(i=0; i<NHASH; i++){
-               for(s = hash[i]; s != S; s = s->hash){
-                       if(s->fnptr && (s->type == STEXT || s->type == SLEAF || s->type == SCONST)){
-                               for(u = s->use; u != U; u = u->link){
-                                       if(!ckuse(s, s, u))
-                                               break;
-                               }
-                               if(u == U){             // can simplify
-                                       for(u = s->use; u != U; u = u->link)
-                                               setuse(s, s, u);
-                               }
-                       }
-               }
-       }
-
-       /*  now free Use structures */
-}
-
-Prog*
-newdata(Sym *s, int o, int w, int t)
-{
-       Prog *p;
-
-       p = prg();
-       p->link = datap;
-       datap = p;
-       p->as = ADATA;
-       p->reg = w;
-       p->from.type = D_OREG;
-       p->from.name = t;
-       p->from.sym = s;
-       p->from.offset = o;
-       p->to.type = D_CONST;
-       p->to.name = D_NONE;
-       s->data = p;
-       return p;
-}
index 4a168870b1799fc5cab323b8c416fd207c236347..e02ee913818285bbe7e58e6c5ebe6a29b9edc9fa 100644 (file)
@@ -165,16 +165,19 @@ void
 span(void)
 {
        Prog *p, *op;
-       Sym *setext, *s;
        Optab *o;
-       int m, bflag, i;
-       int32 c, otxt, v;
+       int m, bflag;
+       int32 c, otxt;
        int lastthumb = -1;
+       Section *rosect, *sect;
+       Sym *sym;
 
        if(debug['v'])
                Bprint(&bso, "%5.2f span\n", cputime());
        Bflush(&bso);
 
+       xdefine("etext", STEXT, 0);
+
        bflag = 0;
        c = INITTEXT;
        op = nil;
@@ -364,36 +367,61 @@ span(void)
                        goto loop;
                }
        }
-
-       if(debug['t']) {
-               /*
-                * add strings to text segment
-                */
-               c = rnd(c, 8);
-               for(i=0; i<NHASH; i++)
-               for(s = hash[i]; s != S; s = s->hash) {
-                       if(s->type != SSTRING)
-                               continue;
-                       v = s->value;
-                       while(v & 3)
-                               v++;
-                       s->value = c;
-                       c += v;
-               }
-       }
-
        c = rnd(c, 8);
 
-       setext = lookup("etext", 0);
-       if(setext != S) {
-               setext->value = c;
-               textsize = c - INITTEXT;
+       xdefine("etext", STEXT, c);
+       for(cursym = textp; cursym != nil; cursym = cursym->next)
+               cursym->value = cursym->text->pc;
+       textsize = c - INITTEXT;
+       
+       rosect = segtext.sect->next;
+       if(rosect) {
+               if(INITRND)
+                       c = rnd(c, INITRND);
+               rosect->vaddr = c;
+               c += rosect->len;
        }
+
        if(INITRND)
                INITDAT = rnd(c, INITRND);
+       
        if(debug['v'])
                Bprint(&bso, "tsize = %ux\n", textsize);
        Bflush(&bso);
+       
+       segtext.rwx = 05;
+       segtext.vaddr = INITTEXT - HEADR;
+       segtext.len = INITDAT - INITTEXT + HEADR;
+       segtext.filelen = segtext.len;
+       
+       sect = segtext.sect;
+       sect->vaddr = INITTEXT;
+       sect->len = textsize;
+
+       // Adjust everything now that we know INITDAT.
+       // This will get simpler when everything is relocatable
+       // and we can run span before dodata.
+
+       segdata.vaddr += INITDAT;
+       for(sect=segdata.sect; sect!=nil; sect=sect->next)
+               sect->vaddr += INITDAT;
+
+       xdefine("data", SBSS, INITDAT);
+       xdefine("edata", SBSS, INITDAT+segdata.filelen);
+       xdefine("end", SBSS, INITDAT+segdata.len);
+
+       for(sym=datap; sym!=nil; sym=sym->next) {
+               switch(sym->type) {
+               case SELFDATA:
+               case SRODATA:
+                       sym->value += rosect->vaddr;
+                       break;
+               case SDATA:
+               case SBSS:
+                       sym->value += INITDAT;
+                       break;
+               }
+       }
 }
 
 /*
@@ -512,10 +540,8 @@ xdefine(char *p, int t, int32 v)
        Sym *s;
 
        s = lookup(p, 0);
-       if(s->type == 0 || s->type == SXREF) {
-               s->type = t;
-               s->value = v;
-       }
+       s->type = t;
+       s->value = v;
 }
 
 int32
@@ -572,6 +598,37 @@ immhalf(int32 v)
        return 0;
 }
 
+int32
+symaddr(Sym *s)
+{
+       int32 v;
+
+       v = s->value;
+       switch(s->type) {
+       default:
+               diag("unexpected type %d in symaddr(%s)", s->type, s->name);
+               return 0;
+       
+       case STEXT:
+#ifdef CALLEEBX
+               v += fnpinc(s);
+#else
+               if(s->thumb)
+                       v++;    // T bit
+#endif
+               break;
+       
+       case SELFDATA:
+       case SRODATA:
+       case SDATA:
+       case SBSS:
+       case SFIXED:
+       case SCONST:
+               break;
+       }
+       return v;
+}
+
 int
 aclass(Adr *a)
 {
@@ -613,7 +670,7 @@ aclass(Adr *a)
                                        s->name, TNAME);
                                s->type = SDATA;
                        }
-                       instoffset = s->value + a->offset - BIG;
+                       instoffset = s->value + a->offset - INITDAT - BIG;
                        t = immaddr(instoffset);
                        if(t) {
                                if(immhalf(instoffset))
@@ -682,21 +739,7 @@ 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) {
-                               instoffset = s->value + a->offset;
-#ifdef CALLEEBX
-                               instoffset += fnpinc(s);
-#else
-                               if(s->thumb)
-                                       instoffset++;   // T bit
-#endif
-                               return C_LCON;
-                       }
+                       instoffset = symaddr(s) + a->offset;
                        return C_LCON;
                }
                return C_GOK;
@@ -735,26 +778,16 @@ aclass(Adr *a)
                                s->type = SDATA;
                                break;
                        case SFIXED:
-                               instoffset = s->value + a->offset;
-                               return C_LCON;
                        case STEXT:
-                       case SSTRING:
                        case SCONST:
-                       case SLEAF:
-                               instoffset = s->value + a->offset;
-#ifdef CALLEEBX
-                               instoffset += fnpinc(s);
-#else
-                               if(s->thumb)
-                                       instoffset++;   // T bit
-#endif
+                               instoffset = symaddr(s) + a->offset;
                                return C_LCON;
                        }
-                       instoffset = s->value + a->offset - BIG;
+                       instoffset = s->value + a->offset - INITDAT - BIG;
                        t = immrot(instoffset);
                        if(t && instoffset != 0)
                                return C_RECON;
-                       instoffset = s->value + a->offset + INITDAT;
+                       instoffset = symaddr(s) + a->offset;
                        return C_LCON;
 
                case D_AUTO:
index 04e50fe1d48f4217fe8ffee0cdbc4982d3e61f73..247024c33fba40fe7cdc045d8ebe91238f948c57 100644 (file)
@@ -46,37 +46,30 @@ asmsym(void)
                putsymb(s->name, 'T', s->value, s->version);
 
        for(h=0; h<NHASH; h++)
-               for(s=hash[h]; s!=S; s=s->hash)
+               for(s=hash[h]; s!=S; s=s->hash) {
+                       if(!s->reachable)
+                               continue;
                        switch(s->type) {
                        case SCONST:
-                               putsymb(s->name, 'D', s->value, s->version);
-                               continue;
-
                        case SDATA:
                        case SELFDATA:
-                               putsymb(s->name, 'D', s->value+INITDAT, s->version);
+                               putsymb(s->name, 'D', s->value, s->version);
                                continue;
 
                        case SBSS:
-                               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;
-
                        case SFILE:
                                putsymb(s->name, 'f', s->value, s->version);
                                continue;
                        }
+               }
 
        for(s=textp; s!=nil; s=s->next) {
                p = s->text;
-               if(s->type != STEXT && s->type != SLEAF)
+               if(s->type != STEXT)
                        continue;
 
                /* filenames first */
@@ -90,7 +83,7 @@ asmsym(void)
                if(!s->reachable)
                        continue;
 
-               if(s->type == STEXT)
+               if(s->leaf == 0)
                        putsymb(s->name, 'T', s->value, s->version);
                else
                        putsymb(s->name, 'L', s->value, s->version);
index db7e01bdd51320f5b5ea5b85eafe1056cbe5c722..415d0d4bd8e3a693a2b082c75f5e8146e53b67bd 100644 (file)
@@ -203,7 +203,7 @@ thumbaclass(Adr *a, Prog *p)
                                        a->sym->name, TNAME);
                                a->sym->type = SDATA;
                        }
-                       instoffset = a->sym->value + a->offset + INITDAT;
+                       instoffset = a->sym->value + a->offset;
                        return C_LEXT;  /* INITDAT unknown at this stage */
                        // return immacon(instoffset, p, C_SEXT, C_LEXT);
                case D_AUTO:
@@ -235,8 +235,8 @@ thumbaclass(Adr *a, Prog *p)
                                        s->name, TNAME);
                                s->type = SDATA;
                        }
-                       instoffset = s->value + a->offset + INITDAT;
-                       if(s->type == STEXT || s->type == SLEAF){
+                       instoffset = s->value + a->offset;
+                       if(s->type == STEXT){
                                instoffset = s->value + a->offset;
 #ifdef CALLEEBX
                                instoffset += fnpinc(s);
@@ -275,7 +275,6 @@ thumbaclass(Adr *a, Prog *p)
                                break;
                        case SCONST:
                        case STEXT:
-                       case SLEAF:
                                instoffset = s->value + a->offset;
 #ifdef CALLEEBX
                                instoffset += fnpinc(s);
@@ -285,7 +284,7 @@ thumbaclass(Adr *a, Prog *p)
 #endif
                                return C_LCON;
                        }
-                       instoffset = s->value + a->offset + INITDAT;
+                       instoffset = s->value + a->offset;
                        return C_LCON;  /* INITDAT unknown at this stage */
                        // return immcon(instoffset, p);
                case D_AUTO:
index 8d396546c3dc85cf7391247ca63087daccd2df5d..94e520a93e031cd4e056bab936eedf6821ebbfe6 100644 (file)
@@ -9,6 +9,7 @@ TARG=6l
 
 OFILES=\
        asm.$O\
+       data.$O\
        dwarf.$O\
        elf.$O\
        enam.$O\
index fcca32748dbc79ec8a40500a8a4c0fdbba60dc65..839ebdf3ded7898385e17b4c6f78163b2fb286aa 100644 (file)
@@ -44,7 +44,6 @@ char linuxdynld[] = "/lib64/ld-linux-x86-64.so.2";
 char freebsddynld[] = "/libexec/ld-elf.so.1";
 
 char   zeroes[32];
-Prog*  datsort(Prog *l);
 
 vlong
 entryvalue(void)
@@ -58,13 +57,8 @@ entryvalue(void)
        s = lookup(a, 0);
        if(s->type == 0)
                return INITTEXT;
-       switch(s->type) {
-       case STEXT:
-               break;
-       case SDATA:
-       default:
+       if(s->type != STEXT)
                diag("entry not text: %s", s->name);
-       }
        return s->value;
 }
 
@@ -114,132 +108,13 @@ vputl(uint64 v)
        lputl(v>>32);
 }
 
-void
-strnput(char *s, int n)
-{
-       int i;
-
-       for(i=0; i<n; i++) {
-               cput(*s);
-               if(*s != 0)
-                       s++;
-       }
-}
-
-vlong
-addstring(Sym *s, char *str)
-{
-       int n, m;
-       vlong r;
-       Prog *p;
-
-       if(s->type == 0)
-               s->type = SDATA;
-       s->reachable = 1;
-       r = s->size;
-       n = strlen(str)+1;
-       if(strcmp(s->name, ".shstrtab") == 0)
-               elfsetstring(str, r);
-       while(n > 0) {
-               m = n;
-               if(m > sizeof(p->to.scon))
-                       m = sizeof(p->to.scon);
-               p = newdata(s, s->size, m, D_EXTERN);
-               p->to.type = D_SCONST;
-               memmove(p->to.scon, str, m);
-               s->size += m;
-               str += m;
-               n -= m;
-       }
-       return r;
-}
-
-vlong
-adduintxx(Sym *s, uint64 v, int wid)
-{
-       vlong r;
-       Prog *p;
-
-       if(s->type == 0)
-               s->type = SDATA;
-       s->reachable = 1;
-       r = s->size;
-       p = newdata(s, s->size, wid, D_EXTERN);
-       s->size += wid;
-       p->to.type = D_CONST;
-       p->to.offset = v;
-       return r;
-}
-
-vlong
-adduint8(Sym *s, uint8 v)
-{
-       return adduintxx(s, v, 1);
-}
-
-vlong
-adduint16(Sym *s, uint16 v)
-{
-       return adduintxx(s, v, 2);
-}
-
-vlong
-adduint32(Sym *s, uint32 v)
-{
-       return adduintxx(s, v, 4);
-}
-
-vlong
-adduint64(Sym *s, uint64 v)
-{
-       return adduintxx(s, v, 8);
-}
-
-vlong
-addaddr(Sym *s, Sym *t)
-{
-       vlong r;
-       Prog *p;
-       enum { Ptrsize = 8 };
-
-       if(s->type == 0)
-               s->type = SDATA;
-       s->reachable = 1;
-       r = s->size;
-       p = newdata(s, s->size, Ptrsize, D_EXTERN);
-       s->size += Ptrsize;
-       p->to.type = D_ADDR;
-       p->to.index = D_EXTERN;
-       p->to.offset = 0;
-       p->to.sym = t;
-       return r;
-}
-
-vlong
-addsize(Sym *s, Sym *t)
-{
-       vlong r;
-       Prog *p;
-       enum { Ptrsize = 8 };
-
-       if(s->type == 0)
-               s->type = SDATA;
-       s->reachable = 1;
-       r = s->size;
-       p = newdata(s, s->size, Ptrsize, D_EXTERN);
-       s->size += Ptrsize;
-       p->to.type = D_SIZE;
-       p->to.index = D_EXTERN;
-       p->to.offset = 0;
-       p->to.sym = t;
-       return r;
-}
-
 vlong
 datoff(vlong addr)
 {
        if(addr >= segdata.vaddr)
                return addr - segdata.vaddr + segdata.fileoff;
+       if(addr >= segtext.vaddr)
+               return addr - segtext.vaddr + segtext.fileoff;
        diag("datoff %#llx", addr);
        return 0;
 }
@@ -295,6 +170,9 @@ doelf(void)
 
        /* predefine strings we need for section headers */
        shstrtab = lookup(".shstrtab", 0);
+       shstrtab->type = SELFDATA;
+       shstrtab->reachable = 1;
+
        elfstr[ElfStrEmpty] = addstring(shstrtab, "");
        elfstr[ElfStrText] = addstring(shstrtab, ".text");
        elfstr[ElfStrData] = addstring(shstrtab, ".data");
@@ -470,7 +348,7 @@ asmb(void)
        int32 v, magic;
        int a, dynsym;
        uchar *op1;
-       vlong vl, va, startva, fo, w, symo, elfsymo, elfstro, elfsymsize, machlink, erodata;
+       vlong vl, va, startva, fo, w, symo, elfsymo, elfstro, elfsymsize, machlink;
        vlong symdatva = SYMDATVA;
        ElfEhdr *eh;
        ElfPhdr *ph, *pph;
@@ -518,17 +396,9 @@ asmb(void)
        }
        cflush();
 
-       datap = datsort(datap);
-
        /* output read-only data in text segment */
        sect = segtext.sect->next;
-       erodata = sect->vaddr + sect->len;
-       for(v = pc; v < erodata; v += sizeof(buf)-Dbufslop) {
-               if(erodata - v > sizeof(buf)-Dbufslop)
-                       datblk(v, sizeof(buf)-Dbufslop);
-               else
-                       datblk(v, erodata-v);
-       }
+       datblk(pc, sect->vaddr + sect->len - pc);
 
        switch(HEADTYPE) {
        default:
@@ -568,12 +438,7 @@ asmb(void)
        Bflush(&bso);
 
        segdata.fileoff = seek(cout, 0, 1);
-       for(v = 0; v < datsize; v += sizeof(buf)-Dbufslop) {
-               if(datsize-v > sizeof(buf)-Dbufslop)
-                       datblk(v+INITDAT, sizeof(buf)-Dbufslop);
-               else
-                       datblk(v+INITDAT, datsize-v);
-       }
+       datblk(INITDAT, segdata.filelen);
 
        machlink = 0;
        if(HEADTYPE == 6)
@@ -592,14 +457,14 @@ asmb(void)
                case 2:
                case 5:
                        debug['s'] = 1;
-                       symo = HEADR+textsize+datsize;
+                       symo = HEADR+textsize+segdata.filelen;
                        break;
                case 6:
-                       symo = rnd(HEADR+textsize, INITRND)+rnd(datsize, INITRND)+machlink;
+                       symo = rnd(HEADR+textsize, INITRND)+rnd(segdata.filelen, INITRND)+machlink;
                        break;
                case 7:
                case 9:
-                       symo = rnd(HEADR+textsize, INITRND)+datsize;
+                       symo = rnd(HEADR+textsize, INITRND)+segdata.filelen;
                        symo = rnd(symo, INITRND);
                        break;
                }
@@ -655,8 +520,8 @@ asmb(void)
                magic |= 0x00008000;            /* fat header */
                lputb(magic);                   /* magic */
                lputb(textsize);                        /* sizes */
-               lputb(datsize);
-               lputb(bsssize);
+               lputb(segdata.filelen);
+               lputb(segdata.len - segdata.filelen);
                lputb(symsize);                 /* nsyms */
                vl = entryvalue();
                lputb(PADDR(vl));               /* va of entry */
@@ -668,8 +533,8 @@ asmb(void)
                magic = 4*26*26+7;
                lputb(magic);                   /* magic */
                lputb(textsize);                /* sizes */
-               lputb(datsize);
-               lputb(bsssize);
+               lputb(segdata.filelen);
+               lputb(segdata.len - segdata.filelen);
                lputb(symsize);                 /* nsyms */
                lputb(entryvalue());            /* va of entry */
                lputb(spsize);                  /* sp offsets */
@@ -928,335 +793,6 @@ cpos(void)
        return seek(cout, 0, 1) + sizeof(buf.cbuf) - cbc;
 }
 
-void
-outa(int n, uchar *cast, uchar *map, vlong l)
-{
-       int i, j;
-
-       Bprint(&bso, pcstr, l);
-       for(i=0; i<n; i++) {
-               j = i;
-               if(map != nil)
-                       j = map[j];
-               Bprint(&bso, "%.2ux", cast[j]);
-       }
-       for(; i<Maxand; i++)
-               Bprint(&bso, "  ");
-       Bprint(&bso, "%P\n", curp);
-}
-
-/*
- * divide-and-conquer list-link
- * sort of Prog* structures.
- * Used for the data block.
- */
-int
-datcmp(Prog *p1, Prog *p2)
-{
-       vlong v1, v2;
-
-       v1 = p1->from.offset;
-       v2 = p2->from.offset;
-       if(v1 > v2)
-               return +1;
-       if(v1 < v2)
-               return -1;
-       return 0;
-}
-
-Prog*
-dsort(Prog *l)
-{
-       Prog *l1, *l2, *le;
-
-       if(l == 0 || l->link == 0)
-               return l;
-
-       l1 = l;
-       l2 = l;
-       for(;;) {
-               l2 = l2->link;
-               if(l2 == 0)
-                       break;
-               l2 = l2->link;
-               if(l2 == 0)
-                       break;
-               l1 = l1->link;
-       }
-
-       l2 = l1->link;
-       l1->link = 0;
-       l1 = dsort(l);
-       l2 = dsort(l2);
-
-       /* set up lead element */
-       if(datcmp(l1, l2) < 0) {
-               l = l1;
-               l1 = l1->link;
-       } else {
-               l = l2;
-               l2 = l2->link;
-       }
-       le = l;
-
-       for(;;) {
-               if(l1 == 0) {
-                       while(l2) {
-                               le->link = l2;
-                               le = l2;
-                               l2 = l2->link;
-                       }
-                       le->link = 0;
-                       break;
-               }
-               if(l2 == 0) {
-                       while(l1) {
-                               le->link = l1;
-                               le = l1;
-                               l1 = l1->link;
-                       }
-                       break;
-               }
-               if(datcmp(l1, l2) < 0) {
-                       le->link = l1;
-                       le = l1;
-                       l1 = l1->link;
-               } else {
-                       le->link = l2;
-                       le = l2;
-                       l2 = l2->link;
-               }
-       }
-       le->link = 0;
-       return l;
-}
-
-static Prog *datp;
-
-Prog*
-datsort(Prog *l)
-{
-       Prog *p;
-       Adr *a;
-
-       for(p = l; p != P; p = p->link) {
-               a = &p->from;
-               a->offset += a->sym->value;
-               if(a->sym->type != SRODATA)
-                       a->offset += INITDAT;
-       }
-       datp = dsort(l);
-       return datp;
-}
-
-void
-datblk(int32 s, int32 n)
-{
-       Prog *p;
-       uchar *cast;
-       int32 l, fl, j;
-       vlong o;
-       int i, c;
-       Adr *a;
-
-       for(p = datp; p != P; p = p->link) {
-               a = &p->from;
-               l = a->offset - s;
-               if(l+a->scale < 0)
-                       continue;
-               datp = p;
-               break;
-       }
-
-       memset(buf.dbuf, 0, n+Dbufslop);
-       for(p = datp; p != P; p = p->link) {
-               a = &p->from;
-
-               l = a->offset - s;
-               if(l >= n)
-                       break;
-
-               c = a->scale;
-               i = 0;
-               if(l < 0) {
-                       if(l+c <= 0)
-                               continue;
-                       i = -l;
-                       l = 0;
-               }
-
-               curp = p;
-               if(!a->sym->reachable)
-                       diag("unreachable symbol in datblk - %s", a->sym->name);
-               if(a->sym->type == SMACHO)
-                       continue;
-
-               for(j=l+(c-i)-1; j>=l; j--)
-                       if(buf.dbuf[j]) {
-                               print("%P\n", p);
-                               diag("multiple initialization for %d %d", s, j);
-                               break;
-                       }
-
-               switch(p->to.type) {
-               case D_FCONST:
-                       switch(c) {
-                       default:
-                       case 4:
-                               fl = ieeedtof(&p->to.ieee);
-                               cast = (uchar*)&fl;
-                               for(; i<c; i++) {
-                                       buf.dbuf[l] = cast[fnuxi4[i]];
-                                       l++;
-                               }
-                               break;
-                       case 8:
-                               cast = (uchar*)&p->to.ieee;
-                               for(; i<c; i++) {
-                                       buf.dbuf[l] = cast[fnuxi8[i]];
-                                       l++;
-                               }
-                               break;
-                       }
-                       break;
-
-               case D_SCONST:
-                       for(; i<c; i++) {
-                               buf.dbuf[l] = p->to.scon[i];
-                               l++;
-                       }
-                       break;
-
-               default:
-                       o = p->to.offset;
-                       if(p->to.type == D_SIZE)
-                               o += p->to.sym->size;
-                       if(p->to.type == D_ADDR) {
-                               if(p->to.index != D_STATIC && p->to.index != D_EXTERN)
-                                       diag("DADDR type%P", p);
-                               if(p->to.sym) {
-                                       if(p->to.sym->type == Sxxx) {
-                                               cursym = p->from.sym;
-                                               diag("missing symbol %s", p->to.sym->name);
-                                               cursym = nil;
-                                       }
-                                       o += p->to.sym->value;
-                                       if(p->to.sym->type != STEXT && p->to.sym->type != SUNDEF && p->to.sym->type != SRODATA)
-                                               o += INITDAT;
-                               }
-                       }
-                       fl = o;
-                       cast = (uchar*)&fl;
-                       switch(c) {
-                       default:
-                               diag("bad nuxi %d %d\n%P", c, i, curp);
-                               break;
-                       case 1:
-                               for(; i<c; i++) {
-                                       buf.dbuf[l] = cast[inuxi1[i]];
-                                       l++;
-                               }
-                               break;
-                       case 2:
-                               for(; i<c; i++) {
-                                       buf.dbuf[l] = cast[inuxi2[i]];
-                                       l++;
-                               }
-                               break;
-                       case 4:
-                               for(; i<c; i++) {
-                                       buf.dbuf[l] = cast[inuxi4[i]];
-                                       l++;
-                               }
-                               break;
-                       case 8:
-                               cast = (uchar*)&o;
-                               for(; i<c; i++) {
-                                       buf.dbuf[l] = cast[inuxi8[i]];
-                                       l++;
-                               }
-                               break;
-                       }
-                       break;
-               }
-       }
-
-       ewrite(cout, buf.dbuf, n);
-       if(!debug['a'])
-               return;
-
-       /*
-        * a second pass just to print the asm
-        */
-       for(p = datap; p != P; p = p->link) {
-               a = &p->from;
-
-               l = a->offset - s;
-               if(l >= n)
-                       continue;
-
-               c = a->scale;
-               i = 0;
-               if(l < 0)
-                       continue;
-
-               if(a->sym->type == SMACHO)
-                       continue;
-
-               curp = p;
-               switch(p->to.type) {
-               case D_FCONST:
-                       switch(c) {
-                       default:
-                       case 4:
-                               fl = ieeedtof(&p->to.ieee);
-                               cast = (uchar*)&fl;
-                               outa(c, cast, fnuxi4, l+s);
-                               break;
-                       case 8:
-                               cast = (uchar*)&p->to.ieee;
-                               outa(c, cast, fnuxi8, l+s);
-                               break;
-                       }
-                       break;
-
-               case D_SCONST:
-                       outa(c, (uchar*)p->to.scon, nil, l+s);
-                       break;
-
-               default:
-                       o = p->to.offset;
-                       if(p->to.type == D_SIZE)
-                               o += p->to.sym->size;
-                       if(p->to.type == D_ADDR) {
-                               if(p->to.sym) {
-                                       o += p->to.sym->value;
-                                       if(p->to.sym->type != STEXT && p->to.sym->type != SUNDEF && p->to.sym->type != SRODATA)
-                                               o += INITDAT;
-                               }
-                       }
-                       fl = o;
-                       cast = (uchar*)&fl;
-                       switch(c) {
-                       case 1:
-                               outa(c, cast, inuxi1, l+s);
-                               break;
-                       case 2:
-                               outa(c, cast, inuxi2, l+s);
-                               break;
-                       case 4:
-                               outa(c, cast, inuxi4, l+s);
-                               break;
-                       case 8:
-                               cast = (uchar*)&o;
-                               outa(c, cast, inuxi8, l+s);
-                               break;
-                       }
-                       break;
-               }
-       }
-}
-
 vlong
 rnd(vlong v, vlong r)
 {
index d8aa25eb9dcc8eccb69a220f841354a28a47665c..b9a283ad34f97010b497bd38a407e636c9a28999 100644 (file)
@@ -56,6 +56,7 @@ typedef       struct  Sym     Sym;
 typedef        struct  Auto    Auto;
 typedef        struct  Optab   Optab;
 typedef        struct  Movtab  Movtab;
+typedef        struct  Reloc   Reloc;
 
 struct Adr
 {
@@ -79,6 +80,15 @@ struct       Adr
 #define        ieee    u0.u0ieee
 #define        sbig    u0.u0sbig
 
+struct Reloc
+{
+       int32   off;
+       uchar   siz;
+       uchar   type;
+       int64   add;
+       Sym*    sym;
+};
+
 struct Prog
 {
        Adr     from;
@@ -99,6 +109,8 @@ struct       Prog
        char    width;  /* fake for DATA */
        char    mode;   /* 16, 32, or 64 */
 };
+#define        datasize        from.scale
+
 struct Auto
 {
        Sym*    asym;
@@ -130,7 +142,12 @@ struct     Sym
        Prog*   text;
        
        // SDATA, SBSS
-       Prog*   data;
+       uchar*  p;
+       int32   np;
+       int32   maxp;
+       Reloc*  r;
+       int32   nr;
+       int32   maxr;
 };
 struct Optab
 {
@@ -151,19 +168,19 @@ struct    Movtab
 enum
 {
        Sxxx,
+       
+       /* order here is order in output file */
        STEXT           = 1,
+       SELFDATA,
+       SRODATA,
        SDATA,
        SBSS,
-       SDATA1,
+
        SXREF,
+       SMACHO,
        SFILE,
        SCONST,
-       SUNDEF,
-
-       SMACHO,
        SFIXED,
-       SELFDATA,
-       SRODATA,
 
        NHASH           = 10007,
        NHUNK           = 100000,
@@ -298,7 +315,6 @@ EXTERN      int32   INITRND;
 EXTERN vlong   INITTEXT;
 EXTERN char*   INITENTRY;              /* entry point */
 EXTERN Biobuf  bso;
-EXTERN int32   bsssize;
 EXTERN int     cbc;
 EXTERN char*   cbp;
 EXTERN char*   pcstr;
@@ -306,9 +322,7 @@ EXTERN      Auto*   curauto;
 EXTERN Auto*   curhist;
 EXTERN Prog*   curp;
 EXTERN Sym*    cursym;
-EXTERN Prog*   datap;
-EXTERN Prog*   edatap;
-EXTERN vlong   datsize;
+EXTERN Sym*    datap;
 EXTERN vlong   elfdatsize;
 EXTERN char    debug[128];
 EXTERN char    literal[32];
@@ -359,11 +373,6 @@ int        Sconv(Fmt*);
 void   addhist(int32, int);
 void   addstackmark(void);
 Prog*  appendp(Prog*);
-vlong  addstring(Sym*, char*);
-vlong  adduint32(Sym*, uint32);
-vlong  adduint64(Sym*, uint64);
-vlong  addaddr(Sym*, Sym*);
-vlong  addsize(Sym*, Sym*);
 void   asmb(void);
 void   asmdyn(void);
 void   asmins(Prog*);
@@ -380,10 +389,8 @@ double     cputime(void);
 void   datblk(int32, int32);
 void   deadcode(void);
 void   diag(char*, ...);
-void   dobss(void);
 void   dodata(void);
 void   doelf(void);
-void   doinit(void);
 void   domacho(void);
 void   doprof1(void);
 void   doprof2(void);
@@ -399,7 +406,6 @@ void        lputl(int32);
 void   instinit(void);
 void   main(int, char*[]);
 void*  mysbrk(uint32);
-Prog*  newdata(Sym*, int, int, int);
 Prog*  newtext(Prog*, Sym*);
 void   nopout(Prog*);
 int    opsize(Prog*);
@@ -407,12 +413,9 @@ void       patch(void);
 Prog*  prg(void);
 void   parsetextconst(vlong);
 int    relinv(int);
-int32  reuse(Prog*, Sym*);
 vlong  rnd(vlong, vlong);
 void   span(void);
-void   strnput(char*, int);
 void   undef(void);
-vlong  vaddr(Adr*);
 vlong  symaddr(Sym*);
 void   vputl(uint64);
 void   wputb(uint16);
index 112199b61c95b647dfb018b07a7010f21304f72f..97b79d53cbc4b9d1989140d4079857aa198228e1 100644 (file)
@@ -223,9 +223,6 @@ main(int argc, char *argv[])
        pcstr = "%.6llux ";
        nuxiinit();
        histgen = 0;
-       textp = nil;
-       datap = P;
-       edatap = P;
        pc = 0;
        dtype = 4;
        version = 0;
@@ -234,16 +231,13 @@ main(int argc, char *argv[])
 
        addlibpath("command line", "command line", argv[0], "main");
        loadlib();
-
        deadcode();
-
        patch();
        follow();
        doelf();
        if(HEADTYPE == 6)
                domacho();
        dodata();
-       dobss();
        dostkoff();
        paramspace = "SP";      /* (FP) now (SP) on output */
        if(debug['p'])
@@ -252,7 +246,7 @@ main(int argc, char *argv[])
                else
                        doprof2();
        span();
-       doinit();
+       reloc();
        asmb();
        undef();
        if(debug['v']) {
@@ -362,7 +356,7 @@ void
 ldobj1(Biobuf *f, char *pkg, int64 len, char *pn)
 {
        vlong ipc;
-       Prog *p, *t;
+       Prog *p;
        int v, o, r, skip, mode;
        Sym *h[NSYM], *s, *di;
        uint32 sig;
@@ -532,27 +526,19 @@ loop:
                // ignore any more ADATA we see, which must be
                // redefinitions.
                s = p->from.sym;
-               if(s != S && s->dupok) {
+               if(s->dupok) {
 //                     if(debug['v'])
 //                             Bprint(&bso, "skipping %s in %s: dupok\n", s->name, pn);
                        goto loop;
                }
-               if(s != S) {
-                       p->dlink = s->data;
-                       s->data = p;
-                       if(s->file == nil)
-                               s->file = pn;
-                       else if(s->file != pn) {
-                               diag("multiple initialization for %s: in both %s and %s", s->name, s->file, pn);
-                               errorexit();
-                       }
+               if(s->file == nil)
+                       s->file = pn;
+               else if(s->file != pn) {
+                       diag("multiple initialization for %s: in both %s and %s", s->name, s->file, pn);
+                       errorexit();
                }
-               if(edatap == P)
-                       datap = p;
-               else
-                       edatap->link = p;
-               edatap = p;
-               p->link = P;
+               savedata(s, p);
+               unmal(p, sizeof *p);
                goto loop;
 
        case AGOK:
@@ -636,21 +622,9 @@ loop:
                        sprint(literal, "$%ux", ieeedtof(&p->from.ieee));
                        s = lookup(literal, 0);
                        if(s->type == 0) {
-                               s->type = SBSS;
-                               s->size = 4;
-                               t = prg();
-                               t->as = ADATA;
-                               t->line = p->line;
-                               t->from.type = D_EXTERN;
-                               t->from.sym = s;
-                               t->from.scale = 4;
-                               t->to = p->from;
-                               if(edatap == P)
-                                       datap = t;
-                               else
-                                       edatap->link = t;
-                               edatap = t;
-                               t->link = P;
+                               s->type = SDATA;
+                               adduint32(s, ieeedtof(&p->from.ieee));
+                               s->reachable = 1;
                        }
                        p->from.type = D_EXTERN;
                        p->from.sym = s;
@@ -682,21 +656,10 @@ loop:
                                p->from.ieee.l, p->from.ieee.h);
                        s = lookup(literal, 0);
                        if(s->type == 0) {
-                               s->type = SBSS;
-                               s->size = 8;
-                               t = prg();
-                               t->as = ADATA;
-                               t->line = p->line;
-                               t->from.type = D_EXTERN;
-                               t->from.sym = s;
-                               t->from.scale = 8;
-                               t->to = p->from;
-                               if(edatap == P)
-                                       datap = t;
-                               else
-                                       edatap->link = t;
-                               edatap = t;
-                               t->link = P;
+                               s->type = SDATA;
+                               adduint32(s, p->from.ieee.l);
+                               adduint32(s, p->from.ieee.h);
+                               s->reachable = 1;
                        }
                        p->from.type = D_EXTERN;
                        p->from.sym = s;
index 2a5a18abd95269b495ffbbd6b60d6cd245d3c090..a2a82a18b5f6a4fd1ee73a30f07864551170c3cf 100644 (file)
@@ -42,168 +42,6 @@ enum
        StackBig = 4096,
 };
 
-void
-dodata(void)
-{
-       int i;
-       Sym *s;
-       Prog *p;
-       int32 t, u;
-       Section *sect;
-
-       if(debug['v'])
-               Bprint(&bso, "%5.2f dodata\n", cputime());
-       Bflush(&bso);
-       
-       segdata.rwx = 06;
-       segdata.vaddr = 0;      /* span will += INITDAT */
-
-       for(p = datap; p != P; p = p->link) {
-               s = p->from.sym;
-               if(s->type == SBSS)
-                       s->type = SDATA;
-               if(s->type != SDATA && s->type != SELFDATA && s->type != SRODATA)
-                       diag("%s: initialize non-data (%d)\n%P",
-                               s->name, s->type, p);
-               t = p->from.offset + p->width;
-               if(t > s->size)
-                       diag("%s: initialize bounds (%lld)\n%P",
-                               s->name, s->size, p);
-       }
-
-       /* 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->hash) {
-               if(!s->reachable)
-                       continue;
-               if(s->type != SELFDATA)
-                       continue;
-               t = rnd(s->size, 8);
-               s->size = t;
-               s->value = datsize;
-               datsize += t;
-       }
-       elfdatsize = datsize;
-       
-       sect = addsection(&segdata, ".data", 06);
-       sect->vaddr = datsize;
-
-       /* allocate small guys */
-       for(i=0; i<NHASH; i++)
-       for(s = hash[i]; s != S; s = s->hash) {
-               if(!s->reachable)
-                       continue;
-               if(s->type != SDATA)
-               if(s->type != SBSS)
-                       continue;
-               t = s->size;
-               if(t == 0 && s->name[0] != '.') {
-                       diag("%s: no size", s->name);
-                       t = 1;
-               }
-               t = rnd(t, 4);
-               if(t > MINSIZ)
-                       continue;
-               if(t >= 8)
-                       datsize = rnd(datsize, 8);
-               s->size = t;
-               s->value = datsize;
-               datsize += t;
-               s->type = SDATA1;
-       }
-
-       /* allocate the rest of the data */
-       for(i=0; i<NHASH; i++)
-       for(s = hash[i]; s != S; s = s->hash) {
-               if(!s->reachable)
-                       continue;
-               if(s->type != SDATA) {
-                       if(s->type == SDATA1)
-                               s->type = SDATA;
-                       continue;
-               }
-               t = s->size;
-               if(t >= 8)
-                       datsize = rnd(datsize, 8);
-               s->value = datsize;
-               datsize += t;
-       }
-       if(datsize)
-               datsize = rnd(datsize, 8);
-
-       if(debug['j']) {
-               /*
-                * pad data with bss that fits up to next
-                * 8k boundary, then push data to 8k
-                */
-               u = rnd(datsize, 8192);
-               u -= datsize;
-               for(i=0; i<NHASH; i++)
-               for(s = hash[i]; s != S; s = s->hash) {
-                       if(!s->reachable)
-                               continue;
-                       if(s->type != SBSS)
-                               continue;
-                       t = s->value;
-                       if(t > u)
-                               continue;
-                       u -= t;
-                       s->size = t;
-                       s->value = datsize;
-                       s->type = SDATA;
-                       datsize += t;
-               }
-               datsize += u;
-       }
-       sect->len = datsize - sect->vaddr;
-}
-
-void
-dobss(void)
-{
-       int i;
-       Sym *s;
-       int32 t;
-       Section *sect;
-
-       if(dynptrsize > 0) {
-               /* dynamic pointer section between data and bss */
-               datsize = rnd(datsize, 8);
-       }
-
-       sect = addsection(&segdata, ".bss", 06);
-       sect->vaddr = datsize;
-
-       /* now the bss */
-       bsssize = 0;
-       for(i=0; i<NHASH; i++)
-       for(s = hash[i]; s != S; s = s->hash) {
-               if(!s->reachable)
-                       continue;
-               if(s->type != SBSS)
-                       continue;
-               t = s->size;
-               if(t >= 8)
-                       bsssize = rnd(bsssize, 8);
-               s->value = bsssize + dynptrsize + datsize;
-               bsssize += t;
-       }
-       sect->len = bsssize;
-       
-       segdata.len = datsize+bsssize;
-       segdata.filelen = datsize;
-
-       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*
 brchain(Prog *p)
 {
@@ -419,28 +257,6 @@ relinv(int a)
        return a;
 }
 
-void
-doinit(void)
-{
-       Sym *s;
-       Prog *p;
-       int x;
-
-       for(p = datap; p != P; p = p->link) {
-               x = p->to.type;
-               if(x != D_EXTERN && x != D_STATIC)
-                       continue;
-               s = p->to.sym;
-               if(s->type == 0 || s->type == SXREF)
-                       diag("undefined %s initializer of %s",
-                               s->name, p->from.sym->name);
-               p->to.offset += s->value;
-               p->to.type = D_CONST;
-               if(s->type == SDATA || s->type == SBSS)
-                       p->to.offset += INITDAT;
-       }
-}
-
 void
 patch(void)
 {
@@ -878,26 +694,3 @@ undef(void)
                if(s->type == SXREF)
                        diag("%s: not defined", s->name);
 }
-
-Prog*
-newdata(Sym *s, int o, int w, int t)
-{
-       Prog *p;
-
-       p = prg();
-       if(edatap == P)
-               datap = p;
-       else
-               edatap->link = p;
-       edatap = p;
-       p->as = ADATA;
-       p->width = w;
-       p->from.scale = w;
-       p->from.type = t;
-       p->from.sym = s;
-       p->from.offset = o;
-       p->to.type = D_CONST;
-       p->dlink = s->data;
-       s->data = p;
-       return p;
-}
index 92f72a32c48a7ae072eee4736730295773428d9f..978ed0088ad9bc262e75fb82d79e4e64df4000bc 100644 (file)
@@ -40,11 +40,11 @@ void
 span(void)
 {
        Prog *p, *q;
-       int32 i, v;
-       vlong c, idat, etext, rodata, erodata;
+       int32 v;
+       vlong c, idat, etext, rosize;
        int m, n, again;
-       Sym *s;
-       Section *sect;
+       Section *sect, *rosect;
+       Sym *sym;
 
        xdefine("etext", STEXT, 0L);
        xdefine("rodata", SRODATA, 0L);
@@ -77,6 +77,9 @@ span(void)
                }
        }
        n = 0;
+       
+       rosect = segtext.sect->next;
+       rosize = rosect->len;
 
 start:
        if(debug['v'])
@@ -128,24 +131,16 @@ loop:
                goto loop;
        }
        etext = c;
-       
-       /*
-        * allocate read-only data to the text segment.
-        */
-       c = rnd(c, 8);
-       rodata = c;
-       xdefine("rodata", SRODATA, c);
-       for(i=0; i<NHASH; i++)
-       for(s = hash[i]; s != S; s = s->hash) {
-               if(s->type != SRODATA)
-                       continue;
-               v = s->size;
-               while(v & 7)
-                       v++;
-               s->value = c;
-               c += v;
+
+       if(rosect) {
+               if(INITRND)
+                       c = rnd(c, INITRND);
+               if(rosect->vaddr != c){
+                       rosect->vaddr = c;
+                       goto start;
+               }
+               c += rosect->len;
        }
-       erodata = c;
 
        if(INITRND) {
                INITDAT = rnd(c, INITRND);
@@ -156,8 +151,6 @@ loop:
        }
        
        xdefine("etext", STEXT, etext);
-       xdefine("rodata", SRODATA, rodata);
-       xdefine("erodata", SRODATA, erodata);
 
        if(debug['v'])
                Bprint(&bso, "etext = %llux\n", c);
@@ -171,17 +164,34 @@ loop:
        segtext.len = INITDAT - INITTEXT + HEADR;
        segtext.filelen = textsize + HEADR;
        
-       sect = addsection(&segtext, ".text", 05);
+       sect = segtext.sect;
        sect->vaddr = INITTEXT;
        sect->len = etext - sect->vaddr;
-       
-       sect = addsection(&segtext, ".rodata", 04);
-       sect->vaddr = rodata;
-       sect->len = erodata - rodata;
-       
+
+       // Adjust everything now that we know INITDAT.
+       // This will get simpler when everything is relocatable
+       // and we can run span before dodata.
+
        segdata.vaddr += INITDAT;
        for(sect=segdata.sect; sect!=nil; sect=sect->next)
                sect->vaddr += INITDAT;
+
+       xdefine("data", SBSS, INITDAT);
+       xdefine("edata", SBSS, INITDAT+segdata.filelen);
+       xdefine("end", SBSS, INITDAT+segdata.len);
+
+       for(sym=datap; sym!=nil; sym=sym->next) {
+               switch(sym->type) {
+               case SELFDATA:
+               case SRODATA:
+                       sym->value += rosect->vaddr;
+                       break;
+               case SDATA:
+               case SBSS:
+                       sym->value += INITDAT;
+                       break;
+               }
+       }
 }
 
 void
@@ -628,6 +638,8 @@ put8(vlong v)
        andptr += 8;
 }
 
+static vlong vaddr(Adr*);
+
 vlong
 symaddr(Sym *s)
 {
@@ -640,7 +652,7 @@ symaddr(Sym *s)
        return vaddr(&a);
 }
 
-vlong
+static vlong
 vaddr(Adr *a)
 {
        int t;
@@ -657,28 +669,16 @@ vaddr(Adr *a)
                s = a->sym;
                if(s != nil) {
                        switch(s->type) {
-                       case SUNDEF:
-                       case STEXT:
-                       case SCONST:
-                       case SRODATA:
-                               if(!s->reachable)
-                                       diag("unreachable symbol in vaddr - %s", s->name);
-                               if((uvlong)s->value < (uvlong)INITTEXT)
-                                       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);
-                               v += INITDAT + datsize + s->value;
+                               v += INITDAT + segdata.filelen - dynptrsize + s->value;
                                break;
                        default:
                                if(!s->reachable)
                                        diag("unreachable symbol in vaddr - %s", s->name);
-                               v += INITDAT + s->value;
+                               v += s->value;
                        }
                }
        }
index ef3e707e06c0ee4af2aa6328e33aff311f8e548a..f2ffa269e3d26483965f68883680d07b155856b6 100644 (file)
@@ -177,28 +177,17 @@ genasmsym(void (*put)(char*, int, vlong, vlong, int, Sym*))
                        switch(s->type) {
                        case SCONST:
                        case SRODATA:
-                               if(!s->reachable)
-                                       continue;
-                               put(s->name, 'D', s->value, s->size, s->version, s->gotype);
-                               continue;
-
                        case SDATA:
                        case SELFDATA:
                                if(!s->reachable)
                                        continue;
-                               put(s->name, 'D', s->value+INITDAT, s->size, s->version, s->gotype);
-                               continue;
-
-                       case SMACHO:
-                               if(!s->reachable)
-                                       continue;
-                               put(s->name, 'D', s->value+INITDAT+segdata.len, s->size, s->version, s->gotype);
+                               put(s->name, 'D', symaddr(s), s->size, s->version, s->gotype);
                                continue;
 
                        case SBSS:
                                if(!s->reachable)
                                        continue;
-                               put(s->name, 'B', s->value+INITDAT, s->size, s->version, s->gotype);
+                               put(s->name, 'B', symaddr(s), s->size, s->version, s->gotype);
                                continue;
 
                        case SFIXED:
index cdaef22b53cb6b983ae27a6d8d2b4249d68ca0c7..f814ab3993826c748bbab30786f389f9659a38c9 100644 (file)
@@ -9,6 +9,7 @@ TARG=8l
 
 OFILES=\
        asm.$O\
+       data.$O\
        dwarf.$O\
        elf.$O\
        enam.$O\
index b76d731e1eddb85810e0cdf407802bd1bc0be760..99d5b61563ec1c95defc1f58b80fb5dbf603752c 100644 (file)
@@ -55,13 +55,8 @@ entryvalue(void)
        s = lookup(a, 0);
        if(s->type == 0)
                return INITTEXT;
-       switch(s->type) {
-       case STEXT:
-               break;
-       case SDATA:
-       default:
+       if(s->type != STEXT)
                diag("entry not text: %s", s->name);
-       }
        return s->value;
 }
 
@@ -104,133 +99,13 @@ vputl(uvlong l)
        lputl(l);
 }
 
-void
-strnput(char *s, int n)
-{
-       for(; *s && n > 0; s++) {
-               cput(*s);
-               n--;
-       }
-       while(n > 0) {
-               cput(0);
-               n--;
-       }
-}
-
-vlong
-addstring(Sym *s, char *str)
-{
-       int n, m;
-       vlong r;
-       Prog *p;
-
-       if(s->type == 0)
-               s->type = SDATA;
-       s->reachable = 1;
-       r = s->size;
-       n = strlen(str)+1;
-       if(strcmp(s->name, ".shstrtab") == 0)
-               elfsetstring(str, r);
-       while(n > 0) {
-               m = n;
-               if(m > sizeof(p->to.scon))
-                       m = sizeof(p->to.scon);
-               p = newdata(s, s->size, m, D_EXTERN);
-               p->to.type = D_SCONST;
-               memmove(p->to.scon, str, m);
-               s->size += m;
-               str += m;
-               n -= m;
-       }
-       return r;
-}
-
-vlong
-adduintxx(Sym *s, uint64 v, int wid)
-{
-       vlong r;
-       Prog *p;
-
-       if(s->type == 0)
-               s->type = SDATA;
-       s->reachable = 1;
-       r = s->size;
-       p = newdata(s, s->size, wid, D_EXTERN);
-       s->size += wid;
-       p->to.type = D_CONST;
-       p->to.offset = v;
-       return r;
-}
-
-vlong
-adduint8(Sym *s, uint8 v)
-{
-       return adduintxx(s, v, 1);
-}
-
-vlong
-adduint16(Sym *s, uint16 v)
-{
-       return adduintxx(s, v, 2);
-}
-
-vlong
-adduint32(Sym *s, uint32 v)
-{
-       return adduintxx(s, v, 4);
-}
-
-vlong
-adduint64(Sym *s, uint64 v)
-{
-       return adduintxx(s, v, 8);
-}
-
-vlong
-addaddr(Sym *s, Sym *t)
-{
-       vlong r;
-       Prog *p;
-       enum { Ptrsize = 4 };
-
-       if(s->type == 0)
-               s->type = SDATA;
-       s->reachable = 1;
-       r = s->size;
-       p = newdata(s, s->size, Ptrsize, D_EXTERN);
-       s->size += Ptrsize;
-       p->to.type = D_ADDR;
-       p->to.index = D_EXTERN;
-       p->to.offset = 0;
-       p->to.sym = t;
-       return r;
-}
-
-vlong
-addsize(Sym *s, Sym *t)
-{
-       vlong r;
-       Prog *p;
-       enum { Ptrsize = 4 };
-
-       if(s->type == 0)
-               s->type = SDATA;
-       s->reachable = 1;
-       r = s->size;
-       p = newdata(s, s->size, Ptrsize, D_EXTERN);
-       s->size += Ptrsize;
-       p->to.type = D_SIZE;
-       p->to.index = D_EXTERN;
-       p->to.offset = 0;
-       p->to.sym = t;
-       return r;
-}
-
 vlong
 datoff(vlong addr)
 {
        if(addr >= segdata.vaddr)
                return addr - segdata.vaddr + segdata.fileoff;
+       if(addr >= segtext.vaddr)
+               return addr - segtext.vaddr + segtext.fileoff;
        diag("datoff %#llx", addr);
        return 0;
 }
@@ -284,7 +159,9 @@ doelf(void)
 
        /* predefine strings we need for section headers */
        shstrtab = lookup(".shstrtab", 0);
+       shstrtab->type = SELFDATA;
        shstrtab->reachable = 1;
+
        elfstr[ElfStrEmpty] = addstring(shstrtab, "");
        elfstr[ElfStrText] = addstring(shstrtab, ".text");
        elfstr[ElfStrData] = addstring(shstrtab, ".data");
@@ -458,7 +335,7 @@ asmb(void)
        Prog *p;
        int32 v, magic;
        int a, dynsym;
-       uint32 va, fo, w, symo, startva, machlink, erodata;
+       uint32 va, fo, w, symo, startva, machlink;
        uchar *op1;
        ulong expectpc;
        ElfEhdr *eh;
@@ -533,20 +410,8 @@ asmb(void)
        cflush();
 
        /* output read-only data in text segment */
-       if(HEADTYPE == 8) {
-               // Native Client
-               sect = segrodata.sect;
-               segrodata.fileoff = seek(cout, 0, 1);
-       } else
-               sect = segtext.sect->next;
-
-       erodata = sect->vaddr + sect->len;
-       for(v = pc; v < erodata; v += sizeof(buf)-Dbufslop) {
-               if(erodata-v > sizeof(buf)-Dbufslop)
-                       datblk(v, sizeof(buf)-Dbufslop, 1);
-               else
-                       datblk(v, erodata-v, 1);
-       }
+       sect = segtext.sect->next;
+       datblk(pc, sect->vaddr + sect->len - pc);
 
        switch(HEADTYPE) {
        default:
@@ -597,12 +462,7 @@ asmb(void)
        Bflush(&bso);
 
        segdata.fileoff = seek(cout, 0, 1);
-       for(v = 0; v < datsize; v += sizeof(buf)-Dbufslop) {
-               if(datsize-v > sizeof(buf)-Dbufslop)
-                       datblk(v, sizeof(buf)-Dbufslop, 0);
-               else
-                       datblk(v, datsize-v, 0);
-       }
+       datblk(INITDAT, segdata.filelen);
 
        machlink = 0;
        if(HEADTYPE == 6)
@@ -621,25 +481,25 @@ asmb(void)
                        if(iself)
                                goto Elfsym;
                case 0:
-                       seek(cout, rnd(HEADR+textsize, 8192)+datsize, 0);
+                       seek(cout, rnd(HEADR+textsize, 8192)+segdata.filelen, 0);
                        break;
                case 1:
-                       seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0);
+                       seek(cout, rnd(HEADR+textsize, INITRND)+segdata.filelen, 0);
                        break;
                case 2:
-                       seek(cout, HEADR+textsize+datsize, 0);
+                       seek(cout, HEADR+textsize+segdata.filelen, 0);
                        break;
                case 3:
                case 4:
                        debug['s'] = 1;
-                       symo = HEADR+textsize+datsize;
+                       symo = HEADR+textsize+segdata.filelen;
                        break;
                case 6:
-                       symo = rnd(HEADR+textsize, INITRND)+rnd(datsize, INITRND)+machlink;
+                       symo = rnd(HEADR+textsize, INITRND)+rnd(segdata.filelen, INITRND)+machlink;
                        break;
                Elfsym:
                case 10:
-                       symo = rnd(HEADR+textsize, INITRND)+datsize;
+                       symo = rnd(HEADR+textsize, INITRND)+segdata.filelen;
                        symo = rnd(symo, INITRND);
                        break;
                }
@@ -679,17 +539,17 @@ asmb(void)
        case 0: /* garbage */
                lput(0x160L<<16);               /* magic and sections */
                lput(0L);                       /* time and date */
-               lput(rnd(HEADR+textsize, 4096)+datsize);
+               lput(rnd(HEADR+textsize, 4096)+segdata.filelen);
                lput(symsize);                  /* nsyms */
                lput((0x38L<<16)|7L);           /* size of optional hdr and flags */
                lput((0413<<16)|0437L);         /* magic and version */
                lput(rnd(HEADR+textsize, 4096));        /* sizes */
-               lput(datsize);
-               lput(bsssize);
+               lput(segdata.filelen);
+               lput(segdata.len - segdata.filelen);
                lput(entryvalue());             /* va of entry */
                lput(INITTEXT-HEADR);           /* va of base of text */
                lput(INITDAT);                  /* va of base of data */
-               lput(INITDAT+datsize);          /* va of base of bss */
+               lput(INITDAT+segdata.filelen);          /* va of base of bss */
                lput(~0L);                      /* gp reg mask */
                lput(0L);
                lput(0L);
@@ -712,8 +572,8 @@ asmb(void)
                 */
                lputl(0x10b);                   /* magic, version stamp */
                lputl(rnd(textsize, INITRND));  /* text sizes */
-               lputl(datsize);                 /* data sizes */
-               lputl(bsssize);                 /* bss sizes */
+               lputl(segdata.filelen);                 /* data sizes */
+               lputl(segdata.len - segdata.filelen);                   /* bss sizes */
                lput(entryvalue());             /* va of entry */
                lputl(INITTEXT);                /* text start */
                lputl(INITDAT);                 /* data start */
@@ -735,7 +595,7 @@ asmb(void)
                s8put(".data");
                lputl(INITDAT);                 /* pa */
                lputl(INITDAT);                 /* va */
-               lputl(datsize);                 /* data size */
+               lputl(segdata.filelen);                 /* data size */
                lputl(HEADR+textsize);          /* file offset */
                lputl(0);                       /* relocation */
                lputl(0);                       /* line numbers */
@@ -745,9 +605,9 @@ asmb(void)
                 * bss section header
                 */
                s8put(".bss");
-               lputl(INITDAT+datsize);         /* pa */
-               lputl(INITDAT+datsize);         /* va */
-               lputl(bsssize);                 /* bss size */
+               lputl(INITDAT+segdata.filelen);         /* pa */
+               lputl(INITDAT+segdata.filelen);         /* va */
+               lputl(segdata.len - segdata.filelen);                   /* bss size */
                lputl(0);                       /* file offset */
                lputl(0);                       /* relocation */
                lputl(0);                       /* line numbers */
@@ -760,9 +620,9 @@ asmb(void)
                lputl(0);                       /* pa */
                lputl(0);                       /* va */
                lputl(symsize+lcsize);          /* comment size */
-               lputl(HEADR+textsize+datsize);  /* file offset */
-               lputl(HEADR+textsize+datsize);  /* offset of syms */
-               lputl(HEADR+textsize+datsize+symsize);/* offset of line numbers */
+               lputl(HEADR+textsize+segdata.filelen);  /* file offset */
+               lputl(HEADR+textsize+segdata.filelen);  /* offset of syms */
+               lputl(HEADR+textsize+segdata.filelen+symsize);/* offset of line numbers */
                lputl(0);                       /* relocation, line numbers */
                lputl(0x200);                   /* flags comment only */
                break;
@@ -770,8 +630,8 @@ asmb(void)
                magic = 4*11*11+7;
                lput(magic);            /* magic */
                lput(textsize);                 /* sizes */
-               lput(datsize);
-               lput(bsssize);
+               lput(segdata.filelen);
+               lput(segdata.len - segdata.filelen);
                lput(symsize);                  /* nsyms */
                lput(entryvalue());             /* va of entry */
                lput(spsize);                   /* sp offsets */
@@ -782,7 +642,7 @@ asmb(void)
                break;
        case 4:
                /* fake MS-DOS .EXE */
-               v = rnd(HEADR+textsize, INITRND)+datsize;
+               v = rnd(HEADR+textsize, INITRND)+segdata.filelen;
                wputl(0x5A4D);                  /* 'MZ' */
                wputl(v % 512);                 /* bytes in last page */
                wputl(rnd(v, 512)/512);         /* total number of pages */
@@ -1072,216 +932,6 @@ cpos(void)
        return seek(cout, 0, 1) + sizeof(buf.cbuf) - cbc;
 }
 
-void
-datblk(int32 s, int32 n, int32 rodata)
-{
-       Prog *p;
-       char *cast;
-       int32 l, fl, j;
-       int i, c;
-       Adr *a;
-       int32 base;
-       
-       base = INITDAT;
-       if(rodata)
-               base = 0;
-
-       memset(buf.dbuf, 0, n+Dbufslop);
-       for(p = datap; p != P; p = p->link) {
-               a = &p->from;
-               if(rodata != (a->sym->type == SRODATA))
-                       continue;
-
-               l = a->sym->value + a->offset - s;
-               if(l >= n)
-                       continue;
-
-               c = a->scale;
-               i = 0;
-               if(l < 0) {
-                       if(l+c <= 0)
-                               continue;
-                       i = -l;
-                       l = 0;
-               }
-
-               curp = p;
-               if(!a->sym->reachable)
-                       diag("unreachable symbol in datblk - %s", a->sym->name);
-               if(a->sym->type == SMACHO)
-                       continue;
-
-               for(j=l+(c-i)-1; j>=l; j--)
-                       if(buf.dbuf[j]) {
-                               print("%P\n", p);
-                               diag("multiple initialization");
-                               break;
-                       }
-               switch(p->to.type) {
-               case D_FCONST:
-                       switch(c) {
-                       default:
-                       case 4:
-                               fl = ieeedtof(&p->to.ieee);
-                               cast = (char*)&fl;
-                               for(; i<c; i++) {
-                                       buf.dbuf[l] = cast[fnuxi4[i]];
-                                       l++;
-                               }
-                               break;
-                       case 8:
-                               cast = (char*)&p->to.ieee;
-                               for(; i<c; i++) {
-                                       buf.dbuf[l] = cast[fnuxi8[i]];
-                                       l++;
-                               }
-                               break;
-                       }
-                       break;
-
-               case D_SCONST:
-                       for(; i<c; i++) {
-                               buf.dbuf[l] = p->to.scon[i];
-                               l++;
-                       }
-                       break;
-
-               default:
-                       fl = p->to.offset;
-                       if(p->to.type == D_SIZE)
-                               fl += p->to.sym->size;
-                       if(p->to.type == D_ADDR) {
-                               if(p->to.index != D_STATIC && p->to.index != D_EXTERN)
-                                       diag("DADDR type%P", p);
-                               if(p->to.sym) {
-                                       if(p->to.sym->type == Sxxx) {
-                                               cursym = p->from.sym;
-                                               diag("missing symbol %s", p->to.sym->name);
-                                               cursym = nil;
-                                       }
-                                       fl += p->to.sym->value;
-                                       if(p->to.sym->type != STEXT && p->to.sym->type != SRODATA)
-                                               fl += INITDAT;
-                               }
-                       }
-                       cast = (char*)&fl;
-                       switch(c) {
-                       default:
-                               diag("bad nuxi %d %d\n%P", c, i, curp);
-                               break;
-                       case 1:
-                               for(; i<c; i++) {
-                                       buf.dbuf[l] = cast[inuxi1[i]];
-                                       l++;
-                               }
-                               break;
-                       case 2:
-                               for(; i<c; i++) {
-                                       buf.dbuf[l] = cast[inuxi2[i]];
-                                       l++;
-                               }
-                               break;
-                       case 4:
-                               for(; i<c; i++) {
-                                       buf.dbuf[l] = cast[inuxi4[i]];
-                                       l++;
-                               }
-                               break;
-                       }
-                       break;
-               }
-       }
-
-       ewrite(cout, buf.dbuf, n);
-       if(!debug['a'])
-               return;
-
-       /*
-        * a second pass just to print the asm
-        */
-       for(p = datap; p != P; p = p->link) {
-               a = &p->from;
-               if(rodata != (a->sym->type == SRODATA))
-                       continue;
-
-               l = a->sym->value + a->offset - s;
-               if(l < 0 || l >= n)
-                       continue;
-
-               c = a->scale;
-               i = 0;
-
-               switch(p->to.type) {
-               case D_FCONST:
-                       switch(c) {
-                       default:
-                       case 4:
-                               fl = ieeedtof(&p->to.ieee);
-                               cast = (char*)&fl;
-                               Bprint(&bso, pcstr, l+s+base);
-                               for(j=0; j<c; j++)
-                                       Bprint(&bso, "%.2ux", cast[fnuxi4[j]] & 0xff);
-                               Bprint(&bso, "\t%P\n", p);
-                               break;
-                       case 8:
-                               cast = (char*)&p->to.ieee;
-                               Bprint(&bso, pcstr, l+s+base);
-                               for(j=0; j<c; j++)
-                                       Bprint(&bso, "%.2ux", cast[fnuxi8[j]] & 0xff);
-                               Bprint(&bso, "\t%P\n", p);
-                               break;
-                       }
-                       break;
-
-               case D_SCONST:
-                       Bprint(&bso, pcstr, l+s+base);
-                       for(j=0; j<c; j++)
-                               Bprint(&bso, "%.2ux", p->to.scon[j] & 0xff);
-                       Bprint(&bso, "\t%P\n", p);
-                       break;
-
-               default:
-                       fl = p->to.offset;
-                       if(p->to.type == D_SIZE)
-                               fl += p->to.sym->size;
-                       if(p->to.type == D_ADDR) {
-                               if(p->to.index != D_STATIC && p->to.index != D_EXTERN)
-                                       diag("DADDR type%P", p);
-                               if(p->to.sym) {
-                                       fl += p->to.sym->value;
-                                       if(p->to.sym->type != STEXT && p->to.sym->type != SRODATA)
-                                               fl += INITDAT;
-                               }
-                       }
-                       cast = (char*)&fl;
-                       switch(c) {
-                       default:
-                               diag("bad nuxi %d %d\n%P", c, i, p);
-                               break;
-                       case 1:
-                               Bprint(&bso, pcstr, l+s+base);
-                               for(j=0; j<c; j++)
-                                       Bprint(&bso, "%.2ux", cast[inuxi1[j]] & 0xff);
-                               Bprint(&bso, "\t%P\n", p);
-                               break;
-                       case 2:
-                               Bprint(&bso, pcstr, l+s+base);
-                               for(j=0; j<c; j++)
-                                       Bprint(&bso, "%.2ux", cast[inuxi2[j]] & 0xff);
-                               Bprint(&bso, "\t%P\n", p);
-                               break;
-                       case 4:
-                               Bprint(&bso, pcstr, l+s+base);
-                               for(j=0; j<c; j++)
-                                       Bprint(&bso, "%.2ux", cast[inuxi4[j]] & 0xff);
-                               Bprint(&bso, "\t%P\n", p);
-                               break;
-                       }
-                       break;
-               }
-       }
-}
-
 int32
 rnd(int32 v, int32 r)
 {
index 670ba133ff6a3b1b258cdf5b2ddcf26735f12653..255ba6e39e116f2653255dd8e98aceca75de9606 100644 (file)
@@ -55,6 +55,7 @@ typedef       struct  Prog    Prog;
 typedef        struct  Sym     Sym;
 typedef        struct  Auto    Auto;
 typedef        struct  Optab   Optab;
+typedef        struct  Reloc   Reloc;
 
 struct Adr
 {
@@ -79,6 +80,15 @@ struct       Adr
 #define        ieee    u0.u0ieee
 #define        sbig    u0.u0sbig
 
+struct Reloc
+{
+       int32   off;
+       uchar   siz;
+       uchar   type;
+       int32   add;
+       Sym*    sym;
+};
+
 struct Prog
 {
        Adr     from;
@@ -97,8 +107,9 @@ struct       Prog
        uchar   mark;   /* work on these */
        uchar   back;
        uchar   bigjmp;
-
 };
+#define datasize from.scale
+
 struct Auto
 {
        Sym*    asym;
@@ -130,7 +141,12 @@ struct     Sym
        Prog*   text;
        
        // SDATA, SBSS
-       Prog*   data;
+       uchar*  p;
+       int32   np;
+       int32   maxp;
+       Reloc*  r;
+       int32   nr;
+       int32   maxr;
 };
 struct Optab
 {
@@ -143,21 +159,19 @@ struct    Optab
 enum
 {
        Sxxx,
-
+       
+       /* order here is order in output file */
        STEXT,
+       SELFDATA,
+       SRODATA,        // TODO(rsc): move
        SDATA,
        SBSS,
-       SDATA1,
+
        SXREF,
+       SMACHO, // TODO(rsc): maybe move between DATA1 and BSS?
        SFILE,
        SCONST,
-       SUNDEF,
-
-       SMACHO, /* pointer to mach-o imported symbol */
-
        SFIXED,
-       SELFDATA,
-       SRODATA,
 
        NHASH           = 10007,
        NHUNK           = 100000,
@@ -263,7 +277,6 @@ EXTERN      int32   INITRND;
 EXTERN int32   INITTEXT;
 EXTERN char*   INITENTRY;              /* entry point */
 EXTERN Biobuf  bso;
-EXTERN int32   bsssize;
 EXTERN int32   casepc;
 EXTERN int     cbc;
 EXTERN char*   cbp;
@@ -272,9 +285,7 @@ EXTERN      Auto*   curauto;
 EXTERN Auto*   curhist;
 EXTERN Prog*   curp;
 EXTERN Sym*    cursym;
-EXTERN Prog*   datap;
-EXTERN Prog*   edatap;
-EXTERN int32   datsize;
+EXTERN Sym*    datap;
 EXTERN int32   elfdatsize;
 EXTERN int32   dynptrsize;
 EXTERN char    debug[128];
@@ -327,11 +338,9 @@ void       cflush(void);
 Prog*  copyp(Prog*);
 vlong  cpos(void);
 double cputime(void);
-void   datblk(int32, int32, int32);
 void   diag(char*, ...);
 void   dodata(void);
 void   doelf(void);
-void   doinit(void);
 void   doprof1(void);
 void   doprof2(void);
 void   dostkoff(void);
@@ -346,18 +355,14 @@ void      vputl(uvlong);
 void   strnput(char*, int);
 void   main(int, char*[]);
 void*  mal(uint32);
-Prog*  newdata(Sym*, int, int, int);
-Prog*  newtext(Prog*, Sym*);
 int    opsize(Prog*);
 void   patch(void);
 Prog*  prg(void);
 int    relinv(int);
-int32  reuse(Prog*, Sym*);
 int32  rnd(int32, int32);
 void   s8put(char*);
 void   span(void);
 void   undef(void);
-int32  vaddr(Adr*);
 int32  symaddr(Sym*);
 void   wput(ushort);
 void   wputl(ushort);
index 1238ebf787230588c69d4666e91344a65252154c..2a5b8ca479b9998bac9e1ac660fda93fe9cc59c7 100644 (file)
@@ -303,9 +303,6 @@ main(int argc, char *argv[])
        pcstr = "%.6ux ";
        nuxiinit();
        histgen = 0;
-       textp = nil;
-       datap = P;
-       edatap = P;
        pc = 0;
        dtype = 4;
        version = 0;
@@ -314,9 +311,7 @@ main(int argc, char *argv[])
 
        addlibpath("command line", "command line", argv[0], "main");
        loadlib();
-
        deadcode();
-
        patch();
        follow();
        doelf();
@@ -330,7 +325,7 @@ main(int argc, char *argv[])
                else
                        doprof2();
        span();
-       doinit();
+       reloc();
        if(HEADTYPE == 10)
                dope();
        asmb();
@@ -444,7 +439,7 @@ void
 ldobj1(Biobuf *f, char *pkg, int64 len, char *pn)
 {
        int32 ipc;
-       Prog *p, *t;
+       Prog *p;
        int v, o, r, skip;
        Sym *h[NSYM], *s, *di;
        uint32 sig;
@@ -604,27 +599,19 @@ loop:
                // ignore any more ADATA we see, which must be
                // redefinitions.
                s = p->from.sym;
-               if(s != S && s->dupok) {
+               if(s->dupok) {
 //                     if(debug['v'])
 //                             Bprint(&bso, "skipping %s in %s: dupok\n", s->name, pn);
                        goto loop;
                }
-               if(s != S) {
-                       p->dlink = s->data;
-                       s->data = p;
-                       if(s->file == nil)
-                               s->file = pn;
-                       else if(s->file != pn) {
-                               diag("multiple initialization for %s: in both %s and %s", s->name, s->file, pn);
-                               errorexit();
-                       }                       
+               if(s->file == nil)
+                       s->file = pn;
+               else if(s->file != pn) {
+                       diag("multiple initialization for %s: in both %s and %s", s->name, s->file, pn);
+                       errorexit();
                }
-               if(edatap == P)
-                       datap = p;
-               else
-                       edatap->link = p;
-               edatap = p;
-               p->link = P;
+               savedata(s, p);
+               unmal(p, sizeof *p);
                goto loop;
 
        case AGOK:
@@ -686,21 +673,9 @@ loop:
                        sprint(literal, "$%ux", ieeedtof(&p->from.ieee));
                        s = lookup(literal, 0);
                        if(s->type == 0) {
-                               s->type = SBSS;
-                               s->size = 4;
-                               t = prg();
-                               t->as = ADATA;
-                               t->line = p->line;
-                               t->from.type = D_EXTERN;
-                               t->from.sym = s;
-                               t->from.scale = 4;
-                               t->to = p->from;
-                               if(edatap == P)
-                                       datap = t;
-                               else
-                                       edatap->link = t;
-                               edatap = t;
-                               t->link = P;
+                               s->type = SDATA;
+                               adduint32(s, ieeedtof(&p->from.ieee));
+                               s->reachable = 0;
                        }
                        p->from.type = D_EXTERN;
                        p->from.sym = s;
@@ -725,21 +700,10 @@ loop:
                                p->from.ieee.l, p->from.ieee.h);
                        s = lookup(literal, 0);
                        if(s->type == 0) {
-                               s->type = SBSS;
-                               s->size = 8;
-                               t = prg();
-                               t->as = ADATA;
-                               t->line = p->line;
-                               t->from.type = D_EXTERN;
-                               t->from.sym = s;
-                               t->from.scale = 8;
-                               t->to = p->from;
-                               if(edatap == P)
-                                       datap = t;
-                               else
-                                       edatap->link = t;
-                               edatap = t;
-                               t->link = P;
+                               s->type = SDATA;
+                               adduint32(s, p->from.ieee.l);
+                               adduint32(s, p->from.ieee.h);
+                               s->reachable = 0;
                        }
                        p->from.type = D_EXTERN;
                        p->from.sym = s;
index bebb0d45e80137233caaaa1e4aa13d70f1d98bab..329a87094b83a1c6708ade4449ca5593b59e2e3f 100644 (file)
@@ -42,148 +42,6 @@ enum
        StackBig = 4096,
 };
 
-void
-dodata(void)
-{
-       int i;
-       Sym *s;
-       Prog *p;
-       int32 t, u;
-       Section *sect;
-
-       if(debug['v'])
-               Bprint(&bso, "%5.2f dodata\n", cputime());
-       Bflush(&bso);
-
-       segdata.rwx = 06;
-       segdata.vaddr = 0;      /* span will += INITDAT */
-
-       for(p = datap; p != P; p = p->link) {
-               s = p->from.sym;
-               if(s->type == SBSS)
-                       s->type = SDATA;
-               if(s->type != SDATA && s->type != SELFDATA && s->type != SRODATA)
-                       diag("%s: initialize non-data (%d)\n%P",
-                               s->name, s->type, p);
-               t = p->from.offset + p->width;
-               if(t > s->size)
-                       diag("%s: initialize bounds (%lld)\n%P",
-                               s->name, s->size, p);
-       }
-
-       /* 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->hash) {
-               if(!s->reachable)
-                       continue;
-               if(s->type != SELFDATA)
-                       continue;
-               t = rnd(s->size, 4);
-               s->size = t;
-               s->value = datsize;
-               datsize += t;
-       }
-       elfdatsize = datsize;
-
-       sect = addsection(&segdata, ".data", 06);
-       sect->vaddr = datsize;
-
-       /* allocate small guys */
-       for(i=0; i<NHASH; i++)
-       for(s = hash[i]; s != S; s = s->hash) {
-               if(!s->reachable)
-                       continue;
-               if(s->type != SDATA)
-               if(s->type != SBSS)
-                       continue;
-               t = s->size;
-               if(t == 0 && s->name[0] != '.') {
-                       diag("%s: no size", s->name);
-                       t = 1;
-               }
-               t = rnd(t, 4);
-               s->size = t;
-               if(t > MINSIZ)
-                       continue;
-               s->value = datsize;
-               datsize += t;
-               s->type = SDATA1;
-       }
-
-       /* allocate the rest of the data */
-       for(i=0; i<NHASH; i++)
-       for(s = hash[i]; s != S; s = s->hash) {
-               if(s->type != SDATA) {
-                       if(s->type == SDATA1)
-                               s->type = SDATA;
-                       continue;
-               }
-               t = s->size;
-               s->value = datsize;
-               datsize += t;
-       }
-
-       if(debug['j']) {
-               /*
-                * pad data with bss that fits up to next
-                * 8k boundary, then push data to 8k
-                */
-               u = rnd(datsize, 8192);
-               u -= datsize;
-               for(i=0; i<NHASH; i++)
-               for(s = hash[i]; s != S; s = s->hash) {
-                       if(!s->reachable)
-                               continue;
-                       if(s->type != SBSS)
-                               continue;
-                       t = s->value;
-                       if(t > u)
-                               continue;
-                       u -= t;
-                       s->size = t;
-                       s->value = datsize;
-                       s->type = SDATA;
-                       datsize += t;
-               }
-               datsize += u;
-       }
-
-       if(dynptrsize > 0) {
-               /* dynamic pointer section between data and bss */
-               datsize = rnd(datsize, 4);
-       }
-       sect->len = datsize - sect->vaddr;
-
-       /* now the bss */
-       sect = addsection(&segdata, ".bss", 06);
-       sect->vaddr = datsize;
-       bsssize = 0;
-       for(i=0; i<NHASH; i++)
-       for(s = hash[i]; s != S; s = s->hash) {
-               if(!s->reachable)
-                       continue;
-               if(s->type != SBSS)
-                       continue;
-               t = s->size;
-               s->value = bsssize + dynptrsize + datsize;
-               bsssize += t;
-       }
-       sect->len = bsssize;
-
-       segdata.len = datsize+bsssize;
-       segdata.filelen = datsize;
-
-       xdefine("data", SBSS, 0);
-       xdefine("edata", SBSS, datsize);
-       xdefine("end", SBSS, dynptrsize + bsssize + datsize);
-
-       if(debug['s'] || HEADTYPE == 8)
-               xdefine("symdat", SFIXED, 0);
-       else
-               xdefine("symdat", SFIXED, SYMDATVA);
-}
-
 Prog*
 brchain(Prog *p)
 {
@@ -279,7 +137,7 @@ loop:
                                continue;
                        }
                        if(nofollow(a) || pushpop(a))   
-                               break;
+                               break;  // NOTE(rsc): arm does goto copy
                        if(q->pcond == P || q->pcond->mark)
                                continue;
                        if(a == ACALL || a == ALOOP)
@@ -378,28 +236,6 @@ relinv(int a)
        return a;
 }
 
-void
-doinit(void)
-{
-       Sym *s;
-       Prog *p;
-       int x;
-
-       for(p = datap; p != P; p = p->link) {
-               x = p->to.type;
-               if(x != D_EXTERN && x != D_STATIC)
-                       continue;
-               s = p->to.sym;
-               if(s->type == 0 || s->type == SXREF)
-                       diag("undefined %s initializer of %s",
-                               s->name, p->from.sym->name);
-               p->to.offset += s->value;
-               p->to.type = D_CONST;
-               if(s->type == SDATA || s->type == SBSS)
-                       p->to.offset += INITDAT;
-       }
-}
-
 void
 patch(void)
 {
@@ -790,26 +626,3 @@ undef(void)
                if(s->type == SXREF)
                        diag("%s: not defined", s->name);
 }
-
-Prog*
-newdata(Sym *s, int o, int w, int t)
-{
-       Prog *p;
-
-       p = prg();
-       if(edatap == P)
-               datap = p;
-       else
-               edatap->link = p;
-       edatap = p;
-       p->as = ADATA;
-       p->width = w;
-       p->from.scale = w;
-       p->from.type = t;
-       p->from.sym = s;
-       p->from.offset = o;
-       p->to.type = D_CONST;
-       p->dlink = s->data;
-       s->data = p;
-       return p;
-}
index a5102e8911a0d2544b4ea995afa70ce89a97394f..42738e34ff8ddbb9a319cb815a770bd9bf9d56dc 100644 (file)
@@ -37,10 +37,10 @@ void
 span(void)
 {
        Prog *p, *q;
-       int32 i, v, c, idat, etext, rodata, erodata;
+       int32 v, c, idat, etext;
        int m, n, again;
        Sym *s;
-       Section *sect;
+       Section *sect, *rosect;
 
        xdefine("etext", STEXT, 0L);
        xdefine("rodata", SRODATA, 0L);
@@ -72,8 +72,10 @@ span(void)
                        }
                }
        }
-
        n = 0;
+       
+       rosect = segtext.sect->next;
+
 start:
        do{
                again = 0;
@@ -115,24 +117,15 @@ start:
        etext = c;
        c += textpad;
        
-       /*
-        * allocate read-only data to the text segment.
-        */
-       if(HEADTYPE == 8)
-               c = rnd(c, INITRND);
-       c = rnd(c, 8);
-       rodata = c;
-       for(i=0; i<NHASH; i++)
-       for(s = hash[i]; s != S; s = s->hash) {
-               if(s->type != SRODATA)
-                       continue;
-               v = s->size;
-               while(v & 3)
-                       v++;
-               s->value = c;
-               c += v;
+       if(rosect) {
+               if(INITRND)
+                       c = rnd(c, INITRND);
+               if(rosect->vaddr != c){
+                       rosect->vaddr = c;
+                       goto start;
+               }
+               c += rosect->len;
        }
-       erodata = c;
 
        if(INITRND) {
                INITDAT = rnd(c, INITRND);
@@ -143,8 +136,6 @@ start:
        }
 
        xdefine("etext", STEXT, etext);
-       xdefine("rodata", SRODATA, rodata);
-       xdefine("erodata", SRODATA, erodata);
 
        if(debug['v'])
                Bprint(&bso, "etext = %ux\n", c);
@@ -154,37 +145,40 @@ start:
        textsize = c - INITTEXT;
 
        segtext.rwx = 05;
-       if(HEADTYPE == 8) {
-               segtext.vaddr = INITTEXT;
-               segtext.len = rodata - INITTEXT;
-               segtext.fileoff = HEADR;
-               segtext.filelen = etext - INITTEXT;
-
-               segrodata.rwx = 04;
-               segrodata.vaddr = rodata;
-               segrodata.len = erodata - rodata;
-               segrodata.filelen = segrodata.len;
-       } else {
-               segtext.vaddr = INITTEXT - HEADR;
-               segtext.len = INITDAT - INITTEXT + HEADR;
-               segtext.fileoff = 0;
-               segtext.filelen = segtext.len;
-       }
-
-       sect = addsection(&segtext, ".text", 05);
+       segtext.vaddr = INITTEXT - HEADR;
+       segtext.len = INITDAT - INITTEXT + HEADR;
+       segtext.filelen = textsize + HEADR;
+       
+       sect = segtext.sect;
        sect->vaddr = INITTEXT;
        sect->len = etext - sect->vaddr;
-       
-       if(HEADTYPE == 8)
-               sect = addsection(&segrodata, ".rodata", 04);
-       else
-               sect = addsection(&segtext, ".rodata", 04);
-       sect->vaddr = rodata;
-       sect->len = erodata - rodata;
+
+       // Adjust everything now that we know INITDAT.
+       // This will get simpler when everything is relocatable
+       // and we can run span before dodata.
 
        segdata.vaddr += INITDAT;
        for(sect=segdata.sect; sect!=nil; sect=sect->next)
                sect->vaddr += INITDAT;
+
+       xdefine("data", SBSS, INITDAT);
+       xdefine("edata", SBSS, INITDAT+segdata.filelen);
+       xdefine("end", SBSS, INITDAT+segdata.len);
+
+       for(s=datap; s!=nil; s=s->next) {
+               switch(s->type) {
+               case SELFDATA:
+               case SRODATA:
+                       s->value += rosect->vaddr;
+                       break;
+               case SDATA:
+               case SBSS:
+                       s->value += INITDAT;
+                       break;
+               }
+       }
+       
+       // TODO(rsc): if HEADTYPE == NACL fix up segrodata.
 }
 
 void
@@ -484,6 +478,8 @@ put4(int32 v)
        andptr += 4;
 }
 
+static int32 vaddr(Adr*);
+
 int32
 symaddr(Sym *s)
 {
@@ -496,7 +492,7 @@ symaddr(Sym *s)
        return vaddr(&a);
 }
 
-int32
+static int32
 vaddr(Adr *a)
 {
        int t;
@@ -513,25 +509,17 @@ vaddr(Adr *a)
                s = a->sym;
                if(s != nil) {
                        switch(s->type) {
-                       case STEXT:
-                       case SCONST:
-                       case SRODATA:
-                               if(!s->reachable)
-                                       sysfatal("unreachable symbol in vaddr - %s", s->name);
+                       case SFIXED:
                                v += s->value;
                                break;
                        case SMACHO:
-                               if(!s->reachable)
-                                       sysfatal("unreachable symbol in vaddr - %s", s->name);
-                               v += INITDAT + datsize + s->value;
-                               break;
-                       case SFIXED:
-                               v += s->value;
+                               v += INITDAT + segdata.filelen - dynptrsize + s->value;
                                break;
                        default:
                                if(!s->reachable)
                                        sysfatal("unreachable symbol in vaddr - %s", s->name);
-                               v += INITDAT + s->value;
+                               v += s->value;
+                               break;
                        }
                }
        }
index 89a6457c44e4fa9e70e020a21cac31459ac6edba..be8636a2d5dfaac61d69b83af4ba29616df5a7ac 100644 (file)
@@ -104,22 +104,17 @@ asmsym(void)
                        switch(s->type) {
                        case SCONST:
                        case SRODATA:
-                               if(!s->reachable)
-                                       continue;
-                               putsymb(s->name, 'D', s->value, s->version, s->gotype);
-                               continue;
-
                        case SDATA:
                        case SELFDATA:
                                if(!s->reachable)
                                        continue;
-                               putsymb(s->name, 'D', s->value+INITDAT, s->version, s->gotype);
+                               putsymb(s->name, 'D', symaddr(s), s->version, s->gotype);
                                continue;
 
                        case SMACHO:
                                if(!s->reachable)
                                        continue;
-                               putsymb(s->name, 'D', s->value+INITDAT+datsize+bsssize, s->version, s->gotype);
+                               putsymb(s->name, 'D', s->value+INITDAT+segdata.filelen-dynptrsize, s->version, s->gotype);
                                continue;
 
                        case SBSS:
diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c
new file mode 100644 (file)
index 0000000..353277a
--- /dev/null
@@ -0,0 +1,641 @@
+// Inferno utils/8l/asm.c
+// http://code.google.com/p/inferno-os/source/browse/utils/8l/asm.c
+//
+//     Copyright Â© 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//     Portions Copyright Â© 1995-1997 C H Forsyth (forsyth@terzarima.net)
+//     Portions Copyright Â© 1997-1999 Vita Nuova Limited
+//     Portions Copyright Â© 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
+//     Portions Copyright Â© 2004,2006 Bruce Ellis
+//     Portions Copyright Â© 2005-2007 C H Forsyth (forsyth@terzarima.net)
+//     Revisions Copyright Â© 2000-2007 Lucent Technologies Inc. and others
+//     Portions Copyright Â© 2009 The Go Authors.  All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+// Data layout and relocation.
+
+#include       "l.h"
+#include       "../ld/lib.h"
+#include       "../ld/elf.h"
+
+/*
+ * divide-and-conquer list-link
+ * sort of Sym* structures.
+ * Used for the data block.
+ */
+int
+datcmp(Sym *s1, Sym *s2)
+{
+       if(s1->type != s2->type)
+               return (int)s1->type - (int)s2->type;
+       if(s1->size != s2->size) {
+               if(s1->size < s2->size)
+                       return -1;
+               return +1;
+       }
+       return strcmp(s1->name, s2->name);
+}
+
+Sym*
+datsort(Sym *l)
+{
+       Sym *l1, *l2, *le;
+
+       if(l == 0 || l->next == 0)
+               return l;
+
+       l1 = l;
+       l2 = l;
+       for(;;) {
+               l2 = l2->next;
+               if(l2 == 0)
+                       break;
+               l2 = l2->next;
+               if(l2 == 0)
+                       break;
+               l1 = l1->next;
+       }
+
+       l2 = l1->next;
+       l1->next = 0;
+       l1 = datsort(l);
+       l2 = datsort(l2);
+
+       /* set up lead element */
+       if(datcmp(l1, l2) < 0) {
+               l = l1;
+               l1 = l1->next;
+       } else {
+               l = l2;
+               l2 = l2->next;
+       }
+       le = l;
+
+       for(;;) {
+               if(l1 == 0) {
+                       while(l2) {
+                               le->next = l2;
+                               le = l2;
+                               l2 = l2->next;
+                       }
+                       le->next = 0;
+                       break;
+               }
+               if(l2 == 0) {
+                       while(l1) {
+                               le->next = l1;
+                               le = l1;
+                               l1 = l1->next;
+                       }
+                       break;
+               }
+               if(datcmp(l1, l2) < 0) {
+                       le->next = l1;
+                       le = l1;
+                       l1 = l1->next;
+               } else {
+                       le->next = l2;
+                       le = l2;
+                       l2 = l2->next;
+               }
+       }
+       le->next = 0;
+       return l;
+}
+
+Reloc*
+addrel(Sym *s)
+{
+       if(s->nr >= s->maxr) {
+               if(s->maxr == 0)
+                       s->maxr = 4;
+               else
+                       s->maxr <<= 1;
+               s->r = realloc(s->r, s->maxr*sizeof s->r[0]);
+               if(s->r == 0) {
+                       diag("out of memory");
+                       errorexit();
+               }
+               memset(s->r+s->nr, 0, (s->maxr-s->nr)*sizeof s->r[0]);
+       }
+       return &s->r[s->nr++];
+}
+
+void
+relocsym(Sym *s)
+{
+       Reloc *r;
+       Prog p;
+       int32 i, off, siz, fl;
+       vlong o;
+       uchar *cast;
+       
+       memset(&p, 0, sizeof p);
+       for(r=s->r; r<s->r+s->nr; r++) {
+               off = r->off;
+               siz = r->siz;
+               switch(r->type) {
+               default:
+                       diag("unknown reloc %d", r->type);
+               case D_ADDR:
+                       o = symaddr(r->sym);
+                       break;
+               case D_SIZE:
+                       o = r->sym->size;
+                       break;
+               }
+               o += r->add;
+               switch(siz) {
+               default:
+                       diag("bad reloc size %d", siz);
+               case 4:
+                       fl = o;
+                       cast = (uchar*)&fl;
+                       for(i=0; i<4; i++)
+                               s->p[off+i] = cast[inuxi4[i]];
+                       break;
+               case 8:
+                       cast = (uchar*)&o;
+                       for(i=0; i<8; i++)
+                               s->p[off+i] = cast[inuxi8[i]];
+                       break;
+               }               
+       }
+}
+
+void
+reloc(void)
+{
+       Sym *s;
+       
+       if(debug['v'])
+               Bprint(&bso, "%5.2f reloc\n", cputime());
+       Bflush(&bso);
+
+       for(s=textp; s!=S; s=s->next)
+               relocsym(s);
+       for(s=datap; s!=S; s=s->next) {
+               if(!s->reachable)
+                       diag("unerachable? %s", s->name);
+               relocsym(s);
+       }
+}
+
+void
+symgrow(Sym *s, int32 siz)
+{
+       if(s->np >= siz)
+               return;
+
+       if(s->maxp < siz) {
+               if(s->maxp == 0)
+                       s->maxp = 8;
+               while(s->maxp < siz)
+                       s->maxp <<= 1;
+               s->p = realloc(s->p, s->maxp);
+               if(s->p == nil) {
+                       diag("out of memory");
+                       errorexit();
+               }
+               memset(s->p+s->np, 0, s->maxp-s->np);
+       }
+       s->np = siz;
+}
+
+void
+savedata(Sym *s, Prog *p)
+{
+       int32 off, siz, i, fl;
+       uchar *cast;
+       vlong o;
+       Reloc *r;
+       
+       off = p->from.offset;
+       siz = p->datasize;
+       symgrow(s, off+siz);
+       
+       switch(p->to.type) {
+       default:
+               diag("bad data: %P", p);
+               break;
+
+       case D_FCONST:
+               switch(siz) {
+               default:
+               case 4:
+                       fl = ieeedtof(&p->to.ieee);
+                       cast = (uchar*)&fl;
+                       for(i=0; i<4; i++)
+                               s->p[off+i] = cast[fnuxi4[i]];
+                       break;
+               case 8:
+                       cast = (uchar*)&p->to.ieee;
+                       for(i=0; i<8; i++)
+                               s->p[off+i] = cast[fnuxi8[i]];
+                       break;
+               }
+               break;
+       
+       case D_SCONST:
+               for(i=0; i<siz; i++)
+                       s->p[off+i] = p->to.scon[i];
+               break;
+       
+       case D_CONST:
+               if(p->to.sym)
+                       goto Addr;
+               o = p->to.offset;
+               fl = o;
+               cast = (uchar*)&fl;
+               switch(siz) {
+               default:
+                       diag("bad nuxi %d\n%P", siz, p);
+                       break;
+               case 1:
+                       s->p[off] = cast[inuxi1[0]];
+                       break;
+               case 2:
+                       for(i=0; i<2; i++)
+                               s->p[off+i] = cast[inuxi2[i]];
+                       break;
+               case 4:
+                       for(i=0; i<4; i++)
+                               s->p[off+i] = cast[inuxi4[i]];
+                       break;
+               case 8:
+                       cast = (uchar*)&o;
+                       for(i=0; i<8; i++)
+                               s->p[off+i] = cast[inuxi8[i]];
+                       break;
+               }
+               break;
+
+       case D_ADDR:
+       case D_SIZE:
+       Addr:
+               r = addrel(s);
+               r->off = off;
+               r->siz = siz;
+               r->sym = p->to.sym;
+               r->type = p->to.type;
+               if(r->type != D_SIZE)
+                       r->type = D_ADDR;
+               r->add = p->to.offset;
+               break;
+       }
+}
+
+static void
+blk(Sym *allsym, int32 addr, int32 size)
+{
+       Sym *sym;
+       int32 eaddr;
+       uchar *p, *ep;
+
+       for(sym = allsym; sym != nil; sym = sym->next)
+               if(sym->value >= addr)
+                       break;
+
+       eaddr = addr+size;
+       for(; sym != nil; sym = sym->next) {
+               if(sym->value >= eaddr)
+                       break;
+               if(sym->value < addr) {
+                       diag("phase error: addr=%#llx but sym=%#llx type=%d", addr, sym->value, sym->type);
+                       errorexit();
+               }
+               cursym = sym;
+               for(; addr < sym->value; addr++)
+                       cput(0);
+               p = sym->p;
+               ep = p + sym->np;
+               while(p < ep)
+                       cput(*p++);
+               addr += sym->np;
+               for(; addr < sym->value+sym->size; addr++)
+                       cput(0);
+               if(addr != sym->value+sym->size) {
+                       diag("phase error: addr=%#llx value+size=%#llx", addr, sym->value+sym->size);
+                       errorexit();
+               }
+       }
+       
+       for(; addr < eaddr; addr++)
+               cput(0);
+       cflush();
+}
+                       
+void
+datblk(int32 addr, int32 size)
+{
+       Sym *sym;
+       int32 eaddr;
+       uchar *p, *ep;
+
+       blk(datap, addr, size);
+
+       /* again for printing */
+       if(!debug['a'])
+               return;
+
+       for(sym = datap; sym != nil; sym = sym->next)
+               if(sym->value >= addr)
+                       break;
+
+       eaddr = addr + size;
+       for(; sym != nil; sym = sym->next) {
+               if(sym->value >= eaddr)
+                       break;
+               if(addr < sym->value) {
+                       Bprint(&bso, "%-20s %.8ux|", "(pre-pad)", addr);
+                       for(; addr < sym->value; addr++)
+                               Bprint(&bso, " %.2ux", 0);
+                       Bprint(&bso, "\n");
+               }
+               Bprint(&bso, "%-20s %.8ux|", sym->name, addr);
+               p = sym->p;
+               ep = p + sym->np;
+               while(p < ep)
+                       Bprint(&bso, " %.2ux", *p++);
+               addr += sym->np;
+               for(; addr < sym->value+sym->size; addr++)
+                       Bprint(&bso, " %.2ux", 0);
+               Bprint(&bso, "\n");
+       }
+
+       if(addr < eaddr) {
+               Bprint(&bso, "%-20s %.8ux|", "(post-pad)", addr);
+               for(; addr < eaddr; addr++)
+                       Bprint(&bso, " %.2ux", 0);
+       }
+}
+
+void
+strnput(char *s, int n)
+{
+       for(; *s && n > 0; s++) {
+               cput(*s);
+               n--;
+       }
+       while(n > 0) {
+               cput(0);
+               n--;
+       }
+}
+
+vlong
+addstring(Sym *s, char *str)
+{
+       int n;
+       int32 r;
+
+       if(s->type == 0)
+               s->type = SDATA;
+       s->reachable = 1;
+       r = s->size;
+       n = strlen(str)+1;
+       if(strcmp(s->name, ".shstrtab") == 0)
+               elfsetstring(str, r);
+       symgrow(s, r+n);
+       memmove(s->p+r, str, n);
+       s->size += n;
+       return r;
+}
+
+vlong
+adduintxx(Sym *s, uint64 v, int wid)
+{
+       int32 i, r, fl;
+       vlong o;
+       uchar *cast;
+
+       if(s->type == 0)
+               s->type = SDATA;
+       s->reachable = 1;
+       r = s->size;
+       s->size += wid;
+       symgrow(s, s->size);
+       fl = v;
+       cast = (uchar*)&fl;
+       switch(wid) {
+       case 1:
+               s->p[r] = cast[inuxi1[0]];
+               break;
+       case 2:
+               for(i=0; i<2; i++)
+                       s->p[r+i] = cast[inuxi2[i]];
+               break;
+       case 4:
+               for(i=0; i<4; i++)
+                       s->p[r+i] = cast[inuxi4[i]];
+               break;
+       case 8:
+               o = v;
+               cast = (uchar*)&o;
+               for(i=0; i<8; i++)
+                       s->p[r+i] = cast[inuxi8[i]];
+               break;
+       }
+       return r;
+}
+
+vlong
+adduint8(Sym *s, uint8 v)
+{
+       return adduintxx(s, v, 1);
+}
+
+vlong
+adduint16(Sym *s, uint16 v)
+{
+       return adduintxx(s, v, 2);
+}
+
+vlong
+adduint32(Sym *s, uint32 v)
+{
+       return adduintxx(s, v, 4);
+}
+
+vlong
+adduint64(Sym *s, uint64 v)
+{
+       return adduintxx(s, v, 8);
+}
+
+vlong
+addaddr(Sym *s, Sym *t)
+{
+       vlong i;
+       Reloc *r;
+
+       if(s->type == 0)
+               s->type = SDATA;
+       s->reachable = 1;
+       i = s->size;
+       s->size += PtrSize;
+       symgrow(s, s->size);
+       r = addrel(s);
+       r->sym = t;
+       r->off = i;
+       r->siz = PtrSize;
+       r->type = D_ADDR;
+       return i;
+}
+
+vlong
+addsize(Sym *s, Sym *t)
+{
+       vlong i;
+       Reloc *r;
+
+       if(s->type == 0)
+               s->type = SDATA;
+       s->reachable = 1;
+       i = s->size;
+       s->size += PtrSize;
+       symgrow(s, s->size);
+       r = addrel(s);
+       r->sym = t;
+       r->off = i;
+       r->siz = PtrSize;
+       r->type = D_SIZE;
+       return i;
+}
+
+void
+dodata(void)
+{
+       int32 h, t, datsize;
+       Section *sect;
+       Sym *s, *last;
+
+       if(debug['v'])
+               Bprint(&bso, "%5.2f dodata\n", cputime());
+       Bflush(&bso);
+
+       segdata.rwx = 06;
+       segdata.vaddr = 0;      /* span will += INITDAT */
+
+       last = nil;
+       datap = nil;
+       for(h=0; h<NHASH; h++) {
+               for(s=hash[h]; s!=S; s=s->hash){
+                       if(!s->reachable)
+                               continue;
+                       if(STEXT < s->type && s->type < SXREF) {
+                               if(last == nil)
+                                       datap = s;
+                               else
+                                       last->next = s;
+                               s->next = nil;
+                               last = s;
+                       }
+               }
+       }
+
+       for(s = datap; s != nil; s = s->next) {
+               if(s->np > 0 && s->type == SBSS)        // TODO: necessary?
+                       s->type = SDATA;
+               if(s->np > s->size)
+                       diag("%s: initialize bounds (%lld < %d)",
+                               s->name, s->size, s->np);
+       }
+       datap = datsort(datap);
+
+       /*
+        * allocate data sections.  list is sorted by type,
+        * so we can just walk it for each piece we want to emit.
+        */
+
+       sect = addsection(&segtext, ".text", 05);       // set up for span TODO(rsc): clumsy
+       
+       /* read-only data */
+       sect = addsection(&segtext, ".rodata", 06);
+       sect->vaddr = 0;
+       datsize = 0;
+       s = datap;
+       for(; s != nil && s->type < SDATA; s = s->next) {
+               s->type = SRODATA;
+               t = rnd(s->size, 4);
+               s->size = t;
+               s->value = datsize;
+               datsize += t;
+       }
+       sect->len = datsize - sect->vaddr;
+       
+       /* data */
+       datsize = 0;
+       sect = addsection(&segdata, ".data", 06);
+       sect->vaddr = 0;
+       for(; s != nil && s->type < SBSS; s = s->next) {
+               s->type = SDATA;
+               t = s->size;
+               if(t == 0 && s->name[0] != '.') {
+                       diag("%s: no size", s->name);
+                       t = 1;
+               }
+               if(t & 1)
+                       ;
+               else if(t & 2)
+                       datsize = rnd(datsize, 2);
+               else if(t & 4)
+                       datsize = rnd(datsize, 4);
+               else
+                       datsize = rnd(datsize, 8);
+               s->value = datsize;
+               datsize += t;
+       }
+       sect->len = datsize - sect->vaddr;
+       segdata.filelen = datsize;
+
+       /* bss */
+       sect = addsection(&segdata, ".bss", 06);
+       sect->vaddr = datsize;
+       for(; s != nil; s = s->next) {
+               if(s->type != SBSS) {
+                       cursym = s;
+                       diag("unexpected symbol type %d", s->type);
+               }
+               t = s->size;
+               if(t & 1)
+                       ;
+               else if(t & 2)
+                       datsize = rnd(datsize, 2);
+               else if(t & 4)
+                       datsize = rnd(datsize, 4);
+               else
+                       datsize = rnd(datsize, 8);
+               s->size = t;
+               s->value = datsize;
+               datsize += t;
+       }
+       sect->len = datsize - sect->vaddr;
+       segdata.len = datsize;
+
+       xdefine("data", SBSS, 0);
+       xdefine("edata", SBSS, segdata.filelen);
+       xdefine("end", SBSS, segdata.len);
+
+       if(debug['s'] || HEADTYPE == 8)
+               xdefine("symdat", SFIXED, 0);
+       else
+               xdefine("symdat", SFIXED, SYMDATVA);
+}
+
index 3672d4cdca2dcdaa58a30d7db40a8d0fd692c2f8..aecbe8612ac4d9d39ca77d8b254e8e1fc2ac6751 100644 (file)
@@ -511,18 +511,6 @@ err:
 
 static int markdepth;
 
-static void
-markdata(Prog *p, Sym *s)
-{
-       markdepth++;
-       if(p != P && debug['v'] > 1)
-               Bprint(&bso, "%d markdata %s\n", markdepth, s->name);
-       for(; p != P; p=p->dlink)
-               if(p->to.sym)
-                       mark(p->to.sym);
-       markdepth--;
-}
-
 static void
 marktext(Sym *s)
 {
@@ -548,47 +536,19 @@ marktext(Sym *s)
 void
 mark(Sym *s)
 {
+       int i;
+
        if(s == S || s->reachable)
                return;
        s->reachable = 1;
        if(s->text)
                marktext(s);
-       if(s->data)
-               markdata(s->data, s);
+       for(i=0; i<s->nr; i++)
+               mark(s->r[i].sym);
        if(s->gotype)
                mark(s->gotype);
 }
 
-static void
-sweeplist(Prog **first, Prog **last)
-{
-       int reachable;
-       Prog *p, *q;
-
-       reachable = 1;
-       q = P;
-       for(p=*first; p != P; p=p->link) {
-               switch(p->as) {
-               case ATEXT:
-               case ADATA:
-               case AGLOBL:
-                       reachable = p->from.sym->reachable;
-               }
-               if(reachable) {
-                       if(q == P)
-                               *first = p;
-                       else
-                               q->link = p;
-                       q = p;
-               }
-       }
-       if(q == P)
-               *first = P;
-       else
-               q->link = P;
-       *last = q;
-}
-
 static char*
 morename[] =
 {
@@ -680,7 +640,4 @@ deadcode(void)
                textp = nil;
        else
                last->next = nil;
-
-       // remove dead data
-       sweeplist(&datap, &edatap);
 }
index dae22f281618b6b320aae1e4eca648077a2dc217..49d398a3c542e36dff4d8c6d213a3e059b0be72a 100644 (file)
@@ -775,8 +775,7 @@ mal(uint32 n)
 {
        void *v;
 
-       while(n & 7)
-               n++;
+       n = (n+7)&~7;
        if(n > NHUNK) {
                v = malloc(n);
                memset(v, 0, n);
@@ -795,6 +794,16 @@ mal(uint32 n)
        return v;
 }
 
+void
+unmal(void *v, uint32 n)
+{
+       n = (n+7)&~7;
+       if(hunk - n == v) {
+               hunk -= n;
+               nhunk += n;
+       }
+}
+
 // Copied from ../gc/subr.c:/^pathtoprefix; must stay in sync.
 /*
  * Convert raw string to the prefix that will be used in the symbol table.
@@ -999,4 +1008,3 @@ mkfwd(void)
                }
        }
 }
-
index 8688a75b2c5e26a08f152ece85d6ce685e87e6b5..f9557e38350ca968ceff8f9b7ce28a05f4aaa34b 100644 (file)
@@ -131,9 +131,24 @@ void       mkfwd(void);
 char*  expandpkg(char*, char*);
 void   deadcode(void);
 void   ewrite(int, void*, int);
+Reloc* addrel(Sym*);
+void   datblk(int32, int32);
+Sym*   datsort(Sym*);
+void   reloc(void);
+void   savedata(Sym*, Prog*);
+void   symgrow(Sym*, int32);
+vlong  addstring(Sym*, char*);
+vlong  adduint32(Sym*, uint32);
+vlong  adduint64(Sym*, uint64);
+vlong  addaddr(Sym*, Sym*);
+vlong  addsize(Sym*, Sym*);
+vlong  adduint8(Sym*, uint8);
+vlong  adduint16(Sym*, uint16);
+void   strnput(char*, int);
 
 int    pathchar(void);
 void*  mal(uint32);
+void   unmal(void*, uint32);
 void   mywhatsys(void);
 
 /* set by call to mywhatsys() */
index b3f608c438ee67c88abd736e797b94783ae7cd78..863fff3c359e3e2d448e7a10d237b7ae971f82b4 100644 (file)
@@ -411,13 +411,13 @@ domacholink(void)
 
        linkoff = 0;
        if(nlinkdata > 0 || nstrtab > 0) {
-               linkoff = rnd(HEADR+textsize, INITRND) + rnd(datsize, INITRND);
+               linkoff = rnd(HEADR+textsize, INITRND) + rnd(segdata.filelen - dynptrsize, INITRND);
                seek(cout, linkoff, 0);
 
                for(i = 0; i<nexpsym; ++i) {
                        s = expsym[i].s;
                        val = s->value;
-                       if(s->type == SUNDEF)
+                       if(s->type == SXREF)
                                diag("export of undefined symbol %s", s->name);
                        if (s->type != STEXT)
                                val += INITDAT;
@@ -492,25 +492,25 @@ asmbmacho(vlong symdatva, vlong symo)
        msect->flag = 0x400;    /* flag - some instructions */
 
        /* data */
-       w = datsize+dynptrsize+bsssize;
+       w = segdata.len;
        ms = newMachoSeg("__DATA", 2+(dynptrsize>0));
        ms->vaddr = va+v;
        ms->vsize = w;
        ms->fileoffset = v;
-       ms->filesize = datsize+dynptrsize;
+       ms->filesize = segdata.filelen;
        ms->prot1 = 7;
        ms->prot2 = 3;
 
        msect = newMachoSect(ms, "__data");
        msect->addr = va+v;
-       msect->size = datsize;
+       msect->size = segdata.filelen - dynptrsize;
        msect->off = v;
 
        if(dynptrsize > 0) {
                msect = newMachoSect(ms, "__nl_symbol_ptr");
-               msect->addr = va+v+datsize;
+               msect->addr = va+v+segdata.filelen - dynptrsize;
                msect->size = dynptrsize;
-               msect->off = v+datsize;
+               msect->off = v+segdata.filelen - dynptrsize;
                msect->align = 2;
                msect->flag = 6;        /* section with nonlazy symbol pointers */
                /*
@@ -525,8 +525,8 @@ asmbmacho(vlong symdatva, vlong symo)
        }
 
        msect = newMachoSect(ms, "__bss");
-       msect->addr = va+v+datsize+dynptrsize;
-       msect->size = bsssize;
+       msect->addr = va+v+segdata.filelen;
+       msect->size = segdata.len - segdata.filelen;
        msect->flag = 1;        /* flag - zero fill */
 
        switch(thechar) {
@@ -554,7 +554,7 @@ asmbmacho(vlong symdatva, vlong symo)
                nsym = dynptrsize/ptrsize;
 
                ms = newMachoSeg("__LINKEDIT", 0);
-               ms->vaddr = va+v+rnd(datsize+dynptrsize+bsssize, INITRND);
+               ms->vaddr = va+v+rnd(segdata.len, INITRND);
                ms->vsize = nlinkdata+nstrtab;
                ms->fileoffset = linkoff;
                ms->filesize = nlinkdata+nstrtab;
index d3439abfb1860dfc7378df4d812b0c89778e3123..6faa515d30ea9b3235062e949f412eb417ca3729 100644 (file)
@@ -86,7 +86,7 @@ pewrite(void)
 {
        int i, j;
 
-       write(cout, dosstub, sizeof dosstub);
+       ewrite(cout, dosstub, sizeof dosstub);
        strnput("PE", 4);
 
        for (i=0; i<sizeof(fh); i++)
@@ -106,12 +106,12 @@ dope(void)
                IMAGE_SCN_CNT_INITIALIZED_DATA|
                IMAGE_SCN_MEM_EXECUTE|IMAGE_SCN_MEM_READ;
 
-       datsect = new_section(".data", datsize, 0);
+       datsect = new_section(".data", segdata.filelen, 0);
        datsect->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|
                IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
        INITDAT = PEBASE+datsect->VirtualAddress;
 
-       bsssect = new_section(".bss", bsssize, 1);
+       bsssect = new_section(".bss", segdata.len - segdata.filelen, 1);
        bsssect->Characteristics = IMAGE_SCN_CNT_UNINITIALIZED_DATA|
                IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
 }