mirror of
https://github.com/golang/go
synced 2024-11-22 04:34:39 -07:00
5l: data-relocatable code layout
R=ken2 CC=golang-dev https://golang.org/cl/2479043
This commit is contained in:
parent
a647f59c1f
commit
3d0a85785a
@ -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 */
|
||||||
@ -1589,6 +1577,14 @@ if(debug['G']) print("%ux: %s: arm %d %d %d %d\n", (uint32)(p->pc), p->from.sym-
|
|||||||
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) {
|
||||||
default:
|
default:
|
||||||
|
@ -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*);
|
||||||
|
@ -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();
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user