summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp50
-rw-r--r--lld/test/mach-o/parse-text-relocs-x86_64.yaml42
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:
OpenPOWER on IntegriCloud