Skip to content

Commit

Permalink
[LLVM_full@12] Add LLVM AArch64 unwind patches
Browse files Browse the repository at this point in the history
  • Loading branch information
Cody Tapscott authored and vchuravy committed Jun 29, 2021
1 parent d659a52 commit f7beab5
Show file tree
Hide file tree
Showing 3 changed files with 190 additions and 1 deletion.
2 changes: 1 addition & 1 deletion L/LLVM/LLVM_full@12.0.0/build_tarballs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ version = v"12.0.0"
include("../common.jl")

build_tarballs(ARGS, configure_build(ARGS, version; experimental_platforms=true)...;
preferred_gcc_version=v"7", preferred_llvm_version=v"8", julia_compat="1.7")
preferred_gcc_version=v"7", preferred_llvm_version=v"9", julia_compat="1.7")
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
From 7133a3d3b0bd639d36d9d40f1135159442ab73c7 Mon Sep 17 00:00:00 2001
From: Cody Tapscott <cody+github@tapscott.me>
Date: Mon, 24 May 2021 15:11:39 -0700
Subject: [PATCH] Do not patch FDE symbols in RuntimeDyld, on targets that use
non-absolute symbol relocations in `.eh_frame`

Since processFDE adds a delta to the values in the FDE, it assumes that the relocations for the .eh_frame section have not been applied by RuntimeDyld. It expects instead that only the relocation addend has been written to the symbol locations, and that the section-to-section offset needs to be added.

However, there are platform differences that interfere with this:
1) X86-64 has DwarfFDESymbolsUseAbsDiff enabled in its AsmInfo, causing an absolute symbol to be emitted for the FDE pcStart. Absolute symbols are skipped as a relocation by RuntimeDyld, so the processFDE function in RuntimeDyldMachO.cpp calculates the relocation correctly.
2) AArch64 has DwarfFDESymbolsUseAbsDiff disabled, so a relocation is emitted in the eh_frame section. Since this isn't absolute, the relocation is applied by RuntimeDyld. This means that processFDE ends up adding an additional section-to-section offset to the pcStart field, generating an incorrect FDE

Differential Revision: https://reviews.llvm.org/D103052
---
.../RuntimeDyld/RuntimeDyldMachO.cpp | 37 +++++++++++--------
.../RuntimeDyld/RuntimeDyldMachO.h | 8 +++-
.../Targets/RuntimeDyldMachOAArch64.h | 2 +
.../RuntimeDyld/Targets/RuntimeDyldMachOARM.h | 2 +
.../Targets/RuntimeDyldMachOI386.h | 2 +
.../Targets/RuntimeDyldMachOX86_64.h | 2 +
6 files changed, 35 insertions(+), 18 deletions(-)

diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
index 9ca76602ea18..e61bfd1bd31c 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
@@ -272,9 +272,9 @@ RuntimeDyldMachOCRTPBase<Impl>::finalizeLoad(const ObjectFile &Obj,
}

template <typename Impl>
-unsigned char *RuntimeDyldMachOCRTPBase<Impl>::processFDE(uint8_t *P,
- int64_t DeltaForText,
- int64_t DeltaForEH) {
+unsigned char *RuntimeDyldMachOCRTPBase<Impl>::patchFDERelocations(uint8_t *P,
+ int64_t DeltaForText,
+ int64_t DeltaForEH) {
typedef typename Impl::TargetPtrT TargetPtrT;

LLVM_DEBUG(dbgs() << "Processing FDE: Delta for text: " << DeltaForText
@@ -324,19 +324,24 @@ void RuntimeDyldMachOCRTPBase<Impl>::registerEHFrames() {
continue;
SectionEntry *Text = &Sections[SectionInfo.TextSID];
SectionEntry *EHFrame = &Sections[SectionInfo.EHFrameSID];
- SectionEntry *ExceptTab = nullptr;
- if (SectionInfo.ExceptTabSID != RTDYLD_INVALID_SECTION_ID)
- ExceptTab = &Sections[SectionInfo.ExceptTabSID];
-
- int64_t DeltaForText = computeDelta(Text, EHFrame);
- int64_t DeltaForEH = 0;
- if (ExceptTab)
- DeltaForEH = computeDelta(ExceptTab, EHFrame);
-
- uint8_t *P = EHFrame->getAddress();
- uint8_t *End = P + EHFrame->getSize();
- while (P != End) {
- P = processFDE(P, DeltaForText, DeltaForEH);
+
+ // If the FDE includes absolute symbol relocations (not supported
+ // by RuntimeDyld), we need to manually patch-up the values
+ if (doDwarfFDESymbolsUseAbsDiff()) {
+ SectionEntry *ExceptTab = nullptr;
+ if (SectionInfo.ExceptTabSID != RTDYLD_INVALID_SECTION_ID)
+ ExceptTab = &Sections[SectionInfo.ExceptTabSID];
+
+ int64_t DeltaForText = computeDelta(Text, EHFrame);
+ int64_t DeltaForEH = 0;
+ if (ExceptTab)
+ DeltaForEH = computeDelta(ExceptTab, EHFrame);
+
+ uint8_t *P = EHFrame->getAddress();
+ uint8_t *End = P + EHFrame->getSize();
+ while (P != End) {
+ P = patchFDERelocations(P, DeltaForText, DeltaForEH);
+ }
}

MemMgr.registerEHFrames(EHFrame->getAddress(), EHFrame->getLoadAddress(),
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
index 650e7b79fbb8..a7e5c9cb56e8 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
@@ -43,6 +43,10 @@ protected:
SID ExceptTabSID;
};

+ // Returns true if the FDE section includes absolute symbol relocations
+ // on this platform.
+ virtual bool doDwarfFDESymbolsUseAbsDiff() = 0;
+
// When a module is loaded we save the SectionID of the EH frame section
// in a table until we receive a request to register all unregistered
// EH frame sections with the memory manager.
@@ -147,8 +151,8 @@ private:
Impl &impl() { return static_cast<Impl &>(*this); }
const Impl &impl() const { return static_cast<const Impl &>(*this); }

- unsigned char *processFDE(uint8_t *P, int64_t DeltaForText,
- int64_t DeltaForEH);
+ unsigned char *patchFDERelocations(uint8_t *P, int64_t DeltaForText,
+ int64_t DeltaForEH);

public:
RuntimeDyldMachOCRTPBase(RuntimeDyld::MemoryManager &MemMgr,
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h
index f2ee1b06d494..90a9a4c44c84 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h
@@ -30,6 +30,8 @@ public:

unsigned getStubAlignment() override { return 8; }

+ bool doDwarfFDESymbolsUseAbsDiff() override { return false; }
+
/// Extract the addend encoded in the instruction / memory location.
Expected<int64_t> decodeAddend(const RelocationEntry &RE) const {
const SectionEntry &Section = Sections[RE.SectionID];
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h
index a76958a9e2c2..7281249d25bf 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h
@@ -33,6 +33,8 @@ public:

unsigned getStubAlignment() override { return 4; }

+ bool doDwarfFDESymbolsUseAbsDiff() override { return false; }
+
Expected<JITSymbolFlags> getJITSymbolFlags(const SymbolRef &SR) override {
auto Flags = RuntimeDyldImpl::getJITSymbolFlags(SR);
if (!Flags)
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h
index 523deb29b723..755bc13afeb4 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h
@@ -30,6 +30,8 @@ public:

unsigned getStubAlignment() override { return 1; }

+ bool doDwarfFDESymbolsUseAbsDiff() override { return true; }
+
Expected<relocation_iterator>
processRelocationRef(unsigned SectionID, relocation_iterator RelI,
const ObjectFile &BaseObjT,
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h
index 28febbdb948c..9854da24a2ce 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h
@@ -30,6 +30,8 @@ public:

unsigned getStubAlignment() override { return 8; }

+ bool doDwarfFDESymbolsUseAbsDiff() override { return true; }
+
Expected<relocation_iterator>
processRelocationRef(unsigned SectionID, relocation_iterator RelI,
const ObjectFile &BaseObjT,
--
2.30.1 (Apple Git-130)

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
From 026f3518c4713e388a8ed06fa032e0925d35c6f5 Mon Sep 17 00:00:00 2001
From: Cody Tapscott <cody+github@tapscott.me>
Date: Mon, 24 May 2021 16:36:06 -0700
Subject: [PATCH] Force `.eh_frame` emission on AArch64

We need to force the emission of the EH Frame section (currently done via SupportsCompactUnwindWithoutEHFrame in the MCObjectFileInfo for the target), since libunwind doesn't yet support dynamically registering compact unwind information at run-time.
---
llvm/lib/MC/MCObjectFileInfo.cpp | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 1a448f040b3b..e12154deca5f 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -57,9 +57,10 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(const Triple &T) {
MachO::S_ATTR_STRIP_STATIC_SYMS | MachO::S_ATTR_LIVE_SUPPORT,
SectionKind::getReadOnly());

- if (T.isOSDarwin() &&
- (T.getArch() == Triple::aarch64 || T.getArch() == Triple::aarch64_32))
- SupportsCompactUnwindWithoutEHFrame = true;
+ // Disabled for now, since we need to emit EH Frames for stack unwinding in the JIT
+ // if (T.isOSDarwin() &&
+ // (T.getArch() == Triple::aarch64 || T.getArch() == Triple::aarch64_32))
+ // SupportsCompactUnwindWithoutEHFrame = true;

if (T.isWatchABI())
OmitDwarfIfHaveCompactUnwind = true;
--
2.30.1 (Apple Git-130)

0 comments on commit f7beab5

Please sign in to comment.