1
0
mirror of https://github.com/golang/go synced 2024-11-24 20:20:03 -07:00

5l: data-relocatable code layout

R=ken2
CC=golang-dev
https://golang.org/cl/2479043
This commit is contained in:
Russ Cox 2010-10-18 11:09:59 -04:00
parent a647f59c1f
commit 3d0a85785a
4 changed files with 63 additions and 39 deletions

View File

@ -291,13 +291,11 @@ phsh(Elf64_Phdr *ph, Elf64_Shdr *sh)
void void
asmb(void) asmb(void)
{ {
Prog *p;
int32 t; int32 t;
int a, dynsym; int a, dynsym;
uint32 va, fo, w, symo, startva; uint32 va, fo, w, symo, startva;
uint32 symdatva = SYMDATVA; uint32 symdatva = SYMDATVA;
int strtabsize; int strtabsize;
Optab *o;
ElfEhdr *eh; ElfEhdr *eh;
ElfPhdr *ph, *pph; ElfPhdr *ph, *pph;
ElfShdr *sh; ElfShdr *sh;
@ -312,28 +310,8 @@ asmb(void)
OFFSET = HEADR; OFFSET = HEADR;
seek(cout, OFFSET, 0); seek(cout, OFFSET, 0);
pc = INITTEXT; pc = INITTEXT;
for(cursym = textp; cursym != nil; cursym = cursym->next) { codeblk(pc, segtext.sect->len);
for(p = cursym->text; p != P; p = p->link) { pc += segtext.sect->len;
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();
if(seek(cout, 0, 1) != pc - segtext.vaddr + segtext.fileoff) if(seek(cout, 0, 1) != pc - segtext.vaddr + segtext.fileoff)
diag("text phase error"); diag("text phase error");
@ -846,10 +824,11 @@ asmthumbmap(void)
} }
void void
asmout(Prog *p, Optab *o) asmout(Prog *p, Optab *o, int32 *out)
{ {
int32 o1, o2, o3, o4, o5, o6, v; int32 o1, o2, o3, o4, o5, o6, v;
int r, rf, rt, rt2; int r, rf, rt, rt2;
Reloc *rel;
PP = p; PP = p;
o1 = 0; 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 */ case 11: /* word */
aclass(&p->to); aclass(&p->to);
o1 = instoffset; 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; break;
case 12: /* movw $lcon, reg */ 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; o1 |= (p->scond & C_SCOND) << 28;
break; break;
} }
out[0] = o1;
out[1] = o2;
out[2] = o3;
out[3] = o4;
out[4] = o5;
out[5] = o6;
return;
v = p->pc; v = p->pc;
switch(o->size) { switch(o->size) {

View File

@ -379,7 +379,7 @@ void addhist(int32, int);
Prog* appendp(Prog*); Prog* appendp(Prog*);
void asmb(void); void asmb(void);
void asmthumbmap(void); void asmthumbmap(void);
void asmout(Prog*, Optab*); void asmout(Prog*, Optab*, int32*);
void thumbasmout(Prog*, Optab*); void thumbasmout(Prog*, Optab*);
void asmsym(void); void asmsym(void);
int32 atolwhex(char*); int32 atolwhex(char*);

View File

@ -70,7 +70,7 @@ main(int argc, char *argv[])
{ {
int c, i; int c, i;
debug['s'] = 1; //debug['s'] = 1; // qemu cannot handle symdat load
Binit(&bso, 1, OWRITE); Binit(&bso, 1, OWRITE);
cout = -1; cout = -1;
listinit(); listinit();

View File

@ -166,11 +166,12 @@ span(void)
{ {
Prog *p, *op; Prog *p, *op;
Optab *o; Optab *o;
int m, bflag; int m, bflag, i, v;
int32 c, otxt; int32 c, otxt, out[6];
int lastthumb = -1; int lastthumb = -1;
Section *rosect, *sect; Section *rosect, *sect;
Sym *sym; Sym *sym;
uchar *bp;
if(debug['v']) if(debug['v'])
Bprint(&bso, "%5.2f span\n", cputime()); Bprint(&bso, "%5.2f span\n", cputime());
@ -187,11 +188,8 @@ span(void)
p = cursym->text; p = cursym->text;
setarch(p); setarch(p);
p->pc = c; 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; lastthumb = thumb;
autosize = p->to.offset + 4; autosize = p->to.offset + 4;
if(p->from.sym != S) if(p->from.sym != S)
@ -216,8 +214,6 @@ span(void)
c = p->pc = scan(op, p, c); c = p->pc = scan(op, p, c);
} }
if(m == 0) { if(m == 0) {
if(p->as == ATEXT) {
}
diag("zero-width instruction\n%P", p); diag("zero-width instruction\n%P", p);
continue; continue;
} }
@ -237,12 +233,13 @@ span(void)
flushpool(p, 0, 0); flushpool(p, 0, 0);
c += m; c += m;
} }
if(blitrl && cursym->next == nil){ if(blitrl){
if(thumb && isbranch(op)) if(thumb && isbranch(op))
pool.extra += brextra(op); pool.extra += brextra(op);
if(checkpool(op, 0)) if(checkpool(op, 0))
c = scan(op, P, c); c = scan(op, P, c);
} }
cursym->size = c - cursym->value;
} }
/* /*
@ -257,6 +254,7 @@ span(void)
bflag = 0; bflag = 0;
c = INITTEXT; c = INITTEXT;
for(cursym = textp; cursym != nil; cursym = cursym->next) { for(cursym = textp; cursym != nil; cursym = cursym->next) {
cursym->value = c;
for(p = cursym->text; p != P; p = p->link) { for(p = cursym->text; p != P; p = p->link) {
setarch(p); setarch(p);
p->pc = c; p->pc = c;
@ -299,6 +297,7 @@ span(void)
} }
c += m; c += m;
} }
cursym->size = c - cursym->value;
} }
} }
@ -318,6 +317,7 @@ span(void)
oop = op = nil; oop = op = nil;
again = 0; again = 0;
for(cursym = textp; cursym != nil; cursym = cursym->next) { for(cursym = textp; cursym != nil; cursym = cursym->next) {
cursym->value = c;
for(p = cursym->text; p != P; oop = op, op = p, p = p->link) { for(p = cursym->text; p != P; oop = op, op = p, p = p->link) {
setarch(p); setarch(p);
if(p->pc != c) if(p->pc != c)
@ -361,6 +361,7 @@ span(void)
} }
c += m; c += m;
} }
cursym->size = c - cursym->value;
} }
if(c != lastc || again){ if(c != lastc || again){
lastc = c; lastc = c;
@ -368,12 +369,39 @@ span(void)
} }
} }
c = rnd(c, 8); c = rnd(c, 8);
xdefine("etext", STEXT, c); xdefine("etext", STEXT, c);
for(cursym = textp; cursym != nil; cursym = cursym->next)
cursym->value = cursym->text->pc;
textsize = c - INITTEXT; 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; rosect = segtext.sect->next;
if(rosect) { if(rosect) {
if(INITRND) if(INITRND)