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