LLVM  16.0.0git
DWARFRecordSectionSplitter.cpp
Go to the documentation of this file.
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 
11 
12 #define DEBUG_TYPE "jitlink"
13 
14 namespace llvm {
15 namespace jitlink {
16 
19 
21  auto *Section = G.findSectionByName(SectionName);
22 
23  if (!Section) {
24  LLVM_DEBUG({
25  dbgs() << "DWARFRecordSectionSplitter: No " << SectionName
26  << " section. Nothing to do\n";
27  });
28  return Error::success();
29  }
30 
31  LLVM_DEBUG({
32  dbgs() << "DWARFRecordSectionSplitter: Processing " << SectionName
33  << "...\n";
34  });
35 
37 
38  {
39  // Pre-build the split caches.
40  for (auto *B : Section->blocks())
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 rather
51  // 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 
63 Error DWARFRecordSectionSplitter::processBlock(
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  while (true) {
82  uint64_t RecordStartOffset = BlockReader.getOffset();
83 
84  LLVM_DEBUG({
85  dbgs() << " Processing CFI record at "
86  << formatv("{0:x16}", B.getAddress()) << "\n";
87  });
88 
89  uint32_t Length;
90  if (auto Err = BlockReader.readInteger(Length))
91  return Err;
92  if (Length != 0xffffffff) {
93  if (auto Err = BlockReader.skip(Length))
94  return Err;
95  } else {
96  uint64_t ExtendedLength;
97  if (auto Err = BlockReader.readInteger(ExtendedLength))
98  return Err;
99  if (auto Err = BlockReader.skip(ExtendedLength))
100  return Err;
101  }
102 
103  // If this was the last block then there's nothing to split
104  if (BlockReader.empty()) {
105  LLVM_DEBUG(dbgs() << " Extracted " << B << "\n");
106  return Error::success();
107  }
108 
109  uint64_t BlockSize = BlockReader.getOffset() - RecordStartOffset;
110  auto &NewBlock = G.splitBlock(B, BlockSize, &Cache);
111  (void)NewBlock;
112  LLVM_DEBUG(dbgs() << " Extracted " << NewBlock << "\n");
113  }
114 }
115 
116 } // namespace jitlink
117 } // namespace llvm
BinaryStreamReader.h
llvm::Optional::value_type
T value_type
Definition: Optional.h:239
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
BlockSize
static const int BlockSize
Definition: TarWriter.cpp:33
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
llvm::Optional
Definition: APInt.h:33
RHS
Value * RHS
Definition: X86PartialReduction.cpp:76
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
LHS
Value * LHS
Definition: X86PartialReduction.cpp:75
llvm::formatv
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Definition: FormatVariadic.h:251
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::BinaryStreamReader
Provides read only access to a subclass of BinaryStream.
Definition: BinaryStreamReader.h:29
llvm::sort
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1657
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:200
uint64_t
llvm::DenseMap
Definition: DenseMap.h:714
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
uint32_t
llvm::SectionName
Definition: DWARFSection.h:21
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
DWARFRecordSectionSplitter.h