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  jitTargetAddressToPointer<const void *>(Addr), Size);
164 }
165 
168  jitTargetAddressToPointer<const void *>(Addr), Size);
169 }
170 
175  .release();
176 }
177 
182  .release();
183 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
BinaryStreamReader.h
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
JITSymbol.h
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
registerEHFrameWrapper
static Error registerEHFrameWrapper(JITTargetAddress Addr, uint64_t Size)
Definition: RegisterEHFrames.cpp:161
llvm::orc::shared::WrapperFunction
Definition: WrapperFunctionUtils.h:431
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::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_deregisterEHFrameSectionWrapper
orc::shared::detail::CWrapperFunctionResult llvm_orc_deregisterEHFrameSectionWrapper(const char *Data, uint64_t Size)
Definition: RegisterEHFrames.cpp:179
llvm::orc
Definition: CompileOnDemandLayer.h:57
deregisterEHFrameWrapper
static Error deregisterEHFrameWrapper(JITTargetAddress Addr, uint64_t Size)
Definition: RegisterEHFrames.cpp:166
llvm::orc::shared::detail::CWrapperFunctionResult
Definition: WrapperFunctionUtils.h:37
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
I
#define I(x, y, z)
Definition: MD5.cpp:59
uint32_t
Compiler.h
llvm::COFF::SectionSize
@ SectionSize
Definition: COFF.h:61
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::shared::SPSExecutorAddress
SPS tag type for executor addresseses.
Definition: SimplePackedSerialization.h:199
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::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
llvm_orc_registerEHFrameSectionWrapper
orc::shared::detail::CWrapperFunctionResult llvm_orc_registerEHFrameSectionWrapper(const char *Data, uint64_t Size)
Definition: RegisterEHFrames.cpp:172