summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ExecutionEngine/JITLink/JITLink_EHFrameSupport.cpp
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2019-04-22 03:03:09 +0000
committerLang Hames <lhames@gmail.com>2019-04-22 03:03:09 +0000
commit1233c15be59160eb48bec08327db012bc3f2aedf (patch)
tree285684ee3fa627d211a9be8d2e13cb8ffad67faa /llvm/lib/ExecutionEngine/JITLink/JITLink_EHFrameSupport.cpp
parente1f3191a0d03a60d41feed18fef3c6b888ff0ceb (diff)
downloadbcm5719-llvm-1233c15be59160eb48bec08327db012bc3f2aedf.tar.gz
bcm5719-llvm-1233c15be59160eb48bec08327db012bc3f2aedf.zip
[JITLink] Remove a lot of reduntant 'JITLink_' prefixes. NFC.
llvm-svn: 358869
Diffstat (limited to 'llvm/lib/ExecutionEngine/JITLink/JITLink_EHFrameSupport.cpp')
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/JITLink_EHFrameSupport.cpp533
1 files changed, 0 insertions, 533 deletions
diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLink_EHFrameSupport.cpp b/llvm/lib/ExecutionEngine/JITLink/JITLink_EHFrameSupport.cpp
deleted file mode 100644
index 38c537b5c78..00000000000
--- a/llvm/lib/ExecutionEngine/JITLink/JITLink_EHFrameSupport.cpp
+++ /dev/null
@@ -1,533 +0,0 @@
-//===-------- JITLink_EHFrameSupport.cpp - JITLink eh-frame utils ---------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "JITLink_EHFrameSupportImpl.h"
-
-#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/Support/DynamicLibrary.h"
-
-#define DEBUG_TYPE "jitlink"
-
-namespace llvm {
-namespace jitlink {
-
-EHFrameParser::EHFrameParser(AtomGraph &G, Section &EHFrameSection,
- StringRef EHFrameContent,
- JITTargetAddress EHFrameAddress,
- Edge::Kind FDEToCIERelocKind,
- Edge::Kind FDEToTargetRelocKind)
- : G(G), EHFrameSection(EHFrameSection), EHFrameContent(EHFrameContent),
- EHFrameAddress(EHFrameAddress),
- EHFrameReader(EHFrameContent, G.getEndianness()),
- FDEToCIERelocKind(FDEToCIERelocKind),
- FDEToTargetRelocKind(FDEToTargetRelocKind) {}
-
-Error EHFrameParser::atomize() {
- while (!EHFrameReader.empty()) {
- size_t RecordOffset = EHFrameReader.getOffset();
-
- LLVM_DEBUG({
- dbgs() << "Processing eh-frame record at "
- << format("0x%016" PRIx64, EHFrameAddress + RecordOffset)
- << " (offset " << RecordOffset << ")\n";
- });
-
- size_t CIELength = 0;
- uint32_t CIELengthField;
- if (auto Err = EHFrameReader.readInteger(CIELengthField))
- return Err;
-
- // Process CIE length/extended-length fields to build the atom.
- //
- // The value of these fields describe the length of the *rest* of the CIE
- // (not including data up to the end of the field itself) so we have to
- // bump CIELength to include the data up to the end of the field: 4 bytes
- // for Length, or 12 bytes (4 bytes + 8 bytes) for ExtendedLength.
- if (CIELengthField == 0) // Length 0 means end of __eh_frame section.
- break;
-
- // If the regular length field's value is 0xffffffff, use extended length.
- if (CIELengthField == 0xffffffff) {
- uint64_t CIEExtendedLengthField;
- if (auto Err = EHFrameReader.readInteger(CIEExtendedLengthField))
- return Err;
- if (CIEExtendedLengthField > EHFrameReader.bytesRemaining())
- return make_error<JITLinkError>("CIE record extends past the end of "
- "the __eh_frame section");
- if (CIEExtendedLengthField + 12 > std::numeric_limits<size_t>::max())
- return make_error<JITLinkError>("CIE record too large to process");
- CIELength = CIEExtendedLengthField + 12;
- } else {
- if (CIELengthField > EHFrameReader.bytesRemaining())
- return make_error<JITLinkError>("CIE record extends past the end of "
- "the __eh_frame section");
- CIELength = CIELengthField + 4;
- }
-
- LLVM_DEBUG(dbgs() << " length: " << CIELength << "\n");
-
- // Add an atom for this record.
- CurRecordAtom = &G.addAnonymousAtom(
- EHFrameSection, EHFrameAddress + RecordOffset, G.getPointerSize());
- CurRecordAtom->setContent(EHFrameContent.substr(RecordOffset, CIELength));
-
- // Read the CIE Pointer.
- size_t CIEPointerAddress = EHFrameAddress + EHFrameReader.getOffset();
- uint32_t CIEPointer;
- if (auto Err = EHFrameReader.readInteger(CIEPointer))
- return Err;
-
- // Based on the CIE pointer value, parse this as a CIE or FDE record.
- if (CIEPointer == 0) {
- if (auto Err = processCIE())
- return Err;
- } else {
- if (auto Err = processFDE(CIEPointerAddress, CIEPointer))
- return Err;
- }
-
- EHFrameReader.setOffset(RecordOffset + CIELength);
- }
-
- return Error::success();
-}
-
-Expected<EHFrameParser::AugmentationInfo>
-EHFrameParser::parseAugmentationString() {
- AugmentationInfo AugInfo;
- uint8_t NextChar;
- uint8_t *NextField = &AugInfo.Fields[0];
-
- if (auto Err = EHFrameReader.readInteger(NextChar))
- return std::move(Err);
-
- while (NextChar != 0) {
- switch (NextChar) {
- case 'z':
- AugInfo.AugmentationDataPresent = true;
- break;
- case 'e':
- if (auto Err = EHFrameReader.readInteger(NextChar))
- return std::move(Err);
- if (NextChar != 'h')
- return make_error<JITLinkError>("Unrecognized substring e" +
- Twine(NextChar) +
- " in augmentation string");
- AugInfo.EHDataFieldPresent = true;
- break;
- case 'L':
- case 'P':
- case 'R':
- *NextField++ = NextChar;
- break;
- default:
- return make_error<JITLinkError>("Unrecognized character " +
- Twine(NextChar) +
- " in augmentation string");
- }
-
- if (auto Err = EHFrameReader.readInteger(NextChar))
- return std::move(Err);
- }
-
- return std::move(AugInfo);
-}
-
-Expected<JITTargetAddress> EHFrameParser::readAbsolutePointer() {
- static_assert(sizeof(JITTargetAddress) == sizeof(uint64_t),
- "Result must be able to hold a uint64_t");
- JITTargetAddress Addr;
- if (G.getPointerSize() == 8) {
- if (auto Err = EHFrameReader.readInteger(Addr))
- return std::move(Err);
- } else if (G.getPointerSize() == 4) {
- uint32_t Addr32;
- if (auto Err = EHFrameReader.readInteger(Addr32))
- return std::move(Err);
- Addr = Addr32;
- } else
- llvm_unreachable("Pointer size is not 32-bit or 64-bit");
- return Addr;
-}
-
-Error EHFrameParser::processCIE() {
- // Use the dwarf namespace for convenient access to pointer encoding
- // constants.
- using namespace dwarf;
-
- LLVM_DEBUG(dbgs() << " Record is CIE\n");
-
- /// Reset state for the new CIE.
- LSDAFieldPresent = false;
-
- uint8_t Version = 0;
- if (auto Err = EHFrameReader.readInteger(Version))
- return Err;
-
- if (Version != 0x01)
- return make_error<JITLinkError>("Bad CIE version " + Twine(Version) +
- " (should be 0x01) in eh-frame");
-
- auto AugInfo = parseAugmentationString();
- if (!AugInfo)
- return AugInfo.takeError();
-
- // Skip the EH Data field if present.
- if (AugInfo->EHDataFieldPresent)
- if (auto Err = EHFrameReader.skip(G.getPointerSize()))
- return Err;
-
- // Read and sanity check the code alignment factor.
- {
- uint64_t CodeAlignmentFactor = 0;
- if (auto Err = EHFrameReader.readULEB128(CodeAlignmentFactor))
- return Err;
- if (CodeAlignmentFactor != 1)
- return make_error<JITLinkError>("Unsupported CIE code alignment factor " +
- Twine(CodeAlignmentFactor) +
- " (expected 1)");
- }
-
- // Read and sanity check the data alignment factor.
- {
- int64_t DataAlignmentFactor = 0;
- if (auto Err = EHFrameReader.readSLEB128(DataAlignmentFactor))
- return Err;
- if (DataAlignmentFactor != -8)
- return make_error<JITLinkError>("Unsupported CIE data alignment factor " +
- Twine(DataAlignmentFactor) +
- " (expected -8)");
- }
-
- // Skip the return address register field.
- if (auto Err = EHFrameReader.skip(1))
- return Err;
-
- uint64_t AugmentationDataLength = 0;
- if (auto Err = EHFrameReader.readULEB128(AugmentationDataLength))
- return Err;
-
- uint32_t AugmentationDataStartOffset = EHFrameReader.getOffset();
-
- uint8_t *NextField = &AugInfo->Fields[0];
- while (uint8_t Field = *NextField++) {
- switch (Field) {
- case 'L': {
- LSDAFieldPresent = true;
- uint8_t LSDAPointerEncoding;
- if (auto Err = EHFrameReader.readInteger(LSDAPointerEncoding))
- return Err;
- if (LSDAPointerEncoding != (DW_EH_PE_pcrel | DW_EH_PE_absptr))
- return make_error<JITLinkError>(
- "Unsupported LSDA pointer encoding " +
- formatv("{0:x2}", LSDAPointerEncoding) + " in CIE at " +
- formatv("{0:x16}", CurRecordAtom->getAddress()));
- break;
- }
- case 'P': {
- uint8_t PersonalityPointerEncoding = 0;
- if (auto Err = EHFrameReader.readInteger(PersonalityPointerEncoding))
- return Err;
- if (PersonalityPointerEncoding !=
- (DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4))
- return make_error<JITLinkError>(
- "Unspported personality pointer "
- "encoding " +
- formatv("{0:x2}", PersonalityPointerEncoding) + " in CIE at " +
- formatv("{0:x16}", CurRecordAtom->getAddress()));
- uint32_t PersonalityPointerAddress;
- if (auto Err = EHFrameReader.readInteger(PersonalityPointerAddress))
- return Err;
- break;
- }
- case 'R': {
- uint8_t FDEPointerEncoding;
- if (auto Err = EHFrameReader.readInteger(FDEPointerEncoding))
- return Err;
- if (FDEPointerEncoding != (DW_EH_PE_pcrel | DW_EH_PE_absptr))
- return make_error<JITLinkError>(
- "Unsupported FDE address pointer "
- "encoding " +
- formatv("{0:x2}", FDEPointerEncoding) + " in CIE at " +
- formatv("{0:x16}", CurRecordAtom->getAddress()));
- break;
- }
- default:
- llvm_unreachable("Invalid augmentation string field");
- }
- }
-
- if (EHFrameReader.getOffset() - AugmentationDataStartOffset >
- AugmentationDataLength)
- return make_error<JITLinkError>("Read past the end of the augmentation "
- "data while parsing fields");
-
- return Error::success();
-}
-
-Error EHFrameParser::processFDE(JITTargetAddress CIEPointerAddress,
- uint32_t CIEPointer) {
- LLVM_DEBUG(dbgs() << " Record is FDE\n");
-
- LLVM_DEBUG({
- dbgs() << " CIE pointer: "
- << format("0x%016" PRIx64, CIEPointerAddress - CIEPointer) << "\n";
- });
-
- auto CIEAtom = G.findAtomByAddress(CIEPointerAddress - CIEPointer);
- if (!CIEAtom)
- return CIEAtom.takeError();
-
- // The CIEPointer looks good. Add a relocation.
- CurRecordAtom->addEdge(FDEToCIERelocKind,
- CIEPointerAddress - CurRecordAtom->getAddress(),
- *CIEAtom, 0);
-
- // Read and sanity check the PC-start pointer and size.
- JITTargetAddress PCBeginAddress = EHFrameAddress + EHFrameReader.getOffset();
-
- auto PCBeginDelta = readAbsolutePointer();
- if (!PCBeginDelta)
- return PCBeginDelta.takeError();
-
- JITTargetAddress PCBegin = PCBeginAddress + *PCBeginDelta;
- LLVM_DEBUG({
- dbgs() << " PC begin: " << format("0x%016" PRIx64, PCBegin) << "\n";
- });
-
- auto *TargetAtom = G.getAtomByAddress(PCBegin);
-
- if (!TargetAtom)
- return make_error<JITLinkError>("FDE PC-begin " +
- formatv("{0:x16}", PCBegin) +
- " does not point at atom");
-
- if (TargetAtom->getAddress() != PCBegin)
- return make_error<JITLinkError>(
- "FDE PC-begin " + formatv("{0:x16}", PCBegin) +
- " does not point to start of atom at " +
- formatv("{0:x16}", TargetAtom->getAddress()));
-
- LLVM_DEBUG(dbgs() << " FDE target: " << *TargetAtom << "\n");
-
- // The PC-start pointer and size look good. Add relocations.
- CurRecordAtom->addEdge(FDEToTargetRelocKind,
- PCBeginAddress - CurRecordAtom->getAddress(),
- *TargetAtom, 0);
-
- // Add a keep-alive relocation from the function to the FDE to ensure it is
- // not dead stripped.
- TargetAtom->addEdge(Edge::KeepAlive, 0, *CurRecordAtom, 0);
-
- // Skip over the PC range size field.
- if (auto Err = EHFrameReader.skip(G.getPointerSize()))
- return Err;
-
- if (LSDAFieldPresent) {
- uint64_t AugmentationDataSize;
- if (auto Err = EHFrameReader.readULEB128(AugmentationDataSize))
- return Err;
- if (AugmentationDataSize != G.getPointerSize())
- return make_error<JITLinkError>("Unexpected FDE augmentation data size "
- "(expected " +
- Twine(G.getPointerSize()) + ", got " +
- Twine(AugmentationDataSize) + ")");
- JITTargetAddress LSDAAddress = EHFrameAddress + EHFrameReader.getOffset();
- auto LSDADelta = readAbsolutePointer();
- if (!LSDADelta)
- return LSDADelta.takeError();
-
- JITTargetAddress LSDA = LSDAAddress + *LSDADelta;
-
- auto *LSDAAtom = G.getAtomByAddress(LSDA);
-
- if (!LSDAAtom)
- return make_error<JITLinkError>("FDE LSDA " + formatv("{0:x16}", LSDA) +
- " does not point at atom");
-
- if (LSDAAtom->getAddress() != LSDA)
- return make_error<JITLinkError>(
- "FDE LSDA " + formatv("{0:x16}", LSDA) +
- " does not point to start of atom at " +
- formatv("{0:x16}", LSDAAtom->getAddress()));
-
- LLVM_DEBUG(dbgs() << " FDE LSDA: " << *LSDAAtom << "\n");
-
- // LSDA looks good. Add relocations.
- CurRecordAtom->addEdge(FDEToTargetRelocKind,
- LSDAAddress - CurRecordAtom->getAddress(), *LSDAAtom,
- 0);
- }
-
- return Error::success();
-}
-
-Error addEHFrame(AtomGraph &G, Section &EHFrameSection,
- StringRef EHFrameContent, JITTargetAddress EHFrameAddress,
- Edge::Kind FDEToCIERelocKind,
- Edge::Kind FDEToTargetRelocKind) {
- return EHFrameParser(G, EHFrameSection, EHFrameContent, EHFrameAddress,
- FDEToCIERelocKind, FDEToTargetRelocKind)
- .atomize();
-}
-
-// Determine whether we can register EH tables.
-#if (defined(__GNUC__) && !defined(__ARM_EABI__) && !defined(__ia64__) && \
- !defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__))
-#define HAVE_EHTABLE_SUPPORT 1
-#else
-#define HAVE_EHTABLE_SUPPORT 0
-#endif
-
-#if HAVE_EHTABLE_SUPPORT
-extern "C" void __register_frame(const void *);
-extern "C" void __deregister_frame(const void *);
-
-Error registerFrameWrapper(const void *P) {
- __register_frame(P);
- return Error::success();
-}
-
-Error deregisterFrameWrapper(const void *P) {
- __deregister_frame(P);
- return Error::success();
-}
-
-#else
-
-// The building compiler does not have __(de)register_frame but
-// it may be found at runtime in a dynamically-loaded library.
-// For example, this happens when building LLVM with Visual C++
-// but using the MingW runtime.
-static Error registerFrameWrapper(const void *P) {
- static void((*RegisterFrame)(const void *)) = 0;
-
- if (!RegisterFrame)
- *(void **)&RegisterFrame =
- llvm::sys::DynamicLibrary::SearchForAddressOfSymbol("__register_frame");
-
- if (RegisterFrame) {
- RegisterFrame(P);
- return Error::success();
- }
-
- return make_error<JITLinkError>("could not register eh-frame: "
- "__register_frame function not found");
-}
-
-static Error deregisterFrameWrapper(const void *P) {
- static void((*DeregisterFrame)(const void *)) = 0;
-
- if (!DeregisterFrame)
- *(void **)&DeregisterFrame =
- llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(
- "__deregister_frame");
-
- if (DeregisterFrame) {
- DeregisterFrame(P);
- return Error::success();
- }
-
- return make_error<JITLinkError>("could not deregister eh-frame: "
- "__deregister_frame function not found");
-}
-#endif
-
-#ifdef __APPLE__
-
-template <typename HandleFDEFn>
-Error walkAppleEHFrameSection(const char *const SectionStart,
- HandleFDEFn HandleFDE) {
- const char *CurCFIRecord = SectionStart;
- uint64_t Size = *reinterpret_cast<const uint32_t *>(CurCFIRecord);
-
- while (Size != 0) {
- const char *OffsetField = CurCFIRecord + (Size == 0xffffffff ? 12 : 4);
- if (Size == 0xffffffff)
- Size = *reinterpret_cast<const uint64_t *>(CurCFIRecord + 4) + 12;
- else
- Size += 4;
- uint32_t Offset = *reinterpret_cast<const uint32_t *>(OffsetField);
- if (Offset != 0)
- if (auto Err = HandleFDE(CurCFIRecord))
- return Err;
-
- LLVM_DEBUG({
- dbgs() << "Registering eh-frame section:\n";
- dbgs() << "Processing " << (Offset ? "FDE" : "CIE") << " @"
- << (void *)CurCFIRecord << ": [";
- for (unsigned I = 0; I < Size; ++I)
- dbgs() << format(" 0x%02" PRIx8, *(CurCFIRecord + I));
- dbgs() << " ]\n";
- });
- CurCFIRecord += Size;
-
- Size = *reinterpret_cast<const uint32_t *>(CurCFIRecord);
- }
-
- return Error::success();
-}
-
-#endif // __APPLE__
-
-Error registerEHFrameSection(const void *EHFrameSectionAddr) {
-#ifdef __APPLE__
- // On Darwin __register_frame has to be called for each FDE entry.
- return walkAppleEHFrameSection(static_cast<const char *>(EHFrameSectionAddr),
- registerFrameWrapper);
-#else
- // On Linux __register_frame takes a single argument:
- // a pointer to the start of the .eh_frame section.
-
- // How can it find the end? Because crtendS.o is linked
- // in and it has an .eh_frame section with four zero chars.
- return registerFrameWrapper(EHFrameSectionAddr);
-#endif
-}
-
-Error deregisterEHFrameSection(const void *EHFrameSectionAddr) {
-#ifdef __APPLE__
- return walkAppleEHFrameSection(static_cast<const char *>(EHFrameSectionAddr),
- deregisterFrameWrapper);
-#else
- return deregisterFrameWrapper(EHFrameSectionAddr);
-#endif
-}
-
-AtomGraphPassFunction createEHFrameRecorderPass(const Triple &TT,
- JITTargetAddress &EHFrameAddr) {
- const char *EHFrameSectionName = nullptr;
- if (TT.getObjectFormat() == Triple::MachO)
- EHFrameSectionName = "__eh_frame";
- else
- EHFrameSectionName = ".eh_frame";
-
- auto RecordEHFrame = [EHFrameSectionName,
- &EHFrameAddr](AtomGraph &G) -> Error {
- // Search for a non-empty eh-frame and record the address of the first atom
- // in it.
- JITTargetAddress Addr = 0;
- for (auto &S : G.sections())
- if (S.getName() == EHFrameSectionName && !S.atoms_empty()) {
- Addr = (*S.atoms().begin())->getAddress();
- for (auto *DA : S.atoms())
- if (DA->getAddress() < Addr)
- Addr = DA->getAddress();
- break;
- }
-
- EHFrameAddr = Addr;
- return Error::success();
- };
-
- return RecordEHFrame;
-}
-
-} // end namespace jitlink
-} // end namespace llvm
OpenPOWER on IntegriCloud