brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.6 KiB · 3a9aa54 Raw
171 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/ExecutionEngine/Orc/TargetProcess/UnwindInfoManager.h"10#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"11#include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"12 13#ifdef __APPLE__14#include <dlfcn.h>15#endif // __APPLE__16 17#define DEBUG_TYPE "orc"18 19using namespace llvm;20using namespace llvm::orc;21using namespace llvm::orc::shared;22 23static orc::shared::CWrapperFunctionResult24llvm_orc_rt_alt_UnwindInfoManager_register(const char *ArgData,25                                           size_t ArgSize) {26  using SPSSig = SPSError(SPSSequence<SPSExecutorAddrRange>, SPSExecutorAddr,27                          SPSExecutorAddrRange, SPSExecutorAddrRange);28 29  return WrapperFunction<SPSSig>::handle(30             ArgData, ArgSize,31             [](std::vector<ExecutorAddrRange> CodeRanges, ExecutorAddr DSOBase,32                ExecutorAddrRange DWARFRange,33                ExecutorAddrRange CompactUnwindRange) {34               return UnwindInfoManager::registerSections(35                   CodeRanges, DSOBase, DWARFRange, CompactUnwindRange);36             })37      .release();38}39 40static orc::shared::CWrapperFunctionResult41llvm_orc_rt_alt_UnwindInfoManager_deregister(const char *ArgData,42                                             size_t ArgSize) {43  using SPSSig = SPSError(SPSSequence<SPSExecutorAddrRange>);44 45  return WrapperFunction<SPSSig>::handle(46             ArgData, ArgSize,47             [](std::vector<ExecutorAddrRange> CodeRanges) {48               return UnwindInfoManager::deregisterSections(CodeRanges);49             })50      .release();51}52 53namespace llvm::orc {54 55[[maybe_unused]] static const char *AddFnName =56    "__unw_add_find_dynamic_unwind_sections";57[[maybe_unused]] static const char *RemoveFnName =58    "__unw_remove_find_dynamic_unwind_sections";59static std::unique_ptr<UnwindInfoManager> Instance;60static int (*RemoveFindDynamicUnwindSections)(void *) = nullptr;61 62UnwindInfoManager::~UnwindInfoManager() {63  if (int Err = RemoveFindDynamicUnwindSections((void *)&findSections)) {64    (void)Err; // Silence unused variable warning in release builds.65    LLVM_DEBUG({66      dbgs() << "Failed call to " << RemoveFnName << ": error = " << Err67             << "\n";68    });69    (void)Err;70  }71}72 73bool UnwindInfoManager::TryEnable() {74#ifdef __APPLE__75  static std::mutex M;76  std::lock_guard<std::mutex> Lock(M);77 78  if (Instance)79    return true;80 81  auto AddFn = (int (*)(void *))dlsym(RTLD_DEFAULT, AddFnName);82  if (!AddFn)83    return false;84 85  auto RemoveFn = (int (*)(void *))dlsym(RTLD_DEFAULT, RemoveFnName);86  if (!RemoveFn)87    return false;88 89  Instance.reset(new UnwindInfoManager());90 91  if (auto Err = AddFn((void *)&findSections)) {92    (void)Err; // Silence unused variable warning in release builds.93    LLVM_DEBUG({94      dbgs() << "Failed call to " << AddFnName << ": error = " << Err << "\n";95    });96    Instance = nullptr;97    return false;98  }99 100  RemoveFindDynamicUnwindSections = RemoveFn;101  return true;102 103#else104  return false;105#endif // __APPLE__106}107 108void UnwindInfoManager::addBootstrapSymbols(StringMap<ExecutorAddr> &M) {109  M[rt_alt::UnwindInfoManagerRegisterActionName] =110      ExecutorAddr::fromPtr(llvm_orc_rt_alt_UnwindInfoManager_register);111  M[rt_alt::UnwindInfoManagerDeregisterActionName] =112      ExecutorAddr::fromPtr(llvm_orc_rt_alt_UnwindInfoManager_deregister);113}114 115Error UnwindInfoManager::registerSections(116    ArrayRef<orc::ExecutorAddrRange> CodeRanges, orc::ExecutorAddr DSOBase,117    orc::ExecutorAddrRange DWARFEHFrame, orc::ExecutorAddrRange CompactUnwind) {118  return Instance->registerSectionsImpl(CodeRanges, DSOBase, DWARFEHFrame,119                                        CompactUnwind);120}121 122Error UnwindInfoManager::deregisterSections(123    ArrayRef<orc::ExecutorAddrRange> CodeRanges) {124  return Instance->deregisterSectionsImpl(CodeRanges);125}126 127int UnwindInfoManager::findSectionsImpl(uintptr_t Addr, UnwindSections *Info) {128  std::lock_guard<std::mutex> Lock(M);129  auto I = UWSecs.upper_bound(Addr);130  if (I == UWSecs.begin())131    return 0;132  --I;133  *Info = I->second;134  return 1;135}136 137int UnwindInfoManager::findSections(uintptr_t Addr, UnwindSections *Info) {138  return Instance->findSectionsImpl(Addr, Info);139}140 141Error UnwindInfoManager::registerSectionsImpl(142    ArrayRef<ExecutorAddrRange> CodeRanges, ExecutorAddr DSOBase,143    ExecutorAddrRange DWARFEHFrame, ExecutorAddrRange CompactUnwind) {144  std::lock_guard<std::mutex> Lock(M);145  for (auto &R : CodeRanges)146    UWSecs[R.Start.getValue()] =147        UnwindSections{static_cast<uintptr_t>(DSOBase.getValue()),148                       static_cast<uintptr_t>(DWARFEHFrame.Start.getValue()),149                       static_cast<size_t>(DWARFEHFrame.size()),150                       static_cast<uintptr_t>(CompactUnwind.Start.getValue()),151                       static_cast<size_t>(CompactUnwind.size())};152  return Error::success();153}154 155Error UnwindInfoManager::deregisterSectionsImpl(156    ArrayRef<ExecutorAddrRange> CodeRanges) {157  std::lock_guard<std::mutex> Lock(M);158  for (auto &R : CodeRanges) {159    auto I = UWSecs.find(R.Start.getValue());160    if (I == UWSecs.end())161      return make_error<StringError>(162          "No unwind-info sections registered for range " +163              formatv("{0:x} - {1:x}", R.Start, R.End),164          inconvertibleErrorCode());165    UWSecs.erase(I);166  }167  return Error::success();168}169 170} // namespace llvm::orc171