aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2026-04-15 19:36:50 +0200
committerlemon <lsof@mailbox.org>2026-04-15 19:36:50 +0200
commit5293b3cc8876cbc775875974e0c1b7e32952b140 (patch)
treeb88988bb249de41a01c774256a238b34c297e36e /src
parent85cc0086e32707ae3bff1fa737ed51028b00a809 (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.
Diffstat (limited to 'src')
-rw-r--r--src/t_x86-64_emit.c18
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));