Path: blob/main/contrib/llvm-project/llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp
35295 views
//===-- LVBinaryReader.cpp ------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This implements the LVBinaryReader class.9//10//===----------------------------------------------------------------------===//1112#include "llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h"13#include "llvm/Support/Errc.h"14#include "llvm/Support/FormatAdapters.h"15#include "llvm/Support/FormatVariadic.h"1617using namespace llvm;18using namespace llvm::logicalview;1920#define DEBUG_TYPE "BinaryReader"2122// Function names extracted from the object symbol table.23void LVSymbolTable::add(StringRef Name, LVScope *Function,24LVSectionIndex SectionIndex) {25std::string SymbolName(Name);26if (SymbolNames.find(SymbolName) == SymbolNames.end()) {27SymbolNames.emplace(28std::piecewise_construct, std::forward_as_tuple(SymbolName),29std::forward_as_tuple(Function, 0, SectionIndex, false));30} else {31// Update a recorded entry with its logical scope and section index.32SymbolNames[SymbolName].Scope = Function;33if (SectionIndex)34SymbolNames[SymbolName].SectionIndex = SectionIndex;35}3637if (Function && SymbolNames[SymbolName].IsComdat)38Function->setIsComdat();3940LLVM_DEBUG({ print(dbgs()); });41}4243void LVSymbolTable::add(StringRef Name, LVAddress Address,44LVSectionIndex SectionIndex, bool IsComdat) {45std::string SymbolName(Name);46if (SymbolNames.find(SymbolName) == SymbolNames.end())47SymbolNames.emplace(48std::piecewise_construct, std::forward_as_tuple(SymbolName),49std::forward_as_tuple(nullptr, Address, SectionIndex, IsComdat));50else51// Update a recorded symbol name with its logical scope.52SymbolNames[SymbolName].Address = Address;5354LVScope *Function = SymbolNames[SymbolName].Scope;55if (Function && IsComdat)56Function->setIsComdat();57LLVM_DEBUG({ print(dbgs()); });58}5960LVSectionIndex LVSymbolTable::update(LVScope *Function) {61LVSectionIndex SectionIndex = getReader().getDotTextSectionIndex();62StringRef Name = Function->getLinkageName();63if (Name.empty())64Name = Function->getName();65std::string SymbolName(Name);6667if (SymbolName.empty() || (SymbolNames.find(SymbolName) == SymbolNames.end()))68return SectionIndex;6970// Update a recorded entry with its logical scope, only if the scope has71// ranges. That is the case when in DWARF there are 2 DIEs connected via72// the DW_AT_specification.73if (Function->getHasRanges()) {74SymbolNames[SymbolName].Scope = Function;75SectionIndex = SymbolNames[SymbolName].SectionIndex;76} else {77SectionIndex = UndefinedSectionIndex;78}7980if (SymbolNames[SymbolName].IsComdat)81Function->setIsComdat();8283LLVM_DEBUG({ print(dbgs()); });84return SectionIndex;85}8687const LVSymbolTableEntry &LVSymbolTable::getEntry(StringRef Name) {88static LVSymbolTableEntry Empty = LVSymbolTableEntry();89LVSymbolNames::iterator Iter = SymbolNames.find(std::string(Name));90return Iter != SymbolNames.end() ? Iter->second : Empty;91}92LVAddress LVSymbolTable::getAddress(StringRef Name) {93LVSymbolNames::iterator Iter = SymbolNames.find(std::string(Name));94return Iter != SymbolNames.end() ? Iter->second.Address : 0;95}96LVSectionIndex LVSymbolTable::getIndex(StringRef Name) {97LVSymbolNames::iterator Iter = SymbolNames.find(std::string(Name));98return Iter != SymbolNames.end() ? Iter->second.SectionIndex99: getReader().getDotTextSectionIndex();100}101bool LVSymbolTable::getIsComdat(StringRef Name) {102LVSymbolNames::iterator Iter = SymbolNames.find(std::string(Name));103return Iter != SymbolNames.end() ? Iter->second.IsComdat : false;104}105106void LVSymbolTable::print(raw_ostream &OS) {107OS << "Symbol Table\n";108for (LVSymbolNames::reference Entry : SymbolNames) {109LVSymbolTableEntry &SymbolName = Entry.second;110LVScope *Scope = SymbolName.Scope;111LVOffset Offset = Scope ? Scope->getOffset() : 0;112OS << "Index: " << hexValue(SymbolName.SectionIndex, 5)113<< " Comdat: " << (SymbolName.IsComdat ? "Y" : "N")114<< " Scope: " << hexValue(Offset)115<< " Address: " << hexValue(SymbolName.Address)116<< " Name: " << Entry.first << "\n";117}118}119120void LVBinaryReader::addToSymbolTable(StringRef Name, LVScope *Function,121LVSectionIndex SectionIndex) {122SymbolTable.add(Name, Function, SectionIndex);123}124void LVBinaryReader::addToSymbolTable(StringRef Name, LVAddress Address,125LVSectionIndex SectionIndex,126bool IsComdat) {127SymbolTable.add(Name, Address, SectionIndex, IsComdat);128}129LVSectionIndex LVBinaryReader::updateSymbolTable(LVScope *Function) {130return SymbolTable.update(Function);131}132133const LVSymbolTableEntry &LVBinaryReader::getSymbolTableEntry(StringRef Name) {134return SymbolTable.getEntry(Name);135}136LVAddress LVBinaryReader::getSymbolTableAddress(StringRef Name) {137return SymbolTable.getAddress(Name);138}139LVSectionIndex LVBinaryReader::getSymbolTableIndex(StringRef Name) {140return SymbolTable.getIndex(Name);141}142bool LVBinaryReader::getSymbolTableIsComdat(StringRef Name) {143return SymbolTable.getIsComdat(Name);144}145146void LVBinaryReader::mapVirtualAddress(const object::ObjectFile &Obj) {147for (const object::SectionRef &Section : Obj.sections()) {148LLVM_DEBUG({149Expected<StringRef> SectionNameOrErr = Section.getName();150StringRef Name;151if (!SectionNameOrErr)152consumeError(SectionNameOrErr.takeError());153else154Name = *SectionNameOrErr;155dbgs() << "Index: " << format_decimal(Section.getIndex(), 3) << ", "156<< "Address: " << hexValue(Section.getAddress()) << ", "157<< "Size: " << hexValue(Section.getSize()) << ", "158<< "Name: " << Name << "\n";159dbgs() << "isCompressed: " << Section.isCompressed() << ", "160<< "isText: " << Section.isText() << ", "161<< "isData: " << Section.isData() << ", "162<< "isBSS: " << Section.isBSS() << ", "163<< "isVirtual: " << Section.isVirtual() << "\n";164dbgs() << "isBitcode: " << Section.isBitcode() << ", "165<< "isStripped: " << Section.isStripped() << ", "166<< "isBerkeleyText: " << Section.isBerkeleyText() << ", "167<< "isBerkeleyData: " << Section.isBerkeleyData() << ", "168<< "isDebugSection: " << Section.isDebugSection() << "\n";169dbgs() << "\n";170});171172if (!Section.isText() || Section.isVirtual() || !Section.getSize())173continue;174175// Record section information required for symbol resolution.176// Note: The section index returned by 'getIndex()' is one based.177Sections.emplace(Section.getIndex(), Section);178addSectionAddress(Section);179180// Identify the ".text" section.181Expected<StringRef> SectionNameOrErr = Section.getName();182if (!SectionNameOrErr) {183consumeError(SectionNameOrErr.takeError());184continue;185}186if (*SectionNameOrErr == ".text" || *SectionNameOrErr == "CODE" ||187*SectionNameOrErr == ".code") {188DotTextSectionIndex = Section.getIndex();189// If the object is WebAssembly, update the address offset that190// will be added to DWARF DW_AT_* attributes.191if (Obj.isWasm())192WasmCodeSectionOffset = Section.getAddress();193}194}195196// Process the symbol table.197mapRangeAddress(Obj);198199LLVM_DEBUG({200dbgs() << "\nSections Information:\n";201for (LVSections::reference Entry : Sections) {202LVSectionIndex SectionIndex = Entry.first;203const object::SectionRef Section = Entry.second;204Expected<StringRef> SectionNameOrErr = Section.getName();205if (!SectionNameOrErr)206consumeError(SectionNameOrErr.takeError());207dbgs() << "\nIndex: " << format_decimal(SectionIndex, 3)208<< " Name: " << *SectionNameOrErr << "\n"209<< "Size: " << hexValue(Section.getSize()) << "\n"210<< "VirtualAddress: " << hexValue(VirtualAddress) << "\n"211<< "SectionAddress: " << hexValue(Section.getAddress()) << "\n";212}213dbgs() << "\nObject Section Information:\n";214for (LVSectionAddresses::const_reference Entry : SectionAddresses)215dbgs() << "[" << hexValue(Entry.first) << ":"216<< hexValue(Entry.first + Entry.second.getSize())217<< "] Size: " << hexValue(Entry.second.getSize()) << "\n";218});219}220221void LVBinaryReader::mapVirtualAddress(const object::COFFObjectFile &COFFObj) {222ErrorOr<uint64_t> ImageBase = COFFObj.getImageBase();223if (ImageBase)224ImageBaseAddress = ImageBase.get();225226LLVM_DEBUG({227dbgs() << "ImageBaseAddress: " << hexValue(ImageBaseAddress) << "\n";228});229230uint32_t Flags = COFF::IMAGE_SCN_CNT_CODE | COFF::IMAGE_SCN_LNK_COMDAT;231232for (const object::SectionRef &Section : COFFObj.sections()) {233if (!Section.isText() || Section.isVirtual() || !Section.getSize())234continue;235236const object::coff_section *COFFSection = COFFObj.getCOFFSection(Section);237VirtualAddress = COFFSection->VirtualAddress;238bool IsComdat = (COFFSection->Characteristics & Flags) == Flags;239240// Record section information required for symbol resolution.241// Note: The section index returned by 'getIndex()' is zero based.242Sections.emplace(Section.getIndex() + 1, Section);243addSectionAddress(Section);244245// Additional initialization on the specific object format.246mapRangeAddress(COFFObj, Section, IsComdat);247}248249LLVM_DEBUG({250dbgs() << "\nSections Information:\n";251for (LVSections::reference Entry : Sections) {252LVSectionIndex SectionIndex = Entry.first;253const object::SectionRef Section = Entry.second;254const object::coff_section *COFFSection = COFFObj.getCOFFSection(Section);255Expected<StringRef> SectionNameOrErr = Section.getName();256if (!SectionNameOrErr)257consumeError(SectionNameOrErr.takeError());258dbgs() << "\nIndex: " << format_decimal(SectionIndex, 3)259<< " Name: " << *SectionNameOrErr << "\n"260<< "Size: " << hexValue(Section.getSize()) << "\n"261<< "VirtualAddress: " << hexValue(VirtualAddress) << "\n"262<< "SectionAddress: " << hexValue(Section.getAddress()) << "\n"263<< "PointerToRawData: " << hexValue(COFFSection->PointerToRawData)264<< "\n"265<< "SizeOfRawData: " << hexValue(COFFSection->SizeOfRawData)266<< "\n";267}268dbgs() << "\nObject Section Information:\n";269for (LVSectionAddresses::const_reference Entry : SectionAddresses)270dbgs() << "[" << hexValue(Entry.first) << ":"271<< hexValue(Entry.first + Entry.second.getSize())272<< "] Size: " << hexValue(Entry.second.getSize()) << "\n";273});274}275276Error LVBinaryReader::loadGenericTargetInfo(StringRef TheTriple,277StringRef TheFeatures) {278std::string TargetLookupError;279const Target *TheTarget =280TargetRegistry::lookupTarget(std::string(TheTriple), TargetLookupError);281if (!TheTarget)282return createStringError(errc::invalid_argument, TargetLookupError.c_str());283284// Register information.285MCRegisterInfo *RegisterInfo = TheTarget->createMCRegInfo(TheTriple);286if (!RegisterInfo)287return createStringError(errc::invalid_argument,288"no register info for target " + TheTriple);289MRI.reset(RegisterInfo);290291// Assembler properties and features.292MCTargetOptions MCOptions;293MCAsmInfo *AsmInfo(TheTarget->createMCAsmInfo(*MRI, TheTriple, MCOptions));294if (!AsmInfo)295return createStringError(errc::invalid_argument,296"no assembly info for target " + TheTriple);297MAI.reset(AsmInfo);298299// Target subtargets.300StringRef CPU;301MCSubtargetInfo *SubtargetInfo(302TheTarget->createMCSubtargetInfo(TheTriple, CPU, TheFeatures));303if (!SubtargetInfo)304return createStringError(errc::invalid_argument,305"no subtarget info for target " + TheTriple);306STI.reset(SubtargetInfo);307308// Instructions Info.309MCInstrInfo *InstructionInfo(TheTarget->createMCInstrInfo());310if (!InstructionInfo)311return createStringError(errc::invalid_argument,312"no instruction info for target " + TheTriple);313MII.reset(InstructionInfo);314315MC = std::make_unique<MCContext>(Triple(TheTriple), MAI.get(), MRI.get(),316STI.get());317318// Assembler.319MCDisassembler *DisAsm(TheTarget->createMCDisassembler(*STI, *MC));320if (!DisAsm)321return createStringError(errc::invalid_argument,322"no disassembler for target " + TheTriple);323MD.reset(DisAsm);324325MCInstPrinter *InstructionPrinter(TheTarget->createMCInstPrinter(326Triple(TheTriple), AsmInfo->getAssemblerDialect(), *MAI, *MII, *MRI));327if (!InstructionPrinter)328return createStringError(errc::invalid_argument,329"no target assembly language printer for target " +330TheTriple);331MIP.reset(InstructionPrinter);332InstructionPrinter->setPrintImmHex(true);333334return Error::success();335}336337Expected<std::pair<uint64_t, object::SectionRef>>338LVBinaryReader::getSection(LVScope *Scope, LVAddress Address,339LVSectionIndex SectionIndex) {340// Return the 'text' section with the code for this logical scope.341// COFF: SectionIndex is zero. Use 'SectionAddresses' data.342// ELF: SectionIndex is the section index in the file.343if (SectionIndex) {344LVSections::iterator Iter = Sections.find(SectionIndex);345if (Iter == Sections.end()) {346return createStringError(errc::invalid_argument,347"invalid section index for: '%s'",348Scope->getName().str().c_str());349}350const object::SectionRef Section = Iter->second;351return std::make_pair(Section.getAddress(), Section);352}353354// Ensure a valid starting address for the public names.355LVSectionAddresses::const_iterator Iter =356SectionAddresses.upper_bound(Address);357if (Iter == SectionAddresses.begin())358return createStringError(errc::invalid_argument,359"invalid section address for: '%s'",360Scope->getName().str().c_str());361362// Get section that contains the code for this function.363Iter = SectionAddresses.lower_bound(Address);364if (Iter != SectionAddresses.begin())365--Iter;366return std::make_pair(Iter->first, Iter->second);367}368369void LVBinaryReader::addSectionRange(LVSectionIndex SectionIndex,370LVScope *Scope) {371LVRange *ScopesWithRanges = getSectionRanges(SectionIndex);372ScopesWithRanges->addEntry(Scope);373}374375void LVBinaryReader::addSectionRange(LVSectionIndex SectionIndex,376LVScope *Scope, LVAddress LowerAddress,377LVAddress UpperAddress) {378LVRange *ScopesWithRanges = getSectionRanges(SectionIndex);379ScopesWithRanges->addEntry(Scope, LowerAddress, UpperAddress);380}381382LVRange *LVBinaryReader::getSectionRanges(LVSectionIndex SectionIndex) {383// Check if we already have a mapping for this section index.384LVSectionRanges::iterator IterSection = SectionRanges.find(SectionIndex);385if (IterSection == SectionRanges.end())386IterSection =387SectionRanges.emplace(SectionIndex, std::make_unique<LVRange>()).first;388LVRange *Range = IterSection->second.get();389assert(Range && "Range is null.");390return Range;391}392393Error LVBinaryReader::createInstructions(LVScope *Scope,394LVSectionIndex SectionIndex,395const LVNameInfo &NameInfo) {396assert(Scope && "Scope is null.");397398// Skip stripped functions.399if (Scope->getIsDiscarded())400return Error::success();401402// Find associated address and size for the given function entry point.403LVAddress Address = NameInfo.first;404uint64_t Size = NameInfo.second;405406LLVM_DEBUG({407dbgs() << "\nPublic Name instructions: '" << Scope->getName() << "' / '"408<< Scope->getLinkageName() << "'\n"409<< "DIE Offset: " << hexValue(Scope->getOffset()) << " Range: ["410<< hexValue(Address) << ":" << hexValue(Address + Size) << "]\n";411});412413Expected<std::pair<uint64_t, const object::SectionRef>> SectionOrErr =414getSection(Scope, Address, SectionIndex);415if (!SectionOrErr)416return SectionOrErr.takeError();417const object::SectionRef Section = (*SectionOrErr).second;418uint64_t SectionAddress = (*SectionOrErr).first;419420Expected<StringRef> SectionContentsOrErr = Section.getContents();421if (!SectionContentsOrErr)422return SectionOrErr.takeError();423424// There are cases where the section size is smaller than the [LowPC,HighPC]425// range; it causes us to decode invalid addresses. The recorded size in the426// logical scope is one less than the real size.427LLVM_DEBUG({428dbgs() << " Size: " << hexValue(Size)429<< ", Section Size: " << hexValue(Section.getSize()) << "\n";430});431Size = std::min(Size + 1, Section.getSize());432433ArrayRef<uint8_t> Bytes = arrayRefFromStringRef(*SectionContentsOrErr);434uint64_t Offset = Address - SectionAddress;435uint8_t const *Begin = Bytes.data() + Offset;436uint8_t const *End = Bytes.data() + Offset + Size;437438LLVM_DEBUG({439Expected<StringRef> SectionNameOrErr = Section.getName();440if (!SectionNameOrErr)441consumeError(SectionNameOrErr.takeError());442else443dbgs() << "Section Index: " << hexValue(Section.getIndex()) << " ["444<< hexValue((uint64_t)Section.getAddress()) << ":"445<< hexValue((uint64_t)Section.getAddress() + Section.getSize(), 10)446<< "] Name: '" << *SectionNameOrErr << "'\n"447<< "Begin: " << hexValue((uint64_t)Begin)448<< ", End: " << hexValue((uint64_t)End) << "\n";449});450451// Address for first instruction line.452LVAddress FirstAddress = Address;453auto InstructionsSP = std::make_unique<LVLines>();454LVLines &Instructions = *InstructionsSP;455DiscoveredLines.emplace_back(std::move(InstructionsSP));456457while (Begin < End) {458MCInst Instruction;459uint64_t BytesConsumed = 0;460SmallVector<char, 64> InsnStr;461raw_svector_ostream Annotations(InsnStr);462MCDisassembler::DecodeStatus const S =463MD->getInstruction(Instruction, BytesConsumed,464ArrayRef<uint8_t>(Begin, End), Address, outs());465switch (S) {466case MCDisassembler::Fail:467LLVM_DEBUG({ dbgs() << "Invalid instruction\n"; });468if (BytesConsumed == 0)469// Skip invalid bytes470BytesConsumed = 1;471break;472case MCDisassembler::SoftFail:473LLVM_DEBUG({ dbgs() << "Potentially undefined instruction:"; });474[[fallthrough]];475case MCDisassembler::Success: {476std::string Buffer;477raw_string_ostream Stream(Buffer);478StringRef AnnotationsStr = Annotations.str();479MIP->printInst(&Instruction, Address, AnnotationsStr, *STI, Stream);480LLVM_DEBUG({481std::string BufferCodes;482raw_string_ostream StreamCodes(BufferCodes);483StreamCodes << format_bytes(484ArrayRef<uint8_t>(Begin, Begin + BytesConsumed), std::nullopt, 16,48516);486dbgs() << "[" << hexValue((uint64_t)Begin) << "] "487<< "Size: " << format_decimal(BytesConsumed, 2) << " ("488<< formatv("{0}",489fmt_align(StreamCodes.str(), AlignStyle::Left, 32))490<< ") " << hexValue((uint64_t)Address) << ": " << Stream.str()491<< "\n";492});493// Here we add logical lines to the Instructions. Later on,494// the 'processLines()' function will move each created logical line495// to its enclosing logical scope, using the debug ranges information496// and they will be released when its scope parent is deleted.497LVLineAssembler *Line = createLineAssembler();498Line->setAddress(Address);499Line->setName(StringRef(Stream.str()).trim());500Instructions.push_back(Line);501break;502}503}504Address += BytesConsumed;505Begin += BytesConsumed;506}507508LLVM_DEBUG({509size_t Index = 0;510dbgs() << "\nSectionIndex: " << format_decimal(SectionIndex, 3)511<< " Scope DIE: " << hexValue(Scope->getOffset()) << "\n"512<< "Address: " << hexValue(FirstAddress)513<< format(" - Collected instructions lines: %d\n",514Instructions.size());515for (const LVLine *Line : Instructions)516dbgs() << format_decimal(++Index, 5) << ": "517<< hexValue(Line->getOffset()) << ", (" << Line->getName()518<< ")\n";519});520521// The scope in the assembler names is linked to its own instructions.522ScopeInstructions.add(SectionIndex, Scope, &Instructions);523AssemblerMappings.add(SectionIndex, FirstAddress, Scope);524525return Error::success();526}527528Error LVBinaryReader::createInstructions(LVScope *Function,529LVSectionIndex SectionIndex) {530if (!options().getPrintInstructions())531return Error::success();532533LVNameInfo Name = CompileUnit->findPublicName(Function);534if (Name.first != LVAddress(UINT64_MAX))535return createInstructions(Function, SectionIndex, Name);536537return Error::success();538}539540Error LVBinaryReader::createInstructions() {541if (!options().getPrintInstructions())542return Error::success();543544LLVM_DEBUG({545size_t Index = 1;546dbgs() << "\nPublic Names (Scope):\n";547for (LVPublicNames::const_reference Name : CompileUnit->getPublicNames()) {548LVScope *Scope = Name.first;549const LVNameInfo &NameInfo = Name.second;550LVAddress Address = NameInfo.first;551uint64_t Size = NameInfo.second;552dbgs() << format_decimal(Index++, 5) << ": "553<< "DIE Offset: " << hexValue(Scope->getOffset()) << " Range: ["554<< hexValue(Address) << ":" << hexValue(Address + Size) << "] "555<< "Name: '" << Scope->getName() << "' / '"556<< Scope->getLinkageName() << "'\n";557}558});559560// For each public name in the current compile unit, create the line561// records that represent the executable instructions.562for (LVPublicNames::const_reference Name : CompileUnit->getPublicNames()) {563LVScope *Scope = Name.first;564// The symbol table extracted from the object file always contains a565// non-empty name (linkage name). However, the logical scope does not566// guarantee to have a name for the linkage name (main is one case).567// For those cases, set the linkage name the same as the name.568if (!Scope->getLinkageNameIndex())569Scope->setLinkageName(Scope->getName());570LVSectionIndex SectionIndex = getSymbolTableIndex(Scope->getLinkageName());571if (Error Err = createInstructions(Scope, SectionIndex, Name.second))572return Err;573}574575return Error::success();576}577578// During the traversal of the debug information sections, we created the579// logical lines representing the disassembled instructions from the text580// section and the logical lines representing the line records from the581// debug line section. Using the ranges associated with the logical scopes,582// we will allocate those logical lines to their logical scopes.583void LVBinaryReader::processLines(LVLines *DebugLines,584LVSectionIndex SectionIndex,585LVScope *Function) {586assert(DebugLines && "DebugLines is null.");587588// Just return if this compilation unit does not have any line records589// and no instruction lines were created.590if (DebugLines->empty() && !options().getPrintInstructions())591return;592593// Merge the debug lines and instruction lines using their text address;594// the logical line representing the debug line record is followed by the595// line(s) representing the disassembled instructions, whose addresses are596// equal or greater that the line address and less than the address of the597// next debug line record.598LLVM_DEBUG({599size_t Index = 1;600size_t PerLine = 4;601dbgs() << format("\nProcess debug lines: %d\n", DebugLines->size());602for (const LVLine *Line : *DebugLines) {603dbgs() << format_decimal(Index, 5) << ": " << hexValue(Line->getOffset())604<< ", (" << Line->getLineNumber() << ")"605<< ((Index % PerLine) ? " " : "\n");606++Index;607}608dbgs() << ((Index % PerLine) ? "\n" : "");609});610611bool TraverseLines = true;612LVLines::iterator Iter = DebugLines->begin();613while (TraverseLines && Iter != DebugLines->end()) {614uint64_t DebugAddress = (*Iter)->getAddress();615616// Get the function with an entry point that matches this line and617// its associated assembler entries. In the case of COMDAT, the input618// 'Function' is not null. Use it to find its address ranges.619LVScope *Scope = Function;620if (!Function) {621Scope = AssemblerMappings.find(SectionIndex, DebugAddress);622if (!Scope) {623++Iter;624continue;625}626}627628// Get the associated instructions for the found 'Scope'.629LVLines InstructionLines;630LVLines *Lines = ScopeInstructions.find(SectionIndex, Scope);631if (Lines)632InstructionLines = std::move(*Lines);633634LLVM_DEBUG({635size_t Index = 0;636dbgs() << "\nSectionIndex: " << format_decimal(SectionIndex, 3)637<< " Scope DIE: " << hexValue(Scope->getOffset()) << "\n"638<< format("Process instruction lines: %d\n",639InstructionLines.size());640for (const LVLine *Line : InstructionLines)641dbgs() << format_decimal(++Index, 5) << ": "642<< hexValue(Line->getOffset()) << ", (" << Line->getName()643<< ")\n";644});645646// Continue with next debug line if there are not instructions lines.647if (InstructionLines.empty()) {648++Iter;649continue;650}651652for (LVLine *InstructionLine : InstructionLines) {653uint64_t InstructionAddress = InstructionLine->getAddress();654LLVM_DEBUG({655dbgs() << "Instruction address: " << hexValue(InstructionAddress)656<< "\n";657});658if (TraverseLines) {659while (Iter != DebugLines->end()) {660DebugAddress = (*Iter)->getAddress();661LLVM_DEBUG({662bool IsDebug = (*Iter)->getIsLineDebug();663dbgs() << "Line " << (IsDebug ? "dbg:" : "ins:") << " ["664<< hexValue(DebugAddress) << "]";665if (IsDebug)666dbgs() << format(" %d", (*Iter)->getLineNumber());667dbgs() << "\n";668});669// Instruction address before debug line.670if (InstructionAddress < DebugAddress) {671LLVM_DEBUG({672dbgs() << "Inserted instruction address: "673<< hexValue(InstructionAddress) << " before line: "674<< format("%d", (*Iter)->getLineNumber()) << " ["675<< hexValue(DebugAddress) << "]\n";676});677Iter = DebugLines->insert(Iter, InstructionLine);678// The returned iterator points to the inserted instruction.679// Skip it and point to the line acting as reference.680++Iter;681break;682}683++Iter;684}685if (Iter == DebugLines->end()) {686// We have reached the end of the source lines and the current687// instruction line address is greater than the last source line.688TraverseLines = false;689DebugLines->push_back(InstructionLine);690}691} else {692DebugLines->push_back(InstructionLine);693}694}695}696697LLVM_DEBUG({698dbgs() << format("Lines after merge: %d\n", DebugLines->size());699size_t Index = 0;700for (const LVLine *Line : *DebugLines) {701dbgs() << format_decimal(++Index, 5) << ": "702<< hexValue(Line->getOffset()) << ", ("703<< ((Line->getIsLineDebug())704? Line->lineNumberAsStringStripped(/*ShowZero=*/true)705: Line->getName())706<< ")\n";707}708});709710// If this compilation unit does not have line records, traverse its scopes711// and take any collected instruction lines as the working set in order712// to move them to their associated scope.713if (DebugLines->empty()) {714if (const LVScopes *Scopes = CompileUnit->getScopes())715for (LVScope *Scope : *Scopes) {716LVLines *Lines = ScopeInstructions.find(Scope);717if (Lines) {718719LLVM_DEBUG({720size_t Index = 0;721dbgs() << "\nSectionIndex: " << format_decimal(SectionIndex, 3)722<< " Scope DIE: " << hexValue(Scope->getOffset()) << "\n"723<< format("Instruction lines: %d\n", Lines->size());724for (const LVLine *Line : *Lines)725dbgs() << format_decimal(++Index, 5) << ": "726<< hexValue(Line->getOffset()) << ", (" << Line->getName()727<< ")\n";728});729730if (Scope->getIsArtificial()) {731// Add the instruction lines to their artificial scope.732for (LVLine *Line : *Lines)733Scope->addElement(Line);734} else {735DebugLines->append(*Lines);736}737Lines->clear();738}739}740}741742LVRange *ScopesWithRanges = getSectionRanges(SectionIndex);743ScopesWithRanges->startSearch();744745// Process collected lines.746LVScope *Scope;747for (LVLine *Line : *DebugLines) {748// Using the current line address, get its associated lexical scope and749// add the line information to it.750Scope = ScopesWithRanges->getEntry(Line->getAddress());751if (!Scope) {752// If missing scope, use the compile unit.753Scope = CompileUnit;754LLVM_DEBUG({755dbgs() << "Adding line to CU: " << hexValue(Line->getOffset()) << ", ("756<< ((Line->getIsLineDebug())757? Line->lineNumberAsStringStripped(/*ShowZero=*/true)758: Line->getName())759<< ")\n";760});761}762763// Add line object to scope.764Scope->addElement(Line);765766// Report any line zero.767if (options().getWarningLines() && Line->getIsLineDebug() &&768!Line->getLineNumber())769CompileUnit->addLineZero(Line);770771// Some compilers generate ranges in the compile unit; other compilers772// only DW_AT_low_pc/DW_AT_high_pc. In order to correctly map global773// variables, we need to generate the map ranges for the compile unit.774// If we use the ranges stored at the scope level, there are cases where775// the address referenced by a symbol location, is not in the enclosing776// scope, but in an outer one. By using the ranges stored in the compile777// unit, we can catch all those addresses.778if (Line->getIsLineDebug())779CompileUnit->addMapping(Line, SectionIndex);780781// Resolve any given pattern.782patterns().resolvePatternMatch(Line);783}784785ScopesWithRanges->endSearch();786}787788void LVBinaryReader::processLines(LVLines *DebugLines,789LVSectionIndex SectionIndex) {790assert(DebugLines && "DebugLines is null.");791if (DebugLines->empty() && !ScopeInstructions.findMap(SectionIndex))792return;793794// If the Compile Unit does not contain comdat functions, use the whole795// set of debug lines, as the addresses don't have conflicts.796if (!CompileUnit->getHasComdatScopes()) {797processLines(DebugLines, SectionIndex, nullptr);798return;799}800801// Find the indexes for the lines whose address is zero.802std::vector<size_t> AddressZero;803LVLines::iterator It =804std::find_if(std::begin(*DebugLines), std::end(*DebugLines),805[](LVLine *Line) { return !Line->getAddress(); });806while (It != std::end(*DebugLines)) {807AddressZero.emplace_back(std::distance(std::begin(*DebugLines), It));808It = std::find_if(std::next(It), std::end(*DebugLines),809[](LVLine *Line) { return !Line->getAddress(); });810}811812// If the set of debug lines does not contain any line with address zero,813// use the whole set. It means we are dealing with an initialization814// section from a fully linked binary.815if (AddressZero.empty()) {816processLines(DebugLines, SectionIndex, nullptr);817return;818}819820// The Compile unit contains comdat functions. Traverse the collected821// debug lines and identify logical groups based on their start and822// address. Each group starts with a zero address.823// Begin, End, Address, IsDone.824using LVBucket = std::tuple<size_t, size_t, LVAddress, bool>;825std::vector<LVBucket> Buckets;826827LVAddress Address;828size_t Begin = 0;829size_t End = 0;830size_t Index = 0;831for (Index = 0; Index < AddressZero.size() - 1; ++Index) {832Begin = AddressZero[Index];833End = AddressZero[Index + 1] - 1;834Address = (*DebugLines)[End]->getAddress();835Buckets.emplace_back(Begin, End, Address, false);836}837838// Add the last bucket.839if (Index) {840Begin = AddressZero[Index];841End = DebugLines->size() - 1;842Address = (*DebugLines)[End]->getAddress();843Buckets.emplace_back(Begin, End, Address, false);844}845846LLVM_DEBUG({847dbgs() << "\nDebug Lines buckets: " << Buckets.size() << "\n";848for (LVBucket &Bucket : Buckets) {849dbgs() << "Begin: " << format_decimal(std::get<0>(Bucket), 5) << ", "850<< "End: " << format_decimal(std::get<1>(Bucket), 5) << ", "851<< "Address: " << hexValue(std::get<2>(Bucket)) << "\n";852}853});854855// Traverse the sections and buckets looking for matches on the section856// sizes. In the unlikely event of different buckets with the same size857// process them in order and mark them as done.858LVLines Group;859for (LVSections::reference Entry : Sections) {860LVSectionIndex SectionIndex = Entry.first;861const object::SectionRef Section = Entry.second;862uint64_t Size = Section.getSize();863LLVM_DEBUG({864dbgs() << "\nSection Index: " << format_decimal(SectionIndex, 3)865<< " , Section Size: " << hexValue(Section.getSize())866<< " , Section Address: " << hexValue(Section.getAddress())867<< "\n";868});869870for (LVBucket &Bucket : Buckets) {871if (std::get<3>(Bucket))872// Already done for previous section.873continue;874if (Size == std::get<2>(Bucket)) {875// We have a match on the section size.876Group.clear();877LVLines::iterator IterStart = DebugLines->begin() + std::get<0>(Bucket);878LVLines::iterator IterEnd =879DebugLines->begin() + std::get<1>(Bucket) + 1;880for (LVLines::iterator Iter = IterStart; Iter < IterEnd; ++Iter)881Group.push_back(*Iter);882processLines(&Group, SectionIndex, /*Function=*/nullptr);883std::get<3>(Bucket) = true;884break;885}886}887}888}889890// Traverse the scopes for the given 'Function' looking for any inlined891// scopes with inlined lines, which are found in 'CUInlineeLines'.892void LVBinaryReader::includeInlineeLines(LVSectionIndex SectionIndex,893LVScope *Function) {894SmallVector<LVInlineeLine::iterator> InlineeIters;895std::function<void(LVScope * Parent)> FindInlinedScopes =896[&](LVScope *Parent) {897if (const LVScopes *Scopes = Parent->getScopes())898for (LVScope *Scope : *Scopes) {899LVInlineeLine::iterator Iter = CUInlineeLines.find(Scope);900if (Iter != CUInlineeLines.end())901InlineeIters.push_back(Iter);902FindInlinedScopes(Scope);903}904};905906// Find all inlined scopes for the given 'Function'.907FindInlinedScopes(Function);908for (LVInlineeLine::iterator InlineeIter : InlineeIters) {909LVScope *Scope = InlineeIter->first;910addToSymbolTable(Scope->getLinkageName(), Scope, SectionIndex);911912// TODO: Convert this into a reference.913LVLines *InlineeLines = InlineeIter->second.get();914LLVM_DEBUG({915dbgs() << "Inlined lines for: " << Scope->getName() << "\n";916for (const LVLine *Line : *InlineeLines)917dbgs() << "[" << hexValue(Line->getAddress()) << "] "918<< Line->getLineNumber() << "\n";919dbgs() << format("Debug lines: %d\n", CULines.size());920for (const LVLine *Line : CULines)921dbgs() << "Line address: " << hexValue(Line->getOffset()) << ", ("922<< Line->getLineNumber() << ")\n";923;924});925926// The inlined lines must be merged using its address, in order to keep927// the real order of the instructions. The inlined lines are mixed with928// the other non-inlined lines.929if (InlineeLines->size()) {930// First address of inlinee code.931uint64_t InlineeStart = (InlineeLines->front())->getAddress();932LVLines::iterator Iter = std::find_if(933CULines.begin(), CULines.end(), [&](LVLine *Item) -> bool {934return Item->getAddress() == InlineeStart;935});936if (Iter != CULines.end()) {937// 'Iter' points to the line where the inlined function is called.938// Emulate the DW_AT_call_line attribute.939Scope->setCallLineNumber((*Iter)->getLineNumber());940// Mark the referenced line as the start of the inlined function.941// Skip the first line during the insertion, as the address and942// line number as the same. Otherwise we have to erase and insert.943(*Iter)->setLineNumber((*InlineeLines->begin())->getLineNumber());944++Iter;945CULines.insert(Iter, InlineeLines->begin() + 1, InlineeLines->end());946}947}948949// Remove this set of lines from the container; each inlined function950// creates an unique set of lines. Remove only the created container.951CUInlineeLines.erase(InlineeIter);952InlineeLines->clear();953}954LLVM_DEBUG({955dbgs() << "Merged Inlined lines for: " << Function->getName() << "\n";956dbgs() << format("Debug lines: %d\n", CULines.size());957for (const LVLine *Line : CULines)958dbgs() << "Line address: " << hexValue(Line->getOffset()) << ", ("959<< Line->getLineNumber() << ")\n";960;961});962}963964void LVBinaryReader::print(raw_ostream &OS) const {965OS << "LVBinaryReader\n";966LLVM_DEBUG(dbgs() << "PrintReader\n");967}968969970