mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[DWARF parser] Turn DILineInfo into a struct.
Immutable DILineInfo doesn't bring any benefits and complicates code. Also, use std::string instead of SmallString<16> for file and function names - their length can vary significantly. No functionality change. llvm-svn: 206654
This commit is contained in:
parent
3465898e26
commit
5a3863a395
@ -16,42 +16,31 @@
|
|||||||
#define LLVM_DEBUGINFO_DICONTEXT_H
|
#define LLVM_DEBUGINFO_DICONTEXT_H
|
||||||
|
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/SmallString.h"
|
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
|
||||||
#include "llvm/Object/ObjectFile.h"
|
#include "llvm/Object/ObjectFile.h"
|
||||||
#include "llvm/Object/RelocVisitor.h"
|
#include "llvm/Object/RelocVisitor.h"
|
||||||
#include "llvm/Support/Casting.h"
|
#include "llvm/Support/Casting.h"
|
||||||
#include "llvm/Support/DataTypes.h"
|
#include "llvm/Support/DataTypes.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class raw_ostream;
|
class raw_ostream;
|
||||||
|
|
||||||
/// DILineInfo - a format-neutral container for source line information.
|
/// DILineInfo - a format-neutral container for source line information.
|
||||||
class DILineInfo {
|
struct DILineInfo {
|
||||||
SmallString<16> FileName;
|
std::string FileName;
|
||||||
SmallString<16> FunctionName;
|
std::string FunctionName;
|
||||||
uint32_t Line;
|
uint32_t Line;
|
||||||
uint32_t Column;
|
uint32_t Column;
|
||||||
public:
|
|
||||||
DILineInfo()
|
|
||||||
: FileName("<invalid>"), FunctionName("<invalid>"),
|
|
||||||
Line(0), Column(0) {}
|
|
||||||
DILineInfo(StringRef fileName, StringRef functionName, uint32_t line,
|
|
||||||
uint32_t column)
|
|
||||||
: FileName(fileName), FunctionName(functionName), Line(line),
|
|
||||||
Column(column) {}
|
|
||||||
|
|
||||||
const char *getFileName() { return FileName.c_str(); }
|
DILineInfo()
|
||||||
const char *getFunctionName() { return FunctionName.c_str(); }
|
: FileName("<invalid>"), FunctionName("<invalid>"), Line(0), Column(0) {}
|
||||||
uint32_t getLine() const { return Line; }
|
|
||||||
uint32_t getColumn() const { return Column; }
|
|
||||||
|
|
||||||
bool operator==(const DILineInfo &RHS) const {
|
bool operator==(const DILineInfo &RHS) const {
|
||||||
return Line == RHS.Line && Column == RHS.Column &&
|
return Line == RHS.Line && Column == RHS.Column &&
|
||||||
FileName.equals(RHS.FileName) &&
|
FileName == RHS.FileName && FunctionName == RHS.FunctionName;
|
||||||
FunctionName.equals(RHS.FunctionName);
|
|
||||||
}
|
}
|
||||||
bool operator!=(const DILineInfo &RHS) const {
|
bool operator!=(const DILineInfo &RHS) const {
|
||||||
return !(*this == RHS);
|
return !(*this == RHS);
|
||||||
|
@ -443,8 +443,7 @@ static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
|
|||||||
const DWARFLineTable *LineTable,
|
const DWARFLineTable *LineTable,
|
||||||
uint64_t Address,
|
uint64_t Address,
|
||||||
bool NeedsAbsoluteFilePath,
|
bool NeedsAbsoluteFilePath,
|
||||||
std::string &FileName,
|
DILineInfo &Result) {
|
||||||
uint32_t &Line, uint32_t &Column) {
|
|
||||||
if (!CU || !LineTable)
|
if (!CU || !LineTable)
|
||||||
return false;
|
return false;
|
||||||
// Get the index of row we're looking for in the line table.
|
// Get the index of row we're looking for in the line table.
|
||||||
@ -453,45 +452,49 @@ static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
|
|||||||
return false;
|
return false;
|
||||||
// Take file number and line/column from the row.
|
// Take file number and line/column from the row.
|
||||||
const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
|
const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
|
||||||
if (!getFileNameForCompileUnit(CU, LineTable, Row.File,
|
if (!getFileNameForCompileUnit(CU, LineTable, Row.File, NeedsAbsoluteFilePath,
|
||||||
NeedsAbsoluteFilePath, FileName))
|
Result.FileName))
|
||||||
return false;
|
return false;
|
||||||
Line = Row.Line;
|
Result.Line = Row.Line;
|
||||||
Column = Row.Column;
|
Result.Column = Row.Column;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address,
|
||||||
|
std::string &FunctionName) {
|
||||||
|
// The address may correspond to instruction in some inlined function,
|
||||||
|
// so we have to build the chain of inlined functions and take the
|
||||||
|
// name of the topmost function in it.
|
||||||
|
const DWARFDebugInfoEntryInlinedChain &InlinedChain =
|
||||||
|
CU->getInlinedChainForAddress(Address);
|
||||||
|
if (InlinedChain.DIEs.size() == 0)
|
||||||
|
return false;
|
||||||
|
const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
|
||||||
|
if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U)) {
|
||||||
|
FunctionName = Name;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
|
DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
|
||||||
DILineInfoSpecifier Specifier) {
|
DILineInfoSpecifier Specifier) {
|
||||||
|
DILineInfo Result;
|
||||||
|
|
||||||
DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
|
DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
|
||||||
if (!CU)
|
if (!CU)
|
||||||
return DILineInfo();
|
return Result;
|
||||||
std::string FileName = "<invalid>";
|
|
||||||
std::string FunctionName = "<invalid>";
|
|
||||||
uint32_t Line = 0;
|
|
||||||
uint32_t Column = 0;
|
|
||||||
if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
|
if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
|
||||||
// The address may correspond to instruction in some inlined function,
|
getFunctionNameForAddress(CU, Address, Result.FunctionName);
|
||||||
// so we have to build the chain of inlined functions and take the
|
|
||||||
// name of the topmost function in it.
|
|
||||||
const DWARFDebugInfoEntryInlinedChain &InlinedChain =
|
|
||||||
CU->getInlinedChainForAddress(Address);
|
|
||||||
if (InlinedChain.DIEs.size() > 0) {
|
|
||||||
const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
|
|
||||||
if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U))
|
|
||||||
FunctionName = Name;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
|
if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
|
||||||
const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
|
const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
|
||||||
const bool NeedsAbsoluteFilePath =
|
const bool NeedsAbsoluteFilePath =
|
||||||
Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
|
Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
|
||||||
getFileLineInfoForCompileUnit(CU, LineTable, Address,
|
getFileLineInfoForCompileUnit(CU, LineTable, Address, NeedsAbsoluteFilePath,
|
||||||
NeedsAbsoluteFilePath,
|
Result);
|
||||||
FileName, Line, Column);
|
|
||||||
}
|
}
|
||||||
return DILineInfo(StringRef(FileName), StringRef(FunctionName),
|
return Result;
|
||||||
Line, Column);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address,
|
DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address,
|
||||||
@ -504,23 +507,15 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address,
|
|||||||
|
|
||||||
std::string FunctionName = "<invalid>";
|
std::string FunctionName = "<invalid>";
|
||||||
if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
|
if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
|
||||||
// The address may correspond to instruction in some inlined function,
|
getFunctionNameForAddress(CU, Address, FunctionName);
|
||||||
// so we have to build the chain of inlined functions and take the
|
|
||||||
// name of the topmost function in it.
|
|
||||||
const DWARFDebugInfoEntryInlinedChain &InlinedChain =
|
|
||||||
CU->getInlinedChainForAddress(Address);
|
|
||||||
if (InlinedChain.DIEs.size() > 0) {
|
|
||||||
const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
|
|
||||||
if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U))
|
|
||||||
FunctionName = Name;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the Specifier says we don't need FileLineInfo, just
|
// If the Specifier says we don't need FileLineInfo, just
|
||||||
// return the top-most function at the starting address.
|
// return the top-most function at the starting address.
|
||||||
if (!Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
|
if (!Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
|
||||||
Lines.push_back(
|
DILineInfo Result;
|
||||||
std::make_pair(Address, DILineInfo("<invalid>", FunctionName, 0, 0)));
|
Result.FunctionName = FunctionName;
|
||||||
|
Lines.push_back(std::make_pair(Address, Result));
|
||||||
return Lines;
|
return Lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -536,11 +531,13 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address,
|
|||||||
for (uint32_t RowIndex : RowVector) {
|
for (uint32_t RowIndex : RowVector) {
|
||||||
// Take file number and line/column from the row.
|
// Take file number and line/column from the row.
|
||||||
const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
|
const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
|
||||||
std::string FileName = "<invalid>";
|
DILineInfo Result;
|
||||||
getFileNameForCompileUnit(CU, LineTable, Row.File,
|
getFileNameForCompileUnit(CU, LineTable, Row.File, NeedsAbsoluteFilePath,
|
||||||
NeedsAbsoluteFilePath, FileName);
|
Result.FileName);
|
||||||
Lines.push_back(std::make_pair(
|
Result.FunctionName = FunctionName;
|
||||||
Row.Address, DILineInfo(FileName, FunctionName, Row.Line, Row.Column)));
|
Result.Line = Row.Line;
|
||||||
|
Result.Column = Row.Column;
|
||||||
|
Lines.push_back(std::make_pair(Row.Address, Result));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Lines;
|
return Lines;
|
||||||
@ -562,14 +559,11 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
|
|||||||
const DWARFLineTable *LineTable = nullptr;
|
const DWARFLineTable *LineTable = nullptr;
|
||||||
for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) {
|
for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) {
|
||||||
const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
|
const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
|
||||||
std::string FileName = "<invalid>";
|
DILineInfo Frame;
|
||||||
std::string FunctionName = "<invalid>";
|
|
||||||
uint32_t Line = 0;
|
|
||||||
uint32_t Column = 0;
|
|
||||||
// Get function name if necessary.
|
// Get function name if necessary.
|
||||||
if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
|
if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
|
||||||
if (const char *Name = FunctionDIE.getSubroutineName(InlinedChain.U))
|
if (const char *Name = FunctionDIE.getSubroutineName(InlinedChain.U))
|
||||||
FunctionName = Name;
|
Frame.FunctionName = Name;
|
||||||
}
|
}
|
||||||
if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
|
if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
|
||||||
const bool NeedsAbsoluteFilePath =
|
const bool NeedsAbsoluteFilePath =
|
||||||
@ -581,14 +575,14 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
|
|||||||
// For the topmost routine, get file/line info from line table.
|
// For the topmost routine, get file/line info from line table.
|
||||||
getFileLineInfoForCompileUnit(CU, LineTable, Address,
|
getFileLineInfoForCompileUnit(CU, LineTable, Address,
|
||||||
NeedsAbsoluteFilePath,
|
NeedsAbsoluteFilePath,
|
||||||
FileName, Line, Column);
|
Frame);
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, use call file, call line and call column from
|
// Otherwise, use call file, call line and call column from
|
||||||
// previous DIE in inlined chain.
|
// previous DIE in inlined chain.
|
||||||
getFileNameForCompileUnit(CU, LineTable, CallFile,
|
getFileNameForCompileUnit(CU, LineTable, CallFile,
|
||||||
NeedsAbsoluteFilePath, FileName);
|
NeedsAbsoluteFilePath, Frame.FileName);
|
||||||
Line = CallLine;
|
Frame.Line = CallLine;
|
||||||
Column = CallColumn;
|
Frame.Column = CallColumn;
|
||||||
}
|
}
|
||||||
// Get call file/line/column of a current DIE.
|
// Get call file/line/column of a current DIE.
|
||||||
if (i + 1 < n) {
|
if (i + 1 < n) {
|
||||||
@ -596,8 +590,6 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
|
|||||||
CallColumn);
|
CallColumn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DILineInfo Frame(StringRef(FileName), StringRef(FunctionName),
|
|
||||||
Line, Column);
|
|
||||||
InliningInfo.addFrame(Frame);
|
InliningInfo.addFrame(Frame);
|
||||||
}
|
}
|
||||||
return InliningInfo;
|
return InliningInfo;
|
||||||
|
@ -80,10 +80,8 @@ DumpType("debug-dump", cl::init(DIDT_All),
|
|||||||
|
|
||||||
static void PrintDILineInfo(DILineInfo dli) {
|
static void PrintDILineInfo(DILineInfo dli) {
|
||||||
if (PrintFunctions)
|
if (PrintFunctions)
|
||||||
outs() << (dli.getFunctionName() ? dli.getFunctionName() : "<unknown>")
|
outs() << dli.FunctionName << "\n";
|
||||||
<< "\n";
|
outs() << dli.FileName << ':' << dli.Line << ':' << dli.Column << '\n';
|
||||||
outs() << (dli.getFileName() ? dli.getFileName() : "<unknown>") << ':'
|
|
||||||
<< dli.getLine() << ':' << dli.getColumn() << '\n';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DumpInput(const StringRef &Filename) {
|
static void DumpInput(const StringRef &Filename) {
|
||||||
|
@ -421,9 +421,9 @@ static void DisassembleInputMachO2(StringRef Filename,
|
|||||||
DILineInfo dli =
|
DILineInfo dli =
|
||||||
diContext->getLineInfoForAddress(SectAddress + Index);
|
diContext->getLineInfoForAddress(SectAddress + Index);
|
||||||
// Print valid line info if it changed.
|
// Print valid line info if it changed.
|
||||||
if (dli != lastLine && dli.getLine() != 0)
|
if (dli != lastLine && dli.Line != 0)
|
||||||
outs() << "\t## " << dli.getFileName() << ':'
|
outs() << "\t## " << dli.FileName << ':' << dli.Line << ':'
|
||||||
<< dli.getLine() << ':' << dli.getColumn();
|
<< dli.Column;
|
||||||
lastLine = dli;
|
lastLine = dli;
|
||||||
}
|
}
|
||||||
outs() << "\n";
|
outs() << "\n";
|
||||||
|
@ -172,8 +172,7 @@ static int printLineInfoForInput() {
|
|||||||
DILineInfoTable::iterator End = Lines.end();
|
DILineInfoTable::iterator End = Lines.end();
|
||||||
for (DILineInfoTable::iterator It = Begin; It != End; ++It) {
|
for (DILineInfoTable::iterator It = Begin; It != End; ++It) {
|
||||||
outs() << " Line info @ " << It->first - Addr << ": "
|
outs() << " Line info @ " << It->first - Addr << ": "
|
||||||
<< It->second.getFileName()
|
<< It->second.FileName << ", line:" << It->second.Line << "\n";
|
||||||
<< ", line:" << It->second.getLine() << "\n";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,13 +44,6 @@ getDILineInfoSpecifierFlags(const LLVMSymbolizer::Options &Opts) {
|
|||||||
return Flags;
|
return Flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void patchFunctionNameInDILineInfo(const std::string &NewFunctionName,
|
|
||||||
DILineInfo &LineInfo) {
|
|
||||||
std::string FileName = LineInfo.getFileName();
|
|
||||||
LineInfo = DILineInfo(StringRef(FileName), StringRef(NewFunctionName),
|
|
||||||
LineInfo.getLine(), LineInfo.getColumn());
|
|
||||||
}
|
|
||||||
|
|
||||||
ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
|
ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
|
||||||
: Module(Obj), DebugInfoContext(DICtx) {
|
: Module(Obj), DebugInfoContext(DICtx) {
|
||||||
for (const SymbolRef &Symbol : Module->symbols()) {
|
for (const SymbolRef &Symbol : Module->symbols()) {
|
||||||
@ -130,7 +123,7 @@ DILineInfo ModuleInfo::symbolizeCode(
|
|||||||
uint64_t Start, Size;
|
uint64_t Start, Size;
|
||||||
if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset,
|
if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset,
|
||||||
FunctionName, Start, Size)) {
|
FunctionName, Start, Size)) {
|
||||||
patchFunctionNameInDILineInfo(FunctionName, LineInfo);
|
LineInfo.FunctionName = FunctionName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return LineInfo;
|
return LineInfo;
|
||||||
@ -157,7 +150,7 @@ DIInliningInfo ModuleInfo::symbolizeInlinedCode(
|
|||||||
uint64_t Start, Size;
|
uint64_t Start, Size;
|
||||||
if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset,
|
if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset,
|
||||||
FunctionName, Start, Size)) {
|
FunctionName, Start, Size)) {
|
||||||
patchFunctionNameInDILineInfo(FunctionName, LineInfo);
|
LineInfo.FunctionName = FunctionName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PatchedInlinedContext.addFrame(LineInfo);
|
PatchedInlinedContext.addFrame(LineInfo);
|
||||||
@ -408,18 +401,17 @@ std::string LLVMSymbolizer::printDILineInfo(DILineInfo LineInfo) const {
|
|||||||
static const std::string kDILineInfoBadString = "<invalid>";
|
static const std::string kDILineInfoBadString = "<invalid>";
|
||||||
std::stringstream Result;
|
std::stringstream Result;
|
||||||
if (Opts.PrintFunctions) {
|
if (Opts.PrintFunctions) {
|
||||||
std::string FunctionName = LineInfo.getFunctionName();
|
std::string FunctionName = LineInfo.FunctionName;
|
||||||
if (FunctionName == kDILineInfoBadString)
|
if (FunctionName == kDILineInfoBadString)
|
||||||
FunctionName = kBadString;
|
FunctionName = kBadString;
|
||||||
else if (Opts.Demangle)
|
else if (Opts.Demangle)
|
||||||
FunctionName = DemangleName(FunctionName);
|
FunctionName = DemangleName(FunctionName);
|
||||||
Result << FunctionName << "\n";
|
Result << FunctionName << "\n";
|
||||||
}
|
}
|
||||||
std::string Filename = LineInfo.getFileName();
|
std::string Filename = LineInfo.FileName;
|
||||||
if (Filename == kDILineInfoBadString)
|
if (Filename == kDILineInfoBadString)
|
||||||
Filename = kBadString;
|
Filename = kBadString;
|
||||||
Result << Filename << ":" << LineInfo.getLine() << ":" << LineInfo.getColumn()
|
Result << Filename << ":" << LineInfo.Line << ":" << LineInfo.Column << "\n";
|
||||||
<< "\n";
|
|
||||||
return Result.str();
|
return Result.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user