forked from OSchip/llvm-project
[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. llvm-svn: 223103
This commit is contained in:
parent
bdf7e1dd4b
commit
a441b7b050
|
@ -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@GOT
|
||||
delta32ToGOT, /// ex: .long _foo@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_arm64::_sKindStrings[] = {
|
|||
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::generateAtomContent(
|
|||
targetAddress, atomAddress, targetUnnamed);
|
||||
} else {
|
||||
applyFixupFinal(*ref, &atomContentBuffer[offset], fixupAddress,
|
||||
targetAddress, atomAddress);
|
||||
targetAddress, atomAddress, imageBaseAddress,
|
||||
findSectionAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -506,7 +526,9 @@ void ArchHandler_arm64::generateAtomContent(
|
|||
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(const Reference &ref, uint8_t *loc,
|
|||
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(const Reference &ref, uint8_t *loc,
|
|||
*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::applyFixupRelocatable(const Reference &ref,
|
|||
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::applyFixupRelocatable(const Reference &ref,
|
|||
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::appendSectionRelocations(
|
|||
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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue