1bdd1243dSDimitry Andric //===-- LVBinaryReader.cpp ------------------------------------------------===// 2bdd1243dSDimitry Andric // 3bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6bdd1243dSDimitry Andric // 7bdd1243dSDimitry Andric //===----------------------------------------------------------------------===// 8bdd1243dSDimitry Andric // 9bdd1243dSDimitry Andric // This implements the LVBinaryReader class. 10bdd1243dSDimitry Andric // 11bdd1243dSDimitry Andric //===----------------------------------------------------------------------===// 12bdd1243dSDimitry Andric 13bdd1243dSDimitry Andric #include "llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h" 14bdd1243dSDimitry Andric #include "llvm/Support/Errc.h" 15bdd1243dSDimitry Andric #include "llvm/Support/FormatAdapters.h" 16bdd1243dSDimitry Andric #include "llvm/Support/FormatVariadic.h" 17bdd1243dSDimitry Andric 18bdd1243dSDimitry Andric using namespace llvm; 19bdd1243dSDimitry Andric using namespace llvm::logicalview; 20bdd1243dSDimitry Andric 21bdd1243dSDimitry Andric #define DEBUG_TYPE "BinaryReader" 22bdd1243dSDimitry Andric 23bdd1243dSDimitry Andric // Function names extracted from the object symbol table. 24bdd1243dSDimitry Andric void LVSymbolTable::add(StringRef Name, LVScope *Function, 25bdd1243dSDimitry Andric LVSectionIndex SectionIndex) { 26bdd1243dSDimitry Andric std::string SymbolName(Name); 27bdd1243dSDimitry Andric if (SymbolNames.find(SymbolName) == SymbolNames.end()) { 28bdd1243dSDimitry Andric SymbolNames.emplace( 29bdd1243dSDimitry Andric std::piecewise_construct, std::forward_as_tuple(SymbolName), 30bdd1243dSDimitry Andric std::forward_as_tuple(Function, 0, SectionIndex, false)); 31bdd1243dSDimitry Andric } else { 32bdd1243dSDimitry Andric // Update a recorded entry with its logical scope and section index. 33bdd1243dSDimitry Andric SymbolNames[SymbolName].Scope = Function; 34bdd1243dSDimitry Andric if (SectionIndex) 35bdd1243dSDimitry Andric SymbolNames[SymbolName].SectionIndex = SectionIndex; 36bdd1243dSDimitry Andric } 37bdd1243dSDimitry Andric 38bdd1243dSDimitry Andric if (Function && SymbolNames[SymbolName].IsComdat) 39bdd1243dSDimitry Andric Function->setIsComdat(); 40bdd1243dSDimitry Andric 41bdd1243dSDimitry Andric LLVM_DEBUG({ print(dbgs()); }); 42bdd1243dSDimitry Andric } 43bdd1243dSDimitry Andric 44bdd1243dSDimitry Andric void LVSymbolTable::add(StringRef Name, LVAddress Address, 45bdd1243dSDimitry Andric LVSectionIndex SectionIndex, bool IsComdat) { 46bdd1243dSDimitry Andric std::string SymbolName(Name); 47bdd1243dSDimitry Andric if (SymbolNames.find(SymbolName) == SymbolNames.end()) 48bdd1243dSDimitry Andric SymbolNames.emplace( 49bdd1243dSDimitry Andric std::piecewise_construct, std::forward_as_tuple(SymbolName), 50bdd1243dSDimitry Andric std::forward_as_tuple(nullptr, Address, SectionIndex, IsComdat)); 51bdd1243dSDimitry Andric else 52bdd1243dSDimitry Andric // Update a recorded symbol name with its logical scope. 53bdd1243dSDimitry Andric SymbolNames[SymbolName].Address = Address; 54bdd1243dSDimitry Andric 55bdd1243dSDimitry Andric LVScope *Function = SymbolNames[SymbolName].Scope; 56bdd1243dSDimitry Andric if (Function && IsComdat) 57bdd1243dSDimitry Andric Function->setIsComdat(); 58bdd1243dSDimitry Andric LLVM_DEBUG({ print(dbgs()); }); 59bdd1243dSDimitry Andric } 60bdd1243dSDimitry Andric 61bdd1243dSDimitry Andric LVSectionIndex LVSymbolTable::update(LVScope *Function) { 62bdd1243dSDimitry Andric LVSectionIndex SectionIndex = getReader().getDotTextSectionIndex(); 63bdd1243dSDimitry Andric StringRef Name = Function->getLinkageName(); 64bdd1243dSDimitry Andric if (Name.empty()) 65bdd1243dSDimitry Andric Name = Function->getName(); 66bdd1243dSDimitry Andric std::string SymbolName(Name); 67bdd1243dSDimitry Andric 68bdd1243dSDimitry Andric if (SymbolName.empty() || (SymbolNames.find(SymbolName) == SymbolNames.end())) 69bdd1243dSDimitry Andric return SectionIndex; 70bdd1243dSDimitry Andric 71bdd1243dSDimitry Andric // Update a recorded entry with its logical scope, only if the scope has 72bdd1243dSDimitry Andric // ranges. That is the case when in DWARF there are 2 DIEs connected via 73bdd1243dSDimitry Andric // the DW_AT_specification. 74bdd1243dSDimitry Andric if (Function->getHasRanges()) { 75bdd1243dSDimitry Andric SymbolNames[SymbolName].Scope = Function; 76bdd1243dSDimitry Andric SectionIndex = SymbolNames[SymbolName].SectionIndex; 77bdd1243dSDimitry Andric } else { 78bdd1243dSDimitry Andric SectionIndex = UndefinedSectionIndex; 79bdd1243dSDimitry Andric } 80bdd1243dSDimitry Andric 81bdd1243dSDimitry Andric if (SymbolNames[SymbolName].IsComdat) 82bdd1243dSDimitry Andric Function->setIsComdat(); 83bdd1243dSDimitry Andric 84bdd1243dSDimitry Andric LLVM_DEBUG({ print(dbgs()); }); 85bdd1243dSDimitry Andric return SectionIndex; 86bdd1243dSDimitry Andric } 87bdd1243dSDimitry Andric 88bdd1243dSDimitry Andric const LVSymbolTableEntry &LVSymbolTable::getEntry(StringRef Name) { 89bdd1243dSDimitry Andric static LVSymbolTableEntry Empty = LVSymbolTableEntry(); 90bdd1243dSDimitry Andric LVSymbolNames::iterator Iter = SymbolNames.find(std::string(Name)); 91bdd1243dSDimitry Andric return Iter != SymbolNames.end() ? Iter->second : Empty; 92bdd1243dSDimitry Andric } 93bdd1243dSDimitry Andric LVAddress LVSymbolTable::getAddress(StringRef Name) { 94bdd1243dSDimitry Andric LVSymbolNames::iterator Iter = SymbolNames.find(std::string(Name)); 95bdd1243dSDimitry Andric return Iter != SymbolNames.end() ? Iter->second.Address : 0; 96bdd1243dSDimitry Andric } 97bdd1243dSDimitry Andric LVSectionIndex LVSymbolTable::getIndex(StringRef Name) { 98bdd1243dSDimitry Andric LVSymbolNames::iterator Iter = SymbolNames.find(std::string(Name)); 99bdd1243dSDimitry Andric return Iter != SymbolNames.end() ? Iter->second.SectionIndex 100bdd1243dSDimitry Andric : getReader().getDotTextSectionIndex(); 101bdd1243dSDimitry Andric } 102bdd1243dSDimitry Andric bool LVSymbolTable::getIsComdat(StringRef Name) { 103bdd1243dSDimitry Andric LVSymbolNames::iterator Iter = SymbolNames.find(std::string(Name)); 104bdd1243dSDimitry Andric return Iter != SymbolNames.end() ? Iter->second.IsComdat : false; 105bdd1243dSDimitry Andric } 106bdd1243dSDimitry Andric 107bdd1243dSDimitry Andric void LVSymbolTable::print(raw_ostream &OS) { 108bdd1243dSDimitry Andric OS << "Symbol Table\n"; 109bdd1243dSDimitry Andric for (LVSymbolNames::reference Entry : SymbolNames) { 110bdd1243dSDimitry Andric LVSymbolTableEntry &SymbolName = Entry.second; 111bdd1243dSDimitry Andric LVScope *Scope = SymbolName.Scope; 112bdd1243dSDimitry Andric LVOffset Offset = Scope ? Scope->getOffset() : 0; 113bdd1243dSDimitry Andric OS << "Index: " << hexValue(SymbolName.SectionIndex, 5) 114bdd1243dSDimitry Andric << " Comdat: " << (SymbolName.IsComdat ? "Y" : "N") 115bdd1243dSDimitry Andric << " Scope: " << hexValue(Offset) 116bdd1243dSDimitry Andric << " Address: " << hexValue(SymbolName.Address) 117bdd1243dSDimitry Andric << " Name: " << Entry.first << "\n"; 118bdd1243dSDimitry Andric } 119bdd1243dSDimitry Andric } 120bdd1243dSDimitry Andric 121bdd1243dSDimitry Andric void LVBinaryReader::addToSymbolTable(StringRef Name, LVScope *Function, 122bdd1243dSDimitry Andric LVSectionIndex SectionIndex) { 123bdd1243dSDimitry Andric SymbolTable.add(Name, Function, SectionIndex); 124bdd1243dSDimitry Andric } 125bdd1243dSDimitry Andric void LVBinaryReader::addToSymbolTable(StringRef Name, LVAddress Address, 126bdd1243dSDimitry Andric LVSectionIndex SectionIndex, 127bdd1243dSDimitry Andric bool IsComdat) { 128bdd1243dSDimitry Andric SymbolTable.add(Name, Address, SectionIndex, IsComdat); 129bdd1243dSDimitry Andric } 130bdd1243dSDimitry Andric LVSectionIndex LVBinaryReader::updateSymbolTable(LVScope *Function) { 131bdd1243dSDimitry Andric return SymbolTable.update(Function); 132bdd1243dSDimitry Andric } 133bdd1243dSDimitry Andric 134bdd1243dSDimitry Andric const LVSymbolTableEntry &LVBinaryReader::getSymbolTableEntry(StringRef Name) { 135bdd1243dSDimitry Andric return SymbolTable.getEntry(Name); 136bdd1243dSDimitry Andric } 137bdd1243dSDimitry Andric LVAddress LVBinaryReader::getSymbolTableAddress(StringRef Name) { 138bdd1243dSDimitry Andric return SymbolTable.getAddress(Name); 139bdd1243dSDimitry Andric } 140bdd1243dSDimitry Andric LVSectionIndex LVBinaryReader::getSymbolTableIndex(StringRef Name) { 141bdd1243dSDimitry Andric return SymbolTable.getIndex(Name); 142bdd1243dSDimitry Andric } 143bdd1243dSDimitry Andric bool LVBinaryReader::getSymbolTableIsComdat(StringRef Name) { 144bdd1243dSDimitry Andric return SymbolTable.getIsComdat(Name); 145bdd1243dSDimitry Andric } 146bdd1243dSDimitry Andric 147bdd1243dSDimitry Andric void LVBinaryReader::mapVirtualAddress(const object::ObjectFile &Obj) { 148bdd1243dSDimitry Andric for (const object::SectionRef &Section : Obj.sections()) { 149*0fca6ea1SDimitry Andric LLVM_DEBUG({ 150*0fca6ea1SDimitry Andric Expected<StringRef> SectionNameOrErr = Section.getName(); 151*0fca6ea1SDimitry Andric StringRef Name; 152*0fca6ea1SDimitry Andric if (!SectionNameOrErr) 153*0fca6ea1SDimitry Andric consumeError(SectionNameOrErr.takeError()); 154*0fca6ea1SDimitry Andric else 155*0fca6ea1SDimitry Andric Name = *SectionNameOrErr; 156*0fca6ea1SDimitry Andric dbgs() << "Index: " << format_decimal(Section.getIndex(), 3) << ", " 157*0fca6ea1SDimitry Andric << "Address: " << hexValue(Section.getAddress()) << ", " 158*0fca6ea1SDimitry Andric << "Size: " << hexValue(Section.getSize()) << ", " 159*0fca6ea1SDimitry Andric << "Name: " << Name << "\n"; 160*0fca6ea1SDimitry Andric dbgs() << "isCompressed: " << Section.isCompressed() << ", " 161*0fca6ea1SDimitry Andric << "isText: " << Section.isText() << ", " 162*0fca6ea1SDimitry Andric << "isData: " << Section.isData() << ", " 163*0fca6ea1SDimitry Andric << "isBSS: " << Section.isBSS() << ", " 164*0fca6ea1SDimitry Andric << "isVirtual: " << Section.isVirtual() << "\n"; 165*0fca6ea1SDimitry Andric dbgs() << "isBitcode: " << Section.isBitcode() << ", " 166*0fca6ea1SDimitry Andric << "isStripped: " << Section.isStripped() << ", " 167*0fca6ea1SDimitry Andric << "isBerkeleyText: " << Section.isBerkeleyText() << ", " 168*0fca6ea1SDimitry Andric << "isBerkeleyData: " << Section.isBerkeleyData() << ", " 169*0fca6ea1SDimitry Andric << "isDebugSection: " << Section.isDebugSection() << "\n"; 170*0fca6ea1SDimitry Andric dbgs() << "\n"; 171*0fca6ea1SDimitry Andric }); 172*0fca6ea1SDimitry Andric 173bdd1243dSDimitry Andric if (!Section.isText() || Section.isVirtual() || !Section.getSize()) 174bdd1243dSDimitry Andric continue; 175bdd1243dSDimitry Andric 176bdd1243dSDimitry Andric // Record section information required for symbol resolution. 177bdd1243dSDimitry Andric // Note: The section index returned by 'getIndex()' is one based. 178bdd1243dSDimitry Andric Sections.emplace(Section.getIndex(), Section); 179bdd1243dSDimitry Andric addSectionAddress(Section); 180bdd1243dSDimitry Andric 181bdd1243dSDimitry Andric // Identify the ".text" section. 182bdd1243dSDimitry Andric Expected<StringRef> SectionNameOrErr = Section.getName(); 183bdd1243dSDimitry Andric if (!SectionNameOrErr) { 184bdd1243dSDimitry Andric consumeError(SectionNameOrErr.takeError()); 185bdd1243dSDimitry Andric continue; 186bdd1243dSDimitry Andric } 187*0fca6ea1SDimitry Andric if (*SectionNameOrErr == ".text" || *SectionNameOrErr == "CODE" || 188*0fca6ea1SDimitry Andric *SectionNameOrErr == ".code") { 189bdd1243dSDimitry Andric DotTextSectionIndex = Section.getIndex(); 190*0fca6ea1SDimitry Andric // If the object is WebAssembly, update the address offset that 191*0fca6ea1SDimitry Andric // will be added to DWARF DW_AT_* attributes. 192*0fca6ea1SDimitry Andric if (Obj.isWasm()) 193*0fca6ea1SDimitry Andric WasmCodeSectionOffset = Section.getAddress(); 194*0fca6ea1SDimitry Andric } 195bdd1243dSDimitry Andric } 196bdd1243dSDimitry Andric 197bdd1243dSDimitry Andric // Process the symbol table. 198bdd1243dSDimitry Andric mapRangeAddress(Obj); 199bdd1243dSDimitry Andric 200bdd1243dSDimitry Andric LLVM_DEBUG({ 201bdd1243dSDimitry Andric dbgs() << "\nSections Information:\n"; 202bdd1243dSDimitry Andric for (LVSections::reference Entry : Sections) { 203bdd1243dSDimitry Andric LVSectionIndex SectionIndex = Entry.first; 204bdd1243dSDimitry Andric const object::SectionRef Section = Entry.second; 205bdd1243dSDimitry Andric Expected<StringRef> SectionNameOrErr = Section.getName(); 206bdd1243dSDimitry Andric if (!SectionNameOrErr) 207bdd1243dSDimitry Andric consumeError(SectionNameOrErr.takeError()); 208bdd1243dSDimitry Andric dbgs() << "\nIndex: " << format_decimal(SectionIndex, 3) 209bdd1243dSDimitry Andric << " Name: " << *SectionNameOrErr << "\n" 210bdd1243dSDimitry Andric << "Size: " << hexValue(Section.getSize()) << "\n" 211bdd1243dSDimitry Andric << "VirtualAddress: " << hexValue(VirtualAddress) << "\n" 212bdd1243dSDimitry Andric << "SectionAddress: " << hexValue(Section.getAddress()) << "\n"; 213bdd1243dSDimitry Andric } 214bdd1243dSDimitry Andric dbgs() << "\nObject Section Information:\n"; 215bdd1243dSDimitry Andric for (LVSectionAddresses::const_reference Entry : SectionAddresses) 216bdd1243dSDimitry Andric dbgs() << "[" << hexValue(Entry.first) << ":" 217bdd1243dSDimitry Andric << hexValue(Entry.first + Entry.second.getSize()) 218bdd1243dSDimitry Andric << "] Size: " << hexValue(Entry.second.getSize()) << "\n"; 219bdd1243dSDimitry Andric }); 220bdd1243dSDimitry Andric } 221bdd1243dSDimitry Andric 22206c3fb27SDimitry Andric void LVBinaryReader::mapVirtualAddress(const object::COFFObjectFile &COFFObj) { 22306c3fb27SDimitry Andric ErrorOr<uint64_t> ImageBase = COFFObj.getImageBase(); 22406c3fb27SDimitry Andric if (ImageBase) 22506c3fb27SDimitry Andric ImageBaseAddress = ImageBase.get(); 22606c3fb27SDimitry Andric 22706c3fb27SDimitry Andric LLVM_DEBUG({ 22806c3fb27SDimitry Andric dbgs() << "ImageBaseAddress: " << hexValue(ImageBaseAddress) << "\n"; 22906c3fb27SDimitry Andric }); 23006c3fb27SDimitry Andric 23106c3fb27SDimitry Andric uint32_t Flags = COFF::IMAGE_SCN_CNT_CODE | COFF::IMAGE_SCN_LNK_COMDAT; 23206c3fb27SDimitry Andric 23306c3fb27SDimitry Andric for (const object::SectionRef &Section : COFFObj.sections()) { 23406c3fb27SDimitry Andric if (!Section.isText() || Section.isVirtual() || !Section.getSize()) 23506c3fb27SDimitry Andric continue; 23606c3fb27SDimitry Andric 23706c3fb27SDimitry Andric const object::coff_section *COFFSection = COFFObj.getCOFFSection(Section); 23806c3fb27SDimitry Andric VirtualAddress = COFFSection->VirtualAddress; 23906c3fb27SDimitry Andric bool IsComdat = (COFFSection->Characteristics & Flags) == Flags; 24006c3fb27SDimitry Andric 24106c3fb27SDimitry Andric // Record section information required for symbol resolution. 24206c3fb27SDimitry Andric // Note: The section index returned by 'getIndex()' is zero based. 24306c3fb27SDimitry Andric Sections.emplace(Section.getIndex() + 1, Section); 24406c3fb27SDimitry Andric addSectionAddress(Section); 24506c3fb27SDimitry Andric 24606c3fb27SDimitry Andric // Additional initialization on the specific object format. 24706c3fb27SDimitry Andric mapRangeAddress(COFFObj, Section, IsComdat); 24806c3fb27SDimitry Andric } 24906c3fb27SDimitry Andric 25006c3fb27SDimitry Andric LLVM_DEBUG({ 25106c3fb27SDimitry Andric dbgs() << "\nSections Information:\n"; 25206c3fb27SDimitry Andric for (LVSections::reference Entry : Sections) { 25306c3fb27SDimitry Andric LVSectionIndex SectionIndex = Entry.first; 25406c3fb27SDimitry Andric const object::SectionRef Section = Entry.second; 25506c3fb27SDimitry Andric const object::coff_section *COFFSection = COFFObj.getCOFFSection(Section); 25606c3fb27SDimitry Andric Expected<StringRef> SectionNameOrErr = Section.getName(); 25706c3fb27SDimitry Andric if (!SectionNameOrErr) 25806c3fb27SDimitry Andric consumeError(SectionNameOrErr.takeError()); 25906c3fb27SDimitry Andric dbgs() << "\nIndex: " << format_decimal(SectionIndex, 3) 26006c3fb27SDimitry Andric << " Name: " << *SectionNameOrErr << "\n" 26106c3fb27SDimitry Andric << "Size: " << hexValue(Section.getSize()) << "\n" 26206c3fb27SDimitry Andric << "VirtualAddress: " << hexValue(VirtualAddress) << "\n" 26306c3fb27SDimitry Andric << "SectionAddress: " << hexValue(Section.getAddress()) << "\n" 26406c3fb27SDimitry Andric << "PointerToRawData: " << hexValue(COFFSection->PointerToRawData) 26506c3fb27SDimitry Andric << "\n" 26606c3fb27SDimitry Andric << "SizeOfRawData: " << hexValue(COFFSection->SizeOfRawData) 26706c3fb27SDimitry Andric << "\n"; 26806c3fb27SDimitry Andric } 26906c3fb27SDimitry Andric dbgs() << "\nObject Section Information:\n"; 27006c3fb27SDimitry Andric for (LVSectionAddresses::const_reference Entry : SectionAddresses) 27106c3fb27SDimitry Andric dbgs() << "[" << hexValue(Entry.first) << ":" 27206c3fb27SDimitry Andric << hexValue(Entry.first + Entry.second.getSize()) 27306c3fb27SDimitry Andric << "] Size: " << hexValue(Entry.second.getSize()) << "\n"; 27406c3fb27SDimitry Andric }); 27506c3fb27SDimitry Andric } 27606c3fb27SDimitry Andric 277bdd1243dSDimitry Andric Error LVBinaryReader::loadGenericTargetInfo(StringRef TheTriple, 278bdd1243dSDimitry Andric StringRef TheFeatures) { 279bdd1243dSDimitry Andric std::string TargetLookupError; 280bdd1243dSDimitry Andric const Target *TheTarget = 281bdd1243dSDimitry Andric TargetRegistry::lookupTarget(std::string(TheTriple), TargetLookupError); 282bdd1243dSDimitry Andric if (!TheTarget) 283bdd1243dSDimitry Andric return createStringError(errc::invalid_argument, TargetLookupError.c_str()); 284bdd1243dSDimitry Andric 285bdd1243dSDimitry Andric // Register information. 286bdd1243dSDimitry Andric MCRegisterInfo *RegisterInfo = TheTarget->createMCRegInfo(TheTriple); 287bdd1243dSDimitry Andric if (!RegisterInfo) 288bdd1243dSDimitry Andric return createStringError(errc::invalid_argument, 289bdd1243dSDimitry Andric "no register info for target " + TheTriple); 290bdd1243dSDimitry Andric MRI.reset(RegisterInfo); 291bdd1243dSDimitry Andric 292bdd1243dSDimitry Andric // Assembler properties and features. 293bdd1243dSDimitry Andric MCTargetOptions MCOptions; 294bdd1243dSDimitry Andric MCAsmInfo *AsmInfo(TheTarget->createMCAsmInfo(*MRI, TheTriple, MCOptions)); 295bdd1243dSDimitry Andric if (!AsmInfo) 296bdd1243dSDimitry Andric return createStringError(errc::invalid_argument, 297bdd1243dSDimitry Andric "no assembly info for target " + TheTriple); 298bdd1243dSDimitry Andric MAI.reset(AsmInfo); 299bdd1243dSDimitry Andric 300bdd1243dSDimitry Andric // Target subtargets. 301bdd1243dSDimitry Andric StringRef CPU; 302bdd1243dSDimitry Andric MCSubtargetInfo *SubtargetInfo( 303bdd1243dSDimitry Andric TheTarget->createMCSubtargetInfo(TheTriple, CPU, TheFeatures)); 304bdd1243dSDimitry Andric if (!SubtargetInfo) 305bdd1243dSDimitry Andric return createStringError(errc::invalid_argument, 306bdd1243dSDimitry Andric "no subtarget info for target " + TheTriple); 307bdd1243dSDimitry Andric STI.reset(SubtargetInfo); 308bdd1243dSDimitry Andric 309bdd1243dSDimitry Andric // Instructions Info. 310bdd1243dSDimitry Andric MCInstrInfo *InstructionInfo(TheTarget->createMCInstrInfo()); 311bdd1243dSDimitry Andric if (!InstructionInfo) 312bdd1243dSDimitry Andric return createStringError(errc::invalid_argument, 313bdd1243dSDimitry Andric "no instruction info for target " + TheTriple); 314bdd1243dSDimitry Andric MII.reset(InstructionInfo); 315bdd1243dSDimitry Andric 316bdd1243dSDimitry Andric MC = std::make_unique<MCContext>(Triple(TheTriple), MAI.get(), MRI.get(), 317bdd1243dSDimitry Andric STI.get()); 318bdd1243dSDimitry Andric 319bdd1243dSDimitry Andric // Assembler. 320bdd1243dSDimitry Andric MCDisassembler *DisAsm(TheTarget->createMCDisassembler(*STI, *MC)); 321bdd1243dSDimitry Andric if (!DisAsm) 322bdd1243dSDimitry Andric return createStringError(errc::invalid_argument, 323bdd1243dSDimitry Andric "no disassembler for target " + TheTriple); 324bdd1243dSDimitry Andric MD.reset(DisAsm); 325bdd1243dSDimitry Andric 326bdd1243dSDimitry Andric MCInstPrinter *InstructionPrinter(TheTarget->createMCInstPrinter( 327bdd1243dSDimitry Andric Triple(TheTriple), AsmInfo->getAssemblerDialect(), *MAI, *MII, *MRI)); 328bdd1243dSDimitry Andric if (!InstructionPrinter) 329bdd1243dSDimitry Andric return createStringError(errc::invalid_argument, 330bdd1243dSDimitry Andric "no target assembly language printer for target " + 331bdd1243dSDimitry Andric TheTriple); 332bdd1243dSDimitry Andric MIP.reset(InstructionPrinter); 333bdd1243dSDimitry Andric InstructionPrinter->setPrintImmHex(true); 334bdd1243dSDimitry Andric 335bdd1243dSDimitry Andric return Error::success(); 336bdd1243dSDimitry Andric } 337bdd1243dSDimitry Andric 338bdd1243dSDimitry Andric Expected<std::pair<uint64_t, object::SectionRef>> 339bdd1243dSDimitry Andric LVBinaryReader::getSection(LVScope *Scope, LVAddress Address, 340bdd1243dSDimitry Andric LVSectionIndex SectionIndex) { 341bdd1243dSDimitry Andric // Return the 'text' section with the code for this logical scope. 342bdd1243dSDimitry Andric // COFF: SectionIndex is zero. Use 'SectionAddresses' data. 343bdd1243dSDimitry Andric // ELF: SectionIndex is the section index in the file. 344bdd1243dSDimitry Andric if (SectionIndex) { 345bdd1243dSDimitry Andric LVSections::iterator Iter = Sections.find(SectionIndex); 346bdd1243dSDimitry Andric if (Iter == Sections.end()) { 347bdd1243dSDimitry Andric return createStringError(errc::invalid_argument, 348bdd1243dSDimitry Andric "invalid section index for: '%s'", 349bdd1243dSDimitry Andric Scope->getName().str().c_str()); 350bdd1243dSDimitry Andric } 351bdd1243dSDimitry Andric const object::SectionRef Section = Iter->second; 352bdd1243dSDimitry Andric return std::make_pair(Section.getAddress(), Section); 353bdd1243dSDimitry Andric } 354bdd1243dSDimitry Andric 355bdd1243dSDimitry Andric // Ensure a valid starting address for the public names. 356bdd1243dSDimitry Andric LVSectionAddresses::const_iterator Iter = 357bdd1243dSDimitry Andric SectionAddresses.upper_bound(Address); 358bdd1243dSDimitry Andric if (Iter == SectionAddresses.begin()) 359bdd1243dSDimitry Andric return createStringError(errc::invalid_argument, 360bdd1243dSDimitry Andric "invalid section address for: '%s'", 361bdd1243dSDimitry Andric Scope->getName().str().c_str()); 362bdd1243dSDimitry Andric 363bdd1243dSDimitry Andric // Get section that contains the code for this function. 364bdd1243dSDimitry Andric Iter = SectionAddresses.lower_bound(Address); 365bdd1243dSDimitry Andric if (Iter != SectionAddresses.begin()) 366bdd1243dSDimitry Andric --Iter; 367bdd1243dSDimitry Andric return std::make_pair(Iter->first, Iter->second); 368bdd1243dSDimitry Andric } 369bdd1243dSDimitry Andric 370bdd1243dSDimitry Andric void LVBinaryReader::addSectionRange(LVSectionIndex SectionIndex, 371bdd1243dSDimitry Andric LVScope *Scope) { 372bdd1243dSDimitry Andric LVRange *ScopesWithRanges = getSectionRanges(SectionIndex); 373bdd1243dSDimitry Andric ScopesWithRanges->addEntry(Scope); 374bdd1243dSDimitry Andric } 375bdd1243dSDimitry Andric 376bdd1243dSDimitry Andric void LVBinaryReader::addSectionRange(LVSectionIndex SectionIndex, 377bdd1243dSDimitry Andric LVScope *Scope, LVAddress LowerAddress, 378bdd1243dSDimitry Andric LVAddress UpperAddress) { 379bdd1243dSDimitry Andric LVRange *ScopesWithRanges = getSectionRanges(SectionIndex); 380bdd1243dSDimitry Andric ScopesWithRanges->addEntry(Scope, LowerAddress, UpperAddress); 381bdd1243dSDimitry Andric } 382bdd1243dSDimitry Andric 383bdd1243dSDimitry Andric LVRange *LVBinaryReader::getSectionRanges(LVSectionIndex SectionIndex) { 384bdd1243dSDimitry Andric // Check if we already have a mapping for this section index. 385bdd1243dSDimitry Andric LVSectionRanges::iterator IterSection = SectionRanges.find(SectionIndex); 38606c3fb27SDimitry Andric if (IterSection == SectionRanges.end()) 38706c3fb27SDimitry Andric IterSection = 38806c3fb27SDimitry Andric SectionRanges.emplace(SectionIndex, std::make_unique<LVRange>()).first; 38906c3fb27SDimitry Andric LVRange *Range = IterSection->second.get(); 390bdd1243dSDimitry Andric assert(Range && "Range is null."); 391bdd1243dSDimitry Andric return Range; 392bdd1243dSDimitry Andric } 393bdd1243dSDimitry Andric 394bdd1243dSDimitry Andric Error LVBinaryReader::createInstructions(LVScope *Scope, 395bdd1243dSDimitry Andric LVSectionIndex SectionIndex, 396bdd1243dSDimitry Andric const LVNameInfo &NameInfo) { 397bdd1243dSDimitry Andric assert(Scope && "Scope is null."); 398bdd1243dSDimitry Andric 399bdd1243dSDimitry Andric // Skip stripped functions. 400bdd1243dSDimitry Andric if (Scope->getIsDiscarded()) 401bdd1243dSDimitry Andric return Error::success(); 402bdd1243dSDimitry Andric 403bdd1243dSDimitry Andric // Find associated address and size for the given function entry point. 404bdd1243dSDimitry Andric LVAddress Address = NameInfo.first; 405bdd1243dSDimitry Andric uint64_t Size = NameInfo.second; 406bdd1243dSDimitry Andric 407bdd1243dSDimitry Andric LLVM_DEBUG({ 408bdd1243dSDimitry Andric dbgs() << "\nPublic Name instructions: '" << Scope->getName() << "' / '" 409bdd1243dSDimitry Andric << Scope->getLinkageName() << "'\n" 410bdd1243dSDimitry Andric << "DIE Offset: " << hexValue(Scope->getOffset()) << " Range: [" 411bdd1243dSDimitry Andric << hexValue(Address) << ":" << hexValue(Address + Size) << "]\n"; 412bdd1243dSDimitry Andric }); 413bdd1243dSDimitry Andric 414bdd1243dSDimitry Andric Expected<std::pair<uint64_t, const object::SectionRef>> SectionOrErr = 415bdd1243dSDimitry Andric getSection(Scope, Address, SectionIndex); 416bdd1243dSDimitry Andric if (!SectionOrErr) 417bdd1243dSDimitry Andric return SectionOrErr.takeError(); 418bdd1243dSDimitry Andric const object::SectionRef Section = (*SectionOrErr).second; 419bdd1243dSDimitry Andric uint64_t SectionAddress = (*SectionOrErr).first; 420bdd1243dSDimitry Andric 421bdd1243dSDimitry Andric Expected<StringRef> SectionContentsOrErr = Section.getContents(); 422bdd1243dSDimitry Andric if (!SectionContentsOrErr) 423bdd1243dSDimitry Andric return SectionOrErr.takeError(); 424bdd1243dSDimitry Andric 425bdd1243dSDimitry Andric // There are cases where the section size is smaller than the [LowPC,HighPC] 426bdd1243dSDimitry Andric // range; it causes us to decode invalid addresses. The recorded size in the 427bdd1243dSDimitry Andric // logical scope is one less than the real size. 428bdd1243dSDimitry Andric LLVM_DEBUG({ 429bdd1243dSDimitry Andric dbgs() << " Size: " << hexValue(Size) 430bdd1243dSDimitry Andric << ", Section Size: " << hexValue(Section.getSize()) << "\n"; 431bdd1243dSDimitry Andric }); 432bdd1243dSDimitry Andric Size = std::min(Size + 1, Section.getSize()); 433bdd1243dSDimitry Andric 434bdd1243dSDimitry Andric ArrayRef<uint8_t> Bytes = arrayRefFromStringRef(*SectionContentsOrErr); 435bdd1243dSDimitry Andric uint64_t Offset = Address - SectionAddress; 436bdd1243dSDimitry Andric uint8_t const *Begin = Bytes.data() + Offset; 437bdd1243dSDimitry Andric uint8_t const *End = Bytes.data() + Offset + Size; 438bdd1243dSDimitry Andric 439bdd1243dSDimitry Andric LLVM_DEBUG({ 440bdd1243dSDimitry Andric Expected<StringRef> SectionNameOrErr = Section.getName(); 441bdd1243dSDimitry Andric if (!SectionNameOrErr) 442bdd1243dSDimitry Andric consumeError(SectionNameOrErr.takeError()); 443bdd1243dSDimitry Andric else 444bdd1243dSDimitry Andric dbgs() << "Section Index: " << hexValue(Section.getIndex()) << " [" 445bdd1243dSDimitry Andric << hexValue((uint64_t)Section.getAddress()) << ":" 446bdd1243dSDimitry Andric << hexValue((uint64_t)Section.getAddress() + Section.getSize(), 10) 447bdd1243dSDimitry Andric << "] Name: '" << *SectionNameOrErr << "'\n" 448bdd1243dSDimitry Andric << "Begin: " << hexValue((uint64_t)Begin) 449bdd1243dSDimitry Andric << ", End: " << hexValue((uint64_t)End) << "\n"; 450bdd1243dSDimitry Andric }); 451bdd1243dSDimitry Andric 452bdd1243dSDimitry Andric // Address for first instruction line. 453bdd1243dSDimitry Andric LVAddress FirstAddress = Address; 45406c3fb27SDimitry Andric auto InstructionsSP = std::make_unique<LVLines>(); 45506c3fb27SDimitry Andric LVLines &Instructions = *InstructionsSP; 45606c3fb27SDimitry Andric DiscoveredLines.emplace_back(std::move(InstructionsSP)); 457bdd1243dSDimitry Andric 458bdd1243dSDimitry Andric while (Begin < End) { 459bdd1243dSDimitry Andric MCInst Instruction; 460bdd1243dSDimitry Andric uint64_t BytesConsumed = 0; 461bdd1243dSDimitry Andric SmallVector<char, 64> InsnStr; 462bdd1243dSDimitry Andric raw_svector_ostream Annotations(InsnStr); 463bdd1243dSDimitry Andric MCDisassembler::DecodeStatus const S = 464bdd1243dSDimitry Andric MD->getInstruction(Instruction, BytesConsumed, 465bdd1243dSDimitry Andric ArrayRef<uint8_t>(Begin, End), Address, outs()); 466bdd1243dSDimitry Andric switch (S) { 467bdd1243dSDimitry Andric case MCDisassembler::Fail: 468bdd1243dSDimitry Andric LLVM_DEBUG({ dbgs() << "Invalid instruction\n"; }); 469bdd1243dSDimitry Andric if (BytesConsumed == 0) 470bdd1243dSDimitry Andric // Skip invalid bytes 471bdd1243dSDimitry Andric BytesConsumed = 1; 472bdd1243dSDimitry Andric break; 473bdd1243dSDimitry Andric case MCDisassembler::SoftFail: 474bdd1243dSDimitry Andric LLVM_DEBUG({ dbgs() << "Potentially undefined instruction:"; }); 47506c3fb27SDimitry Andric [[fallthrough]]; 476bdd1243dSDimitry Andric case MCDisassembler::Success: { 477bdd1243dSDimitry Andric std::string Buffer; 478bdd1243dSDimitry Andric raw_string_ostream Stream(Buffer); 479bdd1243dSDimitry Andric StringRef AnnotationsStr = Annotations.str(); 480bdd1243dSDimitry Andric MIP->printInst(&Instruction, Address, AnnotationsStr, *STI, Stream); 481bdd1243dSDimitry Andric LLVM_DEBUG({ 482bdd1243dSDimitry Andric std::string BufferCodes; 483bdd1243dSDimitry Andric raw_string_ostream StreamCodes(BufferCodes); 484bdd1243dSDimitry Andric StreamCodes << format_bytes( 485bdd1243dSDimitry Andric ArrayRef<uint8_t>(Begin, Begin + BytesConsumed), std::nullopt, 16, 486bdd1243dSDimitry Andric 16); 487bdd1243dSDimitry Andric dbgs() << "[" << hexValue((uint64_t)Begin) << "] " 488bdd1243dSDimitry Andric << "Size: " << format_decimal(BytesConsumed, 2) << " (" 489bdd1243dSDimitry Andric << formatv("{0}", 490bdd1243dSDimitry Andric fmt_align(StreamCodes.str(), AlignStyle::Left, 32)) 491bdd1243dSDimitry Andric << ") " << hexValue((uint64_t)Address) << ": " << Stream.str() 492bdd1243dSDimitry Andric << "\n"; 493bdd1243dSDimitry Andric }); 494bdd1243dSDimitry Andric // Here we add logical lines to the Instructions. Later on, 495bdd1243dSDimitry Andric // the 'processLines()' function will move each created logical line 496bdd1243dSDimitry Andric // to its enclosing logical scope, using the debug ranges information 497bdd1243dSDimitry Andric // and they will be released when its scope parent is deleted. 49806c3fb27SDimitry Andric LVLineAssembler *Line = createLineAssembler(); 499bdd1243dSDimitry Andric Line->setAddress(Address); 500bdd1243dSDimitry Andric Line->setName(StringRef(Stream.str()).trim()); 50106c3fb27SDimitry Andric Instructions.push_back(Line); 502bdd1243dSDimitry Andric break; 503bdd1243dSDimitry Andric } 504bdd1243dSDimitry Andric } 505bdd1243dSDimitry Andric Address += BytesConsumed; 506bdd1243dSDimitry Andric Begin += BytesConsumed; 507bdd1243dSDimitry Andric } 508bdd1243dSDimitry Andric 509bdd1243dSDimitry Andric LLVM_DEBUG({ 510bdd1243dSDimitry Andric size_t Index = 0; 511bdd1243dSDimitry Andric dbgs() << "\nSectionIndex: " << format_decimal(SectionIndex, 3) 512bdd1243dSDimitry Andric << " Scope DIE: " << hexValue(Scope->getOffset()) << "\n" 513bdd1243dSDimitry Andric << "Address: " << hexValue(FirstAddress) 514bdd1243dSDimitry Andric << format(" - Collected instructions lines: %d\n", 51506c3fb27SDimitry Andric Instructions.size()); 51606c3fb27SDimitry Andric for (const LVLine *Line : Instructions) 517bdd1243dSDimitry Andric dbgs() << format_decimal(++Index, 5) << ": " 518bdd1243dSDimitry Andric << hexValue(Line->getOffset()) << ", (" << Line->getName() 519bdd1243dSDimitry Andric << ")\n"; 520bdd1243dSDimitry Andric }); 521bdd1243dSDimitry Andric 522bdd1243dSDimitry Andric // The scope in the assembler names is linked to its own instructions. 52306c3fb27SDimitry Andric ScopeInstructions.add(SectionIndex, Scope, &Instructions); 524bdd1243dSDimitry Andric AssemblerMappings.add(SectionIndex, FirstAddress, Scope); 525bdd1243dSDimitry Andric 526bdd1243dSDimitry Andric return Error::success(); 527bdd1243dSDimitry Andric } 528bdd1243dSDimitry Andric 529bdd1243dSDimitry Andric Error LVBinaryReader::createInstructions(LVScope *Function, 530bdd1243dSDimitry Andric LVSectionIndex SectionIndex) { 531bdd1243dSDimitry Andric if (!options().getPrintInstructions()) 532bdd1243dSDimitry Andric return Error::success(); 533bdd1243dSDimitry Andric 534bdd1243dSDimitry Andric LVNameInfo Name = CompileUnit->findPublicName(Function); 535bdd1243dSDimitry Andric if (Name.first != LVAddress(UINT64_MAX)) 536bdd1243dSDimitry Andric return createInstructions(Function, SectionIndex, Name); 537bdd1243dSDimitry Andric 538bdd1243dSDimitry Andric return Error::success(); 539bdd1243dSDimitry Andric } 540bdd1243dSDimitry Andric 541bdd1243dSDimitry Andric Error LVBinaryReader::createInstructions() { 542bdd1243dSDimitry Andric if (!options().getPrintInstructions()) 543bdd1243dSDimitry Andric return Error::success(); 544bdd1243dSDimitry Andric 545bdd1243dSDimitry Andric LLVM_DEBUG({ 546bdd1243dSDimitry Andric size_t Index = 1; 547bdd1243dSDimitry Andric dbgs() << "\nPublic Names (Scope):\n"; 548bdd1243dSDimitry Andric for (LVPublicNames::const_reference Name : CompileUnit->getPublicNames()) { 549bdd1243dSDimitry Andric LVScope *Scope = Name.first; 550bdd1243dSDimitry Andric const LVNameInfo &NameInfo = Name.second; 551bdd1243dSDimitry Andric LVAddress Address = NameInfo.first; 552bdd1243dSDimitry Andric uint64_t Size = NameInfo.second; 553bdd1243dSDimitry Andric dbgs() << format_decimal(Index++, 5) << ": " 554bdd1243dSDimitry Andric << "DIE Offset: " << hexValue(Scope->getOffset()) << " Range: [" 555bdd1243dSDimitry Andric << hexValue(Address) << ":" << hexValue(Address + Size) << "] " 556bdd1243dSDimitry Andric << "Name: '" << Scope->getName() << "' / '" 557bdd1243dSDimitry Andric << Scope->getLinkageName() << "'\n"; 558bdd1243dSDimitry Andric } 559bdd1243dSDimitry Andric }); 560bdd1243dSDimitry Andric 561bdd1243dSDimitry Andric // For each public name in the current compile unit, create the line 562bdd1243dSDimitry Andric // records that represent the executable instructions. 563bdd1243dSDimitry Andric for (LVPublicNames::const_reference Name : CompileUnit->getPublicNames()) { 564bdd1243dSDimitry Andric LVScope *Scope = Name.first; 565bdd1243dSDimitry Andric // The symbol table extracted from the object file always contains a 566bdd1243dSDimitry Andric // non-empty name (linkage name). However, the logical scope does not 567bdd1243dSDimitry Andric // guarantee to have a name for the linkage name (main is one case). 568bdd1243dSDimitry Andric // For those cases, set the linkage name the same as the name. 569bdd1243dSDimitry Andric if (!Scope->getLinkageNameIndex()) 570bdd1243dSDimitry Andric Scope->setLinkageName(Scope->getName()); 571bdd1243dSDimitry Andric LVSectionIndex SectionIndex = getSymbolTableIndex(Scope->getLinkageName()); 572bdd1243dSDimitry Andric if (Error Err = createInstructions(Scope, SectionIndex, Name.second)) 573bdd1243dSDimitry Andric return Err; 574bdd1243dSDimitry Andric } 575bdd1243dSDimitry Andric 576bdd1243dSDimitry Andric return Error::success(); 577bdd1243dSDimitry Andric } 578bdd1243dSDimitry Andric 579bdd1243dSDimitry Andric // During the traversal of the debug information sections, we created the 580bdd1243dSDimitry Andric // logical lines representing the disassembled instructions from the text 581bdd1243dSDimitry Andric // section and the logical lines representing the line records from the 582bdd1243dSDimitry Andric // debug line section. Using the ranges associated with the logical scopes, 583bdd1243dSDimitry Andric // we will allocate those logical lines to their logical scopes. 584bdd1243dSDimitry Andric void LVBinaryReader::processLines(LVLines *DebugLines, 585bdd1243dSDimitry Andric LVSectionIndex SectionIndex, 586bdd1243dSDimitry Andric LVScope *Function) { 587bdd1243dSDimitry Andric assert(DebugLines && "DebugLines is null."); 588bdd1243dSDimitry Andric 589bdd1243dSDimitry Andric // Just return if this compilation unit does not have any line records 590bdd1243dSDimitry Andric // and no instruction lines were created. 591bdd1243dSDimitry Andric if (DebugLines->empty() && !options().getPrintInstructions()) 592bdd1243dSDimitry Andric return; 593bdd1243dSDimitry Andric 594bdd1243dSDimitry Andric // Merge the debug lines and instruction lines using their text address; 595bdd1243dSDimitry Andric // the logical line representing the debug line record is followed by the 596bdd1243dSDimitry Andric // line(s) representing the disassembled instructions, whose addresses are 597bdd1243dSDimitry Andric // equal or greater that the line address and less than the address of the 598bdd1243dSDimitry Andric // next debug line record. 599bdd1243dSDimitry Andric LLVM_DEBUG({ 600bdd1243dSDimitry Andric size_t Index = 1; 601bdd1243dSDimitry Andric size_t PerLine = 4; 602bdd1243dSDimitry Andric dbgs() << format("\nProcess debug lines: %d\n", DebugLines->size()); 603bdd1243dSDimitry Andric for (const LVLine *Line : *DebugLines) { 604bdd1243dSDimitry Andric dbgs() << format_decimal(Index, 5) << ": " << hexValue(Line->getOffset()) 605bdd1243dSDimitry Andric << ", (" << Line->getLineNumber() << ")" 606bdd1243dSDimitry Andric << ((Index % PerLine) ? " " : "\n"); 607bdd1243dSDimitry Andric ++Index; 608bdd1243dSDimitry Andric } 609bdd1243dSDimitry Andric dbgs() << ((Index % PerLine) ? "\n" : ""); 610bdd1243dSDimitry Andric }); 611bdd1243dSDimitry Andric 612bdd1243dSDimitry Andric bool TraverseLines = true; 613bdd1243dSDimitry Andric LVLines::iterator Iter = DebugLines->begin(); 614bdd1243dSDimitry Andric while (TraverseLines && Iter != DebugLines->end()) { 615bdd1243dSDimitry Andric uint64_t DebugAddress = (*Iter)->getAddress(); 616bdd1243dSDimitry Andric 617bdd1243dSDimitry Andric // Get the function with an entry point that matches this line and 618bdd1243dSDimitry Andric // its associated assembler entries. In the case of COMDAT, the input 619bdd1243dSDimitry Andric // 'Function' is not null. Use it to find its address ranges. 620bdd1243dSDimitry Andric LVScope *Scope = Function; 621bdd1243dSDimitry Andric if (!Function) { 622bdd1243dSDimitry Andric Scope = AssemblerMappings.find(SectionIndex, DebugAddress); 623bdd1243dSDimitry Andric if (!Scope) { 624bdd1243dSDimitry Andric ++Iter; 625bdd1243dSDimitry Andric continue; 626bdd1243dSDimitry Andric } 627bdd1243dSDimitry Andric } 628bdd1243dSDimitry Andric 629bdd1243dSDimitry Andric // Get the associated instructions for the found 'Scope'. 630bdd1243dSDimitry Andric LVLines InstructionLines; 631bdd1243dSDimitry Andric LVLines *Lines = ScopeInstructions.find(SectionIndex, Scope); 632bdd1243dSDimitry Andric if (Lines) 633bdd1243dSDimitry Andric InstructionLines = std::move(*Lines); 634bdd1243dSDimitry Andric 635bdd1243dSDimitry Andric LLVM_DEBUG({ 636bdd1243dSDimitry Andric size_t Index = 0; 637bdd1243dSDimitry Andric dbgs() << "\nSectionIndex: " << format_decimal(SectionIndex, 3) 638bdd1243dSDimitry Andric << " Scope DIE: " << hexValue(Scope->getOffset()) << "\n" 639bdd1243dSDimitry Andric << format("Process instruction lines: %d\n", 640bdd1243dSDimitry Andric InstructionLines.size()); 641bdd1243dSDimitry Andric for (const LVLine *Line : InstructionLines) 642bdd1243dSDimitry Andric dbgs() << format_decimal(++Index, 5) << ": " 643bdd1243dSDimitry Andric << hexValue(Line->getOffset()) << ", (" << Line->getName() 644bdd1243dSDimitry Andric << ")\n"; 645bdd1243dSDimitry Andric }); 646bdd1243dSDimitry Andric 647bdd1243dSDimitry Andric // Continue with next debug line if there are not instructions lines. 648bdd1243dSDimitry Andric if (InstructionLines.empty()) { 649bdd1243dSDimitry Andric ++Iter; 650bdd1243dSDimitry Andric continue; 651bdd1243dSDimitry Andric } 652bdd1243dSDimitry Andric 653bdd1243dSDimitry Andric for (LVLine *InstructionLine : InstructionLines) { 654bdd1243dSDimitry Andric uint64_t InstructionAddress = InstructionLine->getAddress(); 655bdd1243dSDimitry Andric LLVM_DEBUG({ 656bdd1243dSDimitry Andric dbgs() << "Instruction address: " << hexValue(InstructionAddress) 657bdd1243dSDimitry Andric << "\n"; 658bdd1243dSDimitry Andric }); 659bdd1243dSDimitry Andric if (TraverseLines) { 660bdd1243dSDimitry Andric while (Iter != DebugLines->end()) { 661bdd1243dSDimitry Andric DebugAddress = (*Iter)->getAddress(); 662bdd1243dSDimitry Andric LLVM_DEBUG({ 663bdd1243dSDimitry Andric bool IsDebug = (*Iter)->getIsLineDebug(); 664bdd1243dSDimitry Andric dbgs() << "Line " << (IsDebug ? "dbg:" : "ins:") << " [" 665bdd1243dSDimitry Andric << hexValue(DebugAddress) << "]"; 666bdd1243dSDimitry Andric if (IsDebug) 667bdd1243dSDimitry Andric dbgs() << format(" %d", (*Iter)->getLineNumber()); 668bdd1243dSDimitry Andric dbgs() << "\n"; 669bdd1243dSDimitry Andric }); 670bdd1243dSDimitry Andric // Instruction address before debug line. 671bdd1243dSDimitry Andric if (InstructionAddress < DebugAddress) { 672bdd1243dSDimitry Andric LLVM_DEBUG({ 673bdd1243dSDimitry Andric dbgs() << "Inserted instruction address: " 674bdd1243dSDimitry Andric << hexValue(InstructionAddress) << " before line: " 675bdd1243dSDimitry Andric << format("%d", (*Iter)->getLineNumber()) << " [" 676bdd1243dSDimitry Andric << hexValue(DebugAddress) << "]\n"; 677bdd1243dSDimitry Andric }); 678bdd1243dSDimitry Andric Iter = DebugLines->insert(Iter, InstructionLine); 679bdd1243dSDimitry Andric // The returned iterator points to the inserted instruction. 680bdd1243dSDimitry Andric // Skip it and point to the line acting as reference. 681bdd1243dSDimitry Andric ++Iter; 682bdd1243dSDimitry Andric break; 683bdd1243dSDimitry Andric } 684bdd1243dSDimitry Andric ++Iter; 685bdd1243dSDimitry Andric } 686bdd1243dSDimitry Andric if (Iter == DebugLines->end()) { 687bdd1243dSDimitry Andric // We have reached the end of the source lines and the current 688bdd1243dSDimitry Andric // instruction line address is greater than the last source line. 689bdd1243dSDimitry Andric TraverseLines = false; 690bdd1243dSDimitry Andric DebugLines->push_back(InstructionLine); 691bdd1243dSDimitry Andric } 692bdd1243dSDimitry Andric } else { 693bdd1243dSDimitry Andric DebugLines->push_back(InstructionLine); 694bdd1243dSDimitry Andric } 695bdd1243dSDimitry Andric } 696bdd1243dSDimitry Andric } 697bdd1243dSDimitry Andric 698bdd1243dSDimitry Andric LLVM_DEBUG({ 699bdd1243dSDimitry Andric dbgs() << format("Lines after merge: %d\n", DebugLines->size()); 700bdd1243dSDimitry Andric size_t Index = 0; 701bdd1243dSDimitry Andric for (const LVLine *Line : *DebugLines) { 702bdd1243dSDimitry Andric dbgs() << format_decimal(++Index, 5) << ": " 703bdd1243dSDimitry Andric << hexValue(Line->getOffset()) << ", (" 704bdd1243dSDimitry Andric << ((Line->getIsLineDebug()) 705bdd1243dSDimitry Andric ? Line->lineNumberAsStringStripped(/*ShowZero=*/true) 706bdd1243dSDimitry Andric : Line->getName()) 707bdd1243dSDimitry Andric << ")\n"; 708bdd1243dSDimitry Andric } 709bdd1243dSDimitry Andric }); 710bdd1243dSDimitry Andric 711bdd1243dSDimitry Andric // If this compilation unit does not have line records, traverse its scopes 712bdd1243dSDimitry Andric // and take any collected instruction lines as the working set in order 713bdd1243dSDimitry Andric // to move them to their associated scope. 714bdd1243dSDimitry Andric if (DebugLines->empty()) { 715bdd1243dSDimitry Andric if (const LVScopes *Scopes = CompileUnit->getScopes()) 716bdd1243dSDimitry Andric for (LVScope *Scope : *Scopes) { 717bdd1243dSDimitry Andric LVLines *Lines = ScopeInstructions.find(Scope); 718bdd1243dSDimitry Andric if (Lines) { 719bdd1243dSDimitry Andric 720bdd1243dSDimitry Andric LLVM_DEBUG({ 721bdd1243dSDimitry Andric size_t Index = 0; 722bdd1243dSDimitry Andric dbgs() << "\nSectionIndex: " << format_decimal(SectionIndex, 3) 723bdd1243dSDimitry Andric << " Scope DIE: " << hexValue(Scope->getOffset()) << "\n" 724bdd1243dSDimitry Andric << format("Instruction lines: %d\n", Lines->size()); 725bdd1243dSDimitry Andric for (const LVLine *Line : *Lines) 726bdd1243dSDimitry Andric dbgs() << format_decimal(++Index, 5) << ": " 727bdd1243dSDimitry Andric << hexValue(Line->getOffset()) << ", (" << Line->getName() 728bdd1243dSDimitry Andric << ")\n"; 729bdd1243dSDimitry Andric }); 730bdd1243dSDimitry Andric 731bdd1243dSDimitry Andric if (Scope->getIsArtificial()) { 732bdd1243dSDimitry Andric // Add the instruction lines to their artificial scope. 733bdd1243dSDimitry Andric for (LVLine *Line : *Lines) 734bdd1243dSDimitry Andric Scope->addElement(Line); 735bdd1243dSDimitry Andric } else { 736bdd1243dSDimitry Andric DebugLines->append(*Lines); 737bdd1243dSDimitry Andric } 738bdd1243dSDimitry Andric Lines->clear(); 739bdd1243dSDimitry Andric } 740bdd1243dSDimitry Andric } 741bdd1243dSDimitry Andric } 742bdd1243dSDimitry Andric 743bdd1243dSDimitry Andric LVRange *ScopesWithRanges = getSectionRanges(SectionIndex); 744bdd1243dSDimitry Andric ScopesWithRanges->startSearch(); 745bdd1243dSDimitry Andric 746bdd1243dSDimitry Andric // Process collected lines. 747bdd1243dSDimitry Andric LVScope *Scope; 748bdd1243dSDimitry Andric for (LVLine *Line : *DebugLines) { 749bdd1243dSDimitry Andric // Using the current line address, get its associated lexical scope and 750bdd1243dSDimitry Andric // add the line information to it. 751bdd1243dSDimitry Andric Scope = ScopesWithRanges->getEntry(Line->getAddress()); 752bdd1243dSDimitry Andric if (!Scope) { 753bdd1243dSDimitry Andric // If missing scope, use the compile unit. 754bdd1243dSDimitry Andric Scope = CompileUnit; 755bdd1243dSDimitry Andric LLVM_DEBUG({ 756bdd1243dSDimitry Andric dbgs() << "Adding line to CU: " << hexValue(Line->getOffset()) << ", (" 757bdd1243dSDimitry Andric << ((Line->getIsLineDebug()) 758bdd1243dSDimitry Andric ? Line->lineNumberAsStringStripped(/*ShowZero=*/true) 759bdd1243dSDimitry Andric : Line->getName()) 760bdd1243dSDimitry Andric << ")\n"; 761bdd1243dSDimitry Andric }); 762bdd1243dSDimitry Andric } 763bdd1243dSDimitry Andric 764bdd1243dSDimitry Andric // Add line object to scope. 765bdd1243dSDimitry Andric Scope->addElement(Line); 766bdd1243dSDimitry Andric 767bdd1243dSDimitry Andric // Report any line zero. 768bdd1243dSDimitry Andric if (options().getWarningLines() && Line->getIsLineDebug() && 769bdd1243dSDimitry Andric !Line->getLineNumber()) 770bdd1243dSDimitry Andric CompileUnit->addLineZero(Line); 771bdd1243dSDimitry Andric 772bdd1243dSDimitry Andric // Some compilers generate ranges in the compile unit; other compilers 773bdd1243dSDimitry Andric // only DW_AT_low_pc/DW_AT_high_pc. In order to correctly map global 774bdd1243dSDimitry Andric // variables, we need to generate the map ranges for the compile unit. 775bdd1243dSDimitry Andric // If we use the ranges stored at the scope level, there are cases where 776bdd1243dSDimitry Andric // the address referenced by a symbol location, is not in the enclosing 777bdd1243dSDimitry Andric // scope, but in an outer one. By using the ranges stored in the compile 778bdd1243dSDimitry Andric // unit, we can catch all those addresses. 779bdd1243dSDimitry Andric if (Line->getIsLineDebug()) 780bdd1243dSDimitry Andric CompileUnit->addMapping(Line, SectionIndex); 781bdd1243dSDimitry Andric 782bdd1243dSDimitry Andric // Resolve any given pattern. 783bdd1243dSDimitry Andric patterns().resolvePatternMatch(Line); 784bdd1243dSDimitry Andric } 785bdd1243dSDimitry Andric 786bdd1243dSDimitry Andric ScopesWithRanges->endSearch(); 787bdd1243dSDimitry Andric } 788bdd1243dSDimitry Andric 789bdd1243dSDimitry Andric void LVBinaryReader::processLines(LVLines *DebugLines, 790bdd1243dSDimitry Andric LVSectionIndex SectionIndex) { 791bdd1243dSDimitry Andric assert(DebugLines && "DebugLines is null."); 792bdd1243dSDimitry Andric if (DebugLines->empty() && !ScopeInstructions.findMap(SectionIndex)) 793bdd1243dSDimitry Andric return; 794bdd1243dSDimitry Andric 795bdd1243dSDimitry Andric // If the Compile Unit does not contain comdat functions, use the whole 796bdd1243dSDimitry Andric // set of debug lines, as the addresses don't have conflicts. 797bdd1243dSDimitry Andric if (!CompileUnit->getHasComdatScopes()) { 798bdd1243dSDimitry Andric processLines(DebugLines, SectionIndex, nullptr); 799bdd1243dSDimitry Andric return; 800bdd1243dSDimitry Andric } 801bdd1243dSDimitry Andric 802bdd1243dSDimitry Andric // Find the indexes for the lines whose address is zero. 803bdd1243dSDimitry Andric std::vector<size_t> AddressZero; 804bdd1243dSDimitry Andric LVLines::iterator It = 805bdd1243dSDimitry Andric std::find_if(std::begin(*DebugLines), std::end(*DebugLines), 806bdd1243dSDimitry Andric [](LVLine *Line) { return !Line->getAddress(); }); 807bdd1243dSDimitry Andric while (It != std::end(*DebugLines)) { 808bdd1243dSDimitry Andric AddressZero.emplace_back(std::distance(std::begin(*DebugLines), It)); 809bdd1243dSDimitry Andric It = std::find_if(std::next(It), std::end(*DebugLines), 810bdd1243dSDimitry Andric [](LVLine *Line) { return !Line->getAddress(); }); 811bdd1243dSDimitry Andric } 812bdd1243dSDimitry Andric 813bdd1243dSDimitry Andric // If the set of debug lines does not contain any line with address zero, 814bdd1243dSDimitry Andric // use the whole set. It means we are dealing with an initialization 815bdd1243dSDimitry Andric // section from a fully linked binary. 816bdd1243dSDimitry Andric if (AddressZero.empty()) { 817bdd1243dSDimitry Andric processLines(DebugLines, SectionIndex, nullptr); 818bdd1243dSDimitry Andric return; 819bdd1243dSDimitry Andric } 820bdd1243dSDimitry Andric 821bdd1243dSDimitry Andric // The Compile unit contains comdat functions. Traverse the collected 822bdd1243dSDimitry Andric // debug lines and identify logical groups based on their start and 823bdd1243dSDimitry Andric // address. Each group starts with a zero address. 824bdd1243dSDimitry Andric // Begin, End, Address, IsDone. 825bdd1243dSDimitry Andric using LVBucket = std::tuple<size_t, size_t, LVAddress, bool>; 826bdd1243dSDimitry Andric std::vector<LVBucket> Buckets; 827bdd1243dSDimitry Andric 828bdd1243dSDimitry Andric LVAddress Address; 829bdd1243dSDimitry Andric size_t Begin = 0; 830bdd1243dSDimitry Andric size_t End = 0; 831bdd1243dSDimitry Andric size_t Index = 0; 832bdd1243dSDimitry Andric for (Index = 0; Index < AddressZero.size() - 1; ++Index) { 833bdd1243dSDimitry Andric Begin = AddressZero[Index]; 834bdd1243dSDimitry Andric End = AddressZero[Index + 1] - 1; 835bdd1243dSDimitry Andric Address = (*DebugLines)[End]->getAddress(); 836bdd1243dSDimitry Andric Buckets.emplace_back(Begin, End, Address, false); 837bdd1243dSDimitry Andric } 838bdd1243dSDimitry Andric 839bdd1243dSDimitry Andric // Add the last bucket. 840bdd1243dSDimitry Andric if (Index) { 841bdd1243dSDimitry Andric Begin = AddressZero[Index]; 842bdd1243dSDimitry Andric End = DebugLines->size() - 1; 843bdd1243dSDimitry Andric Address = (*DebugLines)[End]->getAddress(); 844bdd1243dSDimitry Andric Buckets.emplace_back(Begin, End, Address, false); 845bdd1243dSDimitry Andric } 846bdd1243dSDimitry Andric 847bdd1243dSDimitry Andric LLVM_DEBUG({ 848bdd1243dSDimitry Andric dbgs() << "\nDebug Lines buckets: " << Buckets.size() << "\n"; 849bdd1243dSDimitry Andric for (LVBucket &Bucket : Buckets) { 850bdd1243dSDimitry Andric dbgs() << "Begin: " << format_decimal(std::get<0>(Bucket), 5) << ", " 851bdd1243dSDimitry Andric << "End: " << format_decimal(std::get<1>(Bucket), 5) << ", " 852bdd1243dSDimitry Andric << "Address: " << hexValue(std::get<2>(Bucket)) << "\n"; 853bdd1243dSDimitry Andric } 854bdd1243dSDimitry Andric }); 855bdd1243dSDimitry Andric 856bdd1243dSDimitry Andric // Traverse the sections and buckets looking for matches on the section 857bdd1243dSDimitry Andric // sizes. In the unlikely event of different buckets with the same size 858bdd1243dSDimitry Andric // process them in order and mark them as done. 859bdd1243dSDimitry Andric LVLines Group; 860bdd1243dSDimitry Andric for (LVSections::reference Entry : Sections) { 861bdd1243dSDimitry Andric LVSectionIndex SectionIndex = Entry.first; 862bdd1243dSDimitry Andric const object::SectionRef Section = Entry.second; 863bdd1243dSDimitry Andric uint64_t Size = Section.getSize(); 864bdd1243dSDimitry Andric LLVM_DEBUG({ 865bdd1243dSDimitry Andric dbgs() << "\nSection Index: " << format_decimal(SectionIndex, 3) 866bdd1243dSDimitry Andric << " , Section Size: " << hexValue(Section.getSize()) 867bdd1243dSDimitry Andric << " , Section Address: " << hexValue(Section.getAddress()) 868bdd1243dSDimitry Andric << "\n"; 869bdd1243dSDimitry Andric }); 870bdd1243dSDimitry Andric 871bdd1243dSDimitry Andric for (LVBucket &Bucket : Buckets) { 872bdd1243dSDimitry Andric if (std::get<3>(Bucket)) 873bdd1243dSDimitry Andric // Already done for previous section. 874bdd1243dSDimitry Andric continue; 875bdd1243dSDimitry Andric if (Size == std::get<2>(Bucket)) { 876bdd1243dSDimitry Andric // We have a match on the section size. 877bdd1243dSDimitry Andric Group.clear(); 878bdd1243dSDimitry Andric LVLines::iterator IterStart = DebugLines->begin() + std::get<0>(Bucket); 879bdd1243dSDimitry Andric LVLines::iterator IterEnd = 880bdd1243dSDimitry Andric DebugLines->begin() + std::get<1>(Bucket) + 1; 881bdd1243dSDimitry Andric for (LVLines::iterator Iter = IterStart; Iter < IterEnd; ++Iter) 882bdd1243dSDimitry Andric Group.push_back(*Iter); 883bdd1243dSDimitry Andric processLines(&Group, SectionIndex, /*Function=*/nullptr); 884bdd1243dSDimitry Andric std::get<3>(Bucket) = true; 885bdd1243dSDimitry Andric break; 886bdd1243dSDimitry Andric } 887bdd1243dSDimitry Andric } 888bdd1243dSDimitry Andric } 889bdd1243dSDimitry Andric } 890bdd1243dSDimitry Andric 89106c3fb27SDimitry Andric // Traverse the scopes for the given 'Function' looking for any inlined 89206c3fb27SDimitry Andric // scopes with inlined lines, which are found in 'CUInlineeLines'. 89306c3fb27SDimitry Andric void LVBinaryReader::includeInlineeLines(LVSectionIndex SectionIndex, 89406c3fb27SDimitry Andric LVScope *Function) { 89506c3fb27SDimitry Andric SmallVector<LVInlineeLine::iterator> InlineeIters; 89606c3fb27SDimitry Andric std::function<void(LVScope * Parent)> FindInlinedScopes = 89706c3fb27SDimitry Andric [&](LVScope *Parent) { 89806c3fb27SDimitry Andric if (const LVScopes *Scopes = Parent->getScopes()) 89906c3fb27SDimitry Andric for (LVScope *Scope : *Scopes) { 90006c3fb27SDimitry Andric LVInlineeLine::iterator Iter = CUInlineeLines.find(Scope); 90106c3fb27SDimitry Andric if (Iter != CUInlineeLines.end()) 90206c3fb27SDimitry Andric InlineeIters.push_back(Iter); 90306c3fb27SDimitry Andric FindInlinedScopes(Scope); 90406c3fb27SDimitry Andric } 90506c3fb27SDimitry Andric }; 90606c3fb27SDimitry Andric 90706c3fb27SDimitry Andric // Find all inlined scopes for the given 'Function'. 90806c3fb27SDimitry Andric FindInlinedScopes(Function); 90906c3fb27SDimitry Andric for (LVInlineeLine::iterator InlineeIter : InlineeIters) { 91006c3fb27SDimitry Andric LVScope *Scope = InlineeIter->first; 91106c3fb27SDimitry Andric addToSymbolTable(Scope->getLinkageName(), Scope, SectionIndex); 91206c3fb27SDimitry Andric 91306c3fb27SDimitry Andric // TODO: Convert this into a reference. 91406c3fb27SDimitry Andric LVLines *InlineeLines = InlineeIter->second.get(); 91506c3fb27SDimitry Andric LLVM_DEBUG({ 91606c3fb27SDimitry Andric dbgs() << "Inlined lines for: " << Scope->getName() << "\n"; 91706c3fb27SDimitry Andric for (const LVLine *Line : *InlineeLines) 91806c3fb27SDimitry Andric dbgs() << "[" << hexValue(Line->getAddress()) << "] " 91906c3fb27SDimitry Andric << Line->getLineNumber() << "\n"; 92006c3fb27SDimitry Andric dbgs() << format("Debug lines: %d\n", CULines.size()); 92106c3fb27SDimitry Andric for (const LVLine *Line : CULines) 92206c3fb27SDimitry Andric dbgs() << "Line address: " << hexValue(Line->getOffset()) << ", (" 92306c3fb27SDimitry Andric << Line->getLineNumber() << ")\n"; 92406c3fb27SDimitry Andric ; 92506c3fb27SDimitry Andric }); 92606c3fb27SDimitry Andric 92706c3fb27SDimitry Andric // The inlined lines must be merged using its address, in order to keep 92806c3fb27SDimitry Andric // the real order of the instructions. The inlined lines are mixed with 92906c3fb27SDimitry Andric // the other non-inlined lines. 93006c3fb27SDimitry Andric if (InlineeLines->size()) { 93106c3fb27SDimitry Andric // First address of inlinee code. 93206c3fb27SDimitry Andric uint64_t InlineeStart = (InlineeLines->front())->getAddress(); 93306c3fb27SDimitry Andric LVLines::iterator Iter = std::find_if( 93406c3fb27SDimitry Andric CULines.begin(), CULines.end(), [&](LVLine *Item) -> bool { 93506c3fb27SDimitry Andric return Item->getAddress() == InlineeStart; 93606c3fb27SDimitry Andric }); 93706c3fb27SDimitry Andric if (Iter != CULines.end()) { 93806c3fb27SDimitry Andric // 'Iter' points to the line where the inlined function is called. 93906c3fb27SDimitry Andric // Emulate the DW_AT_call_line attribute. 94006c3fb27SDimitry Andric Scope->setCallLineNumber((*Iter)->getLineNumber()); 94106c3fb27SDimitry Andric // Mark the referenced line as the start of the inlined function. 94206c3fb27SDimitry Andric // Skip the first line during the insertion, as the address and 94306c3fb27SDimitry Andric // line number as the same. Otherwise we have to erase and insert. 94406c3fb27SDimitry Andric (*Iter)->setLineNumber((*InlineeLines->begin())->getLineNumber()); 94506c3fb27SDimitry Andric ++Iter; 94606c3fb27SDimitry Andric CULines.insert(Iter, InlineeLines->begin() + 1, InlineeLines->end()); 94706c3fb27SDimitry Andric } 94806c3fb27SDimitry Andric } 94906c3fb27SDimitry Andric 95006c3fb27SDimitry Andric // Remove this set of lines from the container; each inlined function 95106c3fb27SDimitry Andric // creates an unique set of lines. Remove only the created container. 95206c3fb27SDimitry Andric CUInlineeLines.erase(InlineeIter); 95306c3fb27SDimitry Andric InlineeLines->clear(); 95406c3fb27SDimitry Andric } 95506c3fb27SDimitry Andric LLVM_DEBUG({ 95606c3fb27SDimitry Andric dbgs() << "Merged Inlined lines for: " << Function->getName() << "\n"; 95706c3fb27SDimitry Andric dbgs() << format("Debug lines: %d\n", CULines.size()); 95806c3fb27SDimitry Andric for (const LVLine *Line : CULines) 95906c3fb27SDimitry Andric dbgs() << "Line address: " << hexValue(Line->getOffset()) << ", (" 96006c3fb27SDimitry Andric << Line->getLineNumber() << ")\n"; 96106c3fb27SDimitry Andric ; 96206c3fb27SDimitry Andric }); 96306c3fb27SDimitry Andric } 96406c3fb27SDimitry Andric 965bdd1243dSDimitry Andric void LVBinaryReader::print(raw_ostream &OS) const { 966bdd1243dSDimitry Andric OS << "LVBinaryReader\n"; 967bdd1243dSDimitry Andric LLVM_DEBUG(dbgs() << "PrintReader\n"); 968bdd1243dSDimitry Andric } 969