1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

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.

llvm-svn: 162895
This commit is contained in:
Alexey Samsonov 2012-08-30 07:49:50 +00:00
parent 5eb7de25c9
commit ac2e149b2d
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) }
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(); return DILineInfo();
SmallString<16> fileName("<invalid>"); std::string FileName = "<invalid>";
SmallString<16> functionName("<invalid>"); std::string FunctionName = "<invalid>";
uint32_t line = 0; uint32_t Line = 0;
uint32_t column = 0; uint32_t Column = 0;
if (specifier.needs(DILineInfoSpecifier::FunctionName)) { if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
const DWARFDebugInfoEntryMinimal *function_die = const DWARFDebugInfoEntryMinimal *FunctionDIE =
cu->getFunctionDIEForAddress(address); CU->getFunctionDIEForAddress(Address);
if (function_die) { if (FunctionDIE) {
if (const char *name = function_die->getSubprogramName(cu)) if (const char *Name = FunctionDIE->getSubprogramName(CU))
functionName = name; FunctionName = Name;
} }
} }
if (specifier.needs(DILineInfoSpecifier::FileLineInfo)) { if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
// Get the line table for this compile unit. const bool NeedsAbsoluteFilePath =
const DWARFDebugLine::LineTable *lineTable = getLineTableForCompileUnit(cu); Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
if (lineTable) { getFileLineInfoForCompileUnit(CU, Address, NeedsAbsoluteFilePath,
// Get the index of the row we're looking for in the line table. FileName, Line, Column);
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;
}
}
} }
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;