1 //===-------- JITLink_DWARFRecordSectionSplitter.cpp - JITLink-------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.h"
10 #include "llvm/Support/BinaryStreamReader.h"
12 #define DEBUG_TYPE "jitlink"
17 DWARFRecordSectionSplitter::DWARFRecordSectionSplitter(StringRef SectionName
)
18 : SectionName(SectionName
) {}
20 Error
DWARFRecordSectionSplitter::operator()(LinkGraph
&G
) {
21 auto *Section
= G
.findSectionByName(SectionName
);
25 dbgs() << "DWARFRecordSectionSplitter: No " << SectionName
26 << " section. Nothing to do\n";
28 return Error::success();
32 dbgs() << "DWARFRecordSectionSplitter: Processing " << SectionName
36 DenseMap
<Block
*, LinkGraph::SplitBlockCache
> Caches
;
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();
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
) {
55 auto &BCache
= KV
.second
;
56 if (auto Err
= processBlock(G
, B
, BCache
))
60 return Error::success();
63 Error
DWARFRecordSectionSplitter::processBlock(
64 LinkGraph
&G
, Block
&B
, LinkGraph::SplitBlockCache
&Cache
) {
65 LLVM_DEBUG(dbgs() << " Processing block at " << B
.getAddress() << "\n");
67 // Section should not contain zero-fill blocks.
69 return make_error
<JITLinkError
>("Unexpected zero-fill block in " +
70 SectionName
+ " section");
72 if (B
.getSize() == 0) {
73 LLVM_DEBUG(dbgs() << " Block is empty. Skipping.\n");
74 return Error::success();
77 BinaryStreamReader
BlockReader(
78 StringRef(B
.getContent().data(), B
.getContent().size()),
82 uint64_t RecordStartOffset
= BlockReader
.getOffset();
85 dbgs() << " Processing CFI record at "
86 << formatv("{0:x16}", B
.getAddress()) << "\n";
90 if (auto Err
= BlockReader
.readInteger(Length
))
92 if (Length
!= 0xffffffff) {
93 if (auto Err
= BlockReader
.skip(Length
))
96 uint64_t ExtendedLength
;
97 if (auto Err
= BlockReader
.readInteger(ExtendedLength
))
99 if (auto Err
= BlockReader
.skip(ExtendedLength
))
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();
109 uint64_t BlockSize
= BlockReader
.getOffset() - RecordStartOffset
;
110 auto &NewBlock
= G
.splitBlock(B
, BlockSize
, &Cache
);
112 LLVM_DEBUG(dbgs() << " Extracted " << NewBlock
<< "\n");
116 } // namespace jitlink