diff options
| author | 2025-12-23 14:22:49 +0100 | |
|---|---|---|
| committer | 2025-12-23 14:22:49 +0100 | |
| commit | 97088545c44d7d974ba82f9e04e1c9bb018cba9e (patch) | |
| tree | 9b6da43b7ac683b03a89c15e92c1bd6ef72a73d4 /x86_64/emit.c | |
| parent | 7036e19098c295a075f97cbd056fdc43bd490fb2 (diff) | |
x86_64: fix -fpic
Diffstat (limited to 'x86_64/emit.c')
| -rw-r--r-- | x86_64/emit.c | 16 |
1 files changed, 7 insertions, 9 deletions
diff --git a/x86_64/emit.c b/x86_64/emit.c index 2786e22..6f989f6 100644 --- a/x86_64/emit.c +++ b/x86_64/emit.c @@ -8,7 +8,7 @@ * a memory reference [base + index * scale + disp], * or a relocatable reference to some symbol plus a displacement and maybe index*scale */ -enum operkind { ONONE, OREG, OIMM, OMEM, OSYM }; +enum operkind { ONONE, OREG, OIMM, OMEM, OSYM, OSYMGOT }; enum { NOBASE = 63, NOINDEX = 63 }; struct oper { uchar t; @@ -236,8 +236,8 @@ opermatch(enum operpat pat, struct oper oper) case PU16: return oper.t == OIMM && (ushort)oper.imm == oper.imm; case PI32: return oper.t == OIMM; case PU32: return oper.t == OIMM && oper.imm >= 0; - case PMEM: return in_range(oper.t, OMEM, OSYM); - case PSYM: return oper.t == OSYM; + case PMEM: return in_range(oper.t, OMEM, OSYMGOT); + case PSYM: return oper.t == OSYM || oper.t == OSYMGOT; } assert(0); } @@ -327,7 +327,7 @@ encode(uchar **pcode, const struct desc *tab, int ntab, enum irclass k, struct o if (rex) B(0x40 | rex); else if (en->r8 && in_range(reg, RSP, RDI)) B(0x40); - if (mem.t == OSYM) { + if (mem.t == OSYM || mem.t == OSYMGOT) { D(opc, nopc); if (mem.cindex == NOINDEX) { /* %rip(var) */ @@ -339,11 +339,9 @@ encode(uchar **pcode, const struct desc *tab, int ntab, enum irclass k, struct o if (objhassym(sym, &addr) == Stext) { I32(addr - (*pcode - objout.textbegin) + disp); } else { - enum relockind r; - if ((!conht[mem.con].deref && ccopt.pic) || conht[mem.con].isfunc) + enum relockind r = REL_PCREL32; + if (mem.t == OSYMGOT) r = (rex ? REL_GOTPCRELX_REX : REL_GOTPCRELX); - else - r = REL_PCREL32; objreloc(xcon2sym(mem.con), r, Stext, *pcode - objout.textbegin, disp); I32(0); } @@ -887,7 +885,7 @@ gencopy(uchar **pcode, enum irclass cls, struct block *blk, int curi, struct ope && !objhassym(xcon2sym(val.i), NULL)) { GOTLoad: /* for mov reg, [rip(sym@GOTPCREL)] */ - Xmov(pcode, cls, dst, mkoper(OSYM, .con = val.i, .cindex = NOINDEX)); + Xmov(pcode, cls, dst, mkoper(OSYMGOT, .con = val.i, .cindex = NOINDEX)); } else { /* for lea reg, [rip(sym)] */ Xlea(pcode, cls, dst, mkoper(OSYM, .con = val.i, .cindex = NOINDEX)); |