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