xref: /llvm-project/llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp (revision 5c9c281c251402fd65bb01717112cf22019ee409)
14f06d46fSCarlos Alberto Enciso //===-- LVBinaryReader.cpp ------------------------------------------------===//
24f06d46fSCarlos Alberto Enciso //
34f06d46fSCarlos Alberto Enciso // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44f06d46fSCarlos Alberto Enciso // See https://llvm.org/LICENSE.txt for license information.
54f06d46fSCarlos Alberto Enciso // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64f06d46fSCarlos Alberto Enciso //
74f06d46fSCarlos Alberto Enciso //===----------------------------------------------------------------------===//
84f06d46fSCarlos Alberto Enciso //
94f06d46fSCarlos Alberto Enciso // This implements the LVBinaryReader class.
104f06d46fSCarlos Alberto Enciso //
114f06d46fSCarlos Alberto Enciso //===----------------------------------------------------------------------===//
124f06d46fSCarlos Alberto Enciso 
134f06d46fSCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h"
144f06d46fSCarlos Alberto Enciso #include "llvm/Support/Errc.h"
154f06d46fSCarlos Alberto Enciso #include "llvm/Support/FormatAdapters.h"
164f06d46fSCarlos Alberto Enciso #include "llvm/Support/FormatVariadic.h"
174f06d46fSCarlos Alberto Enciso 
184f06d46fSCarlos Alberto Enciso using namespace llvm;
194f06d46fSCarlos Alberto Enciso using namespace llvm::logicalview;
204f06d46fSCarlos Alberto Enciso 
214f06d46fSCarlos Alberto Enciso #define DEBUG_TYPE "BinaryReader"
224f06d46fSCarlos Alberto Enciso 
234f06d46fSCarlos Alberto Enciso // Function names extracted from the object symbol table.
244f06d46fSCarlos Alberto Enciso void LVSymbolTable::add(StringRef Name, LVScope *Function,
254f06d46fSCarlos Alberto Enciso                         LVSectionIndex SectionIndex) {
264f06d46fSCarlos Alberto Enciso   std::string SymbolName(Name);
274f06d46fSCarlos Alberto Enciso   if (SymbolNames.find(SymbolName) == SymbolNames.end()) {
284f06d46fSCarlos Alberto Enciso     SymbolNames.emplace(
294f06d46fSCarlos Alberto Enciso         std::piecewise_construct, std::forward_as_tuple(SymbolName),
304f06d46fSCarlos Alberto Enciso         std::forward_as_tuple(Function, 0, SectionIndex, false));
314f06d46fSCarlos Alberto Enciso   } else {
324f06d46fSCarlos Alberto Enciso     // Update a recorded entry with its logical scope and section index.
334f06d46fSCarlos Alberto Enciso     SymbolNames[SymbolName].Scope = Function;
344f06d46fSCarlos Alberto Enciso     if (SectionIndex)
354f06d46fSCarlos Alberto Enciso       SymbolNames[SymbolName].SectionIndex = SectionIndex;
364f06d46fSCarlos Alberto Enciso   }
374f06d46fSCarlos Alberto Enciso 
384f06d46fSCarlos Alberto Enciso   if (Function && SymbolNames[SymbolName].IsComdat)
394f06d46fSCarlos Alberto Enciso     Function->setIsComdat();
404f06d46fSCarlos Alberto Enciso 
414f06d46fSCarlos Alberto Enciso   LLVM_DEBUG({ print(dbgs()); });
424f06d46fSCarlos Alberto Enciso }
434f06d46fSCarlos Alberto Enciso 
444f06d46fSCarlos Alberto Enciso void LVSymbolTable::add(StringRef Name, LVAddress Address,
454f06d46fSCarlos Alberto Enciso                         LVSectionIndex SectionIndex, bool IsComdat) {
464f06d46fSCarlos Alberto Enciso   std::string SymbolName(Name);
474f06d46fSCarlos Alberto Enciso   if (SymbolNames.find(SymbolName) == SymbolNames.end())
484f06d46fSCarlos Alberto Enciso     SymbolNames.emplace(
494f06d46fSCarlos Alberto Enciso         std::piecewise_construct, std::forward_as_tuple(SymbolName),
504f06d46fSCarlos Alberto Enciso         std::forward_as_tuple(nullptr, Address, SectionIndex, IsComdat));
514f06d46fSCarlos Alberto Enciso   else
524f06d46fSCarlos Alberto Enciso     // Update a recorded symbol name with its logical scope.
534f06d46fSCarlos Alberto Enciso     SymbolNames[SymbolName].Address = Address;
544f06d46fSCarlos Alberto Enciso 
554f06d46fSCarlos Alberto Enciso   LVScope *Function = SymbolNames[SymbolName].Scope;
564f06d46fSCarlos Alberto Enciso   if (Function && IsComdat)
574f06d46fSCarlos Alberto Enciso     Function->setIsComdat();
584f06d46fSCarlos Alberto Enciso   LLVM_DEBUG({ print(dbgs()); });
594f06d46fSCarlos Alberto Enciso }
604f06d46fSCarlos Alberto Enciso 
614f06d46fSCarlos Alberto Enciso LVSectionIndex LVSymbolTable::update(LVScope *Function) {
624f06d46fSCarlos Alberto Enciso   LVSectionIndex SectionIndex = getReader().getDotTextSectionIndex();
634f06d46fSCarlos Alberto Enciso   StringRef Name = Function->getLinkageName();
644f06d46fSCarlos Alberto Enciso   if (Name.empty())
654f06d46fSCarlos Alberto Enciso     Name = Function->getName();
664f06d46fSCarlos Alberto Enciso   std::string SymbolName(Name);
674f06d46fSCarlos Alberto Enciso 
684f06d46fSCarlos Alberto Enciso   if (SymbolName.empty() || (SymbolNames.find(SymbolName) == SymbolNames.end()))
694f06d46fSCarlos Alberto Enciso     return SectionIndex;
704f06d46fSCarlos Alberto Enciso 
714f06d46fSCarlos Alberto Enciso   // Update a recorded entry with its logical scope, only if the scope has
724f06d46fSCarlos Alberto Enciso   // ranges. That is the case when in DWARF there are 2 DIEs connected via
734f06d46fSCarlos Alberto Enciso   // the DW_AT_specification.
744f06d46fSCarlos Alberto Enciso   if (Function->getHasRanges()) {
754f06d46fSCarlos Alberto Enciso     SymbolNames[SymbolName].Scope = Function;
764f06d46fSCarlos Alberto Enciso     SectionIndex = SymbolNames[SymbolName].SectionIndex;
774f06d46fSCarlos Alberto Enciso   } else {
784f06d46fSCarlos Alberto Enciso     SectionIndex = UndefinedSectionIndex;
794f06d46fSCarlos Alberto Enciso   }
804f06d46fSCarlos Alberto Enciso 
814f06d46fSCarlos Alberto Enciso   if (SymbolNames[SymbolName].IsComdat)
824f06d46fSCarlos Alberto Enciso     Function->setIsComdat();
834f06d46fSCarlos Alberto Enciso 
844f06d46fSCarlos Alberto Enciso   LLVM_DEBUG({ print(dbgs()); });
854f06d46fSCarlos Alberto Enciso   return SectionIndex;
864f06d46fSCarlos Alberto Enciso }
874f06d46fSCarlos Alberto Enciso 
884f06d46fSCarlos Alberto Enciso const LVSymbolTableEntry &LVSymbolTable::getEntry(StringRef Name) {
894f06d46fSCarlos Alberto Enciso   static LVSymbolTableEntry Empty = LVSymbolTableEntry();
90*5c9c281cSKazu Hirata   LVSymbolNames::iterator Iter = SymbolNames.find(Name);
914f06d46fSCarlos Alberto Enciso   return Iter != SymbolNames.end() ? Iter->second : Empty;
924f06d46fSCarlos Alberto Enciso }
934f06d46fSCarlos Alberto Enciso LVAddress LVSymbolTable::getAddress(StringRef Name) {
94*5c9c281cSKazu Hirata   LVSymbolNames::iterator Iter = SymbolNames.find(Name);
954f06d46fSCarlos Alberto Enciso   return Iter != SymbolNames.end() ? Iter->second.Address : 0;
964f06d46fSCarlos Alberto Enciso }
974f06d46fSCarlos Alberto Enciso LVSectionIndex LVSymbolTable::getIndex(StringRef Name) {
98*5c9c281cSKazu Hirata   LVSymbolNames::iterator Iter = SymbolNames.find(Name);
994f06d46fSCarlos Alberto Enciso   return Iter != SymbolNames.end() ? Iter->second.SectionIndex
1004f06d46fSCarlos Alberto Enciso                                    : getReader().getDotTextSectionIndex();
1014f06d46fSCarlos Alberto Enciso }
1024f06d46fSCarlos Alberto Enciso bool LVSymbolTable::getIsComdat(StringRef Name) {
103*5c9c281cSKazu Hirata   LVSymbolNames::iterator Iter = SymbolNames.find(Name);
1044f06d46fSCarlos Alberto Enciso   return Iter != SymbolNames.end() ? Iter->second.IsComdat : false;
1054f06d46fSCarlos Alberto Enciso }
1064f06d46fSCarlos Alberto Enciso 
1074f06d46fSCarlos Alberto Enciso void LVSymbolTable::print(raw_ostream &OS) {
1084f06d46fSCarlos Alberto Enciso   OS << "Symbol Table\n";
1094f06d46fSCarlos Alberto Enciso   for (LVSymbolNames::reference Entry : SymbolNames) {
1104f06d46fSCarlos Alberto Enciso     LVSymbolTableEntry &SymbolName = Entry.second;
1114f06d46fSCarlos Alberto Enciso     LVScope *Scope = SymbolName.Scope;
1124f06d46fSCarlos Alberto Enciso     LVOffset Offset = Scope ? Scope->getOffset() : 0;
1134f06d46fSCarlos Alberto Enciso     OS << "Index: " << hexValue(SymbolName.SectionIndex, 5)
1144f06d46fSCarlos Alberto Enciso        << " Comdat: " << (SymbolName.IsComdat ? "Y" : "N")
1154f06d46fSCarlos Alberto Enciso        << " Scope: " << hexValue(Offset)
1164f06d46fSCarlos Alberto Enciso        << " Address: " << hexValue(SymbolName.Address)
1174f06d46fSCarlos Alberto Enciso        << " Name: " << Entry.first << "\n";
1184f06d46fSCarlos Alberto Enciso   }
1194f06d46fSCarlos Alberto Enciso }
1204f06d46fSCarlos Alberto Enciso 
1214f06d46fSCarlos Alberto Enciso void LVBinaryReader::addToSymbolTable(StringRef Name, LVScope *Function,
1224f06d46fSCarlos Alberto Enciso                                       LVSectionIndex SectionIndex) {
1234f06d46fSCarlos Alberto Enciso   SymbolTable.add(Name, Function, SectionIndex);
1244f06d46fSCarlos Alberto Enciso }
1254f06d46fSCarlos Alberto Enciso void LVBinaryReader::addToSymbolTable(StringRef Name, LVAddress Address,
1264f06d46fSCarlos Alberto Enciso                                       LVSectionIndex SectionIndex,
1274f06d46fSCarlos Alberto Enciso                                       bool IsComdat) {
1284f06d46fSCarlos Alberto Enciso   SymbolTable.add(Name, Address, SectionIndex, IsComdat);
1294f06d46fSCarlos Alberto Enciso }
1304f06d46fSCarlos Alberto Enciso LVSectionIndex LVBinaryReader::updateSymbolTable(LVScope *Function) {
1314f06d46fSCarlos Alberto Enciso   return SymbolTable.update(Function);
1324f06d46fSCarlos Alberto Enciso }
1334f06d46fSCarlos Alberto Enciso 
1344f06d46fSCarlos Alberto Enciso const LVSymbolTableEntry &LVBinaryReader::getSymbolTableEntry(StringRef Name) {
1354f06d46fSCarlos Alberto Enciso   return SymbolTable.getEntry(Name);
1364f06d46fSCarlos Alberto Enciso }
1374f06d46fSCarlos Alberto Enciso LVAddress LVBinaryReader::getSymbolTableAddress(StringRef Name) {
1384f06d46fSCarlos Alberto Enciso   return SymbolTable.getAddress(Name);
1394f06d46fSCarlos Alberto Enciso }
1404f06d46fSCarlos Alberto Enciso LVSectionIndex LVBinaryReader::getSymbolTableIndex(StringRef Name) {
1414f06d46fSCarlos Alberto Enciso   return SymbolTable.getIndex(Name);
1424f06d46fSCarlos Alberto Enciso }
1434f06d46fSCarlos Alberto Enciso bool LVBinaryReader::getSymbolTableIsComdat(StringRef Name) {
1444f06d46fSCarlos Alberto Enciso   return SymbolTable.getIsComdat(Name);
1454f06d46fSCarlos Alberto Enciso }
1464f06d46fSCarlos Alberto Enciso 
1474f06d46fSCarlos Alberto Enciso void LVBinaryReader::mapVirtualAddress(const object::ObjectFile &Obj) {
1484f06d46fSCarlos Alberto Enciso   for (const object::SectionRef &Section : Obj.sections()) {
149b19cfb91SCarlos Alberto Enciso     LLVM_DEBUG({
150b19cfb91SCarlos Alberto Enciso       Expected<StringRef> SectionNameOrErr = Section.getName();
151b19cfb91SCarlos Alberto Enciso       StringRef Name;
152b19cfb91SCarlos Alberto Enciso       if (!SectionNameOrErr)
153b19cfb91SCarlos Alberto Enciso         consumeError(SectionNameOrErr.takeError());
154b19cfb91SCarlos Alberto Enciso       else
155b19cfb91SCarlos Alberto Enciso         Name = *SectionNameOrErr;
156b19cfb91SCarlos Alberto Enciso       dbgs() << "Index: " << format_decimal(Section.getIndex(), 3) << ", "
157b19cfb91SCarlos Alberto Enciso              << "Address: " << hexValue(Section.getAddress()) << ", "
158b19cfb91SCarlos Alberto Enciso              << "Size: " << hexValue(Section.getSize()) << ", "
159b19cfb91SCarlos Alberto Enciso              << "Name: " << Name << "\n";
160b19cfb91SCarlos Alberto Enciso       dbgs() << "isCompressed:   " << Section.isCompressed() << ", "
161b19cfb91SCarlos Alberto Enciso              << "isText:         " << Section.isText() << ", "
162b19cfb91SCarlos Alberto Enciso              << "isData:         " << Section.isData() << ", "
163b19cfb91SCarlos Alberto Enciso              << "isBSS:          " << Section.isBSS() << ", "
164b19cfb91SCarlos Alberto Enciso              << "isVirtual:      " << Section.isVirtual() << "\n";
165b19cfb91SCarlos Alberto Enciso       dbgs() << "isBitcode:      " << Section.isBitcode() << ", "
166b19cfb91SCarlos Alberto Enciso              << "isStripped:     " << Section.isStripped() << ", "
167b19cfb91SCarlos Alberto Enciso              << "isBerkeleyText: " << Section.isBerkeleyText() << ", "
168b19cfb91SCarlos Alberto Enciso              << "isBerkeleyData: " << Section.isBerkeleyData() << ", "
169b19cfb91SCarlos Alberto Enciso              << "isDebugSection: " << Section.isDebugSection() << "\n";
170b19cfb91SCarlos Alberto Enciso       dbgs() << "\n";
171b19cfb91SCarlos Alberto Enciso     });
172b19cfb91SCarlos Alberto Enciso 
1734f06d46fSCarlos Alberto Enciso     if (!Section.isText() || Section.isVirtual() || !Section.getSize())
1744f06d46fSCarlos Alberto Enciso       continue;
1754f06d46fSCarlos Alberto Enciso 
1764f06d46fSCarlos Alberto Enciso     // Record section information required for symbol resolution.
1774f06d46fSCarlos Alberto Enciso     // Note: The section index returned by 'getIndex()' is one based.
1784f06d46fSCarlos Alberto Enciso     Sections.emplace(Section.getIndex(), Section);
1794f06d46fSCarlos Alberto Enciso     addSectionAddress(Section);
1804f06d46fSCarlos Alberto Enciso 
1814f06d46fSCarlos Alberto Enciso     // Identify the ".text" section.
1824f06d46fSCarlos Alberto Enciso     Expected<StringRef> SectionNameOrErr = Section.getName();
1834f06d46fSCarlos Alberto Enciso     if (!SectionNameOrErr) {
1844f06d46fSCarlos Alberto Enciso       consumeError(SectionNameOrErr.takeError());
1854f06d46fSCarlos Alberto Enciso       continue;
1864f06d46fSCarlos Alberto Enciso     }
187026a29e8SKazu Hirata     if (*SectionNameOrErr == ".text" || *SectionNameOrErr == "CODE" ||
188026a29e8SKazu Hirata         *SectionNameOrErr == ".code") {
1894f06d46fSCarlos Alberto Enciso       DotTextSectionIndex = Section.getIndex();
190b19cfb91SCarlos Alberto Enciso       // If the object is WebAssembly, update the address offset that
191b19cfb91SCarlos Alberto Enciso       // will be added to DWARF DW_AT_* attributes.
192b19cfb91SCarlos Alberto Enciso       if (Obj.isWasm())
193b19cfb91SCarlos Alberto Enciso         WasmCodeSectionOffset = Section.getAddress();
194b19cfb91SCarlos Alberto Enciso     }
1954f06d46fSCarlos Alberto Enciso   }
1964f06d46fSCarlos Alberto Enciso 
1974f06d46fSCarlos Alberto Enciso   // Process the symbol table.
1984f06d46fSCarlos Alberto Enciso   mapRangeAddress(Obj);
1994f06d46fSCarlos Alberto Enciso 
2004f06d46fSCarlos Alberto Enciso   LLVM_DEBUG({
2014f06d46fSCarlos Alberto Enciso     dbgs() << "\nSections Information:\n";
2024f06d46fSCarlos Alberto Enciso     for (LVSections::reference Entry : Sections) {
2034f06d46fSCarlos Alberto Enciso       LVSectionIndex SectionIndex = Entry.first;
2044f06d46fSCarlos Alberto Enciso       const object::SectionRef Section = Entry.second;
2054f06d46fSCarlos Alberto Enciso       Expected<StringRef> SectionNameOrErr = Section.getName();
2064f06d46fSCarlos Alberto Enciso       if (!SectionNameOrErr)
2074f06d46fSCarlos Alberto Enciso         consumeError(SectionNameOrErr.takeError());
2084f06d46fSCarlos Alberto Enciso       dbgs() << "\nIndex: " << format_decimal(SectionIndex, 3)
2094f06d46fSCarlos Alberto Enciso              << " Name: " << *SectionNameOrErr << "\n"
2104f06d46fSCarlos Alberto Enciso              << "Size: " << hexValue(Section.getSize()) << "\n"
2114f06d46fSCarlos Alberto Enciso              << "VirtualAddress: " << hexValue(VirtualAddress) << "\n"
2124f06d46fSCarlos Alberto Enciso              << "SectionAddress: " << hexValue(Section.getAddress()) << "\n";
2134f06d46fSCarlos Alberto Enciso     }
2144f06d46fSCarlos Alberto Enciso     dbgs() << "\nObject Section Information:\n";
2154f06d46fSCarlos Alberto Enciso     for (LVSectionAddresses::const_reference Entry : SectionAddresses)
2164f06d46fSCarlos Alberto Enciso       dbgs() << "[" << hexValue(Entry.first) << ":"
2174f06d46fSCarlos Alberto Enciso              << hexValue(Entry.first + Entry.second.getSize())
2184f06d46fSCarlos Alberto Enciso              << "] Size: " << hexValue(Entry.second.getSize()) << "\n";
2194f06d46fSCarlos Alberto Enciso   });
2204f06d46fSCarlos Alberto Enciso }
2214f06d46fSCarlos Alberto Enciso 
222e7950fceSCarlos Alberto Enciso void LVBinaryReader::mapVirtualAddress(const object::COFFObjectFile &COFFObj) {
223e7950fceSCarlos Alberto Enciso   ErrorOr<uint64_t> ImageBase = COFFObj.getImageBase();
224e7950fceSCarlos Alberto Enciso   if (ImageBase)
225e7950fceSCarlos Alberto Enciso     ImageBaseAddress = ImageBase.get();
226e7950fceSCarlos Alberto Enciso 
227e7950fceSCarlos Alberto Enciso   LLVM_DEBUG({
228e7950fceSCarlos Alberto Enciso     dbgs() << "ImageBaseAddress: " << hexValue(ImageBaseAddress) << "\n";
229e7950fceSCarlos Alberto Enciso   });
230e7950fceSCarlos Alberto Enciso 
231e7950fceSCarlos Alberto Enciso   uint32_t Flags = COFF::IMAGE_SCN_CNT_CODE | COFF::IMAGE_SCN_LNK_COMDAT;
232e7950fceSCarlos Alberto Enciso 
233e7950fceSCarlos Alberto Enciso   for (const object::SectionRef &Section : COFFObj.sections()) {
234e7950fceSCarlos Alberto Enciso     if (!Section.isText() || Section.isVirtual() || !Section.getSize())
235e7950fceSCarlos Alberto Enciso       continue;
236e7950fceSCarlos Alberto Enciso 
237e7950fceSCarlos Alberto Enciso     const object::coff_section *COFFSection = COFFObj.getCOFFSection(Section);
238e7950fceSCarlos Alberto Enciso     VirtualAddress = COFFSection->VirtualAddress;
239e7950fceSCarlos Alberto Enciso     bool IsComdat = (COFFSection->Characteristics & Flags) == Flags;
240e7950fceSCarlos Alberto Enciso 
241e7950fceSCarlos Alberto Enciso     // Record section information required for symbol resolution.
242e7950fceSCarlos Alberto Enciso     // Note: The section index returned by 'getIndex()' is zero based.
243e7950fceSCarlos Alberto Enciso     Sections.emplace(Section.getIndex() + 1, Section);
244e7950fceSCarlos Alberto Enciso     addSectionAddress(Section);
245e7950fceSCarlos Alberto Enciso 
246e7950fceSCarlos Alberto Enciso     // Additional initialization on the specific object format.
247e7950fceSCarlos Alberto Enciso     mapRangeAddress(COFFObj, Section, IsComdat);
248e7950fceSCarlos Alberto Enciso   }
249e7950fceSCarlos Alberto Enciso 
250e7950fceSCarlos Alberto Enciso   LLVM_DEBUG({
251e7950fceSCarlos Alberto Enciso     dbgs() << "\nSections Information:\n";
252e7950fceSCarlos Alberto Enciso     for (LVSections::reference Entry : Sections) {
253e7950fceSCarlos Alberto Enciso       LVSectionIndex SectionIndex = Entry.first;
254e7950fceSCarlos Alberto Enciso       const object::SectionRef Section = Entry.second;
255e7950fceSCarlos Alberto Enciso       const object::coff_section *COFFSection = COFFObj.getCOFFSection(Section);
256e7950fceSCarlos Alberto Enciso       Expected<StringRef> SectionNameOrErr = Section.getName();
257e7950fceSCarlos Alberto Enciso       if (!SectionNameOrErr)
258e7950fceSCarlos Alberto Enciso         consumeError(SectionNameOrErr.takeError());
259e7950fceSCarlos Alberto Enciso       dbgs() << "\nIndex: " << format_decimal(SectionIndex, 3)
260e7950fceSCarlos Alberto Enciso              << " Name: " << *SectionNameOrErr << "\n"
261e7950fceSCarlos Alberto Enciso              << "Size: " << hexValue(Section.getSize()) << "\n"
262e7950fceSCarlos Alberto Enciso              << "VirtualAddress: " << hexValue(VirtualAddress) << "\n"
263e7950fceSCarlos Alberto Enciso              << "SectionAddress: " << hexValue(Section.getAddress()) << "\n"
264e7950fceSCarlos Alberto Enciso              << "PointerToRawData: " << hexValue(COFFSection->PointerToRawData)
265e7950fceSCarlos Alberto Enciso              << "\n"
266e7950fceSCarlos Alberto Enciso              << "SizeOfRawData: " << hexValue(COFFSection->SizeOfRawData)
267e7950fceSCarlos Alberto Enciso              << "\n";
268e7950fceSCarlos Alberto Enciso     }
269e7950fceSCarlos Alberto Enciso     dbgs() << "\nObject Section Information:\n";
270e7950fceSCarlos Alberto Enciso     for (LVSectionAddresses::const_reference Entry : SectionAddresses)
271e7950fceSCarlos Alberto Enciso       dbgs() << "[" << hexValue(Entry.first) << ":"
272e7950fceSCarlos Alberto Enciso              << hexValue(Entry.first + Entry.second.getSize())
273e7950fceSCarlos Alberto Enciso              << "] Size: " << hexValue(Entry.second.getSize()) << "\n";
274e7950fceSCarlos Alberto Enciso   });
275e7950fceSCarlos Alberto Enciso }
276e7950fceSCarlos Alberto Enciso 
2774f06d46fSCarlos Alberto Enciso Error LVBinaryReader::loadGenericTargetInfo(StringRef TheTriple,
2784f06d46fSCarlos Alberto Enciso                                             StringRef TheFeatures) {
2794f06d46fSCarlos Alberto Enciso   std::string TargetLookupError;
2804f06d46fSCarlos Alberto Enciso   const Target *TheTarget =
2814f06d46fSCarlos Alberto Enciso       TargetRegistry::lookupTarget(std::string(TheTriple), TargetLookupError);
2824f06d46fSCarlos Alberto Enciso   if (!TheTarget)
2834f06d46fSCarlos Alberto Enciso     return createStringError(errc::invalid_argument, TargetLookupError.c_str());
2844f06d46fSCarlos Alberto Enciso 
2854f06d46fSCarlos Alberto Enciso   // Register information.
2864f06d46fSCarlos Alberto Enciso   MCRegisterInfo *RegisterInfo = TheTarget->createMCRegInfo(TheTriple);
2874f06d46fSCarlos Alberto Enciso   if (!RegisterInfo)
2884f06d46fSCarlos Alberto Enciso     return createStringError(errc::invalid_argument,
2894f06d46fSCarlos Alberto Enciso                              "no register info for target " + TheTriple);
2904f06d46fSCarlos Alberto Enciso   MRI.reset(RegisterInfo);
2914f06d46fSCarlos Alberto Enciso 
2924f06d46fSCarlos Alberto Enciso   // Assembler properties and features.
2934f06d46fSCarlos Alberto Enciso   MCTargetOptions MCOptions;
2944f06d46fSCarlos Alberto Enciso   MCAsmInfo *AsmInfo(TheTarget->createMCAsmInfo(*MRI, TheTriple, MCOptions));
2954f06d46fSCarlos Alberto Enciso   if (!AsmInfo)
2964f06d46fSCarlos Alberto Enciso     return createStringError(errc::invalid_argument,
2974f06d46fSCarlos Alberto Enciso                              "no assembly info for target " + TheTriple);
2984f06d46fSCarlos Alberto Enciso   MAI.reset(AsmInfo);
2994f06d46fSCarlos Alberto Enciso 
3004f06d46fSCarlos Alberto Enciso   // Target subtargets.
3014f06d46fSCarlos Alberto Enciso   StringRef CPU;
3024f06d46fSCarlos Alberto Enciso   MCSubtargetInfo *SubtargetInfo(
3034f06d46fSCarlos Alberto Enciso       TheTarget->createMCSubtargetInfo(TheTriple, CPU, TheFeatures));
3044f06d46fSCarlos Alberto Enciso   if (!SubtargetInfo)
3054f06d46fSCarlos Alberto Enciso     return createStringError(errc::invalid_argument,
3064f06d46fSCarlos Alberto Enciso                              "no subtarget info for target " + TheTriple);
3074f06d46fSCarlos Alberto Enciso   STI.reset(SubtargetInfo);
3084f06d46fSCarlos Alberto Enciso 
3094f06d46fSCarlos Alberto Enciso   // Instructions Info.
3104f06d46fSCarlos Alberto Enciso   MCInstrInfo *InstructionInfo(TheTarget->createMCInstrInfo());
3114f06d46fSCarlos Alberto Enciso   if (!InstructionInfo)
3124f06d46fSCarlos Alberto Enciso     return createStringError(errc::invalid_argument,
3134f06d46fSCarlos Alberto Enciso                              "no instruction info for target " + TheTriple);
3144f06d46fSCarlos Alberto Enciso   MII.reset(InstructionInfo);
3154f06d46fSCarlos Alberto Enciso 
3164f06d46fSCarlos Alberto Enciso   MC = std::make_unique<MCContext>(Triple(TheTriple), MAI.get(), MRI.get(),
3174f06d46fSCarlos Alberto Enciso                                    STI.get());
3184f06d46fSCarlos Alberto Enciso 
3194f06d46fSCarlos Alberto Enciso   // Assembler.
3204f06d46fSCarlos Alberto Enciso   MCDisassembler *DisAsm(TheTarget->createMCDisassembler(*STI, *MC));
3214f06d46fSCarlos Alberto Enciso   if (!DisAsm)
3224f06d46fSCarlos Alberto Enciso     return createStringError(errc::invalid_argument,
3234f06d46fSCarlos Alberto Enciso                              "no disassembler for target " + TheTriple);
3244f06d46fSCarlos Alberto Enciso   MD.reset(DisAsm);
3254f06d46fSCarlos Alberto Enciso 
3264f06d46fSCarlos Alberto Enciso   MCInstPrinter *InstructionPrinter(TheTarget->createMCInstPrinter(
3274f06d46fSCarlos Alberto Enciso       Triple(TheTriple), AsmInfo->getAssemblerDialect(), *MAI, *MII, *MRI));
3284f06d46fSCarlos Alberto Enciso   if (!InstructionPrinter)
3294f06d46fSCarlos Alberto Enciso     return createStringError(errc::invalid_argument,
3304f06d46fSCarlos Alberto Enciso                              "no target assembly language printer for target " +
3314f06d46fSCarlos Alberto Enciso                                  TheTriple);
3324f06d46fSCarlos Alberto Enciso   MIP.reset(InstructionPrinter);
3334f06d46fSCarlos Alberto Enciso   InstructionPrinter->setPrintImmHex(true);
3344f06d46fSCarlos Alberto Enciso 
3354f06d46fSCarlos Alberto Enciso   return Error::success();
3364f06d46fSCarlos Alberto Enciso }
3374f06d46fSCarlos Alberto Enciso 
3384f06d46fSCarlos Alberto Enciso Expected<std::pair<uint64_t, object::SectionRef>>
3394f06d46fSCarlos Alberto Enciso LVBinaryReader::getSection(LVScope *Scope, LVAddress Address,
3404f06d46fSCarlos Alberto Enciso                            LVSectionIndex SectionIndex) {
3414f06d46fSCarlos Alberto Enciso   // Return the 'text' section with the code for this logical scope.
3424f06d46fSCarlos Alberto Enciso   // COFF: SectionIndex is zero. Use 'SectionAddresses' data.
3434f06d46fSCarlos Alberto Enciso   // ELF: SectionIndex is the section index in the file.
3444f06d46fSCarlos Alberto Enciso   if (SectionIndex) {
3454f06d46fSCarlos Alberto Enciso     LVSections::iterator Iter = Sections.find(SectionIndex);
3464f06d46fSCarlos Alberto Enciso     if (Iter == Sections.end()) {
3474f06d46fSCarlos Alberto Enciso       return createStringError(errc::invalid_argument,
3484f06d46fSCarlos Alberto Enciso                                "invalid section index for: '%s'",
3494f06d46fSCarlos Alberto Enciso                                Scope->getName().str().c_str());
3504f06d46fSCarlos Alberto Enciso     }
3514f06d46fSCarlos Alberto Enciso     const object::SectionRef Section = Iter->second;
3524f06d46fSCarlos Alberto Enciso     return std::make_pair(Section.getAddress(), Section);
3534f06d46fSCarlos Alberto Enciso   }
3544f06d46fSCarlos Alberto Enciso 
3554f06d46fSCarlos Alberto Enciso   // Ensure a valid starting address for the public names.
3564f06d46fSCarlos Alberto Enciso   LVSectionAddresses::const_iterator Iter =
3574f06d46fSCarlos Alberto Enciso       SectionAddresses.upper_bound(Address);
3584f06d46fSCarlos Alberto Enciso   if (Iter == SectionAddresses.begin())
3594f06d46fSCarlos Alberto Enciso     return createStringError(errc::invalid_argument,
3604f06d46fSCarlos Alberto Enciso                              "invalid section address for: '%s'",
3614f06d46fSCarlos Alberto Enciso                              Scope->getName().str().c_str());
3624f06d46fSCarlos Alberto Enciso 
3634f06d46fSCarlos Alberto Enciso   // Get section that contains the code for this function.
3644f06d46fSCarlos Alberto Enciso   Iter = SectionAddresses.lower_bound(Address);
3654f06d46fSCarlos Alberto Enciso   if (Iter != SectionAddresses.begin())
3664f06d46fSCarlos Alberto Enciso     --Iter;
3674f06d46fSCarlos Alberto Enciso   return std::make_pair(Iter->first, Iter->second);
3684f06d46fSCarlos Alberto Enciso }
3694f06d46fSCarlos Alberto Enciso 
3704f06d46fSCarlos Alberto Enciso void LVBinaryReader::addSectionRange(LVSectionIndex SectionIndex,
3714f06d46fSCarlos Alberto Enciso                                      LVScope *Scope) {
3724f06d46fSCarlos Alberto Enciso   LVRange *ScopesWithRanges = getSectionRanges(SectionIndex);
3734f06d46fSCarlos Alberto Enciso   ScopesWithRanges->addEntry(Scope);
3744f06d46fSCarlos Alberto Enciso }
3754f06d46fSCarlos Alberto Enciso 
3764f06d46fSCarlos Alberto Enciso void LVBinaryReader::addSectionRange(LVSectionIndex SectionIndex,
3774f06d46fSCarlos Alberto Enciso                                      LVScope *Scope, LVAddress LowerAddress,
3784f06d46fSCarlos Alberto Enciso                                      LVAddress UpperAddress) {
3794f06d46fSCarlos Alberto Enciso   LVRange *ScopesWithRanges = getSectionRanges(SectionIndex);
3804f06d46fSCarlos Alberto Enciso   ScopesWithRanges->addEntry(Scope, LowerAddress, UpperAddress);
3814f06d46fSCarlos Alberto Enciso }
3824f06d46fSCarlos Alberto Enciso 
3834f06d46fSCarlos Alberto Enciso LVRange *LVBinaryReader::getSectionRanges(LVSectionIndex SectionIndex) {
3844f06d46fSCarlos Alberto Enciso   // Check if we already have a mapping for this section index.
3854f06d46fSCarlos Alberto Enciso   LVSectionRanges::iterator IterSection = SectionRanges.find(SectionIndex);
3867fbcc244SCarlos Alberto Enciso   if (IterSection == SectionRanges.end())
3877fbcc244SCarlos Alberto Enciso     IterSection =
3887fbcc244SCarlos Alberto Enciso         SectionRanges.emplace(SectionIndex, std::make_unique<LVRange>()).first;
3897fbcc244SCarlos Alberto Enciso   LVRange *Range = IterSection->second.get();
3904f06d46fSCarlos Alberto Enciso   assert(Range && "Range is null.");
3914f06d46fSCarlos Alberto Enciso   return Range;
3924f06d46fSCarlos Alberto Enciso }
3934f06d46fSCarlos Alberto Enciso 
3944f06d46fSCarlos Alberto Enciso Error LVBinaryReader::createInstructions(LVScope *Scope,
3954f06d46fSCarlos Alberto Enciso                                          LVSectionIndex SectionIndex,
3964f06d46fSCarlos Alberto Enciso                                          const LVNameInfo &NameInfo) {
3974f06d46fSCarlos Alberto Enciso   assert(Scope && "Scope is null.");
3984f06d46fSCarlos Alberto Enciso 
3994f06d46fSCarlos Alberto Enciso   // Skip stripped functions.
4004f06d46fSCarlos Alberto Enciso   if (Scope->getIsDiscarded())
4014f06d46fSCarlos Alberto Enciso     return Error::success();
4024f06d46fSCarlos Alberto Enciso 
4034f06d46fSCarlos Alberto Enciso   // Find associated address and size for the given function entry point.
4044f06d46fSCarlos Alberto Enciso   LVAddress Address = NameInfo.first;
4054f06d46fSCarlos Alberto Enciso   uint64_t Size = NameInfo.second;
4064f06d46fSCarlos Alberto Enciso 
4074f06d46fSCarlos Alberto Enciso   LLVM_DEBUG({
4084f06d46fSCarlos Alberto Enciso     dbgs() << "\nPublic Name instructions: '" << Scope->getName() << "' / '"
4094f06d46fSCarlos Alberto Enciso            << Scope->getLinkageName() << "'\n"
4104f06d46fSCarlos Alberto Enciso            << "DIE Offset: " << hexValue(Scope->getOffset()) << " Range: ["
4114f06d46fSCarlos Alberto Enciso            << hexValue(Address) << ":" << hexValue(Address + Size) << "]\n";
4124f06d46fSCarlos Alberto Enciso   });
4134f06d46fSCarlos Alberto Enciso 
4144f06d46fSCarlos Alberto Enciso   Expected<std::pair<uint64_t, const object::SectionRef>> SectionOrErr =
4154f06d46fSCarlos Alberto Enciso       getSection(Scope, Address, SectionIndex);
4164f06d46fSCarlos Alberto Enciso   if (!SectionOrErr)
4174f06d46fSCarlos Alberto Enciso     return SectionOrErr.takeError();
4184f06d46fSCarlos Alberto Enciso   const object::SectionRef Section = (*SectionOrErr).second;
4194f06d46fSCarlos Alberto Enciso   uint64_t SectionAddress = (*SectionOrErr).first;
4204f06d46fSCarlos Alberto Enciso 
4214f06d46fSCarlos Alberto Enciso   Expected<StringRef> SectionContentsOrErr = Section.getContents();
4224f06d46fSCarlos Alberto Enciso   if (!SectionContentsOrErr)
4234f06d46fSCarlos Alberto Enciso     return SectionOrErr.takeError();
4244f06d46fSCarlos Alberto Enciso 
4254f06d46fSCarlos Alberto Enciso   // There are cases where the section size is smaller than the [LowPC,HighPC]
4264f06d46fSCarlos Alberto Enciso   // range; it causes us to decode invalid addresses. The recorded size in the
4274f06d46fSCarlos Alberto Enciso   // logical scope is one less than the real size.
4284f06d46fSCarlos Alberto Enciso   LLVM_DEBUG({
4294f06d46fSCarlos Alberto Enciso     dbgs() << " Size: " << hexValue(Size)
4304f06d46fSCarlos Alberto Enciso            << ", Section Size: " << hexValue(Section.getSize()) << "\n";
4314f06d46fSCarlos Alberto Enciso   });
4324f06d46fSCarlos Alberto Enciso   Size = std::min(Size + 1, Section.getSize());
4334f06d46fSCarlos Alberto Enciso 
4344f06d46fSCarlos Alberto Enciso   ArrayRef<uint8_t> Bytes = arrayRefFromStringRef(*SectionContentsOrErr);
4354f06d46fSCarlos Alberto Enciso   uint64_t Offset = Address - SectionAddress;
4364f06d46fSCarlos Alberto Enciso   uint8_t const *Begin = Bytes.data() + Offset;
4374f06d46fSCarlos Alberto Enciso   uint8_t const *End = Bytes.data() + Offset + Size;
4384f06d46fSCarlos Alberto Enciso 
4394f06d46fSCarlos Alberto Enciso   LLVM_DEBUG({
4404f06d46fSCarlos Alberto Enciso     Expected<StringRef> SectionNameOrErr = Section.getName();
4414f06d46fSCarlos Alberto Enciso     if (!SectionNameOrErr)
4424f06d46fSCarlos Alberto Enciso       consumeError(SectionNameOrErr.takeError());
4434f06d46fSCarlos Alberto Enciso     else
4444f06d46fSCarlos Alberto Enciso       dbgs() << "Section Index: " << hexValue(Section.getIndex()) << " ["
4454f06d46fSCarlos Alberto Enciso              << hexValue((uint64_t)Section.getAddress()) << ":"
4464f06d46fSCarlos Alberto Enciso              << hexValue((uint64_t)Section.getAddress() + Section.getSize(), 10)
4474f06d46fSCarlos Alberto Enciso              << "] Name: '" << *SectionNameOrErr << "'\n"
4484f06d46fSCarlos Alberto Enciso              << "Begin: " << hexValue((uint64_t)Begin)
4494f06d46fSCarlos Alberto Enciso              << ", End: " << hexValue((uint64_t)End) << "\n";
4504f06d46fSCarlos Alberto Enciso   });
4514f06d46fSCarlos Alberto Enciso 
4524f06d46fSCarlos Alberto Enciso   // Address for first instruction line.
4534f06d46fSCarlos Alberto Enciso   LVAddress FirstAddress = Address;
4547fbcc244SCarlos Alberto Enciso   auto InstructionsSP = std::make_unique<LVLines>();
4557fbcc244SCarlos Alberto Enciso   LVLines &Instructions = *InstructionsSP;
4567fbcc244SCarlos Alberto Enciso   DiscoveredLines.emplace_back(std::move(InstructionsSP));
4574f06d46fSCarlos Alberto Enciso 
4584f06d46fSCarlos Alberto Enciso   while (Begin < End) {
4594f06d46fSCarlos Alberto Enciso     MCInst Instruction;
4604f06d46fSCarlos Alberto Enciso     uint64_t BytesConsumed = 0;
4614f06d46fSCarlos Alberto Enciso     SmallVector<char, 64> InsnStr;
4624f06d46fSCarlos Alberto Enciso     raw_svector_ostream Annotations(InsnStr);
4634f06d46fSCarlos Alberto Enciso     MCDisassembler::DecodeStatus const S =
4644f06d46fSCarlos Alberto Enciso         MD->getInstruction(Instruction, BytesConsumed,
4654f06d46fSCarlos Alberto Enciso                            ArrayRef<uint8_t>(Begin, End), Address, outs());
4664f06d46fSCarlos Alberto Enciso     switch (S) {
4674f06d46fSCarlos Alberto Enciso     case MCDisassembler::Fail:
4684f06d46fSCarlos Alberto Enciso       LLVM_DEBUG({ dbgs() << "Invalid instruction\n"; });
4694f06d46fSCarlos Alberto Enciso       if (BytesConsumed == 0)
4704f06d46fSCarlos Alberto Enciso         // Skip invalid bytes
4714f06d46fSCarlos Alberto Enciso         BytesConsumed = 1;
4724f06d46fSCarlos Alberto Enciso       break;
4734f06d46fSCarlos Alberto Enciso     case MCDisassembler::SoftFail:
4744f06d46fSCarlos Alberto Enciso       LLVM_DEBUG({ dbgs() << "Potentially undefined instruction:"; });
4756006d43eSCraig Topper       [[fallthrough]];
4764f06d46fSCarlos Alberto Enciso     case MCDisassembler::Success: {
4774f06d46fSCarlos Alberto Enciso       std::string Buffer;
4784f06d46fSCarlos Alberto Enciso       raw_string_ostream Stream(Buffer);
4794f06d46fSCarlos Alberto Enciso       StringRef AnnotationsStr = Annotations.str();
480d22f050eSGregory Alfonso       MIP->printInst(&Instruction, Address, AnnotationsStr, *STI, Stream);
4814f06d46fSCarlos Alberto Enciso       LLVM_DEBUG({
4824f06d46fSCarlos Alberto Enciso         std::string BufferCodes;
4834f06d46fSCarlos Alberto Enciso         raw_string_ostream StreamCodes(BufferCodes);
4844f06d46fSCarlos Alberto Enciso         StreamCodes << format_bytes(
48511011599SKazu Hirata             ArrayRef<uint8_t>(Begin, Begin + BytesConsumed), std::nullopt, 16,
48611011599SKazu Hirata             16);
4874f06d46fSCarlos Alberto Enciso         dbgs() << "[" << hexValue((uint64_t)Begin) << "] "
4884f06d46fSCarlos Alberto Enciso                << "Size: " << format_decimal(BytesConsumed, 2) << " ("
4894f06d46fSCarlos Alberto Enciso                << formatv("{0}",
4904f06d46fSCarlos Alberto Enciso                           fmt_align(StreamCodes.str(), AlignStyle::Left, 32))
4914f06d46fSCarlos Alberto Enciso                << ") " << hexValue((uint64_t)Address) << ": " << Stream.str()
4924f06d46fSCarlos Alberto Enciso                << "\n";
4934f06d46fSCarlos Alberto Enciso       });
4944f06d46fSCarlos Alberto Enciso       // Here we add logical lines to the Instructions. Later on,
4954f06d46fSCarlos Alberto Enciso       // the 'processLines()' function will move each created logical line
4964f06d46fSCarlos Alberto Enciso       // to its enclosing logical scope, using the debug ranges information
4974f06d46fSCarlos Alberto Enciso       // and they will be released when its scope parent is deleted.
4987fbcc244SCarlos Alberto Enciso       LVLineAssembler *Line = createLineAssembler();
4994f06d46fSCarlos Alberto Enciso       Line->setAddress(Address);
5004f06d46fSCarlos Alberto Enciso       Line->setName(StringRef(Stream.str()).trim());
5017fbcc244SCarlos Alberto Enciso       Instructions.push_back(Line);
5024f06d46fSCarlos Alberto Enciso       break;
5034f06d46fSCarlos Alberto Enciso     }
5044f06d46fSCarlos Alberto Enciso     }
5054f06d46fSCarlos Alberto Enciso     Address += BytesConsumed;
5064f06d46fSCarlos Alberto Enciso     Begin += BytesConsumed;
5074f06d46fSCarlos Alberto Enciso   }
5084f06d46fSCarlos Alberto Enciso 
5094f06d46fSCarlos Alberto Enciso   LLVM_DEBUG({
5104f06d46fSCarlos Alberto Enciso     size_t Index = 0;
5114f06d46fSCarlos Alberto Enciso     dbgs() << "\nSectionIndex: " << format_decimal(SectionIndex, 3)
5124f06d46fSCarlos Alberto Enciso            << " Scope DIE: " << hexValue(Scope->getOffset()) << "\n"
5134f06d46fSCarlos Alberto Enciso            << "Address: " << hexValue(FirstAddress)
5144f06d46fSCarlos Alberto Enciso            << format(" - Collected instructions lines: %d\n",
5157fbcc244SCarlos Alberto Enciso                      Instructions.size());
5167fbcc244SCarlos Alberto Enciso     for (const LVLine *Line : Instructions)
5174f06d46fSCarlos Alberto Enciso       dbgs() << format_decimal(++Index, 5) << ": "
5184f06d46fSCarlos Alberto Enciso              << hexValue(Line->getOffset()) << ", (" << Line->getName()
5194f06d46fSCarlos Alberto Enciso              << ")\n";
5204f06d46fSCarlos Alberto Enciso   });
5214f06d46fSCarlos Alberto Enciso 
5224f06d46fSCarlos Alberto Enciso   // The scope in the assembler names is linked to its own instructions.
5237fbcc244SCarlos Alberto Enciso   ScopeInstructions.add(SectionIndex, Scope, &Instructions);
5244f06d46fSCarlos Alberto Enciso   AssemblerMappings.add(SectionIndex, FirstAddress, Scope);
5254f06d46fSCarlos Alberto Enciso 
5264f06d46fSCarlos Alberto Enciso   return Error::success();
5274f06d46fSCarlos Alberto Enciso }
5284f06d46fSCarlos Alberto Enciso 
5294f06d46fSCarlos Alberto Enciso Error LVBinaryReader::createInstructions(LVScope *Function,
5304f06d46fSCarlos Alberto Enciso                                          LVSectionIndex SectionIndex) {
5314f06d46fSCarlos Alberto Enciso   if (!options().getPrintInstructions())
5324f06d46fSCarlos Alberto Enciso     return Error::success();
5334f06d46fSCarlos Alberto Enciso 
5344f06d46fSCarlos Alberto Enciso   LVNameInfo Name = CompileUnit->findPublicName(Function);
5354f06d46fSCarlos Alberto Enciso   if (Name.first != LVAddress(UINT64_MAX))
5364f06d46fSCarlos Alberto Enciso     return createInstructions(Function, SectionIndex, Name);
5374f06d46fSCarlos Alberto Enciso 
5384f06d46fSCarlos Alberto Enciso   return Error::success();
5394f06d46fSCarlos Alberto Enciso }
5404f06d46fSCarlos Alberto Enciso 
5414f06d46fSCarlos Alberto Enciso Error LVBinaryReader::createInstructions() {
5424f06d46fSCarlos Alberto Enciso   if (!options().getPrintInstructions())
5434f06d46fSCarlos Alberto Enciso     return Error::success();
5444f06d46fSCarlos Alberto Enciso 
5454f06d46fSCarlos Alberto Enciso   LLVM_DEBUG({
5464f06d46fSCarlos Alberto Enciso     size_t Index = 1;
5474f06d46fSCarlos Alberto Enciso     dbgs() << "\nPublic Names (Scope):\n";
5484f06d46fSCarlos Alberto Enciso     for (LVPublicNames::const_reference Name : CompileUnit->getPublicNames()) {
5494f06d46fSCarlos Alberto Enciso       LVScope *Scope = Name.first;
5504f06d46fSCarlos Alberto Enciso       const LVNameInfo &NameInfo = Name.second;
5514f06d46fSCarlos Alberto Enciso       LVAddress Address = NameInfo.first;
5524f06d46fSCarlos Alberto Enciso       uint64_t Size = NameInfo.second;
5534f06d46fSCarlos Alberto Enciso       dbgs() << format_decimal(Index++, 5) << ": "
5544f06d46fSCarlos Alberto Enciso              << "DIE Offset: " << hexValue(Scope->getOffset()) << " Range: ["
5554f06d46fSCarlos Alberto Enciso              << hexValue(Address) << ":" << hexValue(Address + Size) << "] "
5564f06d46fSCarlos Alberto Enciso              << "Name: '" << Scope->getName() << "' / '"
5574f06d46fSCarlos Alberto Enciso              << Scope->getLinkageName() << "'\n";
5584f06d46fSCarlos Alberto Enciso     }
5594f06d46fSCarlos Alberto Enciso   });
5604f06d46fSCarlos Alberto Enciso 
5614f06d46fSCarlos Alberto Enciso   // For each public name in the current compile unit, create the line
5624f06d46fSCarlos Alberto Enciso   // records that represent the executable instructions.
5634f06d46fSCarlos Alberto Enciso   for (LVPublicNames::const_reference Name : CompileUnit->getPublicNames()) {
5644f06d46fSCarlos Alberto Enciso     LVScope *Scope = Name.first;
5654f06d46fSCarlos Alberto Enciso     // The symbol table extracted from the object file always contains a
5664f06d46fSCarlos Alberto Enciso     // non-empty name (linkage name). However, the logical scope does not
5674f06d46fSCarlos Alberto Enciso     // guarantee to have a name for the linkage name (main is one case).
5684f06d46fSCarlos Alberto Enciso     // For those cases, set the linkage name the same as the name.
5694f06d46fSCarlos Alberto Enciso     if (!Scope->getLinkageNameIndex())
5704f06d46fSCarlos Alberto Enciso       Scope->setLinkageName(Scope->getName());
5714f06d46fSCarlos Alberto Enciso     LVSectionIndex SectionIndex = getSymbolTableIndex(Scope->getLinkageName());
5724f06d46fSCarlos Alberto Enciso     if (Error Err = createInstructions(Scope, SectionIndex, Name.second))
5734f06d46fSCarlos Alberto Enciso       return Err;
5744f06d46fSCarlos Alberto Enciso   }
5754f06d46fSCarlos Alberto Enciso 
5764f06d46fSCarlos Alberto Enciso   return Error::success();
5774f06d46fSCarlos Alberto Enciso }
5784f06d46fSCarlos Alberto Enciso 
5794f06d46fSCarlos Alberto Enciso // During the traversal of the debug information sections, we created the
5804f06d46fSCarlos Alberto Enciso // logical lines representing the disassembled instructions from the text
5814f06d46fSCarlos Alberto Enciso // section and the logical lines representing the line records from the
5824f06d46fSCarlos Alberto Enciso // debug line section. Using the ranges associated with the logical scopes,
5834f06d46fSCarlos Alberto Enciso // we will allocate those logical lines to their logical scopes.
5844f06d46fSCarlos Alberto Enciso void LVBinaryReader::processLines(LVLines *DebugLines,
5854f06d46fSCarlos Alberto Enciso                                   LVSectionIndex SectionIndex,
5864f06d46fSCarlos Alberto Enciso                                   LVScope *Function) {
5874f06d46fSCarlos Alberto Enciso   assert(DebugLines && "DebugLines is null.");
5884f06d46fSCarlos Alberto Enciso 
5894f06d46fSCarlos Alberto Enciso   // Just return if this compilation unit does not have any line records
5904f06d46fSCarlos Alberto Enciso   // and no instruction lines were created.
5914f06d46fSCarlos Alberto Enciso   if (DebugLines->empty() && !options().getPrintInstructions())
5924f06d46fSCarlos Alberto Enciso     return;
5934f06d46fSCarlos Alberto Enciso 
5944f06d46fSCarlos Alberto Enciso   // Merge the debug lines and instruction lines using their text address;
5954f06d46fSCarlos Alberto Enciso   // the logical line representing the debug line record is followed by the
5964f06d46fSCarlos Alberto Enciso   // line(s) representing the disassembled instructions, whose addresses are
5974f06d46fSCarlos Alberto Enciso   // equal or greater that the line address and less than the address of the
5984f06d46fSCarlos Alberto Enciso   // next debug line record.
5994f06d46fSCarlos Alberto Enciso   LLVM_DEBUG({
6004f06d46fSCarlos Alberto Enciso     size_t Index = 1;
6014f06d46fSCarlos Alberto Enciso     size_t PerLine = 4;
6024f06d46fSCarlos Alberto Enciso     dbgs() << format("\nProcess debug lines: %d\n", DebugLines->size());
6034f06d46fSCarlos Alberto Enciso     for (const LVLine *Line : *DebugLines) {
6044f06d46fSCarlos Alberto Enciso       dbgs() << format_decimal(Index, 5) << ": " << hexValue(Line->getOffset())
6054f06d46fSCarlos Alberto Enciso              << ", (" << Line->getLineNumber() << ")"
6064f06d46fSCarlos Alberto Enciso              << ((Index % PerLine) ? "  " : "\n");
6074f06d46fSCarlos Alberto Enciso       ++Index;
6084f06d46fSCarlos Alberto Enciso     }
6094f06d46fSCarlos Alberto Enciso     dbgs() << ((Index % PerLine) ? "\n" : "");
6104f06d46fSCarlos Alberto Enciso   });
6114f06d46fSCarlos Alberto Enciso 
6124f06d46fSCarlos Alberto Enciso   bool TraverseLines = true;
6134f06d46fSCarlos Alberto Enciso   LVLines::iterator Iter = DebugLines->begin();
6144f06d46fSCarlos Alberto Enciso   while (TraverseLines && Iter != DebugLines->end()) {
6154f06d46fSCarlos Alberto Enciso     uint64_t DebugAddress = (*Iter)->getAddress();
6164f06d46fSCarlos Alberto Enciso 
6174f06d46fSCarlos Alberto Enciso     // Get the function with an entry point that matches this line and
6184f06d46fSCarlos Alberto Enciso     // its associated assembler entries. In the case of COMDAT, the input
6194f06d46fSCarlos Alberto Enciso     // 'Function' is not null. Use it to find its address ranges.
6204f06d46fSCarlos Alberto Enciso     LVScope *Scope = Function;
6214f06d46fSCarlos Alberto Enciso     if (!Function) {
6224f06d46fSCarlos Alberto Enciso       Scope = AssemblerMappings.find(SectionIndex, DebugAddress);
6234f06d46fSCarlos Alberto Enciso       if (!Scope) {
6244f06d46fSCarlos Alberto Enciso         ++Iter;
6254f06d46fSCarlos Alberto Enciso         continue;
6264f06d46fSCarlos Alberto Enciso       }
6274f06d46fSCarlos Alberto Enciso     }
6284f06d46fSCarlos Alberto Enciso 
6294f06d46fSCarlos Alberto Enciso     // Get the associated instructions for the found 'Scope'.
6304f06d46fSCarlos Alberto Enciso     LVLines InstructionLines;
6314f06d46fSCarlos Alberto Enciso     LVLines *Lines = ScopeInstructions.find(SectionIndex, Scope);
6324f06d46fSCarlos Alberto Enciso     if (Lines)
6334f06d46fSCarlos Alberto Enciso       InstructionLines = std::move(*Lines);
6344f06d46fSCarlos Alberto Enciso 
6354f06d46fSCarlos Alberto Enciso     LLVM_DEBUG({
6364f06d46fSCarlos Alberto Enciso       size_t Index = 0;
6374f06d46fSCarlos Alberto Enciso       dbgs() << "\nSectionIndex: " << format_decimal(SectionIndex, 3)
6384f06d46fSCarlos Alberto Enciso              << " Scope DIE: " << hexValue(Scope->getOffset()) << "\n"
6399d56d9a9SCarlos Alberto Enciso              << format("Process instruction lines: %d\n",
6404f06d46fSCarlos Alberto Enciso                        InstructionLines.size());
6414f06d46fSCarlos Alberto Enciso       for (const LVLine *Line : InstructionLines)
6424f06d46fSCarlos Alberto Enciso         dbgs() << format_decimal(++Index, 5) << ": "
6434f06d46fSCarlos Alberto Enciso                << hexValue(Line->getOffset()) << ", (" << Line->getName()
6444f06d46fSCarlos Alberto Enciso                << ")\n";
6454f06d46fSCarlos Alberto Enciso     });
6464f06d46fSCarlos Alberto Enciso 
6474f06d46fSCarlos Alberto Enciso     // Continue with next debug line if there are not instructions lines.
6484f06d46fSCarlos Alberto Enciso     if (InstructionLines.empty()) {
6494f06d46fSCarlos Alberto Enciso       ++Iter;
6504f06d46fSCarlos Alberto Enciso       continue;
6514f06d46fSCarlos Alberto Enciso     }
6524f06d46fSCarlos Alberto Enciso 
6534f06d46fSCarlos Alberto Enciso     for (LVLine *InstructionLine : InstructionLines) {
6544f06d46fSCarlos Alberto Enciso       uint64_t InstructionAddress = InstructionLine->getAddress();
6554f06d46fSCarlos Alberto Enciso       LLVM_DEBUG({
6564f06d46fSCarlos Alberto Enciso         dbgs() << "Instruction address: " << hexValue(InstructionAddress)
6574f06d46fSCarlos Alberto Enciso                << "\n";
6584f06d46fSCarlos Alberto Enciso       });
6594f06d46fSCarlos Alberto Enciso       if (TraverseLines) {
6604f06d46fSCarlos Alberto Enciso         while (Iter != DebugLines->end()) {
6614f06d46fSCarlos Alberto Enciso           DebugAddress = (*Iter)->getAddress();
6624f06d46fSCarlos Alberto Enciso           LLVM_DEBUG({
6634f06d46fSCarlos Alberto Enciso             bool IsDebug = (*Iter)->getIsLineDebug();
6644f06d46fSCarlos Alberto Enciso             dbgs() << "Line " << (IsDebug ? "dbg:" : "ins:") << " ["
6654f06d46fSCarlos Alberto Enciso                    << hexValue(DebugAddress) << "]";
6664f06d46fSCarlos Alberto Enciso             if (IsDebug)
6674f06d46fSCarlos Alberto Enciso               dbgs() << format(" %d", (*Iter)->getLineNumber());
6684f06d46fSCarlos Alberto Enciso             dbgs() << "\n";
6694f06d46fSCarlos Alberto Enciso           });
6704f06d46fSCarlos Alberto Enciso           // Instruction address before debug line.
6714f06d46fSCarlos Alberto Enciso           if (InstructionAddress < DebugAddress) {
6724f06d46fSCarlos Alberto Enciso             LLVM_DEBUG({
6734f06d46fSCarlos Alberto Enciso               dbgs() << "Inserted instruction address: "
6744f06d46fSCarlos Alberto Enciso                      << hexValue(InstructionAddress) << " before line: "
6754f06d46fSCarlos Alberto Enciso                      << format("%d", (*Iter)->getLineNumber()) << " ["
6764f06d46fSCarlos Alberto Enciso                      << hexValue(DebugAddress) << "]\n";
6774f06d46fSCarlos Alberto Enciso             });
6784f06d46fSCarlos Alberto Enciso             Iter = DebugLines->insert(Iter, InstructionLine);
6794f06d46fSCarlos Alberto Enciso             // The returned iterator points to the inserted instruction.
6804f06d46fSCarlos Alberto Enciso             // Skip it and point to the line acting as reference.
6814f06d46fSCarlos Alberto Enciso             ++Iter;
6824f06d46fSCarlos Alberto Enciso             break;
6834f06d46fSCarlos Alberto Enciso           }
6844f06d46fSCarlos Alberto Enciso           ++Iter;
6854f06d46fSCarlos Alberto Enciso         }
6864f06d46fSCarlos Alberto Enciso         if (Iter == DebugLines->end()) {
6874f06d46fSCarlos Alberto Enciso           // We have reached the end of the source lines and the current
6884f06d46fSCarlos Alberto Enciso           // instruction line address is greater than the last source line.
6894f06d46fSCarlos Alberto Enciso           TraverseLines = false;
6904f06d46fSCarlos Alberto Enciso           DebugLines->push_back(InstructionLine);
6914f06d46fSCarlos Alberto Enciso         }
6924f06d46fSCarlos Alberto Enciso       } else {
6934f06d46fSCarlos Alberto Enciso         DebugLines->push_back(InstructionLine);
6944f06d46fSCarlos Alberto Enciso       }
6954f06d46fSCarlos Alberto Enciso     }
6964f06d46fSCarlos Alberto Enciso   }
6974f06d46fSCarlos Alberto Enciso 
6984f06d46fSCarlos Alberto Enciso   LLVM_DEBUG({
6994f06d46fSCarlos Alberto Enciso     dbgs() << format("Lines after merge: %d\n", DebugLines->size());
7004f06d46fSCarlos Alberto Enciso     size_t Index = 0;
7014f06d46fSCarlos Alberto Enciso     for (const LVLine *Line : *DebugLines) {
7024f06d46fSCarlos Alberto Enciso       dbgs() << format_decimal(++Index, 5) << ": "
7034f06d46fSCarlos Alberto Enciso              << hexValue(Line->getOffset()) << ", ("
7044f06d46fSCarlos Alberto Enciso              << ((Line->getIsLineDebug())
7054f06d46fSCarlos Alberto Enciso                      ? Line->lineNumberAsStringStripped(/*ShowZero=*/true)
7064f06d46fSCarlos Alberto Enciso                      : Line->getName())
7074f06d46fSCarlos Alberto Enciso              << ")\n";
7084f06d46fSCarlos Alberto Enciso     }
7094f06d46fSCarlos Alberto Enciso   });
7104f06d46fSCarlos Alberto Enciso 
7114f06d46fSCarlos Alberto Enciso   // If this compilation unit does not have line records, traverse its scopes
7124f06d46fSCarlos Alberto Enciso   // and take any collected instruction lines as the working set in order
7134f06d46fSCarlos Alberto Enciso   // to move them to their associated scope.
7144f06d46fSCarlos Alberto Enciso   if (DebugLines->empty()) {
7154f06d46fSCarlos Alberto Enciso     if (const LVScopes *Scopes = CompileUnit->getScopes())
7164f06d46fSCarlos Alberto Enciso       for (LVScope *Scope : *Scopes) {
7174f06d46fSCarlos Alberto Enciso         LVLines *Lines = ScopeInstructions.find(Scope);
7184f06d46fSCarlos Alberto Enciso         if (Lines) {
7194f06d46fSCarlos Alberto Enciso 
7204f06d46fSCarlos Alberto Enciso           LLVM_DEBUG({
7214f06d46fSCarlos Alberto Enciso             size_t Index = 0;
7224f06d46fSCarlos Alberto Enciso             dbgs() << "\nSectionIndex: " << format_decimal(SectionIndex, 3)
7234f06d46fSCarlos Alberto Enciso                    << " Scope DIE: " << hexValue(Scope->getOffset()) << "\n"
7249d56d9a9SCarlos Alberto Enciso                    << format("Instruction lines: %d\n", Lines->size());
7254f06d46fSCarlos Alberto Enciso             for (const LVLine *Line : *Lines)
7264f06d46fSCarlos Alberto Enciso               dbgs() << format_decimal(++Index, 5) << ": "
7274f06d46fSCarlos Alberto Enciso                      << hexValue(Line->getOffset()) << ", (" << Line->getName()
7284f06d46fSCarlos Alberto Enciso                      << ")\n";
7294f06d46fSCarlos Alberto Enciso           });
7304f06d46fSCarlos Alberto Enciso 
7319d56d9a9SCarlos Alberto Enciso           if (Scope->getIsArtificial()) {
7329d56d9a9SCarlos Alberto Enciso             // Add the instruction lines to their artificial scope.
7339d56d9a9SCarlos Alberto Enciso             for (LVLine *Line : *Lines)
7349d56d9a9SCarlos Alberto Enciso               Scope->addElement(Line);
7359d56d9a9SCarlos Alberto Enciso           } else {
7364f06d46fSCarlos Alberto Enciso             DebugLines->append(*Lines);
7379d56d9a9SCarlos Alberto Enciso           }
7384f06d46fSCarlos Alberto Enciso           Lines->clear();
7394f06d46fSCarlos Alberto Enciso         }
7404f06d46fSCarlos Alberto Enciso       }
7414f06d46fSCarlos Alberto Enciso   }
7424f06d46fSCarlos Alberto Enciso 
7434f06d46fSCarlos Alberto Enciso   LVRange *ScopesWithRanges = getSectionRanges(SectionIndex);
7444f06d46fSCarlos Alberto Enciso   ScopesWithRanges->startSearch();
7454f06d46fSCarlos Alberto Enciso 
7464f06d46fSCarlos Alberto Enciso   // Process collected lines.
7474f06d46fSCarlos Alberto Enciso   LVScope *Scope;
7484f06d46fSCarlos Alberto Enciso   for (LVLine *Line : *DebugLines) {
7494f06d46fSCarlos Alberto Enciso     // Using the current line address, get its associated lexical scope and
7504f06d46fSCarlos Alberto Enciso     // add the line information to it.
7514f06d46fSCarlos Alberto Enciso     Scope = ScopesWithRanges->getEntry(Line->getAddress());
7524f06d46fSCarlos Alberto Enciso     if (!Scope) {
7534f06d46fSCarlos Alberto Enciso       // If missing scope, use the compile unit.
7544f06d46fSCarlos Alberto Enciso       Scope = CompileUnit;
7554f06d46fSCarlos Alberto Enciso       LLVM_DEBUG({
7564f06d46fSCarlos Alberto Enciso         dbgs() << "Adding line to CU: " << hexValue(Line->getOffset()) << ", ("
7574f06d46fSCarlos Alberto Enciso                << ((Line->getIsLineDebug())
7584f06d46fSCarlos Alberto Enciso                        ? Line->lineNumberAsStringStripped(/*ShowZero=*/true)
7594f06d46fSCarlos Alberto Enciso                        : Line->getName())
7604f06d46fSCarlos Alberto Enciso                << ")\n";
7614f06d46fSCarlos Alberto Enciso       });
7624f06d46fSCarlos Alberto Enciso     }
7634f06d46fSCarlos Alberto Enciso 
7644f06d46fSCarlos Alberto Enciso     // Add line object to scope.
7654f06d46fSCarlos Alberto Enciso     Scope->addElement(Line);
7664f06d46fSCarlos Alberto Enciso 
7674f06d46fSCarlos Alberto Enciso     // Report any line zero.
7684f06d46fSCarlos Alberto Enciso     if (options().getWarningLines() && Line->getIsLineDebug() &&
7694f06d46fSCarlos Alberto Enciso         !Line->getLineNumber())
7704f06d46fSCarlos Alberto Enciso       CompileUnit->addLineZero(Line);
7714f06d46fSCarlos Alberto Enciso 
7724f06d46fSCarlos Alberto Enciso     // Some compilers generate ranges in the compile unit; other compilers
7734f06d46fSCarlos Alberto Enciso     // only DW_AT_low_pc/DW_AT_high_pc. In order to correctly map global
7744f06d46fSCarlos Alberto Enciso     // variables, we need to generate the map ranges for the compile unit.
7754f06d46fSCarlos Alberto Enciso     // If we use the ranges stored at the scope level, there are cases where
7764f06d46fSCarlos Alberto Enciso     // the address referenced by a symbol location, is not in the enclosing
7774f06d46fSCarlos Alberto Enciso     // scope, but in an outer one. By using the ranges stored in the compile
7784f06d46fSCarlos Alberto Enciso     // unit, we can catch all those addresses.
7794f06d46fSCarlos Alberto Enciso     if (Line->getIsLineDebug())
7804f06d46fSCarlos Alberto Enciso       CompileUnit->addMapping(Line, SectionIndex);
7814f06d46fSCarlos Alberto Enciso 
7824f06d46fSCarlos Alberto Enciso     // Resolve any given pattern.
7834f06d46fSCarlos Alberto Enciso     patterns().resolvePatternMatch(Line);
7844f06d46fSCarlos Alberto Enciso   }
7854f06d46fSCarlos Alberto Enciso 
7864f06d46fSCarlos Alberto Enciso   ScopesWithRanges->endSearch();
7874f06d46fSCarlos Alberto Enciso }
7884f06d46fSCarlos Alberto Enciso 
7894f06d46fSCarlos Alberto Enciso void LVBinaryReader::processLines(LVLines *DebugLines,
7904f06d46fSCarlos Alberto Enciso                                   LVSectionIndex SectionIndex) {
7914f06d46fSCarlos Alberto Enciso   assert(DebugLines && "DebugLines is null.");
7924f06d46fSCarlos Alberto Enciso   if (DebugLines->empty() && !ScopeInstructions.findMap(SectionIndex))
7934f06d46fSCarlos Alberto Enciso     return;
7944f06d46fSCarlos Alberto Enciso 
7954f06d46fSCarlos Alberto Enciso   // If the Compile Unit does not contain comdat functions, use the whole
7964f06d46fSCarlos Alberto Enciso   // set of debug lines, as the addresses don't have conflicts.
7974f06d46fSCarlos Alberto Enciso   if (!CompileUnit->getHasComdatScopes()) {
7984f06d46fSCarlos Alberto Enciso     processLines(DebugLines, SectionIndex, nullptr);
7994f06d46fSCarlos Alberto Enciso     return;
8004f06d46fSCarlos Alberto Enciso   }
8014f06d46fSCarlos Alberto Enciso 
8024f06d46fSCarlos Alberto Enciso   // Find the indexes for the lines whose address is zero.
8034f06d46fSCarlos Alberto Enciso   std::vector<size_t> AddressZero;
8044f06d46fSCarlos Alberto Enciso   LVLines::iterator It =
8054f06d46fSCarlos Alberto Enciso       std::find_if(std::begin(*DebugLines), std::end(*DebugLines),
8064f06d46fSCarlos Alberto Enciso                    [](LVLine *Line) { return !Line->getAddress(); });
8074f06d46fSCarlos Alberto Enciso   while (It != std::end(*DebugLines)) {
8084f06d46fSCarlos Alberto Enciso     AddressZero.emplace_back(std::distance(std::begin(*DebugLines), It));
8094f06d46fSCarlos Alberto Enciso     It = std::find_if(std::next(It), std::end(*DebugLines),
8104f06d46fSCarlos Alberto Enciso                       [](LVLine *Line) { return !Line->getAddress(); });
8114f06d46fSCarlos Alberto Enciso   }
8124f06d46fSCarlos Alberto Enciso 
8134f06d46fSCarlos Alberto Enciso   // If the set of debug lines does not contain any line with address zero,
8144f06d46fSCarlos Alberto Enciso   // use the whole set. It means we are dealing with an initialization
8154f06d46fSCarlos Alberto Enciso   // section from a fully linked binary.
8164f06d46fSCarlos Alberto Enciso   if (AddressZero.empty()) {
8174f06d46fSCarlos Alberto Enciso     processLines(DebugLines, SectionIndex, nullptr);
8184f06d46fSCarlos Alberto Enciso     return;
8194f06d46fSCarlos Alberto Enciso   }
8204f06d46fSCarlos Alberto Enciso 
8214f06d46fSCarlos Alberto Enciso   // The Compile unit contains comdat functions. Traverse the collected
8224f06d46fSCarlos Alberto Enciso   // debug lines and identify logical groups based on their start and
8234f06d46fSCarlos Alberto Enciso   // address. Each group starts with a zero address.
8244f06d46fSCarlos Alberto Enciso   // Begin, End, Address, IsDone.
8254f06d46fSCarlos Alberto Enciso   using LVBucket = std::tuple<size_t, size_t, LVAddress, bool>;
8264f06d46fSCarlos Alberto Enciso   std::vector<LVBucket> Buckets;
8274f06d46fSCarlos Alberto Enciso 
8284f06d46fSCarlos Alberto Enciso   LVAddress Address;
8294f06d46fSCarlos Alberto Enciso   size_t Begin = 0;
8304f06d46fSCarlos Alberto Enciso   size_t End = 0;
8314f06d46fSCarlos Alberto Enciso   size_t Index = 0;
8324f06d46fSCarlos Alberto Enciso   for (Index = 0; Index < AddressZero.size() - 1; ++Index) {
8334f06d46fSCarlos Alberto Enciso     Begin = AddressZero[Index];
8344f06d46fSCarlos Alberto Enciso     End = AddressZero[Index + 1] - 1;
8354f06d46fSCarlos Alberto Enciso     Address = (*DebugLines)[End]->getAddress();
8364f06d46fSCarlos Alberto Enciso     Buckets.emplace_back(Begin, End, Address, false);
8374f06d46fSCarlos Alberto Enciso   }
8384f06d46fSCarlos Alberto Enciso 
8394f06d46fSCarlos Alberto Enciso   // Add the last bucket.
8404f06d46fSCarlos Alberto Enciso   if (Index) {
8414f06d46fSCarlos Alberto Enciso     Begin = AddressZero[Index];
8424f06d46fSCarlos Alberto Enciso     End = DebugLines->size() - 1;
8434f06d46fSCarlos Alberto Enciso     Address = (*DebugLines)[End]->getAddress();
8444f06d46fSCarlos Alberto Enciso     Buckets.emplace_back(Begin, End, Address, false);
8454f06d46fSCarlos Alberto Enciso   }
8464f06d46fSCarlos Alberto Enciso 
8474f06d46fSCarlos Alberto Enciso   LLVM_DEBUG({
8484f06d46fSCarlos Alberto Enciso     dbgs() << "\nDebug Lines buckets: " << Buckets.size() << "\n";
8494f06d46fSCarlos Alberto Enciso     for (LVBucket &Bucket : Buckets) {
8504f06d46fSCarlos Alberto Enciso       dbgs() << "Begin: " << format_decimal(std::get<0>(Bucket), 5) << ", "
8514f06d46fSCarlos Alberto Enciso              << "End: " << format_decimal(std::get<1>(Bucket), 5) << ", "
8524f06d46fSCarlos Alberto Enciso              << "Address: " << hexValue(std::get<2>(Bucket)) << "\n";
8534f06d46fSCarlos Alberto Enciso     }
8544f06d46fSCarlos Alberto Enciso   });
8554f06d46fSCarlos Alberto Enciso 
8564f06d46fSCarlos Alberto Enciso   // Traverse the sections and buckets looking for matches on the section
8574f06d46fSCarlos Alberto Enciso   // sizes. In the unlikely event of different buckets with the same size
8584f06d46fSCarlos Alberto Enciso   // process them in order and mark them as done.
8594f06d46fSCarlos Alberto Enciso   LVLines Group;
8604f06d46fSCarlos Alberto Enciso   for (LVSections::reference Entry : Sections) {
8614f06d46fSCarlos Alberto Enciso     LVSectionIndex SectionIndex = Entry.first;
8624f06d46fSCarlos Alberto Enciso     const object::SectionRef Section = Entry.second;
8634f06d46fSCarlos Alberto Enciso     uint64_t Size = Section.getSize();
8644f06d46fSCarlos Alberto Enciso     LLVM_DEBUG({
8654f06d46fSCarlos Alberto Enciso       dbgs() << "\nSection Index: " << format_decimal(SectionIndex, 3)
8664f06d46fSCarlos Alberto Enciso              << " , Section Size: " << hexValue(Section.getSize())
8674f06d46fSCarlos Alberto Enciso              << " , Section Address: " << hexValue(Section.getAddress())
8684f06d46fSCarlos Alberto Enciso              << "\n";
8694f06d46fSCarlos Alberto Enciso     });
8704f06d46fSCarlos Alberto Enciso 
8714f06d46fSCarlos Alberto Enciso     for (LVBucket &Bucket : Buckets) {
8724f06d46fSCarlos Alberto Enciso       if (std::get<3>(Bucket))
8734f06d46fSCarlos Alberto Enciso         // Already done for previous section.
8744f06d46fSCarlos Alberto Enciso         continue;
8754f06d46fSCarlos Alberto Enciso       if (Size == std::get<2>(Bucket)) {
8764f06d46fSCarlos Alberto Enciso         // We have a match on the section size.
8774f06d46fSCarlos Alberto Enciso         Group.clear();
8784f06d46fSCarlos Alberto Enciso         LVLines::iterator IterStart = DebugLines->begin() + std::get<0>(Bucket);
8794f06d46fSCarlos Alberto Enciso         LVLines::iterator IterEnd =
8804f06d46fSCarlos Alberto Enciso             DebugLines->begin() + std::get<1>(Bucket) + 1;
8814f06d46fSCarlos Alberto Enciso         for (LVLines::iterator Iter = IterStart; Iter < IterEnd; ++Iter)
8824f06d46fSCarlos Alberto Enciso           Group.push_back(*Iter);
8834f06d46fSCarlos Alberto Enciso         processLines(&Group, SectionIndex, /*Function=*/nullptr);
8844f06d46fSCarlos Alberto Enciso         std::get<3>(Bucket) = true;
8854f06d46fSCarlos Alberto Enciso         break;
8864f06d46fSCarlos Alberto Enciso       }
8874f06d46fSCarlos Alberto Enciso     }
8884f06d46fSCarlos Alberto Enciso   }
8894f06d46fSCarlos Alberto Enciso }
8904f06d46fSCarlos Alberto Enciso 
891e7950fceSCarlos Alberto Enciso // Traverse the scopes for the given 'Function' looking for any inlined
892e7950fceSCarlos Alberto Enciso // scopes with inlined lines, which are found in 'CUInlineeLines'.
893e7950fceSCarlos Alberto Enciso void LVBinaryReader::includeInlineeLines(LVSectionIndex SectionIndex,
894e7950fceSCarlos Alberto Enciso                                          LVScope *Function) {
895e7950fceSCarlos Alberto Enciso   SmallVector<LVInlineeLine::iterator> InlineeIters;
896e7950fceSCarlos Alberto Enciso   std::function<void(LVScope * Parent)> FindInlinedScopes =
897e7950fceSCarlos Alberto Enciso       [&](LVScope *Parent) {
898e7950fceSCarlos Alberto Enciso         if (const LVScopes *Scopes = Parent->getScopes())
899e7950fceSCarlos Alberto Enciso           for (LVScope *Scope : *Scopes) {
900e7950fceSCarlos Alberto Enciso             LVInlineeLine::iterator Iter = CUInlineeLines.find(Scope);
901e7950fceSCarlos Alberto Enciso             if (Iter != CUInlineeLines.end())
902e7950fceSCarlos Alberto Enciso               InlineeIters.push_back(Iter);
903e7950fceSCarlos Alberto Enciso             FindInlinedScopes(Scope);
904e7950fceSCarlos Alberto Enciso           }
905e7950fceSCarlos Alberto Enciso       };
906e7950fceSCarlos Alberto Enciso 
907e7950fceSCarlos Alberto Enciso   // Find all inlined scopes for the given 'Function'.
908e7950fceSCarlos Alberto Enciso   FindInlinedScopes(Function);
909e7950fceSCarlos Alberto Enciso   for (LVInlineeLine::iterator InlineeIter : InlineeIters) {
910e7950fceSCarlos Alberto Enciso     LVScope *Scope = InlineeIter->first;
911e7950fceSCarlos Alberto Enciso     addToSymbolTable(Scope->getLinkageName(), Scope, SectionIndex);
912e7950fceSCarlos Alberto Enciso 
913e7950fceSCarlos Alberto Enciso     // TODO: Convert this into a reference.
914e7950fceSCarlos Alberto Enciso     LVLines *InlineeLines = InlineeIter->second.get();
915e7950fceSCarlos Alberto Enciso     LLVM_DEBUG({
916e7950fceSCarlos Alberto Enciso       dbgs() << "Inlined lines for: " << Scope->getName() << "\n";
917e7950fceSCarlos Alberto Enciso       for (const LVLine *Line : *InlineeLines)
918e7950fceSCarlos Alberto Enciso         dbgs() << "[" << hexValue(Line->getAddress()) << "] "
919e7950fceSCarlos Alberto Enciso                << Line->getLineNumber() << "\n";
920e7950fceSCarlos Alberto Enciso       dbgs() << format("Debug lines: %d\n", CULines.size());
921e7950fceSCarlos Alberto Enciso       for (const LVLine *Line : CULines)
922e7950fceSCarlos Alberto Enciso         dbgs() << "Line address: " << hexValue(Line->getOffset()) << ", ("
923e7950fceSCarlos Alberto Enciso                << Line->getLineNumber() << ")\n";
924e7950fceSCarlos Alberto Enciso       ;
925e7950fceSCarlos Alberto Enciso     });
926e7950fceSCarlos Alberto Enciso 
927e7950fceSCarlos Alberto Enciso     // The inlined lines must be merged using its address, in order to keep
928e7950fceSCarlos Alberto Enciso     // the real order of the instructions. The inlined lines are mixed with
929e7950fceSCarlos Alberto Enciso     // the other non-inlined lines.
930e7950fceSCarlos Alberto Enciso     if (InlineeLines->size()) {
931e7950fceSCarlos Alberto Enciso       // First address of inlinee code.
932e7950fceSCarlos Alberto Enciso       uint64_t InlineeStart = (InlineeLines->front())->getAddress();
933e7950fceSCarlos Alberto Enciso       LVLines::iterator Iter = std::find_if(
934e7950fceSCarlos Alberto Enciso           CULines.begin(), CULines.end(), [&](LVLine *Item) -> bool {
935e7950fceSCarlos Alberto Enciso             return Item->getAddress() == InlineeStart;
936e7950fceSCarlos Alberto Enciso           });
937e7950fceSCarlos Alberto Enciso       if (Iter != CULines.end()) {
938e7950fceSCarlos Alberto Enciso         // 'Iter' points to the line where the inlined function is called.
939e7950fceSCarlos Alberto Enciso         // Emulate the DW_AT_call_line attribute.
940e7950fceSCarlos Alberto Enciso         Scope->setCallLineNumber((*Iter)->getLineNumber());
941e7950fceSCarlos Alberto Enciso         // Mark the referenced line as the start of the inlined function.
942e7950fceSCarlos Alberto Enciso         // Skip the first line during the insertion, as the address and
943e7950fceSCarlos Alberto Enciso         // line number as the same. Otherwise we have to erase and insert.
944e7950fceSCarlos Alberto Enciso         (*Iter)->setLineNumber((*InlineeLines->begin())->getLineNumber());
945e7950fceSCarlos Alberto Enciso         ++Iter;
946e7950fceSCarlos Alberto Enciso         CULines.insert(Iter, InlineeLines->begin() + 1, InlineeLines->end());
947e7950fceSCarlos Alberto Enciso       }
948e7950fceSCarlos Alberto Enciso     }
949e7950fceSCarlos Alberto Enciso 
950e7950fceSCarlos Alberto Enciso     // Remove this set of lines from the container; each inlined function
951e7950fceSCarlos Alberto Enciso     // creates an unique set of lines. Remove only the created container.
952e7950fceSCarlos Alberto Enciso     CUInlineeLines.erase(InlineeIter);
953e7950fceSCarlos Alberto Enciso     InlineeLines->clear();
954e7950fceSCarlos Alberto Enciso   }
955e7950fceSCarlos Alberto Enciso   LLVM_DEBUG({
956e7950fceSCarlos Alberto Enciso     dbgs() << "Merged Inlined lines for: " << Function->getName() << "\n";
957e7950fceSCarlos Alberto Enciso     dbgs() << format("Debug lines: %d\n", CULines.size());
958e7950fceSCarlos Alberto Enciso     for (const LVLine *Line : CULines)
959e7950fceSCarlos Alberto Enciso       dbgs() << "Line address: " << hexValue(Line->getOffset()) << ", ("
960e7950fceSCarlos Alberto Enciso              << Line->getLineNumber() << ")\n";
961e7950fceSCarlos Alberto Enciso     ;
962e7950fceSCarlos Alberto Enciso   });
963e7950fceSCarlos Alberto Enciso }
964e7950fceSCarlos Alberto Enciso 
9654f06d46fSCarlos Alberto Enciso void LVBinaryReader::print(raw_ostream &OS) const {
9664f06d46fSCarlos Alberto Enciso   OS << "LVBinaryReader\n";
9674f06d46fSCarlos Alberto Enciso   LLVM_DEBUG(dbgs() << "PrintReader\n");
9684f06d46fSCarlos Alberto Enciso }
969