• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===------ TPCEHFrameRegistrar.cpp - TPC-based eh-frame registration -----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/ExecutionEngine/Orc/TPCEHFrameRegistrar.h"
10 #include "llvm/Support/BinaryStreamWriter.h"
11 
12 namespace llvm {
13 namespace orc {
14 
15 Expected<std::unique_ptr<TPCEHFrameRegistrar>>
Create(TargetProcessControl & TPC)16 TPCEHFrameRegistrar::Create(TargetProcessControl &TPC) {
17   // FIXME: Proper mangling here -- we really need to decouple linker mangling
18   // from DataLayout.
19 
20   // Find the addresses of the registration/deregistration functions in the
21   // target process.
22   auto ProcessHandle = TPC.loadDylib(nullptr);
23   if (!ProcessHandle)
24     return ProcessHandle.takeError();
25 
26   std::string RegisterWrapperName, DeregisterWrapperName;
27   if (TPC.getTargetTriple().isOSBinFormatMachO()) {
28     RegisterWrapperName += '_';
29     DeregisterWrapperName += '_';
30   }
31   RegisterWrapperName += "llvm_orc_registerEHFrameSectionWrapper";
32   DeregisterWrapperName += "llvm_orc_deregisterEHFrameSectionWrapper";
33 
34   SymbolLookupSet RegistrationSymbols;
35   RegistrationSymbols.add(TPC.intern(RegisterWrapperName));
36   RegistrationSymbols.add(TPC.intern(DeregisterWrapperName));
37 
38   auto Result = TPC.lookupSymbols({{*ProcessHandle, RegistrationSymbols}});
39   if (!Result)
40     return Result.takeError();
41 
42   assert(Result->size() == 1 && "Unexpected number of dylibs in result");
43   assert((*Result)[0].size() == 2 &&
44          "Unexpected number of addresses in result");
45 
46   auto RegisterEHFrameWrapperFnAddr = (*Result)[0][0];
47   auto DeregisterEHFrameWrapperFnAddr = (*Result)[0][1];
48 
49   return std::make_unique<TPCEHFrameRegistrar>(
50       TPC, RegisterEHFrameWrapperFnAddr, DeregisterEHFrameWrapperFnAddr);
51 }
52 
registerEHFrames(JITTargetAddress EHFrameSectionAddr,size_t EHFrameSectionSize)53 Error TPCEHFrameRegistrar::registerEHFrames(JITTargetAddress EHFrameSectionAddr,
54                                             size_t EHFrameSectionSize) {
55   constexpr size_t ArgBufferSize = sizeof(uint64_t) + sizeof(uint64_t);
56   uint8_t ArgBuffer[ArgBufferSize];
57   BinaryStreamWriter ArgWriter(
58       MutableArrayRef<uint8_t>(ArgBuffer, ArgBufferSize),
59       support::endianness::big);
60   cantFail(ArgWriter.writeInteger(static_cast<uint64_t>(EHFrameSectionAddr)));
61   cantFail(ArgWriter.writeInteger(static_cast<uint64_t>(EHFrameSectionSize)));
62 
63   return TPC.runWrapper(RegisterEHFrameWrapperFnAddr, ArgBuffer).takeError();
64 }
65 
deregisterEHFrames(JITTargetAddress EHFrameSectionAddr,size_t EHFrameSectionSize)66 Error TPCEHFrameRegistrar::deregisterEHFrames(
67     JITTargetAddress EHFrameSectionAddr, size_t EHFrameSectionSize) {
68   constexpr size_t ArgBufferSize = sizeof(uint64_t) + sizeof(uint64_t);
69   uint8_t ArgBuffer[ArgBufferSize];
70   BinaryStreamWriter ArgWriter(
71       MutableArrayRef<uint8_t>(ArgBuffer, ArgBufferSize),
72       support::endianness::big);
73   cantFail(ArgWriter.writeInteger(static_cast<uint64_t>(EHFrameSectionAddr)));
74   cantFail(ArgWriter.writeInteger(static_cast<uint64_t>(EHFrameSectionSize)));
75 
76   return TPC.runWrapper(DeregisterEHFrameWrapperFnAddr, ArgBuffer).takeError();
77 }
78 
79 } // end namespace orc
80 } // end namespace llvm
81