]> Cypherpunks repositories - gostls13.git/commitdiff
5l: data-relocatable code layout
authorRuss Cox <rsc@golang.org>
Mon, 18 Oct 2010 15:09:59 +0000 (11:09 -0400)
committerRuss Cox <rsc@golang.org>
Mon, 18 Oct 2010 15:09:59 +0000 (11:09 -0400)
R=ken2
CC=golang-dev
https://golang.org/cl/2479043

src/cmd/5l/asm.c
src/cmd/5l/l.h
src/cmd/5l/obj.c
src/cmd/5l/span.c

index 4d9264c91405d0eb96b8c71566c00ac82a258099..0b38e0b29b54924da8d59eec4d7744dab68cb394 100644 (file)
@@ -291,13 +291,11 @@ phsh(Elf64_Phdr *ph, Elf64_Shdr *sh)
 void
 asmb(void)
 {
-       Prog *p;
        int32 t;
        int a, dynsym;
        uint32 va, fo, w, symo, startva;
        uint32 symdatva = SYMDATVA;
        int strtabsize;
-       Optab *o;
        ElfEhdr *eh;
        ElfPhdr *ph, *pph;
        ElfShdr *sh;
@@ -312,28 +310,8 @@ asmb(void)
        OFFSET = HEADR;
        seek(cout, OFFSET, 0);
        pc = INITTEXT;
-       for(cursym = textp; cursym != nil; cursym = cursym->next) {
-               for(p = cursym->text; p != P; p = p->link) {
-                       setarch(p);
-                       if(p->as == ATEXT)
-                               autosize = p->to.offset + 4;
-                       if(p->pc != pc) {
-                               diag("phase error %ux sb %ux",
-                                       p->pc, pc);
-                               if(!debug['a'])
-                                       prasm(curp);
-                               pc = p->pc;
-                       }
-                       curp = p;
-                       o = oplook(p);  /* could probably avoid this call */
-                       if(thumb)
-                               thumbasmout(p, o);
-                       else
-                               asmout(p, o);
-                       pc += o->size;
-               }
-       }
-       cflush();
+       codeblk(pc, segtext.sect->len);
+       pc += segtext.sect->len;
        if(seek(cout, 0, 1) != pc - segtext.vaddr + segtext.fileoff)
                diag("text phase error");
 
@@ -846,10 +824,11 @@ asmthumbmap(void)
 }
 
 void
-asmout(Prog *p, Optab *o)
+asmout(Prog *p, Optab *o, int32 *out)
 {
        int32 o1, o2, o3, o4, o5, o6, v;
        int r, rf, rt, rt2;
+       Reloc *rel;
 
 PP = p;
        o1 = 0;
@@ -991,6 +970,15 @@ if(debug['G']) print("%ux: %s: arm %d %d %d %d\n", (uint32)(p->pc), p->from.sym-
        case 11:        /* word */
                aclass(&p->to);
                o1 = instoffset;
+               if(p->to.sym != S) {
+                       rel = addrel(cursym);
+                       rel->off = pc - cursym->value;
+                       rel->siz = 4;
+                       rel->type = D_ADDR;
+                       rel->sym = p->to.sym;
+                       rel->add = p->to.offset;
+                       o1 = 0;
+               }
                break;
 
        case 12:        /* movw $lcon, reg */
@@ -1588,6 +1576,14 @@ if(debug['G']) print("%ux: %s: arm %d %d %d %d\n", (uint32)(p->pc), p->from.sym-
                o1 |= (p->scond & C_SCOND) << 28;
                break;
        }
+       
+       out[0] = o1;
+       out[1] = o2;
+       out[2] = o3;
+       out[3] = o4;
+       out[4] = o5;
+       out[5] = o6;
+       return;
 
        v = p->pc;
        switch(o->size) {
index 1e720f3bea5d7d4f4c58f84eb5ac5cb211cc4e9f..4f7ec522356146937871ce15e5da00a6de9f40ae 100644 (file)
@@ -379,7 +379,7 @@ void        addhist(int32, int);
 Prog*  appendp(Prog*);
 void   asmb(void);
 void   asmthumbmap(void);
-void   asmout(Prog*, Optab*);
+void   asmout(Prog*, Optab*, int32*);
 void   thumbasmout(Prog*, Optab*);
 void   asmsym(void);
 int32  atolwhex(char*);
index 6392d93ca8120732c9f9b2c70b467b6e128643a7..5a508b4f4aa149dbade250e9eb659ec32af0bc34 100644 (file)
@@ -70,7 +70,7 @@ main(int argc, char *argv[])
 {
        int c, i;
 
-debug['s'] = 1;
+//debug['s'] = 1;  // qemu cannot handle symdat load
        Binit(&bso, 1, OWRITE);
        cout = -1;
        listinit();
index 3a1c35b62d82ddd91be7d1a10360e0203ffb1286..048a4768b638f146d9dc2c48d646aa41cf022848 100644 (file)
@@ -166,11 +166,12 @@ span(void)
 {
        Prog *p, *op;
        Optab *o;
-       int m, bflag;
-       int32 c, otxt;
+       int m, bflag, i, v;
+       int32 c, otxt, out[6];
        int lastthumb = -1;
        Section *rosect, *sect;
        Sym *sym;
+       uchar *bp;
 
        if(debug['v'])
                Bprint(&bso, "%5.2f span\n", cputime());
@@ -187,11 +188,8 @@ span(void)
                p = cursym->text;
                setarch(p);
                p->pc = c;
+               cursym->value = c;
 
-               if(blitrl && lastthumb != -1 && lastthumb != thumb){    // flush literal pool
-                       if(flushpool(op, 0, 1))
-                               c = p->pc = scan(op, p, c);
-               }
                lastthumb = thumb;
                autosize = p->to.offset + 4;
                if(p->from.sym != S)
@@ -216,8 +214,6 @@ span(void)
                                        c = p->pc = scan(op, p, c);
                        }
                        if(m == 0) {
-                               if(p->as == ATEXT) {
-                               }
                                diag("zero-width instruction\n%P", p);
                                continue;
                        }
@@ -237,12 +233,13 @@ span(void)
                                flushpool(p, 0, 0);
                        c += m;
                }
-               if(blitrl && cursym->next == nil){
+               if(blitrl){
                        if(thumb && isbranch(op))
                                pool.extra += brextra(op);
                        if(checkpool(op, 0))
                                c = scan(op, P, c);
                }
+               cursym->size = c - cursym->value;
        }
 
        /*
@@ -257,6 +254,7 @@ span(void)
                bflag = 0;
                c = INITTEXT;
                for(cursym = textp; cursym != nil; cursym = cursym->next) {
+                       cursym->value = c;
                        for(p = cursym->text; p != P; p = p->link) {
                                setarch(p);
                                p->pc = c;
@@ -299,6 +297,7 @@ span(void)
                                }
                                c += m;
                        }
+                       cursym->size = c - cursym->value;
                }
        }
 
@@ -318,6 +317,7 @@ span(void)
                oop = op = nil;
                again = 0;
                for(cursym = textp; cursym != nil; cursym = cursym->next) {
+                       cursym->value = c;
                        for(p = cursym->text; p != P; oop = op, op = p, p = p->link) {
                                setarch(p);
                                if(p->pc != c)
@@ -361,6 +361,7 @@ span(void)
                                }
                                c += m;
                        }
+                       cursym->size = c - cursym->value;
                }
                if(c != lastc || again){
                        lastc = c;
@@ -368,12 +369,39 @@ span(void)
                }
        }
        c = rnd(c, 8);
-
        xdefine("etext", STEXT, c);
-       for(cursym = textp; cursym != nil; cursym = cursym->next)
-               cursym->value = cursym->text->pc;
        textsize = c - INITTEXT;
        
+       /*
+        * lay out the code.  all the pc-relative code references,
+        * even cross-function, are resolved now;
+        * only data references need to be relocated.
+        * with more work we could leave cross-function
+        * code references to be relocated too, and then
+        * perhaps we'd be able to parallelize the span loop above.
+        */
+       for(cursym = textp; cursym != nil; cursym = cursym->next) {
+               p = cursym->text;
+               setarch(p);
+               autosize = p->to.offset + 4;
+               symgrow(cursym, cursym->size);
+       
+               bp = cursym->p;
+               for(p = p->link; p != P; p = p->link) {
+                       pc = p->pc;
+                       curp = p;
+                       o = oplook(p);
+                       asmout(p, o, out);
+                       for(i=0; i<o->size/4; i++) {
+                               v = out[i];
+                               *bp++ = v;
+                               *bp++ = v>>8;
+                               *bp++ = v>>16;
+                               *bp++ = v>>24;
+                       }
+               }
+       }
+
        rosect = segtext.sect->next;
        if(rosect) {
                if(INITRND)