Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit c2c0420

Browse files
committed
Re-land "[dwarfdump] Add -lookup option"
Add the option to lookup an address in the debug information and print out the file, function, block and line table details. Differential revision: https://reviews.llvm.org/D38409 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316619 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 5d1f72d commit c2c0420

File tree

8 files changed

+382
-10
lines changed

8 files changed

+382
-10
lines changed

include/llvm/DebugInfo/DIContext.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "llvm/ADT/SmallVector.h"
1919
#include "llvm/Object/ObjectFile.h"
20+
#include "llvm/Support/raw_ostream.h"
2021
#include <cassert>
2122
#include <cstdint>
2223
#include <memory>
@@ -26,8 +27,6 @@
2627

2728
namespace llvm {
2829

29-
class raw_ostream;
30-
3130
/// A format-neutral container for source line information.
3231
struct DILineInfo {
3332
std::string FileName;
@@ -46,15 +45,30 @@ struct DILineInfo {
4645
FileName == RHS.FileName && FunctionName == RHS.FunctionName &&
4746
StartLine == RHS.StartLine && Discriminator == RHS.Discriminator;
4847
}
48+
4949
bool operator!=(const DILineInfo &RHS) const {
5050
return !(*this == RHS);
5151
}
52+
5253
bool operator<(const DILineInfo &RHS) const {
5354
return std::tie(FileName, FunctionName, Line, Column, StartLine,
5455
Discriminator) <
5556
std::tie(RHS.FileName, RHS.FunctionName, RHS.Line, RHS.Column,
5657
RHS.StartLine, RHS.Discriminator);
5758
}
59+
60+
explicit operator bool() const { return *this != DILineInfo(); }
61+
62+
void dump(raw_ostream &OS) {
63+
OS << "Line info: ";
64+
if (FileName != "<invalid>")
65+
OS << "file '" << FileName << "', ";
66+
if (FunctionName != "<invalid>")
67+
OS << "function '" << FunctionName << "', ";
68+
OS << "line " << Line << ", ";
69+
OS << "column " << Column << ", ";
70+
OS << "start line " << StartLine << '\n';
71+
}
5872
};
5973

6074
using DILineInfoTable = SmallVector<std::pair<uint64_t, DILineInfo>, 16>;

include/llvm/DebugInfo/DWARF/DWARFContext.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,18 @@ class DWARFContext : public DIContext {
257257
/// Get a pointer to a parsed line table corresponding to a compile unit.
258258
const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *cu);
259259

260+
/// Wraps the returned DIEs for a given address.
261+
struct DIEsForAddress {
262+
DWARFCompileUnit *CompileUnit = nullptr;
263+
DWARFDie FunctionDIE;
264+
DWARFDie BlockDIE;
265+
explicit operator bool() const { return CompileUnit != nullptr; }
266+
};
267+
268+
/// Get the compilation unit, the function DIE and lexical block DIE for the
269+
/// given address where applicable.
270+
DIEsForAddress getDIEsForAddress(uint64_t Address);
271+
260272
DILineInfo getLineInfoForAddress(uint64_t Address,
261273
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
262274
DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size,

include/llvm/DebugInfo/DWARF/DWARFUnit.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,11 @@ class DWARFUnit {
338338

339339
void collectAddressRanges(DWARFAddressRangesVector &CURanges);
340340

341+
/// Returns subprogram DIE with address range encompassing the provided
342+
/// address. The pointer is alive as long as parsed compile unit DIEs are not
343+
/// cleared.
344+
DWARFDie getSubroutineForAddress(uint64_t Address);
345+
341346
/// getInlinedChainForAddress - fetches inlined chain for a given address.
342347
/// Returns empty chain if there is no subprogram containing address. The
343348
/// chain is valid as long as parsed compile unit DIEs are not cleared.
@@ -421,11 +426,6 @@ class DWARFUnit {
421426
/// parseDWO - Parses .dwo file for current compile unit. Returns true if
422427
/// it was actually constructed.
423428
bool parseDWO();
424-
425-
/// getSubroutineForAddress - Returns subprogram DIE with address range
426-
/// encompassing the provided address. The pointer is alive as long as parsed
427-
/// compile unit DIEs are not cleared.
428-
DWARFDie getSubroutineForAddress(uint64_t Address);
429429
};
430430

431431
} // end namespace llvm

lib/DebugInfo/DWARF/DWARFContext.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@
4848
#include <cstdint>
4949
#include <map>
5050
#include <string>
51-
#include <tuple>
5251
#include <utility>
5352
#include <vector>
5453

@@ -723,6 +722,35 @@ DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
723722
return getCompileUnitForOffset(CUOffset);
724723
}
725724

725+
DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address) {
726+
DIEsForAddress Result;
727+
728+
DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
729+
if (!CU)
730+
return Result;
731+
732+
Result.CompileUnit = CU;
733+
Result.FunctionDIE = CU->getSubroutineForAddress(Address);
734+
735+
std::vector<DWARFDie> Worklist;
736+
Worklist.push_back(Result.FunctionDIE);
737+
while (!Worklist.empty()) {
738+
DWARFDie DIE = Worklist.back();
739+
Worklist.pop_back();
740+
741+
if (DIE.getTag() == DW_TAG_lexical_block &&
742+
DIE.addressRangeContainsAddress(Address)) {
743+
Result.BlockDIE = DIE;
744+
break;
745+
}
746+
747+
for (auto Child : DIE)
748+
Worklist.push_back(Child);
749+
}
750+
751+
return Result;
752+
}
753+
726754
static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU,
727755
uint64_t Address,
728756
FunctionNameKind Kind,

lib/DebugInfo/DWARF/DWARFUnit.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ DWARFDie DWARFUnit::getSibling(const DWARFDebugInfoEntry *Die) {
440440
// NULL DIEs don't have siblings.
441441
if (Die->getAbbreviationDeclarationPtr() == nullptr)
442442
return DWARFDie();
443-
443+
444444
// Find the next DIE whose depth is the same as the Die's depth.
445445
for (size_t I = getDIEIndex(Die) + 1, EndIdx = DieArray.size(); I < EndIdx;
446446
++I) {

0 commit comments

Comments
 (0)