xref: /freebsd-src/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/EPCEHFrameRegistrar.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
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