[lld] r223103 - [mach-o] add support for arm64 compact unwind info
Nick Kledzik
kledzik at apple.com
Mon Dec 1 17:50:40 PST 2014
Author: kledzik
Date: Mon Dec 1 19:50:38 2014
New Revision: 223103
URL: http://llvm.org/viewvc/llvm-project?rev=223103&view=rev
Log:
[mach-o] add support for arm64 compact unwind info
Tim previously added generic compact unwind processing and x86_64 support.
This patch adds arm64 support.
Added:
lld/trunk/test/mach-o/unwind-info-simple-arm64.yaml
Modified:
lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
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=223103&r1=223102&r2=223103&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp Mon Dec 1 19:50:38 2014
@@ -51,6 +51,9 @@ public:
case gotOffset12:
canBypassGOT = true;
return true;
+ case imageOffsetGot:
+ canBypassGOT = false;
+ return true;
default:
return false;
}
@@ -72,6 +75,9 @@ public:
const_cast<Reference *>(ref)->setKindValue(targetNowGOT ?
offset12scale8 : addOffset12);
break;
+ case imageOffsetGot:
+ const_cast<Reference *>(ref)->setKindValue(imageOffset);
+ break;
default:
llvm_unreachable("Not a GOT reference");
}
@@ -88,30 +94,29 @@ public:
bool isPairedReloc(const normalized::Relocation &) override;
bool needsCompactUnwind() override {
- return false;
+ return true;
}
Reference::KindValue imageOffsetKind() override {
- return invalid;
+ return imageOffset;
}
Reference::KindValue imageOffsetKindIndirect() override {
- return invalid;
+ return imageOffsetGot;
}
Reference::KindValue unwindRefToCIEKind() override {
- return invalid;
+ return negDelta32;
}
Reference::KindValue unwindRefToFunctionKind() override {
- return invalid;
+ return unwindFDEToFunction;
}
Reference::KindValue unwindRefToEhFrameKind() override {
- return invalid;
+ return unwindInfoToEhFrame;
}
uint32_t dwarfCompactUnwindType() override {
- // FIXME
- return -1;
+ return 0x03000000;
}
std::error_code getReferenceInfo(const normalized::Relocation &reloc,
@@ -176,6 +181,7 @@ private:
pointer64, /// ex: .quad _foo
delta64, /// ex: .quad _foo - .
delta32, /// ex: .long _foo - .
+ negDelta32, /// ex: .long . - _foo
pointer64ToGOT, /// ex: .quad _foo at GOT
delta32ToGOT, /// ex: .long _foo at GOT - .
@@ -183,11 +189,19 @@ private:
addOffset12, /// Location contains LDR to change into ADD.
lazyPointer, /// Location contains a lazy pointer.
lazyImmediateLocation, /// Location contains immediate value used in stub.
+ imageOffset, /// Location contains offset of atom in final image
+ imageOffsetGot, /// Location contains offset of GOT entry for atom in
+ /// final image (typically personality function).
+ unwindFDEToFunction, /// Nearly delta64, but cannot be rematerialized in
+ /// relocatable object (yay for implicit contracts!).
+ unwindInfoToEhFrame, /// Fix low 24 bits of compact unwind encoding to
+ /// refer to __eh_frame entry.
};
void applyFixupFinal(const Reference &ref, uint8_t *location,
uint64_t fixupAddress, uint64_t targetAddress,
- uint64_t inAtomAddress);
+ uint64_t inAtomAddress, uint64_t imageBaseAddress,
+ FindAddressForAtom findSectionAddress);
void applyFixupRelocatable(const Reference &ref, uint8_t *location,
uint64_t fixupAddress, uint64_t targetAddress,
@@ -220,12 +234,17 @@ const Registry::KindStrings ArchHandler_
LLD_KIND_STRING_ENTRY(pointer64),
LLD_KIND_STRING_ENTRY(delta64),
LLD_KIND_STRING_ENTRY(delta32),
+ LLD_KIND_STRING_ENTRY(negDelta32),
LLD_KIND_STRING_ENTRY(pointer64ToGOT),
LLD_KIND_STRING_ENTRY(delta32ToGOT),
LLD_KIND_STRING_ENTRY(addOffset12),
LLD_KIND_STRING_ENTRY(lazyPointer),
LLD_KIND_STRING_ENTRY(lazyImmediateLocation),
+ LLD_KIND_STRING_ENTRY(imageOffset),
+ LLD_KIND_STRING_ENTRY(imageOffsetGot),
+ LLD_KIND_STRING_ENTRY(unwindFDEToFunction),
+ LLD_KIND_STRING_ENTRY(unwindInfoToEhFrame),
LLD_KIND_STRING_END
};
@@ -498,7 +517,8 @@ void ArchHandler_arm64::generateAtomCont
targetAddress, atomAddress, targetUnnamed);
} else {
applyFixupFinal(*ref, &atomContentBuffer[offset], fixupAddress,
- targetAddress, atomAddress);
+ targetAddress, atomAddress, imageBaseAddress,
+ findSectionAddress);
}
}
}
@@ -506,7 +526,9 @@ void ArchHandler_arm64::generateAtomCont
void ArchHandler_arm64::applyFixupFinal(const Reference &ref, uint8_t *loc,
uint64_t fixupAddress,
uint64_t targetAddress,
- uint64_t inAtomAddress) {
+ uint64_t inAtomAddress,
+ uint64_t imageBaseAddress,
+ FindAddressForAtom findSectionAddress) {
if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
return;
assert(ref.kindArch() == Reference::KindArch::AArch64);
@@ -515,6 +537,7 @@ void ArchHandler_arm64::applyFixupFinal(
int32_t displacement;
uint32_t instruction;
uint32_t value32;
+ uint32_t value64;
switch (static_cast<Arm64_Kinds>(ref.kindValue())) {
case branch26:
displacement = (targetAddress - fixupAddress) + ref.addend();
@@ -571,18 +594,33 @@ void ArchHandler_arm64::applyFixupFinal(
*loc64 = targetAddress + ref.addend();
return;
case delta64:
+ case unwindFDEToFunction:
*loc64 = (targetAddress - fixupAddress) + ref.addend();
return;
case delta32:
case delta32ToGOT:
*loc32 = (targetAddress - fixupAddress) + ref.addend();
return;
+ case negDelta32:
+ *loc32 = fixupAddress - targetAddress + ref.addend();
+ return;
case lazyPointer:
// Do nothing
return;
case lazyImmediateLocation:
*loc32 = ref.addend();
return;
+ case imageOffset:
+ *loc32 = (targetAddress - imageBaseAddress) + ref.addend();
+ return;
+ case imageOffsetGot:
+ llvm_unreachable("imageOffsetGot should have been changed to imageOffset");
+ break;
+ case unwindInfoToEhFrame:
+ value64 = targetAddress - findSectionAddress(*ref.target()) + ref.addend();
+ assert(value64 < 0xffffffU && "offset in __eh_frame too large");
+ *loc32 = (*loc32 & 0xff000000U) | value64;
+ return;
case invalid:
// Fall into llvm_unreachable().
break;
@@ -631,6 +669,9 @@ void ArchHandler_arm64::applyFixupReloca
case delta32:
*loc32 = ref.addend() + inAtomAddress - fixupAddress;
return;
+ case negDelta32:
+ *loc32 = fixupAddress - inAtomAddress + ref.addend();
+ return;
case pointer64ToGOT:
*loc64 = 0;
return;
@@ -642,6 +683,14 @@ void ArchHandler_arm64::applyFixupReloca
case lazyPointer:
case lazyImmediateLocation:
llvm_unreachable("lazy reference kind implies Stubs pass was run");
+ case imageOffset:
+ case imageOffsetGot:
+ case unwindInfoToEhFrame:
+ llvm_unreachable("fixup implies __unwind_info");
+ return;
+ case unwindFDEToFunction:
+ // Do nothing for now
+ return;
case invalid:
// Fall into llvm_unreachable().
break;
@@ -751,6 +800,14 @@ void ArchHandler_arm64::appendSectionRel
case lazyPointer:
case lazyImmediateLocation:
llvm_unreachable("lazy reference kind implies Stubs pass was run");
+ case imageOffset:
+ case imageOffsetGot:
+ llvm_unreachable("deltas from mach_header can only be in final images");
+ case unwindFDEToFunction:
+ case unwindInfoToEhFrame:
+ case negDelta32:
+ // Do nothing.
+ return;
case invalid:
// Fall into llvm_unreachable().
break;
Added: lld/trunk/test/mach-o/unwind-info-simple-arm64.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/unwind-info-simple-arm64.yaml?rev=223103&view=auto
==============================================================================
--- lld/trunk/test/mach-o/unwind-info-simple-arm64.yaml (added)
+++ lld/trunk/test/mach-o/unwind-info-simple-arm64.yaml Mon Dec 1 19:50:38 2014
@@ -0,0 +1,280 @@
+# RUN: lld -flavor darwin -arch arm64 %s -o %t -e _main %p/Inputs/libSystem.yaml
+# RUN: llvm-objdump -unwind-info %t | FileCheck %s
+
+--- !mach-o
+arch: arm64
+file-type: MH_OBJECT
+flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+sections:
+ - segment: __TEXT
+ section: __text
+ type: S_REGULAR
+ attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+ alignment: 2
+ address: 0x0000000000000000
+ content: [ 0xFD, 0x7B, 0xBF, 0xA9, 0xFD, 0x03, 0x00, 0x91,
+ 0xE0, 0x03, 0x1E, 0x32, 0x00, 0x00, 0x00, 0x94,
+ 0x48, 0x01, 0x80, 0x52, 0x08, 0x00, 0x00, 0xB9,
+ 0x02, 0x00, 0x80, 0xD2, 0x01, 0x00, 0x00, 0x90,
+ 0x21, 0x00, 0x40, 0xF9, 0x00, 0x00, 0x00, 0x94,
+ 0xFD, 0x7B, 0xBF, 0xA9, 0xFD, 0x03, 0x00, 0x91,
+ 0xE0, 0x03, 0x1E, 0x32, 0x00, 0x00, 0x00, 0x94,
+ 0x48, 0x01, 0x80, 0x52, 0x08, 0x00, 0x00, 0xB9,
+ 0x02, 0x00, 0x80, 0xD2, 0x01, 0x00, 0x00, 0x90,
+ 0x21, 0x00, 0x40, 0xF9, 0x00, 0x00, 0x00, 0x94,
+ 0x3F, 0x04, 0x00, 0x71, 0x81, 0x00, 0x00, 0x54,
+ 0x00, 0x00, 0x00, 0x94, 0xFD, 0x7B, 0xC1, 0xA8,
+ 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x94,
+ 0xFD, 0x7B, 0xBF, 0xA9, 0xFD, 0x03, 0x00, 0x91,
+ 0x00, 0x00, 0x00, 0x94 ]
+ relocations:
+ - offset: 0x00000070
+ type: ARM64_RELOC_BRANCH26
+ length: 2
+ pc-rel: true
+ extern: true
+ symbol: 5
+ - offset: 0x00000064
+ type: ARM64_RELOC_BRANCH26
+ length: 2
+ pc-rel: true
+ extern: true
+ symbol: 7
+ - offset: 0x00000060
+ type: ARM64_RELOC_BRANCH26
+ length: 2
+ pc-rel: true
+ extern: true
+ symbol: 12
+ - offset: 0x00000058
+ type: ARM64_RELOC_BRANCH26
+ length: 2
+ pc-rel: true
+ extern: true
+ symbol: 11
+ - offset: 0x0000004C
+ type: ARM64_RELOC_BRANCH26
+ length: 2
+ pc-rel: true
+ extern: true
+ symbol: 13
+ - offset: 0x00000048
+ type: ARM64_RELOC_GOT_LOAD_PAGEOFF12
+ length: 2
+ pc-rel: false
+ extern: true
+ symbol: 8
+ - offset: 0x00000044
+ type: ARM64_RELOC_GOT_LOAD_PAGE21
+ length: 2
+ pc-rel: true
+ extern: true
+ symbol: 8
+ - offset: 0x00000034
+ type: ARM64_RELOC_BRANCH26
+ length: 2
+ pc-rel: true
+ extern: true
+ symbol: 10
+ - offset: 0x00000024
+ type: ARM64_RELOC_BRANCH26
+ length: 2
+ pc-rel: true
+ extern: true
+ symbol: 13
+ - offset: 0x00000020
+ type: ARM64_RELOC_GOT_LOAD_PAGEOFF12
+ length: 2
+ pc-rel: false
+ extern: true
+ symbol: 8
+ - offset: 0x0000001C
+ type: ARM64_RELOC_GOT_LOAD_PAGE21
+ length: 2
+ pc-rel: true
+ extern: true
+ symbol: 8
+ - offset: 0x0000000C
+ type: ARM64_RELOC_BRANCH26
+ length: 2
+ pc-rel: true
+ extern: true
+ symbol: 10
+ - segment: __TEXT
+ section: __gcc_except_tab
+ type: S_REGULAR
+ attributes: [ ]
+ alignment: 2
+ address: 0x0000000000000074
+ content: [ 0xFF, 0x9B, 0xAF, 0x80, 0x00, 0x03, 0x27, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x01, 0x28, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0xD0, 0xFF, 0xFF, 0xFF ]
+ relocations:
+ - offset: 0x00000030
+ type: ARM64_RELOC_POINTER_TO_GOT
+ length: 2
+ pc-rel: true
+ extern: true
+ symbol: 9
+ - segment: __LD
+ section: __compact_unwind
+ type: S_REGULAR
+ attributes: [ ]
+ alignment: 3
+ address: 0x00000000000000A8
+ content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
+ relocations:
+ - offset: 0x00000040
+ type: ARM64_RELOC_UNSIGNED
+ length: 3
+ pc-rel: false
+ extern: false
+ symbol: 1
+ - offset: 0x00000038
+ type: ARM64_RELOC_UNSIGNED
+ length: 3
+ pc-rel: false
+ extern: false
+ symbol: 2
+ - offset: 0x00000030
+ type: ARM64_RELOC_UNSIGNED
+ length: 3
+ pc-rel: false
+ extern: true
+ symbol: 14
+ - offset: 0x00000020
+ type: ARM64_RELOC_UNSIGNED
+ length: 3
+ pc-rel: false
+ extern: false
+ symbol: 1
+ - offset: 0x00000000
+ type: ARM64_RELOC_UNSIGNED
+ length: 3
+ pc-rel: false
+ extern: false
+ symbol: 1
+local-symbols:
+ - name: ltmp0
+ type: N_SECT
+ sect: 1
+ value: 0x0000000000000000
+ - name: ltmp14
+ type: N_SECT
+ sect: 2
+ value: 0x0000000000000074
+ - name: GCC_except_table1
+ type: N_SECT
+ sect: 2
+ value: 0x0000000000000074
+ - name: ltmp21
+ type: N_SECT
+ sect: 3
+ value: 0x00000000000000A8
+global-symbols:
+ - name: __Z3barv
+ type: N_SECT
+ scope: [ N_EXT ]
+ sect: 1
+ value: 0x0000000000000028
+ - name: __Z3foov
+ type: N_SECT
+ scope: [ N_EXT ]
+ sect: 1
+ value: 0x0000000000000000
+ - name: _main
+ type: N_SECT
+ scope: [ N_EXT ]
+ sect: 1
+ value: 0x0000000000000068
+undefined-symbols:
+ - name: __Unwind_Resume
+ type: N_UNDF
+ scope: [ N_EXT ]
+ value: 0x0000000000000000
+ - name: __ZTIi
+ type: N_UNDF
+ scope: [ N_EXT ]
+ value: 0x0000000000000000
+ - name: __ZTIl
+ type: N_UNDF
+ scope: [ N_EXT ]
+ value: 0x0000000000000000
+ - name: ___cxa_allocate_exception
+ type: N_UNDF
+ scope: [ N_EXT ]
+ value: 0x0000000000000000
+ - name: ___cxa_begin_catch
+ type: N_UNDF
+ scope: [ N_EXT ]
+ value: 0x0000000000000000
+ - name: ___cxa_end_catch
+ type: N_UNDF
+ scope: [ N_EXT ]
+ value: 0x0000000000000000
+ - name: ___cxa_throw
+ type: N_UNDF
+ scope: [ N_EXT ]
+ value: 0x0000000000000000
+ - name: ___gxx_personality_v0
+ type: N_UNDF
+ scope: [ N_EXT ]
+ value: 0x0000000000000000
+
+--- !mach-o
+arch: arm64
+file-type: MH_DYLIB
+install-name: /usr/lib/libc++.dylib
+exports:
+ - name: __Unwind_Resume
+ - name: __ZTIl
+ - name: __ZTIi
+ - name: ___cxa_end_catch
+ - name: ___cxa_begin_catch
+ - name: ___cxa_allocate_exception
+ - name: ___cxa_throw
+ - name: ___gxx_personality_v0
+
+...
+
+
+# CHECK: Contents of __unwind_info section:
+# CHECK: Version: 0x1
+# CHECK: Common encodings array section offset: 0x1c
+# CHECK: Number of common encodings in array: 0x0
+# CHECK: Personality function array section offset: 0x1c
+# CHECK: Number of personality functions in array: 0x1
+# CHECK: Index array section offset: 0x20
+# CHECK: Number of indices in array: 0x2
+# CHECK: Common encodings: (count = 0)
+# CHECK: Personality functions: (count = 1)
+# CHECK: personality[1]: 0x00004018
+# CHECK: Top level indices: (count = 2)
+# CHECK: [0]: function offset=0x00003e68, 2nd level page offset=0x00000040, LSDA offset=0x00000038
+# CHECK: [1]: function offset=0x00003edc, 2nd level page offset=0x00000000, LSDA offset=0x00000040
+# CHECK: LSDA descriptors:
+# CHECK: [0]: function offset=0x00003e90, LSDA offset=0x00003f6c
+# CHECK: Second level indices:
+# CHECK: Second level index[0]: offset in section=0x00000040, base function offset=0x00003e68
+# CHECK: [0]: function offset=0x00003e68, encoding=0x04000000
+# CHECK: [1]: function offset=0x00003e90, encoding=0x54000000
+# CHECK: [2]: function offset=0x00003ed0, encoding=0x04000000
+# CHECK-NOT: Contents of __compact_unwind section
+
+
+
More information about the llvm-commits
mailing list