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>> 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 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 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