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