1 //===------ EPCEHFrameRegistrar.cpp - EPC-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/EPCEHFrameRegistrar.h"
10 #include "llvm/Support/BinaryStreamWriter.h"
11 
12 using namespace llvm::orc::shared;
13 
14 namespace llvm {
15 namespace orc {
16 
17 Expected<std::unique_ptr<EPCEHFrameRegistrar>>
18 EPCEHFrameRegistrar::Create(ExecutorProcessControl &EPC) {
19   // FIXME: Proper mangling here -- we really need to decouple linker mangling
20   // from DataLayout.
21 
22   // Find the addresses of the registration/deregistration functions in the
23   // executor process.
24   auto ProcessHandle = EPC.loadDylib(nullptr);
25   if (!ProcessHandle)
26     return ProcessHandle.takeError();
27 
28   std::string RegisterWrapperName, DeregisterWrapperName;
29   if (EPC.getTargetTriple().isOSBinFormatMachO()) {
30     RegisterWrapperName += '_';
31     DeregisterWrapperName += '_';
32   }
33   RegisterWrapperName += "llvm_orc_registerEHFrameSectionWrapper";
34   DeregisterWrapperName += "llvm_orc_deregisterEHFrameSectionWrapper";
35 
36   SymbolLookupSet RegistrationSymbols;
37   RegistrationSymbols.add(EPC.intern(RegisterWrapperName));
38   RegistrationSymbols.add(EPC.intern(DeregisterWrapperName));
39 
40   auto Result = EPC.lookupSymbols({{*ProcessHandle, RegistrationSymbols}});
41   if (!Result)
42     return Result.takeError();
43 
44   assert(Result->size() == 1 && "Unexpected number of dylibs in result");
45   assert((*Result)[0].size() == 2 &&
46          "Unexpected number of addresses in result");
47 
48   auto RegisterEHFrameWrapperFnAddr = (*Result)[0][0];
49   auto DeregisterEHFrameWrapperFnAddr = (*Result)[0][1];
50 
51   return std::make_unique<EPCEHFrameRegistrar>(
52       EPC, RegisterEHFrameWrapperFnAddr, DeregisterEHFrameWrapperFnAddr);
53 }
54 
55 Error EPCEHFrameRegistrar::registerEHFrames(JITTargetAddress EHFrameSectionAddr,
56                                             size_t EHFrameSectionSize) {
57 
58   return WrapperFunction<void(SPSExecutorAddress, uint64_t)>::call(
59       EPCCaller(EPC, RegisterEHFrameWrapperFnAddr), EHFrameSectionAddr,
60       static_cast<uint64_t>(EHFrameSectionSize));
61 }
62 
63 Error EPCEHFrameRegistrar::deregisterEHFrames(
64     JITTargetAddress EHFrameSectionAddr, size_t EHFrameSectionSize) {
65   return WrapperFunction<void(SPSExecutorAddress, uint64_t)>::call(
66       EPCCaller(EPC, DeregisterEHFrameWrapperFnAddr), EHFrameSectionAddr,
67       static_cast<uint64_t>(EHFrameSectionSize));
68 }
69 
70 } // end namespace orc
71 } // end namespace llvm
72