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

View File

@ -54,9 +54,6 @@ public:
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.
const DWARFDebugAbbrev *getDebugAbbrev();
@ -67,8 +64,8 @@ public:
const DWARFDebugLine::LineTable *
getLineTableForCompileUnit(DWARFCompileUnit *cu);
virtual DILineInfo getLineInfoForAddress(uint64_t address,
DILineInfoSpecifier specifier = DILineInfoSpecifier());
virtual DILineInfo getLineInfoForAddress(uint64_t Address,
DILineInfoSpecifier Specifier = DILineInfoSpecifier());
bool isLittleEndian() const { return IsLittleEndian; }
@ -82,8 +79,22 @@ public:
static bool isSupportedVersion(unsigned version) {
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
/// DWARFContext. It assumes all content is available in memory and stores

View File

@ -10,6 +10,7 @@
#include "DWARFDebugLine.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
using namespace llvm;
@ -513,3 +514,29 @@ DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const {
}
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 <map>
#include <string>
#include <vector>
namespace llvm {
@ -174,6 +175,13 @@ public:
// Returns the index of the row with file/line info for a given address,
// or -1 if there is no such row.
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;
struct Prologue Prologue;