LLVM  14.0.0git
RegisterEHFrames.cpp
Go to the documentation of this file.
1 //===--------- RegisterEHFrames.cpp - Register EH frame 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 
10 
11 #include "llvm/Config/config.h"
14 #include "llvm/Support/Compiler.h"
15 #include "llvm/Support/Debug.h"
18 
20 
21 #define DEBUG_TYPE "orc"
22 
23 using namespace llvm;
24 using namespace llvm::orc;
25 using namespace llvm::orc::shared;
26 
27 namespace llvm {
28 namespace orc {
29 
30 #if defined(HAVE_REGISTER_FRAME) && defined(HAVE_DEREGISTER_FRAME) && \
31  !defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
32 
33 extern "C" void __register_frame(const void *);
34 extern "C" void __deregister_frame(const void *);
35 
38  return Error::success();
39 }
40 
43  return Error::success();
44 }
45 
46 #else
47 
48 // The building compiler does not have __(de)register_frame but
49 // it may be found at runtime in a dynamically-loaded library.
50 // For example, this happens when building LLVM with Visual C++
51 // but using the MingW runtime.
52 static Error registerFrameWrapper(const void *P) {
53  static void((*RegisterFrame)(const void *)) = 0;
54 
55  if (!RegisterFrame)
56  *(void **)&RegisterFrame =
58 
59  if (RegisterFrame) {
60  RegisterFrame(P);
61  return Error::success();
62  }
63 
64  return make_error<StringError>("could not register eh-frame: "
65  "__register_frame function not found",
67 }
68 
69 static Error deregisterFrameWrapper(const void *P) {
70  static void((*DeregisterFrame)(const void *)) = 0;
71 
72  if (!DeregisterFrame)
73  *(void **)&DeregisterFrame =
75  "__deregister_frame");
76 
77  if (DeregisterFrame) {
78  DeregisterFrame(P);
79  return Error::success();
80  }
81 
82  return make_error<StringError>("could not deregister eh-frame: "
83  "__deregister_frame function not found",
85 }
86 #endif
87 
88 #if defined(HAVE_UNW_ADD_DYNAMIC_FDE) || defined(__APPLE__)
89 
90 template <typename HandleFDEFn>
91 Error walkLibunwindEHFrameSection(const char *const SectionStart,
92  size_t SectionSize, HandleFDEFn HandleFDE) {
93  const char *CurCFIRecord = SectionStart;
94  const char *End = SectionStart + SectionSize;
95  uint64_t Size = *reinterpret_cast<const uint32_t *>(CurCFIRecord);
96 
97  while (CurCFIRecord != End && Size != 0) {
98  const char *OffsetField = CurCFIRecord + (Size == 0xffffffff ? 12 : 4);
99  if (Size == 0xffffffff)
100  Size = *reinterpret_cast<const uint64_t *>(CurCFIRecord + 4) + 12;
101  else
102  Size += 4;
103  uint32_t Offset = *reinterpret_cast<const uint32_t *>(OffsetField);
104 
105  LLVM_DEBUG({
106  dbgs() << "Registering eh-frame section:\n";
107  dbgs() << "Processing " << (Offset ? "FDE" : "CIE") << " @"
108  << (void *)CurCFIRecord << ": [";
109  for (unsigned I = 0; I < Size; ++I)
110  dbgs() << format(" 0x%02" PRIx8, *(CurCFIRecord + I));
111  dbgs() << " ]\n";
112  });
113 
114  if (Offset != 0)
115  if (auto Err = HandleFDE(CurCFIRecord))
116  return Err;
117 
118  CurCFIRecord += Size;
119 
120  Size = *reinterpret_cast<const uint32_t *>(CurCFIRecord);
121  }
122 
123  return Error::success();
124 }
125 
126 #endif // HAVE_UNW_ADD_DYNAMIC_FDE || __APPLE__
127 
128 Error registerEHFrameSection(const void *EHFrameSectionAddr,
129  size_t EHFrameSectionSize) {
130  /* libgcc and libunwind __register_frame behave differently. We use the
131  * presence of __unw_add_dynamic_fde to detect libunwind. */
132 #if defined(HAVE_UNW_ADD_DYNAMIC_FDE) || defined(__APPLE__)
133  // With libunwind, __register_frame has to be called for each FDE entry.
134  return walkLibunwindEHFrameSection(
135  static_cast<const char *>(EHFrameSectionAddr), EHFrameSectionSize,
137 #else
138  // With libgcc, __register_frame takes a single argument:
139  // a pointer to the start of the .eh_frame section.
140 
141  // How can it find the end? Because crtendS.o is linked
142  // in and it has an .eh_frame section with four zero chars.
143  return registerFrameWrapper(EHFrameSectionAddr);
144 #endif
145 }
146 
147 Error deregisterEHFrameSection(const void *EHFrameSectionAddr,
148  size_t EHFrameSectionSize) {
149 #if defined(HAVE_UNW_ADD_DYNAMIC_FDE) || defined(__APPLE__)
150  return walkLibunwindEHFrameSection(
151  static_cast<const char *>(EHFrameSectionAddr), EHFrameSectionSize,
153 #else
154  return deregisterFrameWrapper(EHFrameSectionAddr);
155 #endif
156 }
157 
158 } // end namespace orc
159 } // end namespace llvm
160 
163  const char *EHFrameSectionAddr, uint64_t Size) {
164  if (auto Err = registerEHFrameSection(EHFrameSectionAddr, Size))
166  .release();
168 }
169 
172  const char *EHFrameSectionAddr, uint64_t Size) {
173  if (auto Err = deregisterEHFrameSection(EHFrameSectionAddr, Size))
175  .release();
177 }
178 
180  return llvm::orc::registerEHFrameSection(Addr.toPtr<const void *>(), Size);
181 }
182 
184  return llvm::orc::deregisterEHFrameSection(Addr.toPtr<const void *>(), Size);
185 }
186 
191  .release();
192 }
193 
198  .release();
199 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::orc::ExecutorAddr
Represents an address in the executor process.
Definition: ExecutorAddress.h:37
BinaryStreamReader.h
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
JITSymbol.h
llvm::orc::shared::CWrapperFunctionResult
Definition: WrapperFunctionUtils.h:33
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::toString
std::string toString(Error E)
Write all error messages (if any) in E to a string.
Definition: Error.h:1030
deregisterEHFrameWrapper
static Error deregisterEHFrameWrapper(ExecutorAddr Addr, uint64_t Size)
Definition: RegisterEHFrames.cpp:183
llvm::orc::shared::WrapperFunction
Definition: WrapperFunctionUtils.h:425
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:331
DynamicLibrary.h
llvm::orc::shared
Definition: ELFNixPlatform.h:243
llvm_orc_registerEHFrameSectionCustomDirectWrapper
llvm::orc::shared::CWrapperFunctionResult llvm_orc_registerEHFrameSectionCustomDirectWrapper(const char *EHFrameSectionAddr, uint64_t Size)
An eh-frame registration utility suitable for use as a support function call.
Definition: RegisterEHFrames.cpp:162
llvm::orc::deregisterEHFrameSection
Error deregisterEHFrameSection(const void *EHFrameSectionAddr, size_t EHFrameSectionSize)
Unregister frames in the given eh-frame section with libunwind.
Definition: RegisterEHFrames.cpp:147
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
handle
then ret i32 result Tail recursion elimination should handle
Definition: README.txt:355
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::orc::__deregister_frame
void __deregister_frame(const void *)
llvm::orc
Definition: CompileOnDemandLayer.h:57
llvm::orc::shared::SPSExecutorAddr
Definition: ExecutorAddress.h:163
RegisterEHFrames.h
llvm::sys::DynamicLibrary::SearchForAddressOfSymbol
static void * SearchForAddressOfSymbol(const char *symbolName)
This function will search through all previously loaded dynamic libraries for the symbol symbolName.
Definition: DynamicLibrary.cpp:177
FormatVariadic.h
uint64_t
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:80
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
I
#define I(x, y, z)
Definition: MD5.cpp:59
registerEHFrameWrapper
static Error registerEHFrameWrapper(ExecutorAddr Addr, uint64_t Size)
Definition: RegisterEHFrames.cpp:179
llvm_orc_registerEHFrameSectionWrapper
orc::shared::CWrapperFunctionResult llvm_orc_registerEHFrameSectionWrapper(const char *Data, uint64_t Size)
Definition: RegisterEHFrames.cpp:188
uint32_t
Compiler.h
llvm::COFF::SectionSize
@ SectionSize
Definition: COFF.h:61
llvm_orc_deregisterEHFrameSectionCustomDirectWrapper
llvm::orc::shared::CWrapperFunctionResult llvm_orc_deregisterEHFrameSectionCustomDirectWrapper(const char *EHFrameSectionAddr, uint64_t Size)
An eh-frame deregistration utility suitable for use as a support function call.
Definition: RegisterEHFrames.cpp:171
llvm::format
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
llvm::inconvertibleErrorCode
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:77
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm_orc_deregisterEHFrameSectionWrapper
orc::shared::CWrapperFunctionResult llvm_orc_deregisterEHFrameSectionWrapper(const char *Data, uint64_t Size)
Definition: RegisterEHFrames.cpp:195
llvm::orc::shared::WrapperFunctionResult::createOutOfBandError
static WrapperFunctionResult createOutOfBandError(const char *Msg)
Create an out-of-band error by copying the given string.
Definition: WrapperFunctionUtils.h:140
llvm::orc::registerEHFrameSection
Error registerEHFrameSection(const void *EHFrameSectionAddr, size_t EHFrameSectionSize)
Register frames in the given eh-frame section with libunwind.
Definition: RegisterEHFrames.cpp:128
llvm::orc::shared::WrapperFunctionResult::release
CWrapperFunctionResult release()
Release ownership of the contained CWrapperFunctionResult.
Definition: WrapperFunctionUtils.h:79
llvm::orc::deregisterFrameWrapper
Error deregisterFrameWrapper(const void *P)
Definition: RegisterEHFrames.cpp:41
llvm::orc::__register_frame
void __register_frame(const void *)
llvm::orc::registerFrameWrapper
Error registerFrameWrapper(const void *P)
Definition: RegisterEHFrames.cpp:36
raw_ostream.h
Debug.h