1fe6060f1SDimitry Andric //===------ EPCEHFrameRegistrar.cpp - EPC-based eh-frame registration -----===// 2fe6060f1SDimitry Andric // 3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fe6060f1SDimitry Andric // 7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 8fe6060f1SDimitry Andric 9fe6060f1SDimitry Andric #include "llvm/ExecutionEngine/Orc/EPCEHFrameRegistrar.h" 10fe6060f1SDimitry Andric 11fe6060f1SDimitry Andric #include "llvm/ExecutionEngine/Orc/Core.h" 12fe6060f1SDimitry Andric #include "llvm/Support/BinaryStreamWriter.h" 13fe6060f1SDimitry Andric 14fe6060f1SDimitry Andric using namespace llvm::orc::shared; 15fe6060f1SDimitry Andric 16fe6060f1SDimitry Andric namespace llvm { 17fe6060f1SDimitry Andric namespace orc { 18fe6060f1SDimitry Andric 19fe6060f1SDimitry Andric Expected<std::unique_ptr<EPCEHFrameRegistrar>> 20fe6060f1SDimitry Andric EPCEHFrameRegistrar::Create(ExecutionSession &ES) { 21fe6060f1SDimitry Andric // FIXME: Proper mangling here -- we really need to decouple linker mangling 22fe6060f1SDimitry Andric // from DataLayout. 23fe6060f1SDimitry Andric 24fe6060f1SDimitry Andric // Find the addresses of the registration/deregistration functions in the 25fe6060f1SDimitry Andric // executor process. 26fe6060f1SDimitry Andric auto &EPC = ES.getExecutorProcessControl(); 27fe6060f1SDimitry Andric auto ProcessHandle = EPC.loadDylib(nullptr); 28fe6060f1SDimitry Andric if (!ProcessHandle) 29fe6060f1SDimitry Andric return ProcessHandle.takeError(); 30fe6060f1SDimitry Andric 31fe6060f1SDimitry Andric std::string RegisterWrapperName, DeregisterWrapperName; 32fe6060f1SDimitry Andric if (EPC.getTargetTriple().isOSBinFormatMachO()) { 33fe6060f1SDimitry Andric RegisterWrapperName += '_'; 34fe6060f1SDimitry Andric DeregisterWrapperName += '_'; 35fe6060f1SDimitry Andric } 36fe6060f1SDimitry Andric RegisterWrapperName += "llvm_orc_registerEHFrameSectionWrapper"; 37fe6060f1SDimitry Andric DeregisterWrapperName += "llvm_orc_deregisterEHFrameSectionWrapper"; 38fe6060f1SDimitry Andric 39fe6060f1SDimitry Andric SymbolLookupSet RegistrationSymbols; 40fe6060f1SDimitry Andric RegistrationSymbols.add(EPC.intern(RegisterWrapperName)); 41fe6060f1SDimitry Andric RegistrationSymbols.add(EPC.intern(DeregisterWrapperName)); 42fe6060f1SDimitry Andric 43fe6060f1SDimitry Andric auto Result = EPC.lookupSymbols({{*ProcessHandle, RegistrationSymbols}}); 44fe6060f1SDimitry Andric if (!Result) 45fe6060f1SDimitry Andric return Result.takeError(); 46fe6060f1SDimitry Andric 47fe6060f1SDimitry Andric assert(Result->size() == 1 && "Unexpected number of dylibs in result"); 48fe6060f1SDimitry Andric assert((*Result)[0].size() == 2 && 49fe6060f1SDimitry Andric "Unexpected number of addresses in result"); 50fe6060f1SDimitry Andric 51fe6060f1SDimitry Andric auto RegisterEHFrameWrapperFnAddr = (*Result)[0][0]; 52fe6060f1SDimitry Andric auto DeregisterEHFrameWrapperFnAddr = (*Result)[0][1]; 53fe6060f1SDimitry Andric 54*349cc55cSDimitry Andric return std::make_unique<EPCEHFrameRegistrar>( 55*349cc55cSDimitry Andric ES, ExecutorAddr(RegisterEHFrameWrapperFnAddr), 56*349cc55cSDimitry Andric ExecutorAddr(DeregisterEHFrameWrapperFnAddr)); 57fe6060f1SDimitry Andric } 58fe6060f1SDimitry Andric 59fe6060f1SDimitry Andric Error EPCEHFrameRegistrar::registerEHFrames(JITTargetAddress EHFrameSectionAddr, 60fe6060f1SDimitry Andric size_t EHFrameSectionSize) { 61*349cc55cSDimitry Andric return ES.callSPSWrapper<void(SPSExecutorAddr, uint64_t)>( 62*349cc55cSDimitry Andric RegisterEHFrameWrapperFnAddr, ExecutorAddr(EHFrameSectionAddr), 63fe6060f1SDimitry Andric static_cast<uint64_t>(EHFrameSectionSize)); 64fe6060f1SDimitry Andric } 65fe6060f1SDimitry Andric 66fe6060f1SDimitry Andric Error EPCEHFrameRegistrar::deregisterEHFrames( 67fe6060f1SDimitry Andric JITTargetAddress EHFrameSectionAddr, size_t EHFrameSectionSize) { 68*349cc55cSDimitry Andric return ES.callSPSWrapper<void(SPSExecutorAddr, uint64_t)>( 69*349cc55cSDimitry Andric DeregisterEHFrameWrapperFnAddr, ExecutorAddr(EHFrameSectionAddr), 70fe6060f1SDimitry Andric static_cast<uint64_t>(EHFrameSectionSize)); 71fe6060f1SDimitry Andric } 72fe6060f1SDimitry Andric 73fe6060f1SDimitry Andric } // end namespace orc 74fe6060f1SDimitry Andric } // end namespace llvm 75