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 19*bdd1243dSDimitry Andric Expected<std::unique_ptr<EPCEHFrameRegistrar>> EPCEHFrameRegistrar::Create( 20*bdd1243dSDimitry Andric ExecutionSession &ES, 21*bdd1243dSDimitry Andric std::optional<ExecutorAddr> RegistrationFunctionsDylib) { 22fe6060f1SDimitry Andric // FIXME: Proper mangling here -- we really need to decouple linker mangling 23fe6060f1SDimitry Andric // from DataLayout. 24fe6060f1SDimitry Andric 25fe6060f1SDimitry Andric // Find the addresses of the registration/deregistration functions in the 26fe6060f1SDimitry Andric // executor process. 27fe6060f1SDimitry Andric auto &EPC = ES.getExecutorProcessControl(); 28*bdd1243dSDimitry Andric 29*bdd1243dSDimitry Andric if (!RegistrationFunctionsDylib) { 30*bdd1243dSDimitry Andric if (auto D = EPC.loadDylib(nullptr)) 31*bdd1243dSDimitry Andric RegistrationFunctionsDylib = *D; 32*bdd1243dSDimitry Andric else 33*bdd1243dSDimitry Andric return D.takeError(); 34*bdd1243dSDimitry Andric } 35fe6060f1SDimitry Andric 36fe6060f1SDimitry Andric std::string RegisterWrapperName, DeregisterWrapperName; 37fe6060f1SDimitry Andric if (EPC.getTargetTriple().isOSBinFormatMachO()) { 38fe6060f1SDimitry Andric RegisterWrapperName += '_'; 39fe6060f1SDimitry Andric DeregisterWrapperName += '_'; 40fe6060f1SDimitry Andric } 41fe6060f1SDimitry Andric RegisterWrapperName += "llvm_orc_registerEHFrameSectionWrapper"; 42fe6060f1SDimitry Andric DeregisterWrapperName += "llvm_orc_deregisterEHFrameSectionWrapper"; 43fe6060f1SDimitry Andric 44fe6060f1SDimitry Andric SymbolLookupSet RegistrationSymbols; 45fe6060f1SDimitry Andric RegistrationSymbols.add(EPC.intern(RegisterWrapperName)); 46fe6060f1SDimitry Andric RegistrationSymbols.add(EPC.intern(DeregisterWrapperName)); 47fe6060f1SDimitry Andric 48*bdd1243dSDimitry Andric auto Result = 49*bdd1243dSDimitry Andric EPC.lookupSymbols({{*RegistrationFunctionsDylib, RegistrationSymbols}}); 50fe6060f1SDimitry Andric if (!Result) 51fe6060f1SDimitry Andric return Result.takeError(); 52fe6060f1SDimitry Andric 53fe6060f1SDimitry Andric assert(Result->size() == 1 && "Unexpected number of dylibs in result"); 54fe6060f1SDimitry Andric assert((*Result)[0].size() == 2 && 55fe6060f1SDimitry Andric "Unexpected number of addresses in result"); 56fe6060f1SDimitry Andric 57fe6060f1SDimitry Andric auto RegisterEHFrameWrapperFnAddr = (*Result)[0][0]; 58fe6060f1SDimitry Andric auto DeregisterEHFrameWrapperFnAddr = (*Result)[0][1]; 59fe6060f1SDimitry Andric 60349cc55cSDimitry Andric return std::make_unique<EPCEHFrameRegistrar>( 61349cc55cSDimitry Andric ES, ExecutorAddr(RegisterEHFrameWrapperFnAddr), 62349cc55cSDimitry Andric ExecutorAddr(DeregisterEHFrameWrapperFnAddr)); 63fe6060f1SDimitry Andric } 64fe6060f1SDimitry Andric 6504eeddc0SDimitry Andric Error EPCEHFrameRegistrar::registerEHFrames(ExecutorAddrRange EHFrameSection) { 6604eeddc0SDimitry Andric return ES.callSPSWrapper<void(SPSExecutorAddrRange)>( 6704eeddc0SDimitry Andric RegisterEHFrameWrapperFnAddr, EHFrameSection); 68fe6060f1SDimitry Andric } 69fe6060f1SDimitry Andric 70fe6060f1SDimitry Andric Error EPCEHFrameRegistrar::deregisterEHFrames( 7104eeddc0SDimitry Andric ExecutorAddrRange EHFrameSection) { 7204eeddc0SDimitry Andric return ES.callSPSWrapper<void(SPSExecutorAddrRange)>( 7304eeddc0SDimitry Andric DeregisterEHFrameWrapperFnAddr, EHFrameSection); 74fe6060f1SDimitry Andric } 75fe6060f1SDimitry Andric 76fe6060f1SDimitry Andric } // end namespace orc 77fe6060f1SDimitry Andric } // end namespace llvm 78