diff options
-rw-r--r-- | lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp | 50 | ||||
-rw-r--r-- | lld/test/mach-o/parse-text-relocs-x86_64.yaml | 42 |
2 files changed, 87 insertions, 5 deletions
diff --git a/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp b/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp index 3ea959efde8..8605c7a5789 100644 --- a/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp +++ b/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp @@ -168,6 +168,9 @@ private: ripRel32Minus2, /// ex: movw $0x1234, _foo(%rip) ripRel32Minus4, /// ex: movl $0x12345678, _foo(%rip) ripRel32Anon, /// ex: movq L1(%rip), %rax + ripRel32Minus1Anon, /// ex: movb $0x12, L1(%rip) + ripRel32Minus2Anon, /// ex: movw $0x1234, L1(%rip) + ripRel32Minus4Anon, /// ex: movw $0x12345678, L1(%rip) ripRel32GotLoad, /// ex: movq _foo@GOTPCREL(%rip), %rax ripRel32Got, /// ex: pushq _foo@GOTPCREL(%rip) pointer64, /// ex: .quad _foo @@ -218,7 +221,11 @@ const Registry::KindStrings ArchHandler_x86_64::_sKindStrings[] = { LLD_KIND_STRING_ENTRY(invalid), LLD_KIND_STRING_ENTRY(branch32), LLD_KIND_STRING_ENTRY(ripRel32), LLD_KIND_STRING_ENTRY(ripRel32Minus1), LLD_KIND_STRING_ENTRY(ripRel32Minus2), LLD_KIND_STRING_ENTRY(ripRel32Minus4), - LLD_KIND_STRING_ENTRY(ripRel32Anon), LLD_KIND_STRING_ENTRY(ripRel32GotLoad), + LLD_KIND_STRING_ENTRY(ripRel32Anon), + LLD_KIND_STRING_ENTRY(ripRel32Minus1Anon), + LLD_KIND_STRING_ENTRY(ripRel32Minus2Anon), + LLD_KIND_STRING_ENTRY(ripRel32Minus4Anon), + LLD_KIND_STRING_ENTRY(ripRel32GotLoad), LLD_KIND_STRING_ENTRY(ripRel32GotLoadNowLea), LLD_KIND_STRING_ENTRY(ripRel32Got), LLD_KIND_STRING_ENTRY(lazyPointer), LLD_KIND_STRING_ENTRY(lazyImmediateLocation), @@ -301,10 +308,16 @@ ArchHandler_x86_64::kindFromReloc(const Relocation &reloc) { return ripRel32Anon; case X86_64_RELOC_SIGNED_1 | rPcRel | rExtern | rLength4: return ripRel32Minus1; + case X86_64_RELOC_SIGNED_1 | rPcRel | rLength4: + return ripRel32Minus1Anon; case X86_64_RELOC_SIGNED_2 | rPcRel | rExtern | rLength4: return ripRel32Minus2; + case X86_64_RELOC_SIGNED_2 | rPcRel | rLength4: + return ripRel32Minus2Anon; case X86_64_RELOC_SIGNED_4 | rPcRel | rExtern | rLength4: return ripRel32Minus4; + case X86_64_RELOC_SIGNED_4 | rPcRel | rLength4: + return ripRel32Minus4Anon; case X86_64_RELOC_GOT_LOAD | rPcRel | rExtern | rLength4: return ripRel32GotLoad; case X86_64_RELOC_GOT | rPcRel | rExtern | rLength4: @@ -359,6 +372,15 @@ ArchHandler_x86_64::getReferenceInfo(const Relocation &reloc, case ripRel32Anon: targetAddress = fixupAddress + 4 + *(const little32_t *)fixupContent; return atomFromAddress(reloc.symbol, targetAddress, target, addend); + case ripRel32Minus1Anon: + targetAddress = fixupAddress + 5 + *(const little32_t *)fixupContent; + return atomFromAddress(reloc.symbol, targetAddress, target, addend); + case ripRel32Minus2Anon: + targetAddress = fixupAddress + 6 + *(const little32_t *)fixupContent; + return atomFromAddress(reloc.symbol, targetAddress, target, addend); + case ripRel32Minus4Anon: + targetAddress = fixupAddress + 8 + *(const little32_t *)fixupContent; + return atomFromAddress(reloc.symbol, targetAddress, target, addend); case ripRel32GotLoad: case ripRel32Got: if (E ec = atomFromSymbolIndex(reloc.symbol, target)) @@ -493,12 +515,15 @@ void ArchHandler_x86_64::applyFixupFinal( *loc64 = targetAddress + ref.addend(); return; case ripRel32Minus1: + case ripRel32Minus1Anon: *loc32 = targetAddress - (fixupAddress + 5) + ref.addend(); return; case ripRel32Minus2: + case ripRel32Minus2Anon: *loc32 = targetAddress - (fixupAddress + 6) + ref.addend(); return; case ripRel32Minus4: + case ripRel32Minus4Anon: *loc32 = targetAddress - (fixupAddress + 8) + ref.addend(); return; case delta32: @@ -572,12 +597,21 @@ void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref, case ripRel32Minus1: *loc32 = ref.addend() - 1; return; + case ripRel32Minus1Anon: + *loc32 = (targetAddress - (fixupAddress + 5)) + ref.addend(); + return; case ripRel32Minus2: *loc32 = ref.addend() - 2; return; + case ripRel32Minus2Anon: + *loc32 = (targetAddress - (fixupAddress + 6)) + ref.addend(); + return; case ripRel32Minus4: *loc32 = ref.addend() - 4; return; + case ripRel32Minus4Anon: + *loc32 = (targetAddress - (fixupAddress + 8)) + ref.addend(); + return; case delta32: *loc32 = ref.addend() + inAtomAddress - fixupAddress; return; @@ -638,7 +672,7 @@ void ArchHandler_x86_64::appendSectionRelocations( return; case ripRel32Anon: appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0, - X86_64_RELOC_SIGNED | rPcRel | rLength4 ); + X86_64_RELOC_SIGNED | rPcRel | rLength4 ); return; case ripRel32Got: appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0, @@ -660,14 +694,26 @@ void ArchHandler_x86_64::appendSectionRelocations( appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0, X86_64_RELOC_SIGNED_1 | rPcRel | rExtern | rLength4 ); return; + case ripRel32Minus1Anon: + appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0, + X86_64_RELOC_SIGNED_1 | rPcRel | rLength4 ); + return; case ripRel32Minus2: appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0, X86_64_RELOC_SIGNED_2 | rPcRel | rExtern | rLength4 ); return; + case ripRel32Minus2Anon: + appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0, + X86_64_RELOC_SIGNED_2 | rPcRel | rLength4 ); + return; case ripRel32Minus4: appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0, X86_64_RELOC_SIGNED_4 | rPcRel | rExtern | rLength4 ); return; + case ripRel32Minus4Anon: + appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0, + X86_64_RELOC_SIGNED_4 | rPcRel | rLength4 ); + return; case delta32: appendReloc(relocs, sectionOffset, symbolIndexForAtom(atom), 0, X86_64_RELOC_SUBTRACTOR | rExtern | rLength4 ); diff --git a/lld/test/mach-o/parse-text-relocs-x86_64.yaml b/lld/test/mach-o/parse-text-relocs-x86_64.yaml index 9e58e02e377..6d0a52f6004 100644 --- a/lld/test/mach-o/parse-text-relocs-x86_64.yaml +++ b/lld/test/mach-o/parse-text-relocs-x86_64.yaml @@ -19,6 +19,9 @@ # movw $0x1234, _foo(%rip) # movl $0x12345678, _foo(%rip) # movl L2(%rip), %eax +# movb $0x12, L2(%rip) +# movw $0x1234, L2(%rip) +# movl $0x12345678, L2(%rip) # # .data #L2: .long 0 @@ -41,9 +44,30 @@ sections: 0x00, 0x00, 0x00, 0xC6, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0x12, 0x66, 0xC7, 0x05, 0xFE, 0xFF, 0xFF, 0xFF, 0x34, 0x12, 0xC7, 0x05, 0xFC, 0xFF, 0xFF, - 0xFF, 0x78, 0x56, 0x34, 0x12, 0x8B, 0x05, 0x00, - 0x00, 0x00, 0x00 ] + 0xFF, 0x78, 0x56, 0x34, 0x12, 0x8B, 0x05, 0x1A, + 0x00, 0x00, 0x00, 0xc6, 0x05, 0x13, 0x00, 0x00, + 0x00, 0x12, 0x66, 0xc7, 0x05, 0x0a, 0x00, 0x00, + 0x00, 0x34, 0x12, 0xc7, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x78, 0x56, 0x34, 0x12 ] relocations: + - offset: 0x00000055 + type: X86_64_RELOC_SIGNED_4 + length: 2 + pc-rel: true + extern: false + symbol: 2 + - offset: 0x0000004d + type: X86_64_RELOC_SIGNED_2 + length: 2 + pc-rel: true + extern: false + symbol: 2 + - offset: 0x00000045 + type: X86_64_RELOC_SIGNED_1 + length: 2 + pc-rel: true + extern: false + symbol: 2 - offset: 0x0000003F type: X86_64_RELOC_SIGNED length: 2 @@ -108,7 +132,7 @@ sections: section: __data type: S_REGULAR attributes: [ ] - address: 0x0000000000000043 + address: 0x000000000000005D content: [ 0x00, 0x00, 0x00, 0x00 ] local-symbols: - name: _test @@ -166,3 +190,15 @@ undefined-symbols: # CHECK: offset: 63 # CHECK: target: [[LABEL]] # CHECK-NOT: addend: +# CHECK: - kind: ripRel32Minus1Anon +# CHECK: offset: 69 +# CHECK: target: [[LABEL]] +# CHECK-NOT: addend: +# CHECK: - kind: ripRel32Minus2Anon +# CHECK: offset: 77 +# CHECK: target: [[LABEL]] +# CHECK-NOT: addend: +# CHECK: - kind: ripRel32Minus4Anon +# CHECK: offset: 85 +# CHECK: target: [[LABEL]] +# CHECK-NOT: addend: |