Commit 3bdeaf2a authored by Elias Naur's avatar Elias Naur Committed by Russ Cox

6l/5l: PIC and shared library support for the linkers.

Added the -shared flag to 5l/6l to output a PIC executable with the required
dynamic relocations and RIP-relative addressing in machine code.
Added dummy support to 8l to avoid compilation errors

See also:
https://golang.org/cl/6822078
https://golang.org/cl/7064048

and

https://groups.google.com/d/topic/golang-nuts/P05BDjLcQ5k/discussion

R=rsc, iant
CC=golang-dev
https://golang.org/cl/6926049
parent 6adbc545
...@@ -93,6 +93,19 @@ braddoff(int32 a, int32 b) ...@@ -93,6 +93,19 @@ braddoff(int32 a, int32 b)
return (((uint32)a) & 0xff000000U) | (0x00ffffffU & (uint32)(a + b)); return (((uint32)a) & 0xff000000U) | (0x00ffffffU & (uint32)(a + b));
} }
Sym *
lookuprel(void)
{
return lookup(".rel", 0);
}
void
adddynrela(Sym *rel, Sym *s, Reloc *r)
{
addaddrplus(rel, s, r->off);
adduint32(rel, R_ARM_RELATIVE);
}
void void
adddynrel(Sym *s, Reloc *r) adddynrel(Sym *s, Reloc *r)
{ {
...@@ -859,15 +872,22 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p- ...@@ -859,15 +872,22 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p-
rel = addrel(cursym); rel = addrel(cursym);
rel->off = pc - cursym->value; rel->off = pc - cursym->value;
rel->siz = 4; rel->siz = 4;
rel->type = D_ADDR;
rel->sym = p->to.sym; rel->sym = p->to.sym;
rel->add = p->to.offset; rel->add = p->to.offset;
if(flag_shared) {
rel->type = D_PCREL;
rel->add += pc - p->pcrel->pc - 8;
} else
rel->type = D_ADDR;
o1 = 0; o1 = 0;
} }
break; break;
case 12: /* movw $lcon, reg */ case 12: /* movw $lcon, reg */
o1 = omvl(p, &p->from, p->to.reg); o1 = omvl(p, &p->from, p->to.reg);
if(o->flag & LPCREL) {
o2 = oprrr(AADD, p->scond) | p->to.reg | REGPC << 16 | p->to.reg << 12;
}
break; break;
case 13: /* op $lcon, [R], R */ case 13: /* op $lcon, [R], R */
...@@ -1172,13 +1192,23 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p- ...@@ -1172,13 +1192,23 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p-
break; break;
case 62: /* case R -> movw R<<2(PC),PC */ case 62: /* case R -> movw R<<2(PC),PC */
o1 = olrr(p->from.reg, REGPC, REGPC, p->scond); if(o->flag & LPCREL) {
o1 |= 2<<7; o1 = oprrr(AADD, p->scond) | immrot(1) | p->from.reg << 16 | REGTMP << 12;
o2 = olrr(REGTMP, REGPC, REGTMP, p->scond);
o2 |= 2<<7;
o3 = oprrr(AADD, p->scond) | REGTMP | REGPC << 16 | REGPC << 12;
} else {
o1 = olrr(p->from.reg, REGPC, REGPC, p->scond);
o1 |= 2<<7;
}
break; break;
case 63: /* bcase */ case 63: /* bcase */
if(p->cond != P) if(p->cond != P) {
o1 = p->cond->pc; o1 = p->cond->pc;
if(flag_shared)
o1 = o1 - p->pcrel->pc - 16;
}
break; break;
/* reloc ops */ /* reloc ops */
...@@ -1187,6 +1217,10 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p- ...@@ -1187,6 +1217,10 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p-
if(!o1) if(!o1)
break; break;
o2 = osr(p->as, p->from.reg, 0, REGTMP, p->scond); o2 = osr(p->as, p->from.reg, 0, REGTMP, p->scond);
if(o->flag & LPCREL) {
o3 = o2;
o2 = oprrr(AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
}
break; break;
case 65: /* mov/movbu addr,R */ case 65: /* mov/movbu addr,R */
...@@ -1196,6 +1230,10 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p- ...@@ -1196,6 +1230,10 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p-
o2 = olr(0, REGTMP, p->to.reg, p->scond); o2 = olr(0, REGTMP, p->to.reg, p->scond);
if(p->as == AMOVBU || p->as == AMOVB) if(p->as == AMOVBU || p->as == AMOVB)
o2 |= 1<<22; o2 |= 1<<22;
if(o->flag & LPCREL) {
o3 = o2;
o2 = oprrr(AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
}
break; break;
case 68: /* floating point store -> ADDR */ case 68: /* floating point store -> ADDR */
...@@ -1203,6 +1241,10 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p- ...@@ -1203,6 +1241,10 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p-
if(!o1) if(!o1)
break; break;
o2 = ofsr(p->as, p->from.reg, 0, REGTMP, p->scond, p); o2 = ofsr(p->as, p->from.reg, 0, REGTMP, p->scond, p);
if(o->flag & LPCREL) {
o3 = o2;
o2 = oprrr(AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
}
break; break;
case 69: /* floating point load <- ADDR */ case 69: /* floating point load <- ADDR */
...@@ -1210,6 +1252,10 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p- ...@@ -1210,6 +1252,10 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p-
if(!o1) if(!o1)
break; break;
o2 = ofsr(p->as, p->to.reg, 0, REGTMP, p->scond, p) | (1<<20); o2 = ofsr(p->as, p->to.reg, 0, REGTMP, p->scond, p) | (1<<20);
if(o->flag & LPCREL) {
o3 = o2;
o2 = oprrr(AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
}
break; break;
/* ArmV4 ops: */ /* ArmV4 ops: */
...@@ -1406,12 +1452,20 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p- ...@@ -1406,12 +1452,20 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p-
o2 ^= (1<<5)|(1<<6); o2 ^= (1<<5)|(1<<6);
else if(p->as == AMOVH) else if(p->as == AMOVH)
o2 ^= (1<<6); o2 ^= (1<<6);
if(o->flag & LPCREL) {
o3 = o2;
o2 = oprrr(AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
}
break; break;
case 94: /* movh/movhu R,addr -> strh */ case 94: /* movh/movhu R,addr -> strh */
o1 = omvl(p, &p->to, REGTMP); o1 = omvl(p, &p->to, REGTMP);
if(!o1) if(!o1)
break; break;
o2 = oshr(p->from.reg, 0, REGTMP, p->scond); o2 = oshr(p->from.reg, 0, REGTMP, p->scond);
if(o->flag & LPCREL) {
o3 = o2;
o2 = oprrr(AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
}
break; break;
case 95: /* PLD off(reg) */ case 95: /* PLD off(reg) */
o1 = 0xf5d0f000; o1 = 0xf5d0f000;
......
...@@ -111,6 +111,7 @@ struct Prog ...@@ -111,6 +111,7 @@ struct Prog
} u0; } u0;
Prog* cond; Prog* cond;
Prog* link; Prog* link;
Prog* pcrel;
int32 pc; int32 pc;
int32 line; int32 line;
int32 spadj; int32 spadj;
...@@ -175,6 +176,7 @@ struct Sym ...@@ -175,6 +176,7 @@ struct Sym
Reloc* r; Reloc* r;
int32 nr; int32 nr;
int32 maxr; int32 maxr;
int rel_ro;
}; };
#define SIGNINTERN (1729*325*1729) #define SIGNINTERN (1729*325*1729)
...@@ -197,6 +199,7 @@ struct Optab ...@@ -197,6 +199,7 @@ struct Optab
char size; char size;
char param; char param;
char flag; char flag;
uchar pcrelsiz;
}; };
struct Oprang struct Oprang
{ {
...@@ -214,6 +217,7 @@ enum ...@@ -214,6 +217,7 @@ enum
LFROM = 1<<0, LFROM = 1<<0,
LTO = 1<<1, LTO = 1<<1,
LPOOL = 1<<2, LPOOL = 1<<2,
LPCREL = 1<<3,
C_NONE = 0, C_NONE = 0,
C_REG, C_REG,
...@@ -228,6 +232,7 @@ enum ...@@ -228,6 +232,7 @@ enum
C_NCON, /* ~RCON */ C_NCON, /* ~RCON */
C_SCON, /* 0xffff */ C_SCON, /* 0xffff */
C_LCON, C_LCON,
C_LCONADDR,
C_ZFCON, C_ZFCON,
C_SFCON, C_SFCON,
C_LFCON, C_LFCON,
...@@ -281,6 +286,7 @@ EXTERN int32 INITDAT; /* data location */ ...@@ -281,6 +286,7 @@ EXTERN int32 INITDAT; /* data location */
EXTERN int32 INITRND; /* data round above text location */ EXTERN int32 INITRND; /* data round above text location */
EXTERN int32 INITTEXT; /* text location */ EXTERN int32 INITTEXT; /* text location */
EXTERN char* INITENTRY; /* entry point */ EXTERN char* INITENTRY; /* entry point */
EXTERN char* LIBINITENTRY; /* shared library entry point */
EXTERN int32 autosize; EXTERN int32 autosize;
EXTERN Auto* curauto; EXTERN Auto* curauto;
EXTERN Auto* curhist; EXTERN Auto* curhist;
......
...@@ -435,6 +435,7 @@ cnames[] = ...@@ -435,6 +435,7 @@ cnames[] =
[C_LAUTO] = "C_LAUTO", [C_LAUTO] = "C_LAUTO",
[C_LBRA] = "C_LBRA", [C_LBRA] = "C_LBRA",
[C_LCON] = "C_LCON", [C_LCON] = "C_LCON",
[C_LCONADDR] = "C_LCONADDR",
[C_LOREG] = "C_LOREG", [C_LOREG] = "C_LOREG",
[C_NCON] = "C_NCON", [C_NCON] = "C_NCON",
[C_NONE] = "C_NONE", [C_NONE] = "C_NONE",
......
...@@ -45,6 +45,20 @@ static Sym* sym_divu; ...@@ -45,6 +45,20 @@ static Sym* sym_divu;
static Sym* sym_mod; static Sym* sym_mod;
static Sym* sym_modu; static Sym* sym_modu;
static void
linkcase(Prog *casep)
{
Prog *p;
for(p = casep; p != P; p = p->link){
if(p->as == ABCASE) {
for(; p != P && p->as == ABCASE; p = p->link)
p->pcrel = casep;
break;
}
}
}
void void
noops(void) noops(void)
{ {
...@@ -76,6 +90,11 @@ noops(void) ...@@ -76,6 +90,11 @@ noops(void)
for(cursym = textp; cursym != nil; cursym = cursym->next) { for(cursym = textp; cursym != nil; cursym = cursym->next) {
for(p = cursym->text; p != P; p = p->link) { for(p = cursym->text; p != P; p = p->link) {
switch(p->as) { switch(p->as) {
case ACASE:
if(flag_shared)
linkcase(p);
break;
case ATEXT: case ATEXT:
p->mark |= LEAF; p->mark |= LEAF;
break; break;
......
...@@ -80,6 +80,7 @@ main(int argc, char *argv[]) ...@@ -80,6 +80,7 @@ main(int argc, char *argv[])
INITDAT = -1; INITDAT = -1;
INITRND = -1; INITRND = -1;
INITENTRY = 0; INITENTRY = 0;
LIBINITENTRY = 0;
nuxiinit(); nuxiinit();
p = getgoarm(); p = getgoarm();
...@@ -123,6 +124,7 @@ main(int argc, char *argv[]) ...@@ -123,6 +124,7 @@ main(int argc, char *argv[])
flagcount("u", "reject unsafe packages", &debug['u']); flagcount("u", "reject unsafe packages", &debug['u']);
flagcount("v", "print link trace", &debug['v']); flagcount("v", "print link trace", &debug['v']);
flagcount("w", "disable DWARF generation", &debug['w']); flagcount("w", "disable DWARF generation", &debug['w']);
flagcount("shared", "generate shared object", &flag_shared);
flagparse(&argc, &argv, usage); flagparse(&argc, &argv, usage);
......
...@@ -77,10 +77,12 @@ Optab optab[] = ...@@ -77,10 +77,12 @@ Optab optab[] =
{ ASWI, C_NONE, C_NONE, C_LCON, 10, 4, 0 }, { ASWI, C_NONE, C_NONE, C_LCON, 10, 4, 0 },
{ AWORD, C_NONE, C_NONE, C_LCON, 11, 4, 0 }, { AWORD, C_NONE, C_NONE, C_LCON, 11, 4, 0 },
{ AWORD, C_NONE, C_NONE, C_LCONADDR, 11, 4, 0 },
{ AWORD, C_NONE, C_NONE, C_ADDR, 11, 4, 0 }, { AWORD, C_NONE, C_NONE, C_ADDR, 11, 4, 0 },
{ AMOVW, C_NCON, C_NONE, C_REG, 12, 4, 0 }, { AMOVW, C_NCON, C_NONE, C_REG, 12, 4, 0 },
{ AMOVW, C_LCON, C_NONE, C_REG, 12, 4, 0, LFROM }, { AMOVW, C_LCON, C_NONE, C_REG, 12, 4, 0, LFROM },
{ AMOVW, C_LCONADDR, C_NONE, C_REG, 12, 4, 0, LFROM | LPCREL, 4},
{ AADD, C_NCON, C_REG, C_REG, 13, 8, 0 }, { AADD, C_NCON, C_REG, C_REG, 13, 8, 0 },
{ AADD, C_NCON, C_NONE, C_REG, 13, 8, 0 }, { AADD, C_NCON, C_NONE, C_REG, 13, 8, 0 },
...@@ -119,20 +121,20 @@ Optab optab[] = ...@@ -119,20 +121,20 @@ Optab optab[] =
{ AMOVW, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO }, { AMOVW, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO },
{ AMOVW, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO }, { AMOVW, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO },
{ AMOVW, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO }, { AMOVW, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4 },
{ AMOVB, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO }, { AMOVB, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO },
{ AMOVB, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO }, { AMOVB, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO },
{ AMOVB, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO }, { AMOVB, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4 },
{ AMOVBU, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO }, { AMOVBU, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO },
{ AMOVBU, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO }, { AMOVBU, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO },
{ AMOVBU, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO }, { AMOVBU, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4 },
{ AMOVW, C_LAUTO,C_NONE, C_REG, 31, 8, REGSP, LFROM }, { AMOVW, C_LAUTO,C_NONE, C_REG, 31, 8, REGSP, LFROM },
{ AMOVW, C_LOREG,C_NONE, C_REG, 31, 8, 0, LFROM }, { AMOVW, C_LOREG,C_NONE, C_REG, 31, 8, 0, LFROM },
{ AMOVW, C_ADDR, C_NONE, C_REG, 65, 8, 0, LFROM }, { AMOVW, C_ADDR, C_NONE, C_REG, 65, 8, 0, LFROM | LPCREL, 4 },
{ AMOVBU, C_LAUTO,C_NONE, C_REG, 31, 8, REGSP, LFROM }, { AMOVBU, C_LAUTO,C_NONE, C_REG, 31, 8, REGSP, LFROM },
{ AMOVBU, C_LOREG,C_NONE, C_REG, 31, 8, 0, LFROM }, { AMOVBU, C_LOREG,C_NONE, C_REG, 31, 8, 0, LFROM },
{ AMOVBU, C_ADDR, C_NONE, C_REG, 65, 8, 0, LFROM }, { AMOVBU, C_ADDR, C_NONE, C_REG, 65, 8, 0, LFROM | LPCREL, 4 },
{ AMOVW, C_LACON,C_NONE, C_REG, 34, 8, REGSP, LFROM }, { AMOVW, C_LACON,C_NONE, C_REG, 34, 8, REGSP, LFROM },
...@@ -159,8 +161,8 @@ Optab optab[] = ...@@ -159,8 +161,8 @@ Optab optab[] =
{ AMOVF, C_LAUTO,C_NONE, C_FREG, 53, 12, REGSP, LFROM }, { AMOVF, C_LAUTO,C_NONE, C_FREG, 53, 12, REGSP, LFROM },
{ AMOVF, C_LOREG,C_NONE, C_FREG, 53, 12, 0, LFROM }, { AMOVF, C_LOREG,C_NONE, C_FREG, 53, 12, 0, LFROM },
{ AMOVF, C_FREG, C_NONE, C_ADDR, 68, 8, 0, LTO }, { AMOVF, C_FREG, C_NONE, C_ADDR, 68, 8, 0, LTO | LPCREL, 4 },
{ AMOVF, C_ADDR, C_NONE, C_FREG, 69, 8, 0, LFROM }, { AMOVF, C_ADDR, C_NONE, C_FREG, 69, 8, 0, LFROM | LPCREL, 4},
{ AADDF, C_FREG, C_NONE, C_FREG, 54, 4, 0 }, { AADDF, C_FREG, C_NONE, C_FREG, 54, 4, 0 },
{ AADDF, C_FREG, C_REG, C_FREG, 54, 4, 0 }, { AADDF, C_FREG, C_REG, C_FREG, 54, 4, 0 },
...@@ -178,7 +180,7 @@ Optab optab[] = ...@@ -178,7 +180,7 @@ Optab optab[] =
{ AMOVB, C_REG, C_NONE, C_SHIFT, 61, 4, 0 }, { AMOVB, C_REG, C_NONE, C_SHIFT, 61, 4, 0 },
{ AMOVBU, C_REG, C_NONE, C_SHIFT, 61, 4, 0 }, { AMOVBU, C_REG, C_NONE, C_SHIFT, 61, 4, 0 },
{ ACASE, C_REG, C_NONE, C_NONE, 62, 4, 0 }, { ACASE, C_REG, C_NONE, C_NONE, 62, 4, 0, LPCREL, 8 },
{ ABCASE, C_NONE, C_NONE, C_SBRA, 63, 4, 0 }, { ABCASE, C_NONE, C_NONE, C_SBRA, 63, 4, 0 },
{ AMOVH, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0 }, { AMOVH, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0 },
...@@ -195,20 +197,20 @@ Optab optab[] = ...@@ -195,20 +197,20 @@ Optab optab[] =
{ AMOVH, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO }, { AMOVH, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO },
{ AMOVH, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO }, { AMOVH, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO },
{ AMOVH, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO }, { AMOVH, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO | LPCREL, 4 },
{ AMOVHU, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO }, { AMOVHU, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO },
{ AMOVHU, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO }, { AMOVHU, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO },
{ AMOVHU, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO }, { AMOVHU, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO | LPCREL, 4 },
{ AMOVB, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM }, { AMOVB, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM },
{ AMOVB, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM }, { AMOVB, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM },
{ AMOVB, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM }, { AMOVB, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4 },
{ AMOVH, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM }, { AMOVH, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM },
{ AMOVH, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM }, { AMOVH, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM },
{ AMOVH, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM }, { AMOVH, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4 },
{ AMOVHU, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM }, { AMOVHU, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM },
{ AMOVHU, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM }, { AMOVHU, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM },
{ AMOVHU, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM }, { AMOVHU, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4 },
{ ALDREX, C_SOREG,C_NONE, C_REG, 77, 4, 0 }, { ALDREX, C_SOREG,C_NONE, C_REG, 77, 4, 0 },
{ ASTREX, C_SOREG,C_REG, C_REG, 78, 4, 0 }, { ASTREX, C_SOREG,C_REG, C_REG, 78, 4, 0 },
......
...@@ -330,9 +330,11 @@ addpool(Prog *p, Adr *a) ...@@ -330,9 +330,11 @@ addpool(Prog *p, Adr *a)
switch(c) { switch(c) {
default: default:
t.to = *a; t.to = *a;
if(flag_shared && t.to.sym != S)
t.pcrel = p;
break; break;
case C_SROREG: case C_SROREG:
case C_LOREG: case C_LOREG:
case C_ROREG: case C_ROREG:
case C_FOREG: case C_FOREG:
...@@ -347,11 +349,13 @@ addpool(Prog *p, Adr *a) ...@@ -347,11 +349,13 @@ addpool(Prog *p, Adr *a)
break; break;
} }
for(q = blitrl; q != P; q = q->link) /* could hash on t.t0.offset */ if(t.pcrel == P) {
if(memcmp(&q->to, &t.to, sizeof(t.to)) == 0) { for(q = blitrl; q != P; q = q->link) /* could hash on t.t0.offset */
p->cond = q; if(q->pcrel == P && memcmp(&q->to, &t.to, sizeof(t.to)) == 0) {
return; p->cond = q;
} return;
}
}
q = prg(); q = prg();
*q = t; *q = t;
...@@ -570,7 +574,10 @@ aclass(Adr *a) ...@@ -570,7 +574,10 @@ aclass(Adr *a)
if(s == S) if(s == S)
break; break;
instoffset = 0; // s.b. unused but just in case instoffset = 0; // s.b. unused but just in case
return C_LCON; if(flag_shared)
return C_LCONADDR;
else
return C_LCON;
case D_AUTO: case D_AUTO:
instoffset = autosize + a->offset; instoffset = autosize + a->offset;
...@@ -736,8 +743,14 @@ buildop(void) ...@@ -736,8 +743,14 @@ buildop(void)
for(i=0; i<C_GOK; i++) for(i=0; i<C_GOK; i++)
for(n=0; n<C_GOK; n++) for(n=0; n<C_GOK; n++)
xcmp[i][n] = cmp(n, i); xcmp[i][n] = cmp(n, i);
for(n=0; optab[n].as != AXXX; n++) for(n=0; optab[n].as != AXXX; n++) {
; if((optab[n].flag & LPCREL) != 0) {
if(flag_shared)
optab[n].size += optab[n].pcrelsiz;
else
optab[n].flag &= ~LPCREL;
}
}
qsort(optab, n, sizeof(optab[0]), ocmp); qsort(optab, n, sizeof(optab[0]), ocmp);
for(i=0; i<n; i++) { for(i=0; i<n; i++) {
r = optab[i].as; r = optab[i].as;
......
...@@ -99,6 +99,20 @@ int nelfsym = 1; ...@@ -99,6 +99,20 @@ int nelfsym = 1;
static void addpltsym(Sym*); static void addpltsym(Sym*);
static void addgotsym(Sym*); static void addgotsym(Sym*);
Sym *
lookuprel(void)
{
return lookup(".rela", 0);
}
void
adddynrela(Sym *rela, Sym *s, Reloc *r)
{
addaddrplus(rela, s, r->off);
adduint64(rela, R_X86_64_RELATIVE);
addaddrplus(rela, r->sym, r->add); // Addend
}
void void
adddynrel(Sym *s, Reloc *r) adddynrel(Sym *s, Reloc *r)
{ {
...@@ -463,7 +477,7 @@ adddynsym(Sym *s) ...@@ -463,7 +477,7 @@ adddynsym(Sym *s)
addaddr(d, s); addaddr(d, s);
/* size of object */ /* size of object */
adduint64(d, 0); adduint64(d, s->size);
if(!s->dynexport && s->dynimplib && needlib(s->dynimplib)) { if(!s->dynexport && s->dynimplib && needlib(s->dynimplib)) {
elfwritedynent(lookup(".dynamic", 0), DT_NEEDED, elfwritedynent(lookup(".dynamic", 0), DT_NEEDED,
......
...@@ -181,6 +181,7 @@ struct Sym ...@@ -181,6 +181,7 @@ struct Sym
Reloc* r; Reloc* r;
int32 nr; int32 nr;
int32 maxr; int32 maxr;
int rel_ro;
}; };
struct Optab struct Optab
{ {
...@@ -320,6 +321,7 @@ EXTERN int32 INITRND; ...@@ -320,6 +321,7 @@ EXTERN int32 INITRND;
EXTERN int64 INITTEXT; EXTERN int64 INITTEXT;
EXTERN int64 INITDAT; EXTERN int64 INITDAT;
EXTERN char* INITENTRY; /* entry point */ EXTERN char* INITENTRY; /* entry point */
EXTERN char* LIBINITENTRY; /* shared library entry point */
EXTERN char* pcstr; EXTERN char* pcstr;
EXTERN Auto* curauto; EXTERN Auto* curauto;
EXTERN Auto* curhist; EXTERN Auto* curhist;
......
...@@ -82,6 +82,7 @@ main(int argc, char *argv[]) ...@@ -82,6 +82,7 @@ main(int argc, char *argv[])
INITDAT = -1; INITDAT = -1;
INITRND = -1; INITRND = -1;
INITENTRY = 0; INITENTRY = 0;
LIBINITENTRY = 0;
nuxiinit(); nuxiinit();
flagcount("1", "use alternate profiling code", &debug['1']); flagcount("1", "use alternate profiling code", &debug['1']);
...@@ -117,6 +118,7 @@ main(int argc, char *argv[]) ...@@ -117,6 +118,7 @@ main(int argc, char *argv[])
flagcount("u", "reject unsafe packages", &debug['u']); flagcount("u", "reject unsafe packages", &debug['u']);
flagcount("v", "print link trace", &debug['v']); flagcount("v", "print link trace", &debug['v']);
flagcount("w", "disable DWARF generation", &debug['w']); flagcount("w", "disable DWARF generation", &debug['w']);
flagcount("shared", "generate shared object", &flag_shared);
flagparse(&argc, &argv, usage); flagparse(&argc, &argv, usage);
......
...@@ -372,7 +372,10 @@ oclass(Adr *a) ...@@ -372,7 +372,10 @@ oclass(Adr *a)
switch(a->index) { switch(a->index) {
case D_EXTERN: case D_EXTERN:
case D_STATIC: case D_STATIC:
return Yi32; /* TO DO: Yi64 */ if(flag_shared)
return Yiauto;
else
return Yi32; /* TO DO: Yi64 */
case D_AUTO: case D_AUTO:
case D_PARAM: case D_PARAM:
return Yiauto; return Yiauto;
...@@ -731,7 +734,10 @@ vaddr(Adr *a, Reloc *r) ...@@ -731,7 +734,10 @@ vaddr(Adr *a, Reloc *r)
diag("need reloc for %D", a); diag("need reloc for %D", a);
errorexit(); errorexit();
} }
r->type = D_ADDR; if(flag_shared)
r->type = D_PCREL;
else
r->type = D_ADDR;
r->siz = 4; // TODO: 8 for external symbols r->siz = 4; // TODO: 8 for external symbols
r->off = -1; // caller must fill in r->off = -1; // caller must fill in
r->sym = s; r->sym = s;
...@@ -760,6 +766,8 @@ asmandsz(Adr *a, int r, int rex, int m64) ...@@ -760,6 +766,8 @@ asmandsz(Adr *a, int r, int rex, int m64)
goto bad; goto bad;
case D_STATIC: case D_STATIC:
case D_EXTERN: case D_EXTERN:
if(flag_shared)
goto bad;
t = D_NONE; t = D_NONE;
v = vaddr(a, &rel); v = vaddr(a, &rel);
break; break;
...@@ -820,7 +828,7 @@ asmandsz(Adr *a, int r, int rex, int m64) ...@@ -820,7 +828,7 @@ asmandsz(Adr *a, int r, int rex, int m64)
rexflag |= (regrex[t] & Rxb) | rex; rexflag |= (regrex[t] & Rxb) | rex;
if(t == D_NONE || (D_CS <= t && t <= D_GS)) { if(t == D_NONE || (D_CS <= t && t <= D_GS)) {
if(asmode != 64){ if(flag_shared && t == D_NONE && (a->type == D_STATIC || a->type == D_EXTERN) || asmode != 64) {
*andptr++ = (0 << 6) | (5 << 0) | (r << 3); *andptr++ = (0 << 6) | (5 << 0) | (r << 3);
goto putrelv; goto putrelv;
} }
...@@ -1776,13 +1784,17 @@ asmins(Prog *p) ...@@ -1776,13 +1784,17 @@ asmins(Prog *p)
if(c != 0xf2 && c != 0xf3 && (c < 0x64 || c > 0x67) && c != 0x2e && c != 0x3e && c != 0x26) if(c != 0xf2 && c != 0xf3 && (c < 0x64 || c > 0x67) && c != 0x2e && c != 0x3e && c != 0x26)
break; break;
} }
for(r=cursym->r+cursym->nr; r-- > cursym->r; ) {
if(r->off < p->pc)
break;
r->off++;
}
memmove(and+np+1, and+np, n-np); memmove(and+np+1, and+np, n-np);
and[np] = 0x40 | rexflag; and[np] = 0x40 | rexflag;
andptr++; andptr++;
} }
n = andptr - and;
for(r=cursym->r+cursym->nr; r-- > cursym->r; ) {
if(r->off < p->pc)
break;
if(rexflag)
r->off++;
if(r->type == D_PCREL)
r->add -= p->pc + n - (r->off + r->siz);
}
} }
...@@ -95,6 +95,18 @@ int nelfsym = 1; ...@@ -95,6 +95,18 @@ int nelfsym = 1;
static void addpltsym(Sym*); static void addpltsym(Sym*);
static void addgotsym(Sym*); static void addgotsym(Sym*);
Sym *
lookuprel(void)
{
return lookup(".rel", 0);
}
void
adddynrela(Sym *rela, Sym *s, Reloc *r)
{
sysfatal("adddynrela not implemented");
}
void void
adddynrel(Sym *s, Reloc *r) adddynrel(Sym *s, Reloc *r)
{ {
......
...@@ -163,6 +163,7 @@ struct Sym ...@@ -163,6 +163,7 @@ struct Sym
Reloc* r; Reloc* r;
int32 nr; int32 nr;
int32 maxr; int32 maxr;
int rel_ro;
}; };
struct Optab struct Optab
{ {
...@@ -275,6 +276,7 @@ EXTERN int32 INITRND; ...@@ -275,6 +276,7 @@ EXTERN int32 INITRND;
EXTERN int32 INITTEXT; EXTERN int32 INITTEXT;
EXTERN int32 INITDAT; EXTERN int32 INITDAT;
EXTERN char* INITENTRY; /* entry point */ EXTERN char* INITENTRY; /* entry point */
EXTERN char* LIBINITENTRY; /* shared library entry point */
EXTERN int32 casepc; EXTERN int32 casepc;
EXTERN char* pcstr; EXTERN char* pcstr;
EXTERN Auto* curauto; EXTERN Auto* curauto;
......
...@@ -89,6 +89,7 @@ main(int argc, char *argv[]) ...@@ -89,6 +89,7 @@ main(int argc, char *argv[])
INITDAT = -1; INITDAT = -1;
INITRND = -1; INITRND = -1;
INITENTRY = 0; INITENTRY = 0;
LIBINITENTRY = 0;
nuxiinit(); nuxiinit();
flagcount("1", "use alternate profiling code", &debug['1']); flagcount("1", "use alternate profiling code", &debug['1']);
......
...@@ -232,7 +232,9 @@ void ...@@ -232,7 +232,9 @@ void
dynrelocsym(Sym *s) dynrelocsym(Sym *s)
{ {
Reloc *r; Reloc *r;
Sym *rel;
Sym *got;
if(HEADTYPE == Hwindows) { if(HEADTYPE == Hwindows) {
Sym *rel, *targ; Sym *rel, *targ;
...@@ -268,9 +270,23 @@ dynrelocsym(Sym *s) ...@@ -268,9 +270,23 @@ dynrelocsym(Sym *s)
return; return;
} }
for(r=s->r; r<s->r+s->nr; r++) got = rel = nil;
if(flag_shared) {
rel = lookuprel();
got = lookup(".got", 0);
}
s->rel_ro = 0;
for(r=s->r; r<s->r+s->nr; r++) {
if(r->sym != S && r->sym->type == SDYNIMPORT || r->type >= 256) if(r->sym != S && r->sym->type == SDYNIMPORT || r->type >= 256)
adddynrel(s, r); adddynrel(s, r);
if(flag_shared && r->sym != S && (r->sym->dynimpname == nil || r->sym->dynexport) && r->type == D_ADDR
&& (s == got || s->type == SDATA || s->type == SGOSTRING || s->type == STYPE || s->type == SRODATA)) {
// Create address based RELATIVE relocation
adddynrela(rel, s, r);
if(s->type < SNOPTRDATA)
s->rel_ro = 1;
}
}
} }
void void
...@@ -714,6 +730,29 @@ setuint64(Sym *s, vlong r, uint64 v) ...@@ -714,6 +730,29 @@ setuint64(Sym *s, vlong r, uint64 v)
setuintxx(s, r, v, 8); setuintxx(s, r, v, 8);
} }
/*
static vlong
addaddrpcrelplus(Sym *s, Sym *t, int32 add)
{
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_PCREL;
r->add = add;
return i;
}
*/
vlong vlong
addaddrplus(Sym *s, Sym *t, int32 add) addaddrplus(Sym *s, Sym *t, int32 add)
{ {
...@@ -968,6 +1007,12 @@ dodata(void) ...@@ -968,6 +1007,12 @@ dodata(void)
} }
*l = nil; *l = nil;
if(flag_shared) {
for(s=datap; s != nil; s = s->next) {
if(s->rel_ro)
s->type = SDATARELRO;
}
}
datap = datsort(datap); datap = datsort(datap);
/* /*
...@@ -1004,7 +1049,7 @@ dodata(void) ...@@ -1004,7 +1049,7 @@ dodata(void)
sect->vaddr = datsize; sect->vaddr = datsize;
lookup("noptrdata", 0)->sect = sect; lookup("noptrdata", 0)->sect = sect;
lookup("enoptrdata", 0)->sect = sect; lookup("enoptrdata", 0)->sect = sect;
for(; s != nil && s->type < SDATA; s = s->next) { for(; s != nil && s->type < SDATARELRO; s = s->next) {
s->sect = sect; s->sect = sect;
s->type = SDATA; s->type = SDATA;
t = alignsymsize(s->size); t = alignsymsize(s->size);
...@@ -1015,12 +1060,34 @@ dodata(void) ...@@ -1015,12 +1060,34 @@ dodata(void)
sect->len = datsize - sect->vaddr; sect->len = datsize - sect->vaddr;
datsize = rnd(datsize, PtrSize); datsize = rnd(datsize, PtrSize);
/* dynamic relocated rodata */
if(flag_shared) {
sect = addsection(&segdata, ".data.rel.ro", 06);
sect->vaddr = datsize;
lookup("datarelro", 0)->sect = sect;
lookup("edatarelro", 0)->sect = sect;
for(; s != nil && s->type == SDATARELRO; s = s->next) {
if(s->align != 0)
datsize = rnd(datsize, s->align);
s->sect = sect;
s->type = SDATA;
s->value = datsize;
datsize += rnd(s->size, PtrSize);
}
sect->len = datsize - sect->vaddr;
datsize = rnd(datsize, PtrSize);
}
/* data */ /* data */
sect = addsection(&segdata, ".data", 06); sect = addsection(&segdata, ".data", 06);
sect->vaddr = datsize; sect->vaddr = datsize;
lookup("data", 0)->sect = sect; lookup("data", 0)->sect = sect;
lookup("edata", 0)->sect = sect; lookup("edata", 0)->sect = sect;
for(; s != nil && s->type < SBSS; s = s->next) { for(; s != nil && s->type < SBSS; s = s->next) {
if(s->type == SDATARELRO) {
cursym = s;
diag("unexpected symbol type %d", s->type);
}
s->sect = sect; s->sect = sect;
s->type = SDATA; s->type = SDATA;
t = alignsymsize(s->size); t = alignsymsize(s->size);
...@@ -1080,6 +1147,7 @@ dodata(void) ...@@ -1080,6 +1147,7 @@ dodata(void)
sect->vaddr = 0; sect->vaddr = 0;
lookup("rodata", 0)->sect = sect; lookup("rodata", 0)->sect = sect;
lookup("erodata", 0)->sect = sect; lookup("erodata", 0)->sect = sect;
lookup("reloffset", 0)->sect = sect;
datsize = 0; datsize = 0;
s = datap; s = datap;
for(; s != nil && s->type < STYPELINK; s = s->next) { for(; s != nil && s->type < STYPELINK; s = s->next) {
...@@ -1227,7 +1295,7 @@ textaddress(void) ...@@ -1227,7 +1295,7 @@ textaddress(void)
void void
address(void) address(void)
{ {
Section *s, *text, *data, *rodata, *symtab, *pclntab, *noptr, *bss, *noptrbss; Section *s, *text, *data, *rodata, *symtab, *pclntab, *noptr, *bss, *noptrbss, *datarelro;
Section *gcdata, *gcbss, *typelink; Section *gcdata, *gcbss, *typelink;
Sym *sym, *sub; Sym *sym, *sub;
uvlong va; uvlong va;
...@@ -1257,6 +1325,7 @@ address(void) ...@@ -1257,6 +1325,7 @@ address(void)
noptr = nil; noptr = nil;
bss = nil; bss = nil;
noptrbss = nil; noptrbss = nil;
datarelro = nil;
for(s=segdata.sect; s != nil; s=s->next) { for(s=segdata.sect; s != nil; s=s->next) {
s->vaddr = va; s->vaddr = va;
va += s->len; va += s->len;
...@@ -1270,6 +1339,8 @@ address(void) ...@@ -1270,6 +1339,8 @@ address(void)
bss = s; bss = s;
if(strcmp(s->name, ".noptrbss") == 0) if(strcmp(s->name, ".noptrbss") == 0)
noptrbss = s; noptrbss = s;
if(strcmp(s->name, ".data.rel.ro") == 0)
datarelro = s;
} }
segdata.filelen -= bss->len + noptrbss->len; // deduct .bss segdata.filelen -= bss->len + noptrbss->len; // deduct .bss
...@@ -1297,6 +1368,10 @@ address(void) ...@@ -1297,6 +1368,10 @@ address(void)
xdefine("erodata", SRODATA, rodata->vaddr + rodata->len); xdefine("erodata", SRODATA, rodata->vaddr + rodata->len);
xdefine("typelink", SRODATA, typelink->vaddr); xdefine("typelink", SRODATA, typelink->vaddr);
xdefine("etypelink", SRODATA, typelink->vaddr + typelink->len); xdefine("etypelink", SRODATA, typelink->vaddr + typelink->len);
if(datarelro != nil) {
xdefine("datarelro", SRODATA, datarelro->vaddr);
xdefine("edatarelro", SRODATA, datarelro->vaddr + datarelro->len);
}
xdefine("gcdata", SGCDATA, gcdata->vaddr); xdefine("gcdata", SGCDATA, gcdata->vaddr);
xdefine("egcdata", SGCDATA, gcdata->vaddr + gcdata->len); xdefine("egcdata", SGCDATA, gcdata->vaddr + gcdata->len);
xdefine("gcbss", SGCBSS, gcbss->vaddr); xdefine("gcbss", SGCBSS, gcbss->vaddr);
......
...@@ -794,6 +794,8 @@ doelf(void) ...@@ -794,6 +794,8 @@ doelf(void)
addstring(shstrtab, ".elfdata"); addstring(shstrtab, ".elfdata");
addstring(shstrtab, ".rodata"); addstring(shstrtab, ".rodata");
addstring(shstrtab, ".typelink"); addstring(shstrtab, ".typelink");
if(flag_shared)
addstring(shstrtab, ".data.rel.ro");
addstring(shstrtab, ".gcdata"); addstring(shstrtab, ".gcdata");
addstring(shstrtab, ".gcbss"); addstring(shstrtab, ".gcbss");
addstring(shstrtab, ".gosymtab"); addstring(shstrtab, ".gosymtab");
...@@ -927,6 +929,13 @@ doelf(void) ...@@ -927,6 +929,13 @@ doelf(void)
elfwritedynent(s, DT_DEBUG, 0); elfwritedynent(s, DT_DEBUG, 0);
if(flag_shared) {
Sym *init_sym = lookup(LIBINITENTRY, 0);
if(init_sym->type != STEXT)
diag("entry not text: %s", init_sym->name);
elfwritedynentsym(s, DT_INIT, init_sym);
}
// Do not write DT_NULL. elfdynhash will finish it. // Do not write DT_NULL. elfdynhash will finish it.
} }
} }
...@@ -1277,7 +1286,11 @@ asmbelf(vlong symo) ...@@ -1277,7 +1286,11 @@ asmbelf(vlong symo)
eh->ident[EI_DATA] = ELFDATA2LSB; eh->ident[EI_DATA] = ELFDATA2LSB;
eh->ident[EI_VERSION] = EV_CURRENT; eh->ident[EI_VERSION] = EV_CURRENT;
eh->type = ET_EXEC; if(flag_shared)
eh->type = ET_DYN;
else
eh->type = ET_EXEC;
eh->version = EV_CURRENT; eh->version = EV_CURRENT;
eh->entry = entryvalue(); eh->entry = entryvalue();
......
...@@ -732,6 +732,8 @@ deadcode(void) ...@@ -732,6 +732,8 @@ deadcode(void)
Bprint(&bso, "%5.2f deadcode\n", cputime()); Bprint(&bso, "%5.2f deadcode\n", cputime());
mark(lookup(INITENTRY, 0)); mark(lookup(INITENTRY, 0));
if(flag_shared)
mark(lookup(LIBINITENTRY, 0));
for(i=0; i<nelem(morename); i++) for(i=0; i<nelem(morename); i++)
mark(lookup(morename[i], 0)); mark(lookup(morename[i], 0));
......
...@@ -104,6 +104,13 @@ libinit(void) ...@@ -104,6 +104,13 @@ libinit(void)
sprint(INITENTRY, "_rt0_%s_%s", goarch, goos); sprint(INITENTRY, "_rt0_%s_%s", goarch, goos);
} }
lookup(INITENTRY, 0)->type = SXREF; lookup(INITENTRY, 0)->type = SXREF;
if(flag_shared) {
if(LIBINITENTRY == nil) {
LIBINITENTRY = mal(strlen(goarch)+strlen(goos)+20);
sprint(LIBINITENTRY, "_rt0_%s_%s_lib", goarch, goos);
}
lookup(LIBINITENTRY, 0)->type = SXREF;
}
} }
void void
...@@ -305,7 +312,7 @@ loadlib(void) ...@@ -305,7 +312,7 @@ loadlib(void)
// //
// Exception: on OS X, programs such as Shark only work with dynamic // Exception: on OS X, programs such as Shark only work with dynamic
// binaries, so leave it enabled on OS X (Mach-O) binaries. // binaries, so leave it enabled on OS X (Mach-O) binaries.
if(!havedynamic && HEADTYPE != Hdarwin) if(!flag_shared && !havedynamic && HEADTYPE != Hdarwin)
debug['d'] = 1; debug['d'] = 1;
importcycles(); importcycles();
......
...@@ -47,6 +47,7 @@ enum ...@@ -47,6 +47,7 @@ enum
SELFROSECT, SELFROSECT,
SELFSECT, SELFSECT,
SNOPTRDATA, SNOPTRDATA,
SDATARELRO,
SDATA, SDATA,
SMACHO, /* Mach-O __nl_symbol_ptr */ SMACHO, /* Mach-O __nl_symbol_ptr */
SMACHOGOT, SMACHOGOT,
...@@ -138,6 +139,7 @@ EXTERN int havedynamic; ...@@ -138,6 +139,7 @@ EXTERN int havedynamic;
EXTERN int iscgo; EXTERN int iscgo;
EXTERN int elfglobalsymndx; EXTERN int elfglobalsymndx;
EXTERN int flag_race; EXTERN int flag_race;
EXTERN int flag_shared;
EXTERN char* tracksym; EXTERN char* tracksym;
EXTERN char* interpreter; EXTERN char* interpreter;
...@@ -176,6 +178,8 @@ void symtab(void); ...@@ -176,6 +178,8 @@ void symtab(void);
void Lflag(char *arg); void Lflag(char *arg);
void usage(void); void usage(void);
void adddynrel(Sym*, Reloc*); void adddynrel(Sym*, Reloc*);
void adddynrela(Sym*, Sym*, Reloc*);
Sym* lookuprel();
void ldobj1(Biobuf *f, char*, int64 len, char *pn); void ldobj1(Biobuf *f, char*, int64 len, char *pn);
void ldobj(Biobuf*, char*, int64, char*, int); void ldobj(Biobuf*, char*, int64, char*, int);
void ldelf(Biobuf*, char*, int64, char*); void ldelf(Biobuf*, char*, int64, char*);
......
...@@ -387,6 +387,11 @@ symtab(void) ...@@ -387,6 +387,11 @@ symtab(void)
xdefine("etypelink", SRODATA, 0); xdefine("etypelink", SRODATA, 0);
xdefine("rodata", SRODATA, 0); xdefine("rodata", SRODATA, 0);
xdefine("erodata", SRODATA, 0); xdefine("erodata", SRODATA, 0);
xdefine("reloffset", SRODATA, 0);
if(flag_shared) {
xdefine("datarelro", SDATARELRO, 0);
xdefine("edatarelro", SDATARELRO, 0);
}
xdefine("gcdata", SGCDATA, 0); xdefine("gcdata", SGCDATA, 0);
xdefine("egcdata", SGCDATA, 0); xdefine("egcdata", SGCDATA, 0);
xdefine("gcbss", SGCBSS, 0); xdefine("gcbss", SGCBSS, 0);
......
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