Go to the documentation of this file.
10 #include <unordered_set>
51 return Addr == UINT32_MAX;
71 if (GsymFileIdx != UINT32_MAX)
100 if (Die.
getTag() == dwarf::DW_TAG_inlined_subroutine)
107 switch (ParentDie.
getTag()) {
108 case dwarf::DW_TAG_namespace:
109 case dwarf::DW_TAG_structure_type:
110 case dwarf::DW_TAG_union_type:
111 case dwarf::DW_TAG_class_type:
112 case dwarf::DW_TAG_subprogram:
114 case dwarf::DW_TAG_lexical_block:
136 dwarf::DW_AT_linkage_name}),
145 if (!(
Language == dwarf::DW_LANG_C_plus_plus ||
146 Language == dwarf::DW_LANG_C_plus_plus_03 ||
147 Language == dwarf::DW_LANG_C_plus_plus_11 ||
148 Language == dwarf::DW_LANG_C_plus_plus_14 ||
149 Language == dwarf::DW_LANG_ObjC_plus_plus ||
163 if (ParentDeclCtxDie) {
165 while (ParentDeclCtxDie) {
167 if (!ParentName.
empty()) {
171 if (ParentName.
front() ==
'<' && ParentName.
back() ==
'>')
187 bool CheckChildren =
true;
189 case dwarf::DW_TAG_subprogram:
191 CheckChildren =
Depth == 0;
193 case dwarf::DW_TAG_inlined_subroutine:
214 if (Tag == dwarf::DW_TAG_inlined_subroutine) {
224 if (FuncRange.
LowPC <= Range.LowPC && Range.HighPC <= FuncRange.
HighPC)
232 II.
Name = *NameIndex;
242 if (Tag == dwarf::DW_TAG_subprogram || Tag == dwarf::DW_TAG_lexical_block) {
252 std::vector<uint32_t> RowVector;
255 const uint64_t RangeSize = EndAddress - StartAddress;
280 for (
uint32_t RowIndex : RowVector) {
293 Log <<
"error: DIE has a start address whose LowPC is between the "
294 "line table Row[" << RowIndex <<
"] with address "
295 <<
HEX64(RowAddress) <<
" and the next one.\n";
312 if (FirstLE && *FirstLE ==
LE) {
313 Log <<
"warning: duplicate line table detected for DIE:\n";
317 Log <<
"error: line table has addresses that do not "
318 <<
"monotonically increase:\n";
319 for (
uint32_t RowIndex2 : RowVector) {
329 if (LastLE && LastLE->File == FileIdx && LastLE->Line == Row.
Line)
353 case dwarf::DW_TAG_subprogram: {
355 if (!RangesOrError) {
365 <<
" has no name\n ";
392 if (Range.LowPC != 0) {
394 Log <<
"warning: DIE has an address range whose start address is "
395 "not in any executable sections (" <<
405 FI.
Name = *NameIndex;
411 FI.
Inline->Name = *NameIndex;
422 handleDie(OS, CUI, ChildDie);
427 if (NumThreads == 1) {
432 CUInfo CUI(DICtx, dyn_cast<DWARFCompileUnit>(
CU.get()));
433 handleDie(Log, CUI, Die);
444 CU->getAbbreviations();
450 pool.async([&
CU]() {
CU->getUnitDIE(
false ); });
458 CUInfo CUI(DICtx, dyn_cast<DWARFCompileUnit>(
CU.get()));
459 pool.async([
this, CUI, &LogMutex, Die]()
mutable {
460 std::string ThreadLogStorage;
462 handleDie(ThreadOS, CUI, Die);
464 if (!ThreadLogStorage.empty()) {
466 std::lock_guard<std::mutex> guard(LogMutex);
467 Log << ThreadLogStorage;
475 Log <<
"Loaded " << FunctionsAddedCount <<
" functions from DWARF.\n";
480 Log <<
"Verifying GSYM file \"" << GsymPath <<
"\":\n";
484 return Gsym.takeError();
486 auto NumAddrs = Gsym->getNumAddresses();
490 std::string gsymFilename;
492 auto FuncAddr = Gsym->getAddress(
I);
495 "failed to extract address[%i]",
I);
497 auto FI = Gsym->getFunctionInfo(*FuncAddr);
500 "failed to extract function info for address 0x%"
506 auto LR = Gsym->lookup(
Addr);
508 return LR.takeError();
510 auto DwarfInlineInfos =
512 uint32_t NumDwarfInlineInfos = DwarfInlineInfos.getNumberOfFrames();
513 if (NumDwarfInlineInfos == 0) {
514 DwarfInlineInfos.addFrame(
519 if (NumDwarfInlineInfos == 1 &&
520 DwarfInlineInfos.getFrame(0).FileName ==
"<invalid>") {
522 NumDwarfInlineInfos = 0;
524 if (NumDwarfInlineInfos > 0 &&
525 NumDwarfInlineInfos != LR->Locations.size()) {
526 Log <<
"error: address " <<
HEX64(
Addr) <<
" has "
527 << NumDwarfInlineInfos <<
" DWARF inline frames and GSYM has "
528 << LR->Locations.size() <<
"\n";
529 Log <<
" " << NumDwarfInlineInfos <<
" DWARF frames:\n";
530 for (
size_t Idx = 0; Idx < NumDwarfInlineInfos; ++Idx) {
531 const auto dii = DwarfInlineInfos.getFrame(Idx);
532 Log <<
" [" << Idx <<
"]: " << dii.FunctionName <<
" @ "
533 << dii.FileName <<
':' << dii.Line <<
'\n';
535 Log <<
" " << LR->Locations.size() <<
" GSYM frames:\n";
536 for (
size_t Idx = 0,
count = LR->Locations.size();
537 Idx <
count; ++Idx) {
538 const auto &gii = LR->Locations[Idx];
539 Log <<
" [" << Idx <<
"]: " << gii.Name <<
" @ " << gii.Dir
540 <<
'/' << gii.Base <<
':' << gii.Line <<
'\n';
543 Gsym->dump(Log, *FI);
547 for (
size_t Idx = 0,
count = LR->Locations.size(); Idx <
count;
549 const auto &gii = LR->Locations[Idx];
550 if (Idx < NumDwarfInlineInfos) {
551 const auto dii = DwarfInlineInfos.getFrame(Idx);
552 gsymFilename = LR->getSourceFile(Idx);
554 if (dii.FunctionName.find(gii.Name.str()) != 0)
555 Log <<
"error: address " <<
HEX64(
Addr) <<
" DWARF function \""
556 << dii.FunctionName.c_str()
557 <<
"\" doesn't match GSYM function \"" << gii.Name <<
"\"\n";
559 if (dii.FileName != gsymFilename)
560 Log <<
"error: address " <<
HEX64(
Addr) <<
" DWARF path \""
561 << dii.FileName.c_str() <<
"\" doesn't match GSYM path \""
562 << gsymFilename.c_str() <<
"\"\n";
564 if (dii.Line != gii.Line)
565 Log <<
"error: address " <<
HEX64(
Addr) <<
" DWARF line "
566 << dii.Line <<
" != GSYM line " << gii.Line <<
"\n";
LLVM_NODISCARD char back() const
back - Get the last character in the string.
const DWARFDebugLine::LineTable * getLineTableForUnit(DWARFUnit *U)
Get a pointer to a parsed line table corresponding to a compile unit.
ThreadPoolStrategy hardware_concurrency(unsigned ThreadCount=0)
Returns a default thread strategy where all available hardware resources are to be used,...
This class represents lattice values for constants.
DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE as the referenced DIE.
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
uint32_t Name
String table offset in the string table.
static llvm::Expected< GsymReader > openFile(StringRef Path)
Construct a GsymReader from a file on disk.
uint32_t DWARFToGSYMFileIndex(GsymCreator &Gsym, uint32_t DwarfFileIdx)
Convert a DWARF compile unit file index into a GSYM global file index.
A ThreadPool for asynchronous parallel execution on a defined number of threads.
GsymCreator is used to emit GSYM data to a stand alone file or section within a file.
A format-neutral container for inlined code description.
Controls which fields of DILineInfo container should be filled with data.
void insert(AddressRange Range)
A raw_ostream that writes to an std::string.
Line entries are used to encode the line tables in FunctionInfo objects.
static ErrorSuccess success()
Create a success value.
Implement PPCInstrInfo::isLoadFromStackSlot isStoreToStackSlot for vector to generate better spill code The first should be a single lvx from the constant pool
llvm::Optional< LineTable > OptLineTable
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
Expected< DWARFAddressRangesVector > getAddressRanges() const
Get the address ranges for this DIE.
std::vector< uint32_t > FileCache
bool IsValidTextAddress(uint64_t Addr) const
Check if an address is a valid code address.
const char * getName(DINameKind Kind) const
Return the DIE name resolving DW_AT_specification or DW_AT_abstract_origin references if necessary.
Tagged union holding either a T or a Error.
uint32_t CallFile
1 based file index in the file table.
iterator_range< iterator > children() const
Inline information stores the name of the inline function along with an array of address ranges.
void consumeError(Error Err)
Consume a Error without doing anything.
DIInliningInfo getInliningInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
LLVM_NODISCARD StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
uint8_t EndSequence
A boolean indicating that the current address is that of the first byte after the end of a sequence o...
CUInfo(DWARFContext &DICtx, DWARFCompileUnit *CU)
uint32_t CallLine
Source line number.
Standard .debug_line state machine structure.
static DIDumpOptions getForSingleDIE()
Return default option set for printing a single DIE without children.
constexpr char Language[]
Key for Kernel::Metadata::mLanguage.
uint64_t startAddress() const
This class implements an extremely fast bulk output stream that can only output to a stream.
DWARFDie getParent() const
Get the parent of this DIE object.
llvm::Optional< InlineInfo > Inline
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
LineTable class contains deserialized versions of line tables for each function's address ranges.
bool lookupAddressRange(object::SectionedAddress Address, uint64_t Size, std::vector< uint32_t > &Result) const
compile_unit_range compile_units()
Get compile units in this context.
Function information in GSYM files encodes information for one contiguous address range.
const Optional< AddressRanges > GetValidTextRanges() const
Get the valid text ranges.
uint32_t Name
String table offset in the string table.
Optional< DWARFFormValue > findRecursively(ArrayRef< dwarf::Attribute > Attrs) const
Extract the first value of any attribute in Attrs from this DIE and recurse into any DW_AT_specificat...
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
const static uint64_t UndefSection
LLVM_NODISCARD char front() const
front - Get the first character in the string.
Optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
uint64_t getOffset() const
Get the absolute offset into the debug info or types section.
uint64_t endAddress() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void setEndAddress(uint64_t Addr)
Optional< const char * > toString(const Optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
size_t getNumFunctionInfos() const
Get the current number of FunctionInfo objects contained in this object.
StringRef - Represent a constant reference to a string, i.e.
void addFunctionInfo(FunctionInfo &&FI)
Add a function info to this GSYM creator.
reference get()
Returns a reference to the stored T value.
uint32_t insertString(StringRef S, bool Copy=true)
Insert a string into the GSYM string table.
DILineInfo getLineInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
A class that represents an address range.
const DWARFDebugLine::LineTable * LineTable
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
std::vector< DWARFAddressRange > DWARFAddressRangesVector
DWARFAddressRangesVector - represents a set of absolute address ranges.
void setStartAddress(uint64_t Addr)
Lightweight error class with error context and mandatory checking.
bool isHighestAddress(uint64_t Addr) const
Return true if Addr is the highest address for a given compile unit.
uint32_t Line
An unsigned integer indicating a source line number.
object::SectionedAddress Address
The program-counter value corresponding to a machine instruction generated by the compiler and sectio...
uint32_t insertFile(StringRef Path, sys::path::Style Style=sys::path::Style::native)
Insert a file into this GSYM creator.
Optional< uint64_t > toUnsigned(const Optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an unsigned constant.
Error takeError()
Take ownership of the stored error.
dwarf::Tag getTag() const
bool contains(uint64_t Addr) const
uint16_t File
An unsigned integer indicating the identity of the source file corresponding to a machine instruction...
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
LLVM_NODISCARD size_t size() const
size - Get the string size.
void dump(raw_ostream &OS, unsigned indent=0, DIDumpOptions DumpOpts=DIDumpOptions()) const
Dump the DIE and all of its attributes to the supplied stream.
Instrumentation for Order File
std::vector< InlineInfo > Children