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