mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[JITLink] Re-apply 6884fbc2c4f (ELF eh support) with fix for broken test case.
This commit is contained in:
parent
0571d7eb26
commit
907267f02a
@ -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,
|
||||
|
@ -40,7 +40,8 @@ private:
|
||||
/// 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 @@ private:
|
||||
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 @@ private:
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -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 @@ private:
|
||||
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 @@ private:
|
||||
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 @@ private:
|
||||
*(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));
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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()))
|
||||
|
115
test/ExecutionEngine/JITLink/X86/ELF_ehframe_basic.s
Normal file
115
test/ExecutionEngine/JITLink/X86/ELF_ehframe_basic.s
Normal file
@ -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 \
|
||||
# RUN: -define-abs _ZTIi=0x02 -noexec %t 2>&1 | 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,@function
|
||||
foo:
|
||||
.cfi_startproc
|
||||
|
||||
pushq %rax
|
||||
.cfi_def_cfa_offset 16
|
||||
movl $4, %edi
|
||||
callq __cxa_allocate_exception@PLT
|
||||
movl $1, (%rax)
|
||||
movq _ZTIi@GOTPCREL(%rip), %rsi
|
||||
movq %rax, %rdi
|
||||
xorl %edx, %edx
|
||||
callq __cxa_throw@PLT
|
||||
.Lfunc_end0:
|
||||
.size foo, .Lfunc_end0-foo
|
||||
.cfi_endproc
|
||||
|
||||
.globl main
|
||||
.p2align 4, 0x90
|
||||
.type main,@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@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@PLT
|
||||
callq __cxa_end_catch@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",@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",@progbits,DW.ref.__gxx_personality_v0,comdat
|
||||
.p2align 3
|
||||
.type DW.ref.__gxx_personality_v0,@object
|
||||
.size DW.ref.__gxx_personality_v0, 8
|
||||
DW.ref.__gxx_personality_v0:
|
||||
.quad __gxx_personality_v0
|
||||
.ident "clang version 12.0.0 (git@github.com:llvm/llvm-project.git afd483e57d166418e94a65bd9716e7dc4c114eed)"
|
||||
.section ".note.GNU-stack","",@progbits
|
||||
.addrsig
|
||||
.addrsig_sym __gxx_personality_v0
|
||||
.addrsig_sym _ZTIi
|
Loading…
Reference in New Issue
Block a user