DWARFRecordSectionSplitter.cpp 3.6 KB

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