diff options
| author | 2025-12-13 14:21:22 +0100 | |
|---|---|---|
| committer | 2025-12-13 14:24:30 +0100 | |
| commit | 854df54e1839c8b96d1aaa9aeaa32c2ebbf535f8 (patch) | |
| tree | ba0d2d8b79300d0af2a53aeccd628111733ae7e8 /c/c.c | |
| parent | 17e5a9f573b1a60e12ed60948f45f5992914d324 (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.c | 6 |
1 files changed, 3 insertions, 3 deletions
@@ -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); } |