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