diff options
Diffstat (limited to 'x86_64')
| -rw-r--r-- | x86_64/emit.c | 12 | ||||
| -rw-r--r-- | x86_64/isel.c | 2 |
2 files changed, 6 insertions, 8 deletions
diff --git a/x86_64/emit.c b/x86_64/emit.c index 6f989f6..6e48965 100644 --- a/x86_64/emit.c +++ b/x86_64/emit.c @@ -336,12 +336,11 @@ encode(uchar **pcode, const struct desc *tab, int ntab, enum irclass k, struct o int disp = mem.disp - 4 - offs[en->operenc]; internstr sym = xcon2sym(mem.con); B(/*mod 0*/ (reg & 7) << 3 | RBP); - if (objhassym(sym, &addr) == Stext) { + if (objhassym(sym, &addr) == Stext && mem.t != OSYMGOT) { I32(addr - (*pcode - objout.textbegin) + disp); } else { enum relockind r = REL_PCREL32; - if (mem.t == OSYMGOT) - r = (rex ? REL_GOTPCRELX_REX : REL_GOTPCRELX); + if (mem.t == OSYMGOT) r = rex ? REL_GOTPCRELX_REX : REL_GOTPCRELX; objreloc(xcon2sym(mem.con), r, Stext, *pcode - objout.textbegin, disp); I32(0); } @@ -870,8 +869,8 @@ gencopy(uchar **pcode, enum irclass cls, struct block *blk, int curi, struct ope } /* normal (not 2-address) case */ Lea: - if (isaddrcon(addr->base,0) && (ccopt.pic || conht[addr->base.i].isfunc) - && !objhassym(xcon2sym(addr->base.i), NULL)) { + if (isaddrcon(addr->base,0) && (ccopt.pic || (conht[addr->base.i].flag & SFUNC)) + && !(conht[addr->base.i].flag & SLOCAL)) { assert(!addr->disp && !addr->index.bits); val = addr->base; goto GOTLoad; @@ -881,8 +880,7 @@ gencopy(uchar **pcode, enum irclass cls, struct block *blk, int curi, struct ope /* dst = 0 -> xor dst, dst; but only if it is ok to clobber flags */ Xxor(pcode, kisint(cls) ? KI32 : cls, dst, dst); } else if (isaddrcon(val,0)) { - if ((ccopt.pic || conht[val.i].isfunc) - && !objhassym(xcon2sym(val.i), NULL)) { + if ((ccopt.pic || (conht[val.i].flag & SFUNC)) && !(conht[val.i].flag & SLOCAL)) { GOTLoad: /* for mov reg, [rip(sym@GOTPCREL)] */ Xmov(pcode, cls, dst, mkoper(OSYMGOT, .con = val.i, .cindex = NOINDEX)); diff --git a/x86_64/isel.c b/x86_64/isel.c index 9c99608..40d8db4 100644 --- a/x86_64/isel.c +++ b/x86_64/isel.c @@ -305,7 +305,7 @@ fuseaddr(union ref *r, struct block *blk, int *curi) if (r->t != RSTACK && r->t != RTMP) return 0; if (!aadd(&addr, blk, curi, *r)) return 0; - if (isaddrcon(addr.base,0) && (ccopt.pic || (ccopt.pie && addr.index.bits) || conht[addr.base.i].isfunc)) { + if (isaddrcon(addr.base,0) && (ccopt.pic || (ccopt.pie && addr.index.bits) || (conht[addr.base.i].flag & SFUNC))) { /* pic needs to load from GOT */ /* pie cannot encode RIP-relative address with index register */ /* first load symbol address into a temp register */ |