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