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