[llvm-branch-commits] [llvm] 6884fbc - [JITLink] Enable exception handling for ELF.
Lang Hames via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Jan 24 20:35:39 PST 2021
Author: Lang Hames
Date: 2021-01-25T15:31:27+11:00
New Revision: 6884fbc2c4fb46d0528c02d16d510f4f725fac11
URL: https://github.com/llvm/llvm-project/commit/6884fbc2c4fb46d0528c02d16d510f4f725fac11
DIFF: https://github.com/llvm/llvm-project/commit/6884fbc2c4fb46d0528c02d16d510f4f725fac11.diff
LOG: [JITLink] Enable exception handling for ELF.
Adds the EHFrameSplitter and EHFrameEdgeFixer passes to the default JITLink
pass pipeline for ELF/x86-64, and teaches EHFrameEdgeFixer to handle some
new pointer encodings.
Together these changes enable exception handling (at least for the basic
cases that I've tested so far) for ELF/x86-64 objects loaded via JITLink.
Added:
llvm/test/ExecutionEngine/JITLink/X86/ELF_ehframe_basic.s
Modified:
llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp
llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h
llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h
llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp
Removed:
################################################################################
diff --git a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp
index 8b730bc23ce0..3602601287f4 100644
--- a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp
@@ -119,9 +119,10 @@ Error EHFrameSplitter::processBlock(LinkGraph &G, Block &B,
}
EHFrameEdgeFixer::EHFrameEdgeFixer(StringRef EHFrameSectionName,
- Edge::Kind Delta64, Edge::Kind NegDelta32)
- : EHFrameSectionName(EHFrameSectionName), Delta64(Delta64),
- NegDelta32(NegDelta32) {}
+ unsigned PointerSize, Edge::Kind Delta64,
+ Edge::Kind Delta32, Edge::Kind NegDelta32)
+ : EHFrameSectionName(EHFrameSectionName), PointerSize(PointerSize),
+ Delta64(Delta64), Delta32(Delta32), NegDelta32(NegDelta32) {}
Error EHFrameEdgeFixer::operator()(LinkGraph &G) {
auto *EHFrame = G.findSectionByName(EHFrameSectionName);
@@ -134,6 +135,11 @@ Error EHFrameEdgeFixer::operator()(LinkGraph &G) {
return Error::success();
}
+ // Check that we support the graph's pointer size.
+ if (G.getPointerSize() != 4 && G.getPointerSize() != 8)
+ return make_error<JITLinkError>(
+ "EHFrameEdgeFixer only supports 32 and 64 bit targets");
+
LLVM_DEBUG({
dbgs() << "EHFrameEdgeFixer: Processing " << EHFrameSectionName << "...\n";
});
@@ -258,7 +264,6 @@ Error EHFrameEdgeFixer::processBlock(ParseContext &PC, Block &B) {
Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
size_t RecordOffset, size_t RecordLength,
size_t CIEDeltaFieldOffset) {
- using namespace dwarf;
LLVM_DEBUG(dbgs() << " Record is CIE\n");
@@ -329,11 +334,12 @@ Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
uint8_t LSDAPointerEncoding;
if (auto Err = RecordReader.readInteger(LSDAPointerEncoding))
return Err;
- if (LSDAPointerEncoding != (DW_EH_PE_pcrel | DW_EH_PE_absptr))
+ if (!isSupportedPointerEncoding(LSDAPointerEncoding))
return make_error<JITLinkError>(
"Unsupported LSDA pointer encoding " +
formatv("{0:x2}", LSDAPointerEncoding) + " in CIE at " +
formatv("{0:x16}", CIESymbol.getAddress()));
+ CIEInfo.LSDAPointerEncoding = LSDAPointerEncoding;
break;
}
case 'P': {
@@ -341,7 +347,8 @@ Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
if (auto Err = RecordReader.readInteger(PersonalityPointerEncoding))
return Err;
if (PersonalityPointerEncoding !=
- (DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4))
+ (dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
+ dwarf::DW_EH_PE_sdata4))
return make_error<JITLinkError>(
"Unspported personality pointer "
"encoding " +
@@ -356,12 +363,12 @@ Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
uint8_t FDEPointerEncoding;
if (auto Err = RecordReader.readInteger(FDEPointerEncoding))
return Err;
- if (FDEPointerEncoding != (DW_EH_PE_pcrel | DW_EH_PE_absptr))
+ if (!isSupportedPointerEncoding(FDEPointerEncoding))
return make_error<JITLinkError>(
- "Unsupported FDE address pointer "
- "encoding " +
+ "Unsupported FDE pointer encoding " +
formatv("{0:x2}", FDEPointerEncoding) + " in CIE at " +
formatv("{0:x16}", CIESymbol.getAddress()));
+ CIEInfo.FDEPointerEncoding = FDEPointerEncoding;
break;
}
default:
@@ -445,11 +452,13 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
JITTargetAddress PCBeginFieldOffset = RecordReader.getOffset();
auto PCEdgeItr = BlockEdges.find(RecordOffset + PCBeginFieldOffset);
if (PCEdgeItr == BlockEdges.end()) {
- auto PCBeginDelta = readAbsolutePointer(PC.G, RecordReader);
- if (!PCBeginDelta)
- return PCBeginDelta.takeError();
- JITTargetAddress PCBegin =
- RecordAddress + PCBeginFieldOffset + *PCBeginDelta;
+ auto PCBeginPtrInfo =
+ readEncodedPointer(CIEInfo->FDEPointerEncoding,
+ RecordAddress + PCBeginFieldOffset, RecordReader);
+ if (!PCBeginPtrInfo)
+ return PCBeginPtrInfo.takeError();
+ JITTargetAddress PCBegin = PCBeginPtrInfo->first;
+ Edge::Kind PCBeginEdgeKind = PCBeginPtrInfo->second;
LLVM_DEBUG({
dbgs() << " Adding edge at "
<< formatv("{0:x16}", RecordAddress + PCBeginFieldOffset)
@@ -458,7 +467,8 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
auto PCBeginSym = getOrCreateSymbol(PC, PCBegin);
if (!PCBeginSym)
return PCBeginSym.takeError();
- B.addEdge(Delta64, RecordOffset + PCBeginFieldOffset, *PCBeginSym, 0);
+ B.addEdge(PCBeginEdgeKind, RecordOffset + PCBeginFieldOffset, *PCBeginSym,
+ 0);
PCBeginBlock = &PCBeginSym->getBlock();
} else {
auto &EI = PCEdgeItr->second;
@@ -479,38 +489,42 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
" points at external block");
}
PCBeginBlock = &EI.Target->getBlock();
- if (auto Err = RecordReader.skip(PC.G.getPointerSize()))
+ if (auto Err = RecordReader.skip(
+ getPointerEncodingDataSize(CIEInfo->FDEPointerEncoding)))
return Err;
}
// Add a keep-alive edge from the FDE target to the FDE to ensure that the
// FDE is kept alive if its target is.
assert(PCBeginBlock && "PC-begin block not recorded");
+ LLVM_DEBUG({
+ dbgs() << " Adding keep-alive edge from target at "
+ << formatv("{0:x16}", PCBeginBlock->getAddress()) << " to FDE at "
+ << formatv("{0:x16}", RecordAddress) << "\n";
+ });
PCBeginBlock->addEdge(Edge::KeepAlive, 0, FDESymbol, 0);
}
// Skip over the PC range size field.
- if (auto Err = RecordReader.skip(PC.G.getPointerSize()))
+ if (auto Err = RecordReader.skip(
+ getPointerEncodingDataSize(CIEInfo->FDEPointerEncoding)))
return Err;
if (CIEInfo->FDEsHaveLSDAField) {
uint64_t AugmentationDataSize;
if (auto Err = RecordReader.readULEB128(AugmentationDataSize))
return Err;
- if (AugmentationDataSize != PC.G.getPointerSize())
- return make_error<JITLinkError>(
- "Unexpected FDE augmentation data size (expected " +
- Twine(PC.G.getPointerSize()) + ", got " +
- Twine(AugmentationDataSize) + ") for FDE at " +
- formatv("{0:x16}", RecordAddress));
JITTargetAddress LSDAFieldOffset = RecordReader.getOffset();
auto LSDAEdgeItr = BlockEdges.find(RecordOffset + LSDAFieldOffset);
if (LSDAEdgeItr == BlockEdges.end()) {
- auto LSDADelta = readAbsolutePointer(PC.G, RecordReader);
- if (!LSDADelta)
- return LSDADelta.takeError();
- JITTargetAddress LSDA = RecordAddress + LSDAFieldOffset + *LSDADelta;
+ auto LSDAPointerInfo =
+ readEncodedPointer(CIEInfo->LSDAPointerEncoding,
+ RecordAddress + LSDAFieldOffset, RecordReader);
+ if (!LSDAPointerInfo)
+ return LSDAPointerInfo.takeError();
+ JITTargetAddress LSDA = LSDAPointerInfo->first;
+ Edge::Kind LSDAEdgeKind = LSDAPointerInfo->second;
auto LSDASym = getOrCreateSymbol(PC, LSDA);
if (!LSDASym)
return LSDASym.takeError();
@@ -519,7 +533,7 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
<< formatv("{0:x16}", RecordAddress + LSDAFieldOffset)
<< " to LSDA at " << formatv("{0:x16}", LSDA) << "\n";
});
- B.addEdge(Delta64, RecordOffset + LSDAFieldOffset, *LSDASym, 0);
+ B.addEdge(LSDAEdgeKind, RecordOffset + LSDAFieldOffset, *LSDASym, 0);
} else {
LLVM_DEBUG({
auto &EI = LSDAEdgeItr->second;
@@ -530,7 +544,7 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
dbgs() << " + " << formatv("{0:x16}", EI.Addend);
dbgs() << "\n";
});
- if (auto Err = RecordReader.skip(PC.G.getPointerSize()))
+ if (auto Err = RecordReader.skip(AugmentationDataSize))
return Err;
}
} else {
@@ -581,23 +595,110 @@ EHFrameEdgeFixer::parseAugmentationString(BinaryStreamReader &RecordReader) {
return std::move(AugInfo);
}
-Expected<JITTargetAddress>
-EHFrameEdgeFixer::readAbsolutePointer(LinkGraph &G,
- BinaryStreamReader &RecordReader) {
+bool EHFrameEdgeFixer::isSupportedPointerEncoding(uint8_t PointerEncoding) {
+ using namespace dwarf;
+
+ // We only support PC-rel for now.
+ if ((PointerEncoding & 0x70) != DW_EH_PE_pcrel)
+ return false;
+
+ // readEncodedPointer does not handle indirect.
+ if (PointerEncoding & DW_EH_PE_indirect)
+ return false;
+
+ // Supported datatypes.
+ switch (PointerEncoding & 0xf) {
+ case DW_EH_PE_absptr:
+ case DW_EH_PE_udata4:
+ case DW_EH_PE_udata8:
+ case DW_EH_PE_sdata4:
+ case DW_EH_PE_sdata8:
+ return true;
+ }
+
+ return false;
+}
+
+unsigned EHFrameEdgeFixer::getPointerEncodingDataSize(uint8_t PointerEncoding) {
+ using namespace dwarf;
+
+ assert(isSupportedPointerEncoding(PointerEncoding) &&
+ "Unsupported pointer encoding");
+ switch (PointerEncoding & 0xf) {
+ case DW_EH_PE_absptr:
+ return PointerSize;
+ case DW_EH_PE_udata4:
+ case DW_EH_PE_sdata4:
+ return 4;
+ case DW_EH_PE_udata8:
+ case DW_EH_PE_sdata8:
+ return 8;
+ default:
+ llvm_unreachable("Unsupported encoding");
+ }
+}
+
+Expected<std::pair<JITTargetAddress, Edge::Kind>>
+EHFrameEdgeFixer::readEncodedPointer(uint8_t PointerEncoding,
+ JITTargetAddress PointerFieldAddress,
+ BinaryStreamReader &RecordReader) {
static_assert(sizeof(JITTargetAddress) == sizeof(uint64_t),
"Result must be able to hold a uint64_t");
+ assert(isSupportedPointerEncoding(PointerEncoding) &&
+ "Unsupported pointer encoding");
+
+ using namespace dwarf;
+
+ // Isolate data type, remap absptr to udata4 or udata8. This relies on us
+ // having verified that the graph uses 32-bit or 64-bit pointers only at the
+ // start of this pass.
+ uint8_t EffectiveType = PointerEncoding & 0xf;
+ if (EffectiveType == DW_EH_PE_absptr)
+ EffectiveType = (PointerSize == 8) ? DW_EH_PE_udata8 : DW_EH_PE_udata4;
+
JITTargetAddress Addr;
- if (G.getPointerSize() == 8) {
- if (auto Err = RecordReader.readInteger(Addr))
+ Edge::Kind PointerEdgeKind;
+ switch (EffectiveType) {
+ case DW_EH_PE_udata4: {
+ uint32_t Val;
+ if (auto Err = RecordReader.readInteger(Val))
return std::move(Err);
- } else if (G.getPointerSize() == 4) {
- uint32_t Addr32;
- if (auto Err = RecordReader.readInteger(Addr32))
+ Addr = PointerFieldAddress + Val;
+ PointerEdgeKind = Delta32;
+ break;
+ }
+ case DW_EH_PE_udata8: {
+ uint64_t Val;
+ if (auto Err = RecordReader.readInteger(Val))
return std::move(Err);
- Addr = Addr32;
- } else
- llvm_unreachable("Pointer size is not 32-bit or 64-bit");
- return Addr;
+ Addr = PointerFieldAddress + Val;
+ PointerEdgeKind = Delta64;
+ break;
+ }
+ case DW_EH_PE_sdata4: {
+ int32_t Val;
+ if (auto Err = RecordReader.readInteger(Val))
+ return std::move(Err);
+ Addr = PointerFieldAddress + Val;
+ PointerEdgeKind = Delta32;
+ break;
+ }
+ case DW_EH_PE_sdata8: {
+ int64_t Val;
+ if (auto Err = RecordReader.readInteger(Val))
+ return std::move(Err);
+ Addr = PointerFieldAddress + Val;
+ PointerEdgeKind = Delta64;
+ break;
+ }
+ }
+
+ if (PointerEdgeKind == Edge::Invalid)
+ return make_error<JITLinkError>(
+ "Unspported edge kind for encoded pointer at " +
+ formatv("{0:x}", PointerFieldAddress));
+
+ return std::make_pair(Addr, Delta64);
}
Expected<Symbol &> EHFrameEdgeFixer::getOrCreateSymbol(ParseContext &PC,
diff --git a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h
index 83f27a285998..5e68e72ba18d 100644
--- a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h
+++ b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h
@@ -40,7 +40,8 @@ class EHFrameSplitter {
/// edges.
class EHFrameEdgeFixer {
public:
- EHFrameEdgeFixer(StringRef EHFrameSectionName, Edge::Kind Delta64,
+ EHFrameEdgeFixer(StringRef EHFrameSectionName, unsigned PointerSize,
+ Edge::Kind Delta64, Edge::Kind Delta32,
Edge::Kind NegDelta32);
Error operator()(LinkGraph &G);
@@ -57,6 +58,8 @@ class EHFrameEdgeFixer {
CIEInformation(Symbol &CIESymbol) : CIESymbol(&CIESymbol) {}
Symbol *CIESymbol = nullptr;
bool FDEsHaveLSDAField = false;
+ uint8_t FDEPointerEncoding = 0;
+ uint8_t LSDAPointerEncoding = 0;
};
struct EdgeTarget {
@@ -96,12 +99,20 @@ class EHFrameEdgeFixer {
Expected<AugmentationInfo>
parseAugmentationString(BinaryStreamReader &RecordReader);
- Expected<JITTargetAddress>
- readAbsolutePointer(LinkGraph &G, BinaryStreamReader &RecordReader);
+
+ static bool isSupportedPointerEncoding(uint8_t PointerEncoding);
+ unsigned getPointerEncodingDataSize(uint8_t PointerEncoding);
+ Expected<std::pair<JITTargetAddress, Edge::Kind>>
+ readEncodedPointer(uint8_t PointerEncoding,
+ JITTargetAddress PointerFieldAddress,
+ BinaryStreamReader &RecordReader);
+
Expected<Symbol &> getOrCreateSymbol(ParseContext &PC, JITTargetAddress Addr);
StringRef EHFrameSectionName;
+ unsigned PointerSize;
Edge::Kind Delta64;
+ Edge::Kind Delta32;
Edge::Kind NegDelta32;
};
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
index 0ca2130150a6..2a92f28030ce 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
@@ -11,12 +11,14 @@
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/JITLink/ELF_x86_64.h"
-#include "BasicGOTAndStubsBuilder.h"
-#include "JITLinkGeneric.h"
#include "llvm/ExecutionEngine/JITLink/JITLink.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Support/Endian.h"
+#include "BasicGOTAndStubsBuilder.h"
+#include "EHFrameSupportImpl.h"
+#include "JITLinkGeneric.h"
+
#define DEBUG_TYPE "jitlink"
using namespace llvm;
@@ -238,6 +240,8 @@ class ELFLinkGraphBuilder_x86_64 {
switch (Type) {
case ELF::R_X86_64_PC32:
return ELF_x86_64_Edges::ELFX86RelocationKind::PCRel32;
+ case ELF::R_X86_64_PC64:
+ return ELF_x86_64_Edges::ELFX86RelocationKind::Delta64;
case ELF::R_X86_64_64:
return ELF_x86_64_Edges::ELFX86RelocationKind::Pointer64;
case ELF::R_X86_64_GOTPCREL:
@@ -404,9 +408,6 @@ class ELFLinkGraphBuilder_x86_64 {
LLVM_DEBUG({
dbgs() << "Adding relocations from section " << *RelSectName << "\n";
});
- // Deal with .eh_frame later
- if (*RelSectName == StringRef(".rela.eh_frame"))
- continue;
auto UpdateSection = Obj.getSection(SecRef.sh_info);
if (!UpdateSection)
@@ -734,6 +735,11 @@ class ELFJITLinker_x86_64 : public JITLinker<ELFJITLinker_x86_64> {
*(ulittle64_t *)FixupPtr = Value;
break;
}
+ case ELFX86RelocationKind::Delta64: {
+ int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
+ *(little64_t *)FixupPtr = Value;
+ break;
+ }
}
return Error::success();
}
@@ -760,21 +766,28 @@ void link_ELF_x86_64(std::unique_ptr<LinkGraph> G,
std::unique_ptr<JITLinkContext> Ctx) {
PassConfiguration Config;
- // Construct a JITLinker and run the link function.
- // Add a mark-live pass.
- if (auto MarkLive = Ctx->getMarkLivePass(G->getTargetTriple()))
- Config.PrePrunePasses.push_back(std::move(MarkLive));
- else
- Config.PrePrunePasses.push_back(markAllSymbolsLive);
+ if (Ctx->shouldAddDefaultTargetPasses(G->getTargetTriple())) {
- // Add an in-place GOT/Stubs pass.
- Config.PostPrunePasses.push_back([](LinkGraph &G) -> Error {
- ELF_x86_64_GOTAndStubsBuilder(G).run();
- return Error::success();
- });
+ Config.PrePrunePasses.push_back(EHFrameSplitter(".eh_frame"));
+ Config.PrePrunePasses.push_back(EHFrameEdgeFixer(
+ ".eh_frame", G->getPointerSize(), Delta64, Delta32, NegDelta32));
- // Add GOT/Stubs optimizer pass.
- Config.PreFixupPasses.push_back(optimizeELF_x86_64_GOTAndStubs);
+ // Construct a JITLinker and run the link function.
+ // Add a mark-live pass.
+ if (auto MarkLive = Ctx->getMarkLivePass(G->getTargetTriple()))
+ Config.PrePrunePasses.push_back(std::move(MarkLive));
+ else
+ Config.PrePrunePasses.push_back(markAllSymbolsLive);
+
+ // Add an in-place GOT/Stubs pass.
+ Config.PostPrunePasses.push_back([](LinkGraph &G) -> Error {
+ ELF_x86_64_GOTAndStubsBuilder(G).run();
+ return Error::success();
+ });
+
+ // Add GOT/Stubs optimizer pass.
+ Config.PreFixupPasses.push_back(optimizeELF_x86_64_GOTAndStubs);
+ }
if (auto Err = Ctx->modifyPassConfig(G->getTargetTriple(), Config))
return Ctx->notifyFailed(std::move(Err));
diff --git a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h
index 3555d66ace35..26e6859de91d 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h
+++ b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h
@@ -16,10 +16,10 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ExecutionEngine/JITLink/JITLink.h"
+#include "llvm/Object/MachO.h"
#include "EHFrameSupportImpl.h"
#include "JITLinkGeneric.h"
-#include "llvm/Object/MachO.h"
#include <list>
diff --git a/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp
index 24559cc7e772..bde4a19e71ba 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp
@@ -669,8 +669,8 @@ void link_MachO_x86_64(std::unique_ptr<LinkGraph> G,
if (Ctx->shouldAddDefaultTargetPasses(G->getTargetTriple())) {
// Add eh-frame passses.
Config.PrePrunePasses.push_back(EHFrameSplitter("__eh_frame"));
- Config.PrePrunePasses.push_back(
- EHFrameEdgeFixer("__eh_frame", Delta64, NegDelta32));
+ Config.PrePrunePasses.push_back(EHFrameEdgeFixer(
+ "__eh_frame", G->getPointerSize(), Delta64, Delta32, NegDelta32));
// Add a mark-live pass.
if (auto MarkLive = Ctx->getMarkLivePass(G->getTargetTriple()))
diff --git a/llvm/test/ExecutionEngine/JITLink/X86/ELF_ehframe_basic.s b/llvm/test/ExecutionEngine/JITLink/X86/ELF_ehframe_basic.s
new file mode 100644
index 000000000000..fe00d23f6f66
--- /dev/null
+++ b/llvm/test/ExecutionEngine/JITLink/X86/ELF_ehframe_basic.s
@@ -0,0 +1,115 @@
+# REQUIRES: asserts
+# RUN: llvm-mc -triple=x86_64-unknown-linux -position-independent \
+# RUN: -filetype=obj -o %t %s
+# RUN: llvm-jitlink -debug-only=jitlink -define-abs bar=0x01 -noexec %t 2>&1 | \
+# RUN: FileCheck %s
+#
+# Check that a basic .eh-frame section is recognized and parsed. We
+# Expect to see two FDEs with corresponding keep-alive edges.
+#
+# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at
+# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at
+
+ .text
+ .file "exceptions.cpp"
+ .globl foo
+ .p2align 4, 0x90
+ .type foo, at function
+foo:
+ .cfi_startproc
+
+ pushq %rax
+ .cfi_def_cfa_offset 16
+ movl $4, %edi
+ callq __cxa_allocate_exception at PLT
+ movl $1, (%rax)
+ movq _ZTIi at GOTPCREL(%rip), %rsi
+ movq %rax, %rdi
+ xorl %edx, %edx
+ callq __cxa_throw at PLT
+.Lfunc_end0:
+ .size foo, .Lfunc_end0-foo
+ .cfi_endproc
+
+ .globl main
+ .p2align 4, 0x90
+ .type main, at function
+main:
+.Lfunc_begin0:
+ .cfi_startproc
+ .cfi_personality 155, DW.ref.__gxx_personality_v0
+ .cfi_lsda 27, .Lexception0
+
+ pushq %rbx
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbx, -16
+ xorl %ebx, %ebx
+.Ltmp0:
+ callq bar at PLT
+.Ltmp1:
+
+ movl %ebx, %eax
+ popq %rbx
+ .cfi_def_cfa_offset 8
+ retq
+.LBB1_1:
+ .cfi_def_cfa_offset 16
+.Ltmp2:
+ movq %rax, %rdi
+ callq __cxa_begin_catch at PLT
+ callq __cxa_end_catch at PLT
+ movl $1, %ebx
+ movl %ebx, %eax
+ popq %rbx
+ .cfi_def_cfa_offset 8
+ retq
+.Lfunc_end1:
+ .size main, .Lfunc_end1-main
+ .cfi_endproc
+ .section .gcc_except_table,"a", at progbits
+ .p2align 2
+GCC_except_table1:
+.Lexception0:
+ .byte 255
+ .byte 156
+ .uleb128 .Lttbase0-.Lttbaseref0
+.Lttbaseref0:
+ .byte 1
+ .uleb128 .Lcst_end0-.Lcst_begin0
+.Lcst_begin0:
+ .uleb128 .Ltmp0-.Lfunc_begin0
+ .uleb128 .Ltmp1-.Ltmp0
+ .uleb128 .Ltmp2-.Lfunc_begin0
+ .byte 1
+ .uleb128 .Ltmp1-.Lfunc_begin0
+ .uleb128 .Lfunc_end1-.Ltmp1
+ .byte 0
+ .byte 0
+.Lcst_end0:
+ .byte 1
+
+ .byte 0
+ .p2align 2
+
+.Ltmp3:
+ .quad .L_ZTIi.DW.stub-.Ltmp3
+.Lttbase0:
+ .p2align 2
+
+ .data
+ .p2align 3
+.L_ZTIi.DW.stub:
+ .quad _ZTIi
+ .hidden DW.ref.__gxx_personality_v0
+ .weak DW.ref.__gxx_personality_v0
+ .section .data.DW.ref.__gxx_personality_v0,"aGw", at progbits,DW.ref.__gxx_personality_v0,comdat
+ .p2align 3
+ .type DW.ref.__gxx_personality_v0, at object
+ .size DW.ref.__gxx_personality_v0, 8
+DW.ref.__gxx_personality_v0:
+ .quad __gxx_personality_v0
+ .ident "clang version 12.0.0 (git at github.com:llvm/llvm-project.git afd483e57d166418e94a65bd9716e7dc4c114eed)"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .addrsig_sym __gxx_personality_v0
+ .addrsig_sym _ZTIi
More information about the llvm-branch-commits
mailing list