diff options
author | Moritz Angermann <moritz.angermann@gmail.com> | 2021-06-22 15:39:44 +0800 |
---|---|---|
committer | GHC GitLab CI <ghc-ci@gitlab-haskell.org> | 2021-06-22 22:31:24 +0800 |
commit | d2e6fdd57ffdd7497e3149779df533b8599d5643 (patch) | |
tree | 1471caa1f07ededc25bcba8bebaf19ab412d8229 | |
parent | 62d720db4f6a53014400a608baf5c56555258eee (diff) | |
download | haskell-d2e6fdd57ffdd7497e3149779df533b8599d5643.tar.gz |
[aarch64-macho] Fix off-by-one error in the linkerwip/angerman/fix-macho-linker
We need to be careful about the sign bit for BR26 relocation
otherwise we end up encoding a large positive number and reading
back a large negative number.
-rw-r--r-- | rts/linker/MachO.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/rts/linker/MachO.c b/rts/linker/MachO.c index cdafcb1c89..1a18ee6a74 100644 --- a/rts/linker/MachO.c +++ b/rts/linker/MachO.c @@ -551,7 +551,17 @@ relocateSectionAarch64(ObjectCode * oc, Section * section) } else { value = (uint64_t)symbol->addr; // address of the symbol. } - if((value - pc + addend) >> (2 + 26)) { + // We've got: + // + 2 bits, for alignment + // + 26 bits for for the relocation value + // - 1 bit for signage. + // + // Thus we can encode 26 bits for relocation, including the sign + // bit. However as branches need to be 4-byte aligned, we only + // need 26 bits to address a 28 bit range. Thus discarding the + // sign bit, we can encode a range of +/- 27bits. + // + if((value - pc + addend) >> (2 + 26 - 1)) { /* we need a stub */ /* check if we already have that stub */ if(findStub(section, (void**)&value, 0)) { |