diff --git a/rts/linker/MachO.c b/rts/linker/MachO.c
index 0b7b7957f7575004cf09d483d2d926d03b91bb7d..1505b2833526125e2d35a36774e4ae85a3d59d7b 100644
--- a/rts/linker/MachO.c
+++ b/rts/linker/MachO.c
@@ -552,7 +552,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)) {