brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.4 KiB · 2bfbda9 Raw
116 lines · cpp
1//===-------- JITLink_DWARFRecordSectionSplitter.cpp - JITLink-------------===//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/JITLink/DWARFRecordSectionSplitter.h"10#include "llvm/Support/BinaryStreamReader.h"11 12#define DEBUG_TYPE "jitlink"13 14namespace llvm {15namespace jitlink {16 17DWARFRecordSectionSplitter::DWARFRecordSectionSplitter(StringRef SectionName)18    : SectionName(SectionName) {}19 20Error DWARFRecordSectionSplitter::operator()(LinkGraph &G) {21  auto *Section = G.findSectionByName(SectionName);22 23  if (!Section) {24    LLVM_DEBUG({25      dbgs() << "DWARFRecordSectionSplitter: No " << SectionName26             << " section. Nothing to do\n";27    });28    return Error::success();29  }30 31  LLVM_DEBUG({32    dbgs() << "DWARFRecordSectionSplitter: Processing " << SectionName33           << "...\n";34  });35 36  DenseMap<Block *, LinkGraph::SplitBlockCache> Caches;37 38  {39    // Pre-build the split caches.40    for (auto *B : Section->blocks())41      Caches[B] = LinkGraph::SplitBlockCache::value_type();42    for (auto *Sym : Section->symbols())43      Caches[&Sym->getBlock()]->push_back(Sym);44    for (auto *B : Section->blocks())45      llvm::sort(*Caches[B], [](const Symbol *LHS, const Symbol *RHS) {46        return LHS->getOffset() > RHS->getOffset();47      });48  }49 50  // Iterate over blocks (we do this by iterating over Caches entries rather51  // than Section->blocks() as we will be inserting new blocks along the way,52  // which would invalidate iterators in the latter sequence.53  for (auto &KV : Caches) {54    auto &B = *KV.first;55    auto &BCache = KV.second;56    if (auto Err = processBlock(G, B, BCache))57      return Err;58  }59 60  return Error::success();61}62 63Error DWARFRecordSectionSplitter::processBlock(64    LinkGraph &G, Block &B, LinkGraph::SplitBlockCache &Cache) {65  LLVM_DEBUG(dbgs() << "  Processing block at " << B.getAddress() << "\n");66 67  // Section should not contain zero-fill blocks.68  if (B.isZeroFill())69    return make_error<JITLinkError>("Unexpected zero-fill block in " +70                                    SectionName + " section");71 72  if (B.getSize() == 0) {73    LLVM_DEBUG(dbgs() << "    Block is empty. Skipping.\n");74    return Error::success();75  }76 77  BinaryStreamReader BlockReader(78      StringRef(B.getContent().data(), B.getContent().size()),79      G.getEndianness());80 81  std::vector<Edge::OffsetT> SplitOffsets;82  while (true) {83    LLVM_DEBUG({84      dbgs() << "    Processing CFI record at "85             << (B.getAddress() + BlockReader.getOffset()) << "\n";86    });87 88    uint32_t Length;89    if (auto Err = BlockReader.readInteger(Length))90      return Err;91    if (Length != 0xffffffff) {92      if (auto Err = BlockReader.skip(Length))93        return Err;94    } else {95      uint64_t ExtendedLength;96      if (auto Err = BlockReader.readInteger(ExtendedLength))97        return Err;98      if (auto Err = BlockReader.skip(ExtendedLength))99        return Err;100    }101 102    // If this was the last block then there's nothing more to split103    if (BlockReader.empty())104      break;105 106    SplitOffsets.push_back(BlockReader.getOffset());107  }108 109  G.splitBlock(B, SplitOffsets);110 111  return Error::success();112}113 114} // namespace jitlink115} // namespace llvm116