aboutsummaryrefslogtreecommitdiffhomepage
path: root/c/c.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-12-13 14:21:22 +0100
committerlemon <lsof@mailbox.org>2025-12-13 14:24:30 +0100
commit854df54e1839c8b96d1aaa9aeaa32c2ebbf535f8 (patch)
treeba0d2d8b79300d0af2a53aeccd628111733ae7e8 /c/c.c
parent17e5a9f573b1a60e12ed60948f45f5992914d324 (diff)
fix position independent loads of function symbols.
For `extern int x[1];`, can use PCREL32 for &x. But for `extern int x(int)`, must use GOTREL, when not being called directly (that's PLT). Therefore the type of an external symbol (actually just whether it denotes a function) matters when deciding what kind of relocation to emit, so keep that information.
Diffstat (limited to 'c/c.c')
-rw-r--r--c/c.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/c/c.c b/c/c.c
index aff0a9d..7e521b6 100644
--- a/c/c.c
+++ b/c/c.c
@@ -2755,7 +2755,7 @@ expraddr(struct function *fn, const struct expr *ex)
assert(decl->id >= 0);
return mkref(RTMP, decl->id);
case SCEXTERN: case SCNONE: case SCSTATIC:
- return mksymref(decl->sym);
+ return mksymref(decl->sym, decl->ty.t == TYFUNC);
default:
assert(0);
}
@@ -2798,7 +2798,7 @@ expraddr(struct function *fn, const struct expr *ex)
ip->off = objnewdat(sym, ip->sec, 0, typesize(ty), typealign(ty));
if (!iniwriterec(NULL, ip, 0, (struct expr *)ex))
error(&ex->span, "cannot not evaluate expression statically");
- return mksymref(sym);
+ return mksymref(sym, 0);
}
case ESEQ:
expreffects(fn, &ex->sub[0]);
@@ -2888,7 +2888,7 @@ geninit(struct function *fn, union type t, union ref dst, const struct expr *src
addinstr(fn, mkarginstr(cls2type(KPTR), dst));
addinstr(fn, mkarginstr(cls2type(KI32), ZEROREF));
addinstr(fn, mkarginstr(cls2type(type2cls[targ_sizetype]), mkintcon(type2cls[targ_sizetype], siz)));
- call.l = mksymref("memset");
+ call.l = mksymref("memset", 1);
call.r = mkcallarg(cls2type(KPTR), 3, -1);
addinstr(fn, call);
}