Refactor fetching file/line info from DWARFContext to simplify the

code and allow better code reuse. Make the code a bit more conforming
to LLVM code style.
No functionality change.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162895 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Alexey Samsonov 2012-08-30 07:49:50 +00:00
parent 6b1e1d8b3d
commit 38a6381c0a
4 changed files with 127 additions and 63 deletions

View File

@ -145,75 +145,93 @@ namespace {
}; };
} }
DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t offset) { DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
if (CUs.empty()) if (CUs.empty())
parseCompileUnits(); parseCompileUnits();
DWARFCompileUnit *i = std::lower_bound(CUs.begin(), CUs.end(), offset, DWARFCompileUnit *CU = std::lower_bound(CUs.begin(), CUs.end(), Offset,
OffsetComparator()); OffsetComparator());
if (i != CUs.end()) if (CU != CUs.end())
return &*i; return &*CU;
return 0; return 0;
} }
DILineInfo DWARFContext::getLineInfoForAddress(uint64_t address, DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
DILineInfoSpecifier specifier) {
// First, get the offset of the compile unit. // First, get the offset of the compile unit.
uint32_t cuOffset = getDebugAranges()->findAddress(address); uint32_t CUOffset = getDebugAranges()->findAddress(Address);
// Retrieve the compile unit. // Retrieve the compile unit.
DWARFCompileUnit *cu = getCompileUnitForOffset(cuOffset); return getCompileUnitForOffset(CUOffset);
if (!cu) }
return DILineInfo();
SmallString<16> fileName("<invalid>"); static bool getFileNameForCompileUnit(
SmallString<16> functionName("<invalid>"); DWARFCompileUnit *CU, const DWARFDebugLine::LineTable *LineTable,
uint32_t line = 0; uint64_t FileIndex, bool NeedsAbsoluteFilePath, std::string &FileName) {
uint32_t column = 0; if (CU == 0 ||
if (specifier.needs(DILineInfoSpecifier::FunctionName)) { LineTable == 0 ||
const DWARFDebugInfoEntryMinimal *function_die = !LineTable->getFileNameByIndex(FileIndex, NeedsAbsoluteFilePath,
cu->getFunctionDIEForAddress(address); FileName))
if (function_die) { return false;
if (const char *name = function_die->getSubprogramName(cu)) if (NeedsAbsoluteFilePath && sys::path::is_relative(FileName)) {
functionName = name; // We may still need to append compilation directory of compile unit.
SmallString<16> AbsolutePath;
if (const char *CompilationDir = CU->getCompilationDir()) {
sys::path::append(AbsolutePath, CompilationDir);
} }
sys::path::append(AbsolutePath, FileName);
FileName = AbsolutePath.str();
} }
if (specifier.needs(DILineInfoSpecifier::FileLineInfo)) { return true;
}
bool
DWARFContext::getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
uint64_t Address,
bool NeedsAbsoluteFilePath,
std::string &FileName,
uint32_t &Line, uint32_t &Column) {
// Get the line table for this compile unit. // Get the line table for this compile unit.
const DWARFDebugLine::LineTable *lineTable = getLineTableForCompileUnit(cu); const DWARFDebugLine::LineTable *LineTable = getLineTableForCompileUnit(CU);
if (lineTable) { if (!LineTable)
// Get the index of the row we're looking for in the line table. return false;
uint32_t rowIndex = lineTable->lookupAddress(address); // Get the index of row we're looking for in the line table.
if (rowIndex != -1U) { uint32_t RowIndex = LineTable->lookupAddress(Address);
const DWARFDebugLine::Row &row = lineTable->Rows[rowIndex]; if (RowIndex == -1U)
// Take file/line info from the line table. return false;
const DWARFDebugLine::FileNameEntry &fileNameEntry = // Take file number and line/column from the row.
lineTable->Prologue.FileNames[row.File - 1]; const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
fileName = fileNameEntry.Name; if (!getFileNameForCompileUnit(CU, LineTable, Row.File,
if (specifier.needs(DILineInfoSpecifier::AbsoluteFilePath) && NeedsAbsoluteFilePath, FileName))
sys::path::is_relative(fileName.str())) { return false;
// Append include directory of file (if it is present in line table) Line = Row.Line;
// and compilation directory of compile unit to make path absolute. Column = Row.Column;
const char *includeDir = 0; return true;
if (uint64_t includeDirIndex = fileNameEntry.DirIdx) { }
includeDir = lineTable->Prologue
.IncludeDirectories[includeDirIndex - 1]; DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
} DILineInfoSpecifier Specifier) {
SmallString<16> absFileName; DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
if (includeDir == 0 || sys::path::is_relative(includeDir)) { if (!CU)
if (const char *compilationDir = cu->getCompilationDir()) return DILineInfo();
sys::path::append(absFileName, compilationDir); std::string FileName = "<invalid>";
} std::string FunctionName = "<invalid>";
if (includeDir) { uint32_t Line = 0;
sys::path::append(absFileName, includeDir); uint32_t Column = 0;
} if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
sys::path::append(absFileName, fileName.str()); const DWARFDebugInfoEntryMinimal *FunctionDIE =
fileName = absFileName; CU->getFunctionDIEForAddress(Address);
} if (FunctionDIE) {
line = row.Line; if (const char *Name = FunctionDIE->getSubprogramName(CU))
column = row.Column; FunctionName = Name;
} }
} }
if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
const bool NeedsAbsoluteFilePath =
Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
getFileLineInfoForCompileUnit(CU, Address, NeedsAbsoluteFilePath,
FileName, Line, Column);
} }
return DILineInfo(fileName, functionName, line, column); return DILineInfo(StringRef(FileName), StringRef(FunctionName),
Line, Column);
} }
void DWARFContextInMemory::anchor() { } void DWARFContextInMemory::anchor() { }

View File

@ -54,9 +54,6 @@ public:
return &CUs[index]; return &CUs[index];
} }
/// Return the compile unit that includes an offset (relative to .debug_info).
DWARFCompileUnit *getCompileUnitForOffset(uint32_t offset);
/// Get a pointer to the parsed DebugAbbrev object. /// Get a pointer to the parsed DebugAbbrev object.
const DWARFDebugAbbrev *getDebugAbbrev(); const DWARFDebugAbbrev *getDebugAbbrev();
@ -67,8 +64,8 @@ public:
const DWARFDebugLine::LineTable * const DWARFDebugLine::LineTable *
getLineTableForCompileUnit(DWARFCompileUnit *cu); getLineTableForCompileUnit(DWARFCompileUnit *cu);
virtual DILineInfo getLineInfoForAddress(uint64_t address, virtual DILineInfo getLineInfoForAddress(uint64_t Address,
DILineInfoSpecifier specifier = DILineInfoSpecifier()); DILineInfoSpecifier Specifier = DILineInfoSpecifier());
bool isLittleEndian() const { return IsLittleEndian; } bool isLittleEndian() const { return IsLittleEndian; }
@ -82,8 +79,22 @@ public:
static bool isSupportedVersion(unsigned version) { static bool isSupportedVersion(unsigned version) {
return version == 2 || version == 3; return version == 2 || version == 3;
} }
}; private:
/// Return the compile unit that includes an offset (relative to .debug_info).
DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset);
/// Return the compile unit which contains instruction with provided
/// address.
DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
/// Fetches filename, line and column number for given address and
/// compile unit. Returns true on success.
bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
uint64_t Address,
bool NeedsAbsoluteFilePath,
std::string &FileName,
uint32_t &Line, uint32_t &Column);
};
/// DWARFContextInMemory is the simplest possible implementation of a /// DWARFContextInMemory is the simplest possible implementation of a
/// DWARFContext. It assumes all content is available in memory and stores /// DWARFContext. It assumes all content is available in memory and stores

View File

@ -10,6 +10,7 @@
#include "DWARFDebugLine.h" #include "DWARFDebugLine.h"
#include "llvm/Support/Dwarf.h" #include "llvm/Support/Dwarf.h"
#include "llvm/Support/Format.h" #include "llvm/Support/Format.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include <algorithm> #include <algorithm>
using namespace llvm; using namespace llvm;
@ -513,3 +514,29 @@ DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const {
} }
return index; return index;
} }
bool
DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex,
bool NeedsAbsoluteFilePath,
std::string &Result) const {
if (FileIndex == 0 || FileIndex > Prologue.FileNames.size())
return false;
const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1];
const char *FileName = Entry.Name;
if (!NeedsAbsoluteFilePath ||
sys::path::is_absolute(FileName)) {
Result = FileName;
return true;
}
SmallString<16> FilePath;
uint64_t IncludeDirIndex = Entry.DirIdx;
// Be defensive about the contents of Entry.
if (IncludeDirIndex > 0 &&
IncludeDirIndex <= Prologue.IncludeDirectories.size()) {
const char *IncludeDir = Prologue.IncludeDirectories[IncludeDirIndex - 1];
sys::path::append(FilePath, IncludeDir);
}
sys::path::append(FilePath, FileName);
Result = FilePath.str();
return true;
}

View File

@ -12,6 +12,7 @@
#include "llvm/Support/DataExtractor.h" #include "llvm/Support/DataExtractor.h"
#include <map> #include <map>
#include <string>
#include <vector> #include <vector>
namespace llvm { namespace llvm {
@ -174,6 +175,13 @@ public:
// Returns the index of the row with file/line info for a given address, // Returns the index of the row with file/line info for a given address,
// or -1 if there is no such row. // or -1 if there is no such row.
uint32_t lookupAddress(uint64_t address) const; uint32_t lookupAddress(uint64_t address) const;
// Extracts filename by its index in filename table in prologue.
// Returns true on success.
bool getFileNameByIndex(uint64_t FileIndex,
bool NeedsAbsoluteFilePath,
std::string &Result) const;
void dump(raw_ostream &OS) const; void dump(raw_ostream &OS) const;
struct Prologue Prologue; struct Prologue Prologue;