diff options
| author | 2026-04-15 19:36:50 +0200 | |
|---|---|---|
| committer | 2026-04-15 19:36:50 +0200 | |
| commit | 5293b3cc8876cbc775875974e0c1b7e32952b140 (patch) | |
| tree | b88988bb249de41a01c774256a238b34c297e36e | |
| parent | 85cc0086e32707ae3bff1fa737ed51028b00a809 (diff) | |
x86-64 backend: fix some edgecases not emitting GOT relocations
Logic for this was duplicated. Updated in c4d9087746 but only in one of
the places, so broke on some PIC code.
| -rw-r--r-- | src/t_x86-64_emit.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/src/t_x86-64_emit.c b/src/t_x86-64_emit.c index 06ad803..261881d 100644 --- a/src/t_x86-64_emit.c +++ b/src/t_x86-64_emit.c @@ -870,6 +870,17 @@ flagslivep(Block *blk, int curi) return 1; } +static bool +shouldusegot(int con) +{ + IRCon *xcon = &contab.p[con]; + if ((ccopt.pic || (xcon->flag & SFUNC)) && (xcon->flag & (SLOCAL|SFUNC)) != (SLOCAL|SFUNC)) + return 1; + if (ccopt.pic && objhassym(xcon2sym(con), NULL) != Stext) + return 1; + return 0; +} + /* Copy dst = val, with some peephole optimizations */ static void gencopy(uchar **pcode, enum irclass cls, Block *blk, int curi, Oper dst, Ref val) @@ -916,8 +927,7 @@ gencopy(uchar **pcode, enum irclass cls, Block *blk, int curi, Oper dst, Ref val } /* normal (not 2-address) case */ Lea: - if (isaddrcon(addr->base,0) && (ccopt.pic || (contab.p[addr->base.i].flag & SFUNC)) - && !(contab.p[addr->base.i].flag & SLOCAL)) { + if (isaddrcon(addr->base,0) && shouldusegot(addr->base.i)) { assert(!addr->disp && !addr->index.bits); val = addr->base; goto GOTLoad; @@ -929,12 +939,10 @@ gencopy(uchar **pcode, enum irclass cls, Block *blk, int curi, Oper dst, Ref val /* 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 || (contab.p[val.i].flag & SFUNC)) && (contab.p[val.i].flag & (SLOCAL|SFUNC)) != (SLOCAL|SFUNC)) { + if (shouldusegot(val.i)) { GOTLoad: /* for mov reg, [rip(sym@GOTPCREL)] */ Xmov(pcode, cls, dst, mkoper(OSYMGOT, .con = val.i, .cindex = NOINDEX)); - } else if (ccopt.pic && (contab.p[val.i].flag & SFUNC) && !objhassym(xcon2sym(val.i), NULL)) { - goto GOTLoad; } else { /* for lea reg, [rip(sym)] */ Xlea(pcode, cls, dst, mkoper(OSYM, .con = val.i, .cindex = NOINDEX)); |