diff --git a/lld/MachO/Arch/ARM64.cpp b/lld/MachO/Arch/ARM64.cpp --- a/lld/MachO/Arch/ARM64.cpp +++ b/lld/MachO/Arch/ARM64.cpp @@ -79,8 +79,23 @@ uint64_t ARM64::getEmbeddedAddend(MemoryBufferRef mb, const section_64 &sec, const relocation_info rel) const { - // TODO(gkm): extract embedded addend just so we can assert that it is 0 - return 0; + if (rel.r_type != ARM64_RELOC_UNSIGNED) { + // All other reloc types should use the ADDEND relocation to store their + // addends. + // TODO(gkm): extract embedded addend just so we can assert that it is 0 + return 0; + } + + auto *buf = reinterpret_cast(mb.getBufferStart()); + const uint8_t *loc = buf + sec.offset + rel.r_address; + switch (rel.r_length) { + case 2: + return read32le(loc); + case 3: + return read64le(loc); + default: + llvm_unreachable("invalid r_length"); + } } inline uint64_t bitField(uint64_t value, int right, int width, int left) { diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -278,9 +278,6 @@ continue; if (relInfo.r_address & R_SCATTERED) fatal("TODO: Scattered relocations not supported"); - uint64_t embeddedAddend = target->getEmbeddedAddend(mb, sec, relInfo); - assert(!(embeddedAddend && pairedAddend)); - uint64_t totalAddend = pairedAddend + embeddedAddend; Reloc p; if (target->hasAttr(relInfo.r_type, RelocAttrBits::SUBTRAHEND)) { @@ -292,6 +289,9 @@ assert(target->hasAttr(relInfo.r_type, RelocAttrBits::UNSIGNED) && relInfo.r_extern); } + uint64_t embeddedAddend = target->getEmbeddedAddend(mb, sec, relInfo); + assert(!(embeddedAddend && pairedAddend)); + uint64_t totalAddend = pairedAddend + embeddedAddend; Reloc r; r.type = relInfo.r_type; r.pcrel = relInfo.r_pcrel; diff --git a/lld/test/MachO/arm64-relocs.s b/lld/test/MachO/arm64-relocs.s --- a/lld/test/MachO/arm64-relocs.s +++ b/lld/test/MachO/arm64-relocs.s @@ -18,8 +18,8 @@ # CHECK-NEXT: ret # CHECK-LABEL: Contents of (__DATA_CONST,__const) section -# CHECK: [[#PTR_1]] {{0*}}[[#BAZ]] 00000000 00000000 00000000 -# CHECK: [[#PTR_2]] {{0*}}[[#BAZ]] 00000000 00000000 00000000 +# CHECK: [[#PTR_1]] {{0*}}[[#BAZ]] 00000000 00000000 00000000 +# CHECK: [[#PTR_2]] {{0*}}[[#BAZ+123]] 00000000 00000000 00000000 .text .globl _foo, _bar, _baz @@ -50,7 +50,7 @@ .quad _baz .space 8 _ptr_2: - .quad _baz + .quad _baz + 123 .space 8 .subsections_via_symbols diff --git a/lld/test/MachO/reloc-subtractor.s b/lld/test/MachO/reloc-subtractor.s --- a/lld/test/MachO/reloc-subtractor.s +++ b/lld/test/MachO/reloc-subtractor.s @@ -14,9 +14,9 @@ # CHECK: {{0*}}[[#%x, SUB4ADDR:]] l {{.*}} __DATA,__data _sub4 # CHECK-LABEL: Contents of section __DATA,__data: # CHECK: [[#SUB1ADDR]] 10000000 -# CHECK-NEXT: [[#SUB2ADDR]] f0ffffff -# CHECK-NEXT: [[#SUB3ADDR]] 10000000 00000000 -# CHECK-NEXT: [[#SUB4ADDR]] f0ffffff ffffffff +# CHECK-NEXT: [[#SUB2ADDR]] f2ffffff +# CHECK-NEXT: [[#SUB3ADDR]] 14000000 00000000 +# CHECK-NEXT: [[#SUB4ADDR]] f6ffffff ffffffff # CHECK: Rebase table: # CHECK-NEXT: segment section address type # CHECK-EMPTY: @@ -36,13 +36,13 @@ .long _minuend_1 - _subtrahend_1 .space 12 _sub2: - .long _minuend_2 - _subtrahend_2 + .long _minuend_2 - _subtrahend_2 + 2 .space 12 _sub3: - .quad _minuend_1 - _subtrahend_1 + .quad _minuend_1 - _subtrahend_1 + 4 .space 8 _sub4: - .quad _minuend_2 - _subtrahend_2 + .quad _minuend_2 - _subtrahend_2 + 6 .text .p2align 2