Skip to content

Commit

Permalink
[dwarfdump] Add -lookup option
Browse files Browse the repository at this point in the history
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

llvm-svn: 314817
  • Loading branch information
JDevlieghere committed Oct 3, 2017
1 parent 2ce23ab commit f998c50
Show file tree
Hide file tree
Showing 8 changed files with 385 additions and 14 deletions.
18 changes: 16 additions & 2 deletions llvm/include/llvm/DebugInfo/DIContext.h
Expand Up @@ -17,6 +17,7 @@

#include "llvm/ADT/SmallVector.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstdint>
#include <memory>
Expand All @@ -26,8 +27,6 @@

namespace llvm {

class raw_ostream;

/// A format-neutral container for source line information.
struct DILineInfo {
std::string FileName;
Expand All @@ -46,15 +45,30 @@ struct DILineInfo {
FileName == RHS.FileName && FunctionName == RHS.FunctionName &&
StartLine == RHS.StartLine && Discriminator == RHS.Discriminator;
}

bool operator!=(const DILineInfo &RHS) const {
return !(*this == RHS);
}

bool operator<(const DILineInfo &RHS) const {
return std::tie(FileName, FunctionName, Line, Column, StartLine,
Discriminator) <
std::tie(RHS.FileName, RHS.FunctionName, RHS.Line, RHS.Column,
RHS.StartLine, RHS.Discriminator);
}

operator bool() const { return (*this) != DILineInfo(); }

void dump(raw_ostream &OS) {
OS << "Line info: ";
if (FileName != "<invalid>")
OS << "file '" << FileName << "', ";
if (FunctionName != "<invalid>")
OS << "function '" << FunctionName << "', ";
OS << "line " << Line << ", ";
OS << "column " << Column << ", ";
OS << "start line " << StartLine << '\n';
}
};

using DILineInfoTable = SmallVector<std::pair<uint64_t, DILineInfo>, 16>;
Expand Down
12 changes: 12 additions & 0 deletions llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
Expand Up @@ -257,6 +257,18 @@ class DWARFContext : public DIContext {
/// Get a pointer to a parsed line table corresponding to a compile unit.
const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *cu);

/// Wraps the returned DIEs for a given address.
struct DIEsForAddress {
DWARFCompileUnit *CompileUnit = nullptr;
DWARFDie FunctionDIE;
DWARFDie BlockDIE;
operator bool() const { return CompileUnit != nullptr; }
};

/// Get the compilation unit, the function DIE and lexical block DIE for the
/// given address where applicable.
DIEsForAddress getDIEsForAddress(uint64_t Address);

DILineInfo getLineInfoForAddress(uint64_t Address,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
Expand Down
10 changes: 5 additions & 5 deletions llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
Expand Up @@ -329,6 +329,11 @@ class DWARFUnit {

void collectAddressRanges(DWARFAddressRangesVector &CURanges);

/// Returns subprogram DIE with address range encompassing the provided
/// address. The pointer is alive as long as parsed compile unit DIEs are not
/// cleared.
DWARFDie getSubroutineForAddress(uint64_t Address);

/// getInlinedChainForAddress - fetches inlined chain for a given address.
/// Returns empty chain if there is no subprogram containing address. The
/// chain is valid as long as parsed compile unit DIEs are not cleared.
Expand Down Expand Up @@ -411,11 +416,6 @@ class DWARFUnit {
/// parseDWO - Parses .dwo file for current compile unit. Returns true if
/// it was actually constructed.
bool parseDWO();

/// getSubroutineForAddress - Returns subprogram DIE with address range
/// encompassing the provided address. The pointer is alive as long as parsed
/// compile unit DIEs are not cleared.
DWARFDie getSubroutineForAddress(uint64_t Address);
};

} // end namespace llvm
Expand Down
30 changes: 29 additions & 1 deletion llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
Expand Up @@ -48,7 +48,6 @@
#include <cstdint>
#include <map>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

Expand Down Expand Up @@ -723,6 +722,35 @@ DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
return getCompileUnitForOffset(CUOffset);
}

DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address) {
DIEsForAddress Result;

DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
if (!CU)
return Result;

Result.CompileUnit = CU;
Result.FunctionDIE = CU->getSubroutineForAddress(Address);

std::vector<DWARFDie> Worklist;
Worklist.push_back(Result.FunctionDIE);
while (!Worklist.empty()) {
DWARFDie DIE = Worklist.back();
Worklist.pop_back();

if (DIE.getTag() == DW_TAG_lexical_block &&
DIE.addressRangeContainsAddress(Address)) {
Result.BlockDIE = DIE;
break;
}

for (auto Child : DIE)
Worklist.push_back(Child);
}

return Result;
}

static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU,
uint64_t Address,
FunctionNameKind Kind,
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
Expand Up @@ -440,7 +440,7 @@ DWARFDie DWARFUnit::getSibling(const DWARFDebugInfoEntry *Die) {
// NULL DIEs don't have siblings.
if (Die->getAbbreviationDeclarationPtr() == nullptr)
return DWARFDie();

// Find the next DIE whose depth is the same as the Die's depth.
for (size_t I = getDIEIndex(Die) + 1, EndIdx = DieArray.size(); I < EndIdx;
++I) {
Expand Down

0 comments on commit f998c50

Please sign in to comment.