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