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