summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTamar Christina <tamar@zhox.com>2022-03-15 15:45:01 +0000
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-03-17 10:16:37 -0400
commit36d20d4d5f089becd4dadb7bd6d477806e0b24a6 (patch)
treeabc7990fc44ddb2ee80fcd9ace890f231e4b2b27
parent0f0e2394942842c700484ecf4b473a929a436b0d (diff)
downloadhaskell-36d20d4d5f089becd4dadb7bd6d477806e0b24a6.tar.gz
linker: Fix ADDR32NB relocations on Windows
-rw-r--r--rts/linker/PEi386.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/rts/linker/PEi386.c b/rts/linker/PEi386.c
index 57b762e60a..b0be4efad4 100644
--- a/rts/linker/PEi386.c
+++ b/rts/linker/PEi386.c
@@ -1895,11 +1895,16 @@ ocResolve_PEi386 ( ObjectCode* oc )
break;
}
case 2: /* R_X86_64_32 (ELF constant 10) - IMAGE_REL_AMD64_ADDR32 (PE constant 2) */
- case 3: /* R_X86_64_32S (ELF constant 11) - IMAGE_REL_AMD64_ADDR32NB (PE constant 3) */
+ case 3: /* IMAGE_REL_AMD64_ADDR32NB (PE constant 3) */
case 17: /* R_X86_64_32S ELF constant, no PE mapping. See note [ELF constant in PE file] */
{
uint64_t v;
v = S + A;
+
+ /* If IMAGE_REL_AMD64_ADDR32NB then subtract the image base. */
+ if (reloc->Type == 3)
+ v -= (uint64_t)__image_base;
+
// N.B. in the case of the sign-extended relocations we must ensure that v
// fits in a signed 32-bit value. See #15808.
if (((int64_t) v > (int64_t) INT32_MAX) || ((int64_t) v < (int64_t) INT32_MIN)) {
@@ -1908,6 +1913,11 @@ ocResolve_PEi386 ( ObjectCode* oc )
S = makeSymbolExtra_PEi386(oc, symIndex, S, (char *)symbol);
/* And retry */
v = S + A;
+
+ /* If IMAGE_REL_AMD64_ADDR32NB then subtract the image base. */
+ if (reloc->Type == 3)
+ v -= (uint64_t)__image_base;
+
if (((int64_t) v > (int64_t) INT32_MAX) || ((int64_t) v < (int64_t) INT32_MIN)) {
barf("IMAGE_REL_AMD64_ADDR32[NB]: High bits are set in %zx for %s",
v, (char *)symbol);