LLVM 24.0.0git
UnwindInfoManager.cpp
Go to the documentation of this file.
1//===------- UnwindInfoManager.cpp - Register unwind info sections --------===//
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
15
16#ifdef __APPLE__
17#include <dlfcn.h>
18#endif // __APPLE__
19
20#define DEBUG_TYPE "orc"
21
22using namespace llvm;
23using namespace llvm::orc;
24using namespace llvm::orc::shared;
25
28 size_t ArgSize) {
31
33 ArgData, ArgSize,
34 [](std::vector<ExecutorAddrRange> CodeRanges, ExecutorAddr DSOBase,
35 ExecutorAddrRange DWARFRange,
36 ExecutorAddrRange CompactUnwindRange) {
38 CodeRanges, DSOBase, DWARFRange, CompactUnwindRange);
39 })
40 .release();
41}
42
45 size_t ArgSize) {
46 using SPSSig = SPSError(SPSSequence<SPSExecutorAddrRange>);
47
49 ArgData, ArgSize,
50 [](std::vector<ExecutorAddrRange> CodeRanges) {
52 })
53 .release();
54}
55
56namespace llvm::orc {
57
58[[maybe_unused]] static const char *AddFnName =
59 "__unw_add_find_dynamic_unwind_sections";
60[[maybe_unused]] static const char *RemoveFnName =
61 "__unw_remove_find_dynamic_unwind_sections";
62static std::unique_ptr<UnwindInfoManager> Instance;
63static int (*RemoveFindDynamicUnwindSections)(void *) = nullptr;
64
66 if (int Err = RemoveFindDynamicUnwindSections((void *)&findSections)) {
67 (void)Err; // Silence unused variable warning in release builds.
69 dbgs() << "Failed call to " << RemoveFnName << ": error = " << Err
70 << "\n";
71 });
72 (void)Err;
73 }
74}
75
77#ifdef __APPLE__
78 static std::mutex M;
79 std::lock_guard<std::mutex> Lock(M);
80
81 if (Instance)
82 return true;
83
84 auto AddFn = (int (*)(void *))dlsym(RTLD_DEFAULT, AddFnName);
85 if (!AddFn)
86 return false;
87
88 auto RemoveFn = (int (*)(void *))dlsym(RTLD_DEFAULT, RemoveFnName);
89 if (!RemoveFn)
90 return false;
91
92 Instance.reset(new UnwindInfoManager());
93
94 if (auto Err = AddFn((void *)&findSections)) {
95 (void)Err; // Silence unused variable warning in release builds.
97 dbgs() << "Failed call to " << AddFnName << ": error = " << Err << "\n";
98 });
99 Instance = nullptr;
100 return false;
101 }
102
104 return true;
105
106#else
107 return false;
108#endif // __APPLE__
109}
110
113 // Provide the symbols for the StandaloneMachOUnwindInfoRegistrar SPS
114 // interface in the ORC runtime.
116 M[Mangle.mangledCopy(SNs.RegisterSectionsName)] =
118 M[Mangle.mangledCopy(SNs.DeregisterSectionsName)] =
120}
121
124 orc::ExecutorAddrRange DWARFEHFrame, orc::ExecutorAddrRange CompactUnwind) {
125 return Instance->registerSectionsImpl(CodeRanges, DSOBase, DWARFEHFrame,
126 CompactUnwind);
127}
128
131 return Instance->deregisterSectionsImpl(CodeRanges);
132}
133
134int UnwindInfoManager::findSectionsImpl(uintptr_t Addr, UnwindSections *Info) {
135 std::lock_guard<std::mutex> Lock(M);
136 auto I = UWSecs.upper_bound(Addr);
137 if (I == UWSecs.begin())
138 return 0;
139 --I;
140 *Info = I->second;
141 return 1;
142}
143
144int UnwindInfoManager::findSections(uintptr_t Addr, UnwindSections *Info) {
145 return Instance->findSectionsImpl(Addr, Info);
146}
147
148Error UnwindInfoManager::registerSectionsImpl(
149 ArrayRef<ExecutorAddrRange> CodeRanges, ExecutorAddr DSOBase,
150 ExecutorAddrRange DWARFEHFrame, ExecutorAddrRange CompactUnwind) {
151 std::lock_guard<std::mutex> Lock(M);
152 for (auto &R : CodeRanges)
153 UWSecs[R.Start.getValue()] =
154 UnwindSections{static_cast<uintptr_t>(DSOBase.getValue()),
155 static_cast<uintptr_t>(DWARFEHFrame.Start.getValue()),
156 static_cast<size_t>(DWARFEHFrame.size()),
157 static_cast<uintptr_t>(CompactUnwind.Start.getValue()),
158 static_cast<size_t>(CompactUnwind.size())};
159 return Error::success();
160}
161
162Error UnwindInfoManager::deregisterSectionsImpl(
163 ArrayRef<ExecutorAddrRange> CodeRanges) {
164 std::lock_guard<std::mutex> Lock(M);
165 for (auto &R : CodeRanges) {
166 auto I = UWSecs.find(R.Start.getValue());
167 if (I == UWSecs.end())
169 "No unwind-info sections registered for range " +
170 formatv("{0:x} - {1:x}", R.Start, R.End),
172 UWSecs.erase(I);
173 }
174 return Error::success();
175}
176
177} // namespace llvm::orc
#define I(x, y, z)
Definition MD5.cpp:57
#define LLVM_DEBUG(...)
Definition Debug.h:119
static orc::shared::CWrapperFunctionBuffer llvm_orc_rt_alt_UnwindInfoManager_deregister(const char *ArgData, size_t ArgSize)
static orc::shared::CWrapperFunctionBuffer llvm_orc_rt_alt_UnwindInfoManager_register(const char *ArgData, size_t ArgSize)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:129
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
Represents an address in the executor process.
uint64_t getValue() const
static ExecutorAddr fromPtr(T *Ptr, UnwrapFn &&Unwrap=UnwrapFn())
Create an ExecutorAddr from the given pointer.
Applies linker name-mangling for a target.
Definition Mangler.h:31
static LLVM_ABI bool TryEnable()
If the libunwind find-dynamic-unwind-info callback registration APIs are available then this method w...
UnwindInfoManager(UnwindInfoManager &&)=delete
static LLVM_ABI void addBootstrapSymbols(StringMap< ExecutorAddr > &M)
static LLVM_ABI Error deregisterSections(ArrayRef< orc::ExecutorAddrRange > CodeRanges)
static LLVM_ABI Error registerSections(ArrayRef< orc::ExecutorAddrRange > CodeRanges, orc::ExecutorAddr DSOBase, orc::ExecutorAddrRange DWARFEHFrame, orc::ExecutorAddrRange CompactUnwind)
const LLVM_ABI MachOUnwindInfoRegistrarSymbolNames orc_rt_MachOUnwindInfoRegistrarSPSSymbols
Default symbol names for the ORC runtime's StandaloneMachOUnwindInfoRegistrar SPS interface.
SPSTuple< SPSExecutorAddr, SPSExecutorAddr > SPSExecutorAddrRange
static std::unique_ptr< UnwindInfoManager > Instance
static const char * RemoveFnName
static int(* RemoveFindDynamicUnwindSections)(void *)
static const char * AddFnName
LLVM_ABI std::string getProcessTriple()
getProcessTriple() - Return an appropriate target triple for generating code to be loaded into the cu...
Definition Host.cpp:2674
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition Error.cpp:94
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
ArrayRef(const T &OneElt) -> ArrayRef< T >
Represents an address range in the exceutor process.
ExecutorAddrDiff size() const