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