llvm.org GIT mirror llvm / b043c3d
[DWARF parser] Use enums instead of bitfields in DILineInfoSpecifier. It is more appropriate than the current situation, when one flag (AbsoluteFilePath) is relevant only if another flag is set. This refactoring would also simplify fetching the short function name (stored in DW_AT_name) instead of a linkage name returned currently. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208921 91177308-0d34-0410-b5e6-96231b3b80d8 Alexey Samsonov 6 years ago
8 changed file(s) with 79 addition(s) and 81 deletion(s). Raw diff Collapse all Expand all
6767
6868 /// DILineInfoSpecifier - controls which fields of DILineInfo container
6969 /// should be filled with data.
70 class DILineInfoSpecifier {
71 const uint32_t Flags; // Or'ed flags that set the info we want to fetch.
72 public:
73 enum Specification {
74 FileLineInfo = 1 << 0,
75 AbsoluteFilePath = 1 << 1,
76 FunctionName = 1 << 2
77 };
78 // Use file/line info by default.
79 DILineInfoSpecifier(uint32_t flags = FileLineInfo) : Flags(flags) {}
80 bool needs(Specification spec) const {
81 return (Flags & spec) > 0;
82 }
70 struct DILineInfoSpecifier {
71 enum class FileLineInfoKind { None, Default, AbsoluteFilePath };
72 enum class FunctionNameKind { None, LinkageName };
73
74 FileLineInfoKind FLIKind;
75 FunctionNameKind FNKind;
76
77 DILineInfoSpecifier(FileLineInfoKind FLIKind = FileLineInfoKind::Default,
78 FunctionNameKind FNKind = FunctionNameKind::None)
79 : FLIKind(FLIKind), FNKind(FNKind) {}
8380 };
8481
8582 /// Selects which debug sections get dumped.
2424 #define DEBUG_TYPE "dwarf"
2525
2626 typedef DWARFDebugLine::LineTable DWARFLineTable;
27 typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
28 typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
2729
2830 static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data,
2931 bool LittleEndian, bool GnuStyle) {
424426
425427 static bool getFileNameForCompileUnit(DWARFCompileUnit *CU,
426428 const DWARFLineTable *LineTable,
427 uint64_t FileIndex,
428 bool NeedsAbsoluteFilePath,
429 uint64_t FileIndex, FileLineInfoKind Kind,
429430 std::string &FileName) {
430 if (!CU || !LineTable ||
431 !LineTable->getFileNameByIndex(FileIndex, NeedsAbsoluteFilePath,
432 FileName))
431 if (!CU || !LineTable || Kind == FileLineInfoKind::None ||
432 !LineTable->getFileNameByIndex(FileIndex, Kind, FileName))
433433 return false;
434 if (NeedsAbsoluteFilePath && sys::path::is_relative(FileName)) {
434 if (Kind == FileLineInfoKind::AbsoluteFilePath &&
435 sys::path::is_relative(FileName)) {
435436 // We may still need to append compilation directory of compile unit.
436437 SmallString<16> AbsolutePath;
437438 if (const char *CompilationDir = CU->getCompilationDir()) {
446447 static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
447448 const DWARFLineTable *LineTable,
448449 uint64_t Address,
449 bool NeedsAbsoluteFilePath,
450 FileLineInfoKind Kind,
450451 DILineInfo &Result) {
451452 if (!CU || !LineTable)
452453 return false;
456457 return false;
457458 // Take file number and line/column from the row.
458459 const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
459 if (!getFileNameForCompileUnit(CU, LineTable, Row.File, NeedsAbsoluteFilePath,
460 if (!getFileNameForCompileUnit(CU, LineTable, Row.File, Kind,
460461 Result.FileName))
461462 return false;
462463 Result.Line = Row.Line;
465466 }
466467
467468 static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address,
469 FunctionNameKind Kind,
468470 std::string &FunctionName) {
471 if (Kind == FunctionNameKind::None)
472 return false;
469473 // The address may correspond to instruction in some inlined function,
470474 // so we have to build the chain of inlined functions and take the
471475 // name of the topmost function in it.
474478 if (InlinedChain.DIEs.size() == 0)
475479 return false;
476480 const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
477 if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U)) {
481 if (const char *Name =
482 TopFunctionDIE.getSubroutineName(InlinedChain.U, Kind)) {
478483 FunctionName = Name;
479484 return true;
480485 }
482487 }
483488
484489 DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
485 DILineInfoSpecifier Specifier) {
490 DILineInfoSpecifier Spec) {
486491 DILineInfo Result;
487492
488493 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
489494 if (!CU)
490495 return Result;
491 if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
492 getFunctionNameForAddress(CU, Address, Result.FunctionName);
493 }
494 if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
496 getFunctionNameForAddress(CU, Address, Spec.FNKind, Result.FunctionName);
497 if (Spec.FLIKind != FileLineInfoKind::None) {
495498 const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
496 const bool NeedsAbsoluteFilePath =
497 Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
498 getFileLineInfoForCompileUnit(CU, LineTable, Address, NeedsAbsoluteFilePath,
499 Result);
499 getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind, Result);
500500 }
501501 return Result;
502502 }
503503
504 DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address,
505 uint64_t Size,
506 DILineInfoSpecifier Specifier) {
504 DILineInfoTable
505 DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
506 DILineInfoSpecifier Spec) {
507507 DILineInfoTable Lines;
508508 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
509509 if (!CU)
510510 return Lines;
511511
512512 std::string FunctionName = "";
513 if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
514 getFunctionNameForAddress(CU, Address, FunctionName);
515 }
513 getFunctionNameForAddress(CU, Address, Spec.FNKind, FunctionName);
516514
517515 // If the Specifier says we don't need FileLineInfo, just
518516 // return the top-most function at the starting address.
519 if (!Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
517 if (Spec.FLIKind == FileLineInfoKind::None) {
520518 DILineInfo Result;
521519 Result.FunctionName = FunctionName;
522520 Lines.push_back(std::make_pair(Address, Result));
524522 }
525523
526524 const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
527 const bool NeedsAbsoluteFilePath =
528 Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
529525
530526 // Get the index of row we're looking for in the line table.
531527 std::vector RowVector;
536532 // Take file number and line/column from the row.
537533 const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
538534 DILineInfo Result;
539 getFileNameForCompileUnit(CU, LineTable, Row.File, NeedsAbsoluteFilePath,
535 getFileNameForCompileUnit(CU, LineTable, Row.File, Spec.FLIKind,
540536 Result.FileName);
541537 Result.FunctionName = FunctionName;
542538 Result.Line = Row.Line;
547543 return Lines;
548544 }
549545
550 DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
551 DILineInfoSpecifier Specifier) {
546 DIInliningInfo
547 DWARFContext::getInliningInfoForAddress(uint64_t Address,
548 DILineInfoSpecifier Spec) {
552549 DIInliningInfo InliningInfo;
553550
554551 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
556553 return InliningInfo;
557554
558555 const DWARFLineTable *LineTable = nullptr;
559 const bool NeedsAbsoluteFilePath =
560 Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
561556 const DWARFDebugInfoEntryInlinedChain &InlinedChain =
562557 CU->getInlinedChainForAddress(Address);
563558 if (InlinedChain.DIEs.size() == 0) {
564559 // If there is no DIE for address (e.g. it is in unavailable .dwo file),
565560 // try to at least get file/line info from symbol table.
566 if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
561 if (Spec.FLIKind != FileLineInfoKind::None) {
567562 DILineInfo Frame;
568563 LineTable = getLineTableForCompileUnit(CU);
569 if (getFileLineInfoForCompileUnit(CU, LineTable, Address,
570 NeedsAbsoluteFilePath, Frame)) {
564 if (getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind,
565 Frame)) {
571566 InliningInfo.addFrame(Frame);
572567 }
573568 }
579574 const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
580575 DILineInfo Frame;
581576 // Get function name if necessary.
582 if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
583 if (const char *Name = FunctionDIE.getSubroutineName(InlinedChain.U))
584 Frame.FunctionName = Name;
585 }
586 if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
577 if (const char *Name =
578 FunctionDIE.getSubroutineName(InlinedChain.U, Spec.FNKind))
579 Frame.FunctionName = Name;
580 if (Spec.FLIKind != FileLineInfoKind::None) {
587581 if (i == 0) {
588582 // For the topmost frame, initialize the line table of this
589583 // compile unit and fetch file/line info from it.
590584 LineTable = getLineTableForCompileUnit(CU);
591585 // For the topmost routine, get file/line info from line table.
592 getFileLineInfoForCompileUnit(CU, LineTable, Address,
593 NeedsAbsoluteFilePath, Frame);
586 getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind,
587 Frame);
594588 } else {
595589 // Otherwise, use call file, call line and call column from
596590 // previous DIE in inlined chain.
597 getFileNameForCompileUnit(CU, LineTable, CallFile,
598 NeedsAbsoluteFilePath, Frame.FileName);
591 getFileNameForCompileUnit(CU, LineTable, CallFile, Spec.FLIKind,
592 Frame.FileName);
599593 Frame.Line = CallLine;
600594 Frame.Column = CallColumn;
601595 }
1717 #include "llvm/Support/raw_ostream.h"
1818 using namespace llvm;
1919 using namespace dwarf;
20 typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
2021
2122 void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u,
2223 unsigned recurseDepth,
271272 }
272273
273274 const char *
274 DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U) const {
275 if (!isSubroutineDIE())
275 DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U,
276 FunctionNameKind Kind) const {
277 if (!isSubroutineDIE() || Kind == FunctionNameKind::None)
276278 return nullptr;
277279 // Try to get mangled name if possible.
278280 if (const char *name =
289291 if (spec_ref != -1U) {
290292 DWARFDebugInfoEntryMinimal spec_die;
291293 if (spec_die.extractFast(U, &spec_ref)) {
292 if (const char *name = spec_die.getSubroutineName(U))
294 if (const char *name = spec_die.getSubroutineName(U, Kind))
293295 return name;
294296 }
295297 }
299301 if (abs_origin_ref != -1U) {
300302 DWARFDebugInfoEntryMinimal abs_origin_die;
301303 if (abs_origin_die.extractFast(U, &abs_origin_ref)) {
302 if (const char *name = abs_origin_die.getSubroutineName(U))
304 if (const char *name = abs_origin_die.getSubroutineName(U, Kind))
303305 return name;
304306 }
305307 }
1212 #include "DWARFAbbreviationDeclaration.h"
1313 #include "DWARFDebugRangeList.h"
1414 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/DebugInfo/DIContext.h"
1516 #include "llvm/Support/DataTypes.h"
1617
1718 namespace llvm {
121122 /// returns its mangled name (or short name, if mangled is missing).
122123 /// This name may be fetched from specification or abstract origin
123124 /// for this subprogram. Returns null if no name is found.
124 const char *getSubroutineName(const DWARFUnit *U) const;
125 const char *
126 getSubroutineName(const DWARFUnit *U,
127 DILineInfoSpecifier::FunctionNameKind Kind) const;
125128
126129 /// Retrieves values of DW_AT_call_file, DW_AT_call_line and
127130 /// DW_AT_call_column from DIE (or zeroes if they are missing).
1414 #include
1515 using namespace llvm;
1616 using namespace dwarf;
17 typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
1718
1819 DWARFDebugLine::Prologue::Prologue() {
1920 clear();
642643
643644 bool
644645 DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex,
645 bool NeedsAbsoluteFilePath,
646 FileLineInfoKind Kind,
646647 std::string &Result) const {
647 if (FileIndex == 0 || FileIndex > Prologue.FileNames.size())
648 if (FileIndex == 0 || FileIndex > Prologue.FileNames.size() ||
649 Kind == FileLineInfoKind::None)
648650 return false;
649651 const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1];
650652 const char *FileName = Entry.Name;
651 if (!NeedsAbsoluteFilePath ||
653 if (Kind != FileLineInfoKind::AbsoluteFilePath ||
652654 sys::path::is_absolute(FileName)) {
653655 Result = FileName;
654656 return true;
1010 #define LLVM_DEBUGINFO_DWARFDEBUGLINE_H
1111
1212 #include "DWARFRelocMap.h"
13 #include "llvm/DebugInfo/DIContext.h"
1314 #include "llvm/Support/DataExtractor.h"
1415 #include
1516 #include
178179 // Extracts filename by its index in filename table in prologue.
179180 // Returns true on success.
180181 bool getFileNameByIndex(uint64_t FileIndex,
181 bool NeedsAbsoluteFilePath,
182 DILineInfoSpecifier::FileLineInfoKind Kind,
182183 std::string &Result) const;
183184
184185 void dump(raw_ostream &OS) const;
107107 DICtx->dump(outs(), DumpType);
108108 } else {
109109 // Print line info for the specified address.
110 int SpecFlags = DILineInfoSpecifier::FileLineInfo |
111 DILineInfoSpecifier::AbsoluteFilePath;
112 if (PrintFunctions)
113 SpecFlags |= DILineInfoSpecifier::FunctionName;
110 DILineInfoSpecifier Spec(
111 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
112 PrintFunctions ? DILineInfoSpecifier::FunctionNameKind::LinkageName
113 : DILineInfoSpecifier::FunctionNameKind::None);
114114 if (PrintInlining) {
115115 DIInliningInfo InliningInfo =
116 DICtx->getInliningInfoForAddress(Address, SpecFlags);
116 DICtx->getInliningInfoForAddress(Address, Spec);
117117 uint32_t n = InliningInfo.getNumberOfFrames();
118118 if (n == 0) {
119119 // Print one empty debug line info in any case.
125125 }
126126 }
127127 } else {
128 DILineInfo dli = DICtx->getLineInfoForAddress(Address, SpecFlags);
128 DILineInfo dli = DICtx->getLineInfoForAddress(Address, Spec);
129129 PrintDILineInfo(dli);
130130 }
131131 }
3434 return true;
3535 }
3636
37 static uint32_t
38 getDILineInfoSpecifierFlags(const LLVMSymbolizer::Options &Opts) {
39 uint32_t Flags = llvm::DILineInfoSpecifier::FileLineInfo |
40 llvm::DILineInfoSpecifier::AbsoluteFilePath;
41 if (Opts.PrintFunctions)
42 Flags |= llvm::DILineInfoSpecifier::FunctionName;
43 return Flags;
37 static DILineInfoSpecifier
38 getDILineInfoSpecifier(const LLVMSymbolizer::Options &Opts) {
39 return DILineInfoSpecifier(
40 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
41 Opts.PrintFunctions ? DILineInfoSpecifier::FunctionNameKind::LinkageName
42 : DILineInfoSpecifier::FunctionNameKind::None);
4443 }
4544
4645 ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
114113 DILineInfo LineInfo;
115114 if (DebugInfoContext) {
116115 LineInfo = DebugInfoContext->getLineInfoForAddress(
117 ModuleOffset, getDILineInfoSpecifierFlags(Opts));
116 ModuleOffset, getDILineInfoSpecifier(Opts));
118117 }
119118 // Override function name from symbol table if necessary.
120119 if (Opts.PrintFunctions && Opts.UseSymbolTable) {
133132 DIInliningInfo InlinedContext;
134133 if (DebugInfoContext) {
135134 InlinedContext = DebugInfoContext->getInliningInfoForAddress(
136 ModuleOffset, getDILineInfoSpecifierFlags(Opts));
135 ModuleOffset, getDILineInfoSpecifier(Opts));
137136 }
138137 // Make sure there is at least one frame in context.
139138 if (InlinedContext.getNumberOfFrames() == 0) {