mirror of
https://github.com/RPCS3/llvm.git
synced 2025-05-13 17:06:15 +00: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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162895 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6b1e1d8b3d
commit
38a6381c0a
@ -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() { }
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user