Commit 3d0a8578 authored by Russ Cox's avatar Russ Cox

5l: data-relocatable code layout

R=ken2
CC=golang-dev
https://golang.org/cl/2479043
parent a647f59c
......@@ -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) {
......
......@@ -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*);
......
......@@ -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();
......
......@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment