[lld] r222198 - [mach-o] enhance arm64 reloc parser to support local pointer relocations
Nick Kledzik
kledzik at apple.com
Mon Nov 17 16:30:17 PST 2014
Author: kledzik
Date: Mon Nov 17 18:30:17 2014
New Revision: 222198
URL: http://llvm.org/viewvc/llvm-project?rev=222198&view=rev
Log:
[mach-o] enhance arm64 reloc parser to support local pointer relocations
The arm64 assembler almost always uses r_extern=1 relocations in which the
r_symbolnum field is the index of the symbol the relocation references. But
sometimes it will set r_extern=0 in which case the linker needs to read the
content of the reloction to determine the target.
Add test case that the r_extern=0 relocation round trips.
Modified:
lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
lld/trunk/test/mach-o/parse-data-relocs-arm64.yaml
Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp?rev=222198&r1=222197&r2=222198&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp Mon Nov 17 18:30:17 2014
@@ -191,7 +191,7 @@ private:
void applyFixupRelocatable(const Reference &ref, uint8_t *location,
uint64_t fixupAddress, uint64_t targetAddress,
- uint64_t inAtomAddress);
+ uint64_t inAtomAddress, bool targetUnnamed);
// Utility functions for inspecting/updating instructions.
static uint32_t setDisplacementInBranch26(uint32_t instr, int32_t disp);
@@ -399,6 +399,11 @@ std::error_code ArchHandler_arm64::getRe
return ec;
*addend = *(const little64_t *)fixupContent;
return std::error_code();
+ case ARM64_RELOC_UNSIGNED | rLength8:
+ // ex: .quad Lfoo + N
+ *kind = pointer64;
+ return atomFromAddress(reloc.symbol, *(little64_t *)fixupContent,
+ target, addend);
case ARM64_RELOC_POINTER_TO_GOT | rExtern | rLength8:
// ex: .quad _foo at GOT
*kind = pointer64ToGOT;
@@ -482,6 +487,7 @@ void ArchHandler_arm64::generateAtomCont
for (const Reference *ref : atom) {
uint32_t offset = ref->offsetInAtom();
const Atom *target = ref->target();
+ bool targetUnnamed = target->name().empty();
uint64_t targetAddress = 0;
if (isa<DefinedAtom>(target))
targetAddress = findAddress(*target);
@@ -489,7 +495,7 @@ void ArchHandler_arm64::generateAtomCont
uint64_t fixupAddress = atomAddress + offset;
if (relocatable) {
applyFixupRelocatable(*ref, &atomContentBuffer[offset], fixupAddress,
- targetAddress, atomAddress);
+ targetAddress, atomAddress, targetUnnamed);
} else {
applyFixupFinal(*ref, &atomContentBuffer[offset], fixupAddress,
targetAddress, atomAddress);
@@ -588,7 +594,8 @@ void ArchHandler_arm64::applyFixupReloca
uint8_t *loc,
uint64_t fixupAddress,
uint64_t targetAddress,
- uint64_t inAtomAddress) {
+ uint64_t inAtomAddress,
+ bool targetUnnamed) {
if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
return;
assert(ref.kindArch() == Reference::KindArch::AArch64);
@@ -613,7 +620,10 @@ void ArchHandler_arm64::applyFixupReloca
*loc32 = setImm12(*loc32, 0);
return;
case pointer64:
- *loc64 = ref.addend();
+ if (targetUnnamed)
+ *loc64 = targetAddress + ref.addend();
+ else
+ *loc64 = ref.addend();
return;
case delta64:
*loc64 = ref.addend() + inAtomAddress - fixupAddress;
@@ -707,7 +717,11 @@ void ArchHandler_arm64::appendSectionRel
ARM64_RELOC_TLVP_LOAD_PAGEOFF12 | rExtern | rLength4);
return;
case pointer64:
- appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
+ if (ref.target()->name().empty())
+ appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0,
+ ARM64_RELOC_UNSIGNED | rLength8);
+ else
+ appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
ARM64_RELOC_UNSIGNED | rExtern | rLength8);
return;
case delta64:
Modified: lld/trunk/test/mach-o/parse-data-relocs-arm64.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/parse-data-relocs-arm64.yaml?rev=222198&r1=222197&r2=222198&view=diff
==============================================================================
--- lld/trunk/test/mach-o/parse-data-relocs-arm64.yaml (original)
+++ lld/trunk/test/mach-o/parse-data-relocs-arm64.yaml Mon Nov 17 18:30:17 2014
@@ -1,5 +1,5 @@
-# RUN: lld -flavor darwin -arch arm64 -r -print_atoms %s -o %t | FileCheck %s \
-# RUN: && lld -flavor darwin -arch arm64 -r -print_atoms %t -o %t2 | FileCheck %s
+# RUN: lld -flavor darwin -arch arm64 -r -print_atoms %s -o %t | FileCheck %s
+# RUN: lld -flavor darwin -arch arm64 -r -print_atoms %t -o %t2 | FileCheck %s
#
# Test parsing and writing of arm64 data relocations.
#
@@ -14,127 +14,126 @@
--- !mach-o
arch: arm64
file-type: MH_OBJECT
-flags: [ ]
-has-UUID: false
-OS: unknown
+flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
sections:
- - segment: __TEXT
- section: __text
- type: S_REGULAR
- attributes: [ S_ATTR_PURE_INSTRUCTIONS ]
- address: 0x0000000000000000
- segment: __DATA
section: __data
type: S_REGULAR
attributes: [ ]
- alignment: 3
address: 0x0000000000000000
content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xDC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xD0, 0xFF, 0xFF, 0xFF, 0xCE, 0xFF, 0xFF, 0xFF,
- 0xC8, 0xFF, 0xFF, 0xFF ]
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC0, 0xFF, 0xFF, 0xFF, 0xBE, 0xFF, 0xFF, 0xFF,
+ 0xB0, 0xFF, 0xFF, 0xFF ]
relocations:
- - offset: 0x00000038
+ - offset: 0x00000050
type: ARM64_RELOC_POINTER_TO_GOT
length: 2
pc-rel: true
extern: true
- symbol: 3
- - offset: 0x00000034
+ symbol: 1
+ - offset: 0x0000004C
type: ARM64_RELOC_SUBTRACTOR
length: 2
pc-rel: false
extern: true
- symbol: 2
- - offset: 0x00000034
+ symbol: 1
+ - offset: 0x0000004C
type: ARM64_RELOC_UNSIGNED
length: 2
pc-rel: false
extern: true
- symbol: 3
- - offset: 0x00000030
+ symbol: 1
+ - offset: 0x00000048
type: ARM64_RELOC_SUBTRACTOR
length: 2
pc-rel: false
extern: true
- symbol: 2
- - offset: 0x00000030
+ symbol: 1
+ - offset: 0x00000048
type: ARM64_RELOC_UNSIGNED
length: 2
pc-rel: false
extern: true
- symbol: 3
- - offset: 0x00000028
+ symbol: 1
+ - offset: 0x00000040
+ type: ARM64_RELOC_UNSIGNED
+ length: 3
+ pc-rel: false
+ extern: true
+ symbol: 1
+ - offset: 0x00000038
+ type: ARM64_RELOC_UNSIGNED
+ length: 3
+ pc-rel: false
+ extern: false
+ symbol: 1
+ - offset: 0x00000030
type: ARM64_RELOC_SUBTRACTOR
length: 3
pc-rel: false
extern: true
- symbol: 2
- - offset: 0x00000028
+ symbol: 1
+ - offset: 0x00000030
type: ARM64_RELOC_UNSIGNED
length: 3
pc-rel: false
extern: true
- symbol: 3
- - offset: 0x00000020
+ symbol: 1
+ - offset: 0x00000028
type: ARM64_RELOC_SUBTRACTOR
length: 3
pc-rel: false
extern: true
- symbol: 2
- - offset: 0x00000020
+ symbol: 1
+ - offset: 0x00000028
type: ARM64_RELOC_UNSIGNED
length: 3
pc-rel: false
extern: true
- symbol: 3
- - offset: 0x00000018
+ symbol: 1
+ - offset: 0x00000020
type: ARM64_RELOC_SUBTRACTOR
length: 3
pc-rel: false
extern: true
- symbol: 2
- - offset: 0x00000018
+ symbol: 1
+ - offset: 0x00000020
type: ARM64_RELOC_UNSIGNED
length: 3
pc-rel: false
extern: true
- symbol: 3
- - offset: 0x00000010
+ symbol: 1
+ - offset: 0x00000018
type: ARM64_RELOC_POINTER_TO_GOT
length: 3
pc-rel: false
extern: true
- symbol: 3
- - offset: 0x00000008
+ symbol: 1
+ - offset: 0x00000010
type: ARM64_RELOC_UNSIGNED
length: 3
pc-rel: false
extern: true
- symbol: 3
- - offset: 0x00000000
+ symbol: 1
+ - offset: 0x00000008
type: ARM64_RELOC_UNSIGNED
length: 3
pc-rel: false
extern: true
- symbol: 3
+ symbol: 1
local-symbols:
- - name: ltmp0
- type: N_SECT
- sect: 1
- value: 0x0000000000000000
- - name: ltmp1
- type: N_SECT
- sect: 2
- value: 0x0000000000000000
- name: _v1
type: N_SECT
- sect: 2
- value: 0x0000000000000000
+ sect: 1
+ value: 0x0000000000000008
undefined-symbols:
- name: _foo
type: N_UNDF
@@ -143,13 +142,18 @@ undefined-symbols:
...
# CHECK: defined-atoms:
+# CHECK: - ref-name: L000
+# CHECK: type: data
+# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
# CHECK: - name: _v1
# CHECK: type: data
# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00, 08, 00, 00, 00,
# CHECK: 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
# CHECK: 00, 00, 00, 00, 00, 00, 00, 00, E0, FF, FF, FF,
# CHECK: FF, FF, FF, FF, DC, FF, FF, FF, FF, FF, FF, FF,
-# CHECK: D0, FF, FF, FF, CE, FF, FF, FF, C8, FF, FF, FF ]
+# CHECK: 00, 00, 00, 00, 00, 00, 00, 00, 04, 00, 00, 00,
+# CHECK: 00, 00, 00, 00, C0, FF, FF, FF, BE, FF, FF, FF,
+# CHECK: B0, FF, FF, FF ]
# CHECK: references:
# CHECK: - kind: pointer64
# CHECK: offset: 0
@@ -175,17 +179,44 @@ undefined-symbols:
# CHECK: offset: 40
# CHECK: target: _foo
# CHECK: addend: 4
-# CHECK: - kind: delta32
+# CHECK: - kind: pointer64
# CHECK: offset: 48
+# CHECK: target: L000
+# CHECK-NOT: addend:
+# CHECK: - kind: pointer64
+# CHECK: offset: 56
+# CHECK: target: _foo
+# CHECK: addend: 4
+# CHECK: - kind: delta32
+# CHECK: offset: 64
# CHECK: target: _foo
# CHECK-NOT: addend:
# CHECK: - kind: delta32
-# CHECK: offset: 52
+# CHECK: offset: 68
# CHECK: target: _foo
# CHECK: addend: 2
# CHECK: - kind: delta32ToGOT
-# CHECK: offset: 56
+# CHECK: offset: 72
# CHECK: target: _foo
# CHECK-NOT: addend:
# CHECK: undefined-atoms:
# CHECK: - name: _foo
+
+
+
+# .data
+#Lanon:
+# .quad 0
+#_v1:
+# .quad _foo
+# .quad _foo + 8
+# .quad _foo at GOT
+# .quad _foo + 24 - .
+# .quad _foo - .
+# .quad _foo + 4 - .
+# .quad Lanon
+# .quad Lanon + 4
+# .long _foo - .
+# .long _foo +2 - .
+# .long _foo at GOT - .
+
More information about the llvm-commits
mailing list