brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.3 KiB · 178c7ee Raw
123 lines · cpp
1//===----- UnwindInfoRegistrationPlugin.cpp - libunwind registration ------===//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/UnwindInfoRegistrationPlugin.h"10 11#include "llvm/ExecutionEngine/Orc/Shared/MachOObjectFormat.h"12#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"13#include "llvm/IR/Module.h"14 15#define DEBUG_TYPE "orc"16 17using namespace llvm::jitlink;18 19namespace llvm::orc {20 21Expected<std::shared_ptr<UnwindInfoRegistrationPlugin>>22UnwindInfoRegistrationPlugin::Create(ExecutionSession &ES) {23 24  ExecutorAddr Register, Deregister;25 26  auto &EPC = ES.getExecutorProcessControl();27  if (auto Err = EPC.getBootstrapSymbols(28          {{Register, rt_alt::UnwindInfoManagerRegisterActionName},29           {Deregister, rt_alt::UnwindInfoManagerDeregisterActionName}}))30    return std::move(Err);31 32  return std::make_shared<UnwindInfoRegistrationPlugin>(ES, Register,33                                                        Deregister);34}35 36void UnwindInfoRegistrationPlugin::modifyPassConfig(37    MaterializationResponsibility &MR, LinkGraph &G,38    PassConfiguration &PassConfig) {39 40  PassConfig.PostFixupPasses.push_back(41      [this](LinkGraph &G) { return addUnwindInfoRegistrationActions(G); });42}43 44Error UnwindInfoRegistrationPlugin::addUnwindInfoRegistrationActions(45    LinkGraph &G) {46  ExecutorAddrRange EHFrameRange, UnwindInfoRange;47 48  std::vector<Block *> CodeBlocks;49 50  auto ScanUnwindInfoSection = [&](Section &Sec, ExecutorAddrRange &SecRange) {51    if (Sec.empty())52      return;53 54    SecRange.Start = (*Sec.blocks().begin())->getAddress();55    for (auto *B : Sec.blocks()) {56      auto R = B->getRange();57      SecRange.Start = std::min(SecRange.Start, R.Start);58      SecRange.End = std::max(SecRange.End, R.End);59      for (auto &E : B->edges()) {60        if (E.getKind() != Edge::KeepAlive || !E.getTarget().isDefined())61          continue;62        auto &TargetBlock = E.getTarget().getBlock();63        auto &TargetSection = TargetBlock.getSection();64        if ((TargetSection.getMemProt() & MemProt::Exec) == MemProt::Exec)65          CodeBlocks.push_back(&TargetBlock);66      }67    }68  };69 70  if (auto *EHFrame = G.findSectionByName(MachOEHFrameSectionName))71    ScanUnwindInfoSection(*EHFrame, EHFrameRange);72 73  if (auto *UnwindInfo = G.findSectionByName(MachOUnwindInfoSectionName))74    ScanUnwindInfoSection(*UnwindInfo, UnwindInfoRange);75 76  if (CodeBlocks.empty())77    return Error::success();78 79  if ((EHFrameRange == ExecutorAddrRange() &&80       UnwindInfoRange == ExecutorAddrRange()))81    return Error::success();82 83  llvm::sort(CodeBlocks, [](const Block *LHS, const Block *RHS) {84    return LHS->getAddress() < RHS->getAddress();85  });86 87  SmallVector<ExecutorAddrRange> CodeRanges;88  for (auto *B : CodeBlocks) {89    if (CodeRanges.empty() || CodeRanges.back().End != B->getAddress())90      CodeRanges.push_back(B->getRange());91    else92      CodeRanges.back().End = B->getRange().End;93  }94 95  ExecutorAddr DSOBase;96  if (auto *DSOBaseSym = G.findAbsoluteSymbolByName(DSOBaseName))97    DSOBase = DSOBaseSym->getAddress();98  else if (auto *DSOBaseSym = G.findExternalSymbolByName(DSOBaseName))99    DSOBase = DSOBaseSym->getAddress();100  else if (auto *DSOBaseSym = G.findDefinedSymbolByName(DSOBaseName))101    DSOBase = DSOBaseSym->getAddress();102  else103    return make_error<StringError>("In " + G.getName() +104                                       " could not find dso base symbol",105                                   inconvertibleErrorCode());106 107  using namespace shared;108  using SPSRegisterArgs =109      SPSArgList<SPSSequence<SPSExecutorAddrRange>, SPSExecutorAddr,110                 SPSExecutorAddrRange, SPSExecutorAddrRange>;111  using SPSDeregisterArgs = SPSArgList<SPSSequence<SPSExecutorAddrRange>>;112 113  G.allocActions().push_back(114      {cantFail(WrapperFunctionCall::Create<SPSRegisterArgs>(115           Register, CodeRanges, DSOBase, EHFrameRange, UnwindInfoRange)),116       cantFail(WrapperFunctionCall::Create<SPSDeregisterArgs>(Deregister,117                                                               CodeRanges))});118 119  return Error::success();120}121 122} // namespace llvm::orc123