brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.1 KiB · 9b84218 Raw
120 lines · cpp
1//===--- DebugInfoSupport.cpp -- Utils for debug info support ---*- C++ -*-===//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// Utilities to preserve and parse debug info from LinkGraphs.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/ExecutionEngine/Orc/Debugging/DebugInfoSupport.h"14 15#include "llvm/Support/SmallVectorMemoryBuffer.h"16 17#define DEBUG_TYPE "orc"18 19using namespace llvm;20using namespace llvm::orc;21using namespace llvm::jitlink;22 23namespace {24static DenseSet<StringRef> DWARFSectionNames = {25#define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME, OPTION)        \26  StringRef(ELF_NAME),27#include "llvm/BinaryFormat/Dwarf.def"28#undef HANDLE_DWARF_SECTION29};30 31// We might be able to drop relocations to symbols that do end up32// being pruned by the linker, but for now we just preserve all33static void preserveDWARFSection(LinkGraph &G, Section &Sec) {34  DenseMap<Block *, Symbol *> Preserved;35  for (auto Sym : Sec.symbols()) {36    auto [It, Inserted] = Preserved.try_emplace(&Sym->getBlock());37    if (Inserted || Sym->isLive())38      It->second = Sym;39  }40  for (auto Block : Sec.blocks()) {41    auto &PSym = Preserved[Block];42    if (!PSym)43      PSym = &G.addAnonymousSymbol(*Block, 0, 0, false, true);44    else if (!PSym->isLive())45      PSym->setLive(true);46  }47}48 49static SmallVector<char, 0> getSectionData(Section &Sec) {50  SmallVector<char, 0> SecData;51  SmallVector<Block *, 8> SecBlocks(Sec.blocks().begin(), Sec.blocks().end());52  std::sort(SecBlocks.begin(), SecBlocks.end(), [](Block *LHS, Block *RHS) {53    return LHS->getAddress() < RHS->getAddress();54  });55  // Convert back to what object file would have, one blob of section content56  // Assumes all zerofill57  // TODO handle alignment?58  // TODO handle alignment offset?59  for (auto *Block : SecBlocks) {60    if (Block->isZeroFill())61      SecData.resize(SecData.size() + Block->getSize(), 0);62    else63      SecData.append(Block->getContent().begin(), Block->getContent().end());64  }65  return SecData;66}67 68static void dumpDWARFContext(DWARFContext &DC) {69  auto options = llvm::DIDumpOptions();70  options.DumpType &= ~DIDT_UUID;71  options.DumpType &= ~(1 << DIDT_ID_DebugFrame);72  LLVM_DEBUG(DC.dump(dbgs(), options));73}74 75} // namespace76 77Error llvm::orc::preserveDebugSections(LinkGraph &G) {78  if (!G.getTargetTriple().isOSBinFormatELF()) {79    return make_error<StringError>(80        "preserveDebugSections only supports ELF LinkGraphs!",81        inconvertibleErrorCode());82  }83  for (auto &Sec : G.sections()) {84    if (DWARFSectionNames.count(Sec.getName())) {85      LLVM_DEBUG(dbgs() << "Preserving DWARF section " << Sec.getName()86                        << "\n");87      preserveDWARFSection(G, Sec);88    }89  }90  return Error::success();91}92 93Expected<std::pair<std::unique_ptr<DWARFContext>,94                   StringMap<std::unique_ptr<MemoryBuffer>>>>95llvm::orc::createDWARFContext(LinkGraph &G) {96  if (!G.getTargetTriple().isOSBinFormatELF()) {97    return make_error<StringError>(98        "createDWARFContext only supports ELF LinkGraphs!",99        inconvertibleErrorCode());100  }101  StringMap<std::unique_ptr<MemoryBuffer>> DWARFSectionData;102  for (auto &Sec : G.sections()) {103    if (DWARFSectionNames.count(Sec.getName())) {104      auto SecData = getSectionData(Sec);105      auto Name = Sec.getName();106      // DWARFContext expects the section name to not start with a dot107      Name.consume_front(".");108      LLVM_DEBUG(dbgs() << "Creating DWARFContext section " << Name109                        << " with size " << SecData.size() << "\n");110      DWARFSectionData[Name] =111          std::make_unique<SmallVectorMemoryBuffer>(std::move(SecData));112    }113  }114  auto Ctx =115      DWARFContext::create(DWARFSectionData, G.getPointerSize(),116                           G.getEndianness() == llvm::endianness::little);117  dumpDWARFContext(*Ctx);118  return std::make_pair(std::move(Ctx), std::move(DWARFSectionData));119}120