mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
[DWARF parser] Use enums instead of bitfields in DILineInfoSpecifier.
It is more appropriate than the current situation, when one flag (AbsoluteFilePath) is relevant only if another flag is set. This refactoring would also simplify fetching the short function name (stored in DW_AT_name) instead of a linkage name returned currently. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208921 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
48ea98d1d2
commit
b043c3d94a
@ -68,19 +68,16 @@ class DIInliningInfo {
|
||||
|
||||
/// DILineInfoSpecifier - controls which fields of DILineInfo container
|
||||
/// should be filled with data.
|
||||
class DILineInfoSpecifier {
|
||||
const uint32_t Flags; // Or'ed flags that set the info we want to fetch.
|
||||
public:
|
||||
enum Specification {
|
||||
FileLineInfo = 1 << 0,
|
||||
AbsoluteFilePath = 1 << 1,
|
||||
FunctionName = 1 << 2
|
||||
};
|
||||
// Use file/line info by default.
|
||||
DILineInfoSpecifier(uint32_t flags = FileLineInfo) : Flags(flags) {}
|
||||
bool needs(Specification spec) const {
|
||||
return (Flags & spec) > 0;
|
||||
}
|
||||
struct DILineInfoSpecifier {
|
||||
enum class FileLineInfoKind { None, Default, AbsoluteFilePath };
|
||||
enum class FunctionNameKind { None, LinkageName };
|
||||
|
||||
FileLineInfoKind FLIKind;
|
||||
FunctionNameKind FNKind;
|
||||
|
||||
DILineInfoSpecifier(FileLineInfoKind FLIKind = FileLineInfoKind::Default,
|
||||
FunctionNameKind FNKind = FunctionNameKind::None)
|
||||
: FLIKind(FLIKind), FNKind(FNKind) {}
|
||||
};
|
||||
|
||||
/// Selects which debug sections get dumped.
|
||||
|
@ -25,6 +25,8 @@ using namespace object;
|
||||
#define DEBUG_TYPE "dwarf"
|
||||
|
||||
typedef DWARFDebugLine::LineTable DWARFLineTable;
|
||||
typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
|
||||
typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
|
||||
|
||||
static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data,
|
||||
bool LittleEndian, bool GnuStyle) {
|
||||
@ -425,14 +427,13 @@ DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
|
||||
|
||||
static bool getFileNameForCompileUnit(DWARFCompileUnit *CU,
|
||||
const DWARFLineTable *LineTable,
|
||||
uint64_t FileIndex,
|
||||
bool NeedsAbsoluteFilePath,
|
||||
uint64_t FileIndex, FileLineInfoKind Kind,
|
||||
std::string &FileName) {
|
||||
if (!CU || !LineTable ||
|
||||
!LineTable->getFileNameByIndex(FileIndex, NeedsAbsoluteFilePath,
|
||||
FileName))
|
||||
if (!CU || !LineTable || Kind == FileLineInfoKind::None ||
|
||||
!LineTable->getFileNameByIndex(FileIndex, Kind, FileName))
|
||||
return false;
|
||||
if (NeedsAbsoluteFilePath && sys::path::is_relative(FileName)) {
|
||||
if (Kind == FileLineInfoKind::AbsoluteFilePath &&
|
||||
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()) {
|
||||
@ -447,7 +448,7 @@ static bool getFileNameForCompileUnit(DWARFCompileUnit *CU,
|
||||
static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
|
||||
const DWARFLineTable *LineTable,
|
||||
uint64_t Address,
|
||||
bool NeedsAbsoluteFilePath,
|
||||
FileLineInfoKind Kind,
|
||||
DILineInfo &Result) {
|
||||
if (!CU || !LineTable)
|
||||
return false;
|
||||
@ -457,7 +458,7 @@ static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
|
||||
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,
|
||||
if (!getFileNameForCompileUnit(CU, LineTable, Row.File, Kind,
|
||||
Result.FileName))
|
||||
return false;
|
||||
Result.Line = Row.Line;
|
||||
@ -466,7 +467,10 @@ static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
|
||||
}
|
||||
|
||||
static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address,
|
||||
FunctionNameKind Kind,
|
||||
std::string &FunctionName) {
|
||||
if (Kind == FunctionNameKind::None)
|
||||
return false;
|
||||
// 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.
|
||||
@ -475,7 +479,8 @@ static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address,
|
||||
if (InlinedChain.DIEs.size() == 0)
|
||||
return false;
|
||||
const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
|
||||
if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U)) {
|
||||
if (const char *Name =
|
||||
TopFunctionDIE.getSubroutineName(InlinedChain.U, Kind)) {
|
||||
FunctionName = Name;
|
||||
return true;
|
||||
}
|
||||
@ -483,41 +488,34 @@ static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address,
|
||||
}
|
||||
|
||||
DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
|
||||
DILineInfoSpecifier Specifier) {
|
||||
DILineInfoSpecifier Spec) {
|
||||
DILineInfo Result;
|
||||
|
||||
DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
|
||||
if (!CU)
|
||||
return Result;
|
||||
if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
|
||||
getFunctionNameForAddress(CU, Address, Result.FunctionName);
|
||||
}
|
||||
if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
|
||||
getFunctionNameForAddress(CU, Address, Spec.FNKind, Result.FunctionName);
|
||||
if (Spec.FLIKind != FileLineInfoKind::None) {
|
||||
const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
|
||||
const bool NeedsAbsoluteFilePath =
|
||||
Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
|
||||
getFileLineInfoForCompileUnit(CU, LineTable, Address, NeedsAbsoluteFilePath,
|
||||
Result);
|
||||
getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind, Result);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address,
|
||||
uint64_t Size,
|
||||
DILineInfoSpecifier Specifier) {
|
||||
DILineInfoTable
|
||||
DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
|
||||
DILineInfoSpecifier Spec) {
|
||||
DILineInfoTable Lines;
|
||||
DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
|
||||
if (!CU)
|
||||
return Lines;
|
||||
|
||||
std::string FunctionName = "<invalid>";
|
||||
if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
|
||||
getFunctionNameForAddress(CU, Address, FunctionName);
|
||||
}
|
||||
getFunctionNameForAddress(CU, Address, Spec.FNKind, FunctionName);
|
||||
|
||||
// If the Specifier says we don't need FileLineInfo, just
|
||||
// return the top-most function at the starting address.
|
||||
if (!Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
|
||||
if (Spec.FLIKind == FileLineInfoKind::None) {
|
||||
DILineInfo Result;
|
||||
Result.FunctionName = FunctionName;
|
||||
Lines.push_back(std::make_pair(Address, Result));
|
||||
@ -525,8 +523,6 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address,
|
||||
}
|
||||
|
||||
const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
|
||||
const bool NeedsAbsoluteFilePath =
|
||||
Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
|
||||
|
||||
// Get the index of row we're looking for in the line table.
|
||||
std::vector<uint32_t> RowVector;
|
||||
@ -537,7 +533,7 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address,
|
||||
// Take file number and line/column from the row.
|
||||
const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
|
||||
DILineInfo Result;
|
||||
getFileNameForCompileUnit(CU, LineTable, Row.File, NeedsAbsoluteFilePath,
|
||||
getFileNameForCompileUnit(CU, LineTable, Row.File, Spec.FLIKind,
|
||||
Result.FileName);
|
||||
Result.FunctionName = FunctionName;
|
||||
Result.Line = Row.Line;
|
||||
@ -548,8 +544,9 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address,
|
||||
return Lines;
|
||||
}
|
||||
|
||||
DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
|
||||
DILineInfoSpecifier Specifier) {
|
||||
DIInliningInfo
|
||||
DWARFContext::getInliningInfoForAddress(uint64_t Address,
|
||||
DILineInfoSpecifier Spec) {
|
||||
DIInliningInfo InliningInfo;
|
||||
|
||||
DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
|
||||
@ -557,18 +554,16 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
|
||||
return InliningInfo;
|
||||
|
||||
const DWARFLineTable *LineTable = nullptr;
|
||||
const bool NeedsAbsoluteFilePath =
|
||||
Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
|
||||
const DWARFDebugInfoEntryInlinedChain &InlinedChain =
|
||||
CU->getInlinedChainForAddress(Address);
|
||||
if (InlinedChain.DIEs.size() == 0) {
|
||||
// If there is no DIE for address (e.g. it is in unavailable .dwo file),
|
||||
// try to at least get file/line info from symbol table.
|
||||
if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
|
||||
if (Spec.FLIKind != FileLineInfoKind::None) {
|
||||
DILineInfo Frame;
|
||||
LineTable = getLineTableForCompileUnit(CU);
|
||||
if (getFileLineInfoForCompileUnit(CU, LineTable, Address,
|
||||
NeedsAbsoluteFilePath, Frame)) {
|
||||
if (getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind,
|
||||
Frame)) {
|
||||
InliningInfo.addFrame(Frame);
|
||||
}
|
||||
}
|
||||
@ -580,23 +575,22 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
|
||||
const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
|
||||
DILineInfo Frame;
|
||||
// Get function name if necessary.
|
||||
if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
|
||||
if (const char *Name = FunctionDIE.getSubroutineName(InlinedChain.U))
|
||||
Frame.FunctionName = Name;
|
||||
}
|
||||
if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
|
||||
if (const char *Name =
|
||||
FunctionDIE.getSubroutineName(InlinedChain.U, Spec.FNKind))
|
||||
Frame.FunctionName = Name;
|
||||
if (Spec.FLIKind != FileLineInfoKind::None) {
|
||||
if (i == 0) {
|
||||
// For the topmost frame, initialize the line table of this
|
||||
// compile unit and fetch file/line info from it.
|
||||
LineTable = getLineTableForCompileUnit(CU);
|
||||
// For the topmost routine, get file/line info from line table.
|
||||
getFileLineInfoForCompileUnit(CU, LineTable, Address,
|
||||
NeedsAbsoluteFilePath, Frame);
|
||||
getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind,
|
||||
Frame);
|
||||
} else {
|
||||
// Otherwise, use call file, call line and call column from
|
||||
// previous DIE in inlined chain.
|
||||
getFileNameForCompileUnit(CU, LineTable, CallFile,
|
||||
NeedsAbsoluteFilePath, Frame.FileName);
|
||||
getFileNameForCompileUnit(CU, LineTable, CallFile, Spec.FLIKind,
|
||||
Frame.FileName);
|
||||
Frame.Line = CallLine;
|
||||
Frame.Column = CallColumn;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
using namespace dwarf;
|
||||
typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
|
||||
|
||||
void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u,
|
||||
unsigned recurseDepth,
|
||||
@ -272,8 +273,9 @@ bool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
|
||||
}
|
||||
|
||||
const char *
|
||||
DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U) const {
|
||||
if (!isSubroutineDIE())
|
||||
DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U,
|
||||
FunctionNameKind Kind) const {
|
||||
if (!isSubroutineDIE() || Kind == FunctionNameKind::None)
|
||||
return nullptr;
|
||||
// Try to get mangled name if possible.
|
||||
if (const char *name =
|
||||
@ -290,7 +292,7 @@ DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U) const {
|
||||
if (spec_ref != -1U) {
|
||||
DWARFDebugInfoEntryMinimal spec_die;
|
||||
if (spec_die.extractFast(U, &spec_ref)) {
|
||||
if (const char *name = spec_die.getSubroutineName(U))
|
||||
if (const char *name = spec_die.getSubroutineName(U, Kind))
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@ -300,7 +302,7 @@ DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U) const {
|
||||
if (abs_origin_ref != -1U) {
|
||||
DWARFDebugInfoEntryMinimal abs_origin_die;
|
||||
if (abs_origin_die.extractFast(U, &abs_origin_ref)) {
|
||||
if (const char *name = abs_origin_die.getSubroutineName(U))
|
||||
if (const char *name = abs_origin_die.getSubroutineName(U, Kind))
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "DWARFAbbreviationDeclaration.h"
|
||||
#include "DWARFDebugRangeList.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/DebugInfo/DIContext.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
@ -122,7 +123,9 @@ public:
|
||||
/// returns its mangled name (or short name, if mangled is missing).
|
||||
/// This name may be fetched from specification or abstract origin
|
||||
/// for this subprogram. Returns null if no name is found.
|
||||
const char *getSubroutineName(const DWARFUnit *U) const;
|
||||
const char *
|
||||
getSubroutineName(const DWARFUnit *U,
|
||||
DILineInfoSpecifier::FunctionNameKind Kind) const;
|
||||
|
||||
/// Retrieves values of DW_AT_call_file, DW_AT_call_line and
|
||||
/// DW_AT_call_column from DIE (or zeroes if they are missing).
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <algorithm>
|
||||
using namespace llvm;
|
||||
using namespace dwarf;
|
||||
typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
|
||||
|
||||
DWARFDebugLine::Prologue::Prologue() {
|
||||
clear();
|
||||
@ -643,13 +644,14 @@ bool DWARFDebugLine::LineTable::lookupAddressRange(
|
||||
|
||||
bool
|
||||
DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex,
|
||||
bool NeedsAbsoluteFilePath,
|
||||
FileLineInfoKind Kind,
|
||||
std::string &Result) const {
|
||||
if (FileIndex == 0 || FileIndex > Prologue.FileNames.size())
|
||||
if (FileIndex == 0 || FileIndex > Prologue.FileNames.size() ||
|
||||
Kind == FileLineInfoKind::None)
|
||||
return false;
|
||||
const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1];
|
||||
const char *FileName = Entry.Name;
|
||||
if (!NeedsAbsoluteFilePath ||
|
||||
if (Kind != FileLineInfoKind::AbsoluteFilePath ||
|
||||
sys::path::is_absolute(FileName)) {
|
||||
Result = FileName;
|
||||
return true;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#define LLVM_DEBUGINFO_DWARFDEBUGLINE_H
|
||||
|
||||
#include "DWARFRelocMap.h"
|
||||
#include "llvm/DebugInfo/DIContext.h"
|
||||
#include "llvm/Support/DataExtractor.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
@ -179,7 +180,7 @@ public:
|
||||
// Extracts filename by its index in filename table in prologue.
|
||||
// Returns true on success.
|
||||
bool getFileNameByIndex(uint64_t FileIndex,
|
||||
bool NeedsAbsoluteFilePath,
|
||||
DILineInfoSpecifier::FileLineInfoKind Kind,
|
||||
std::string &Result) const;
|
||||
|
||||
void dump(raw_ostream &OS) const;
|
||||
|
@ -108,13 +108,13 @@ static void DumpInput(const StringRef &Filename) {
|
||||
DICtx->dump(outs(), DumpType);
|
||||
} else {
|
||||
// Print line info for the specified address.
|
||||
int SpecFlags = DILineInfoSpecifier::FileLineInfo |
|
||||
DILineInfoSpecifier::AbsoluteFilePath;
|
||||
if (PrintFunctions)
|
||||
SpecFlags |= DILineInfoSpecifier::FunctionName;
|
||||
DILineInfoSpecifier Spec(
|
||||
DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
|
||||
PrintFunctions ? DILineInfoSpecifier::FunctionNameKind::LinkageName
|
||||
: DILineInfoSpecifier::FunctionNameKind::None);
|
||||
if (PrintInlining) {
|
||||
DIInliningInfo InliningInfo =
|
||||
DICtx->getInliningInfoForAddress(Address, SpecFlags);
|
||||
DICtx->getInliningInfoForAddress(Address, Spec);
|
||||
uint32_t n = InliningInfo.getNumberOfFrames();
|
||||
if (n == 0) {
|
||||
// Print one empty debug line info in any case.
|
||||
@ -126,7 +126,7 @@ static void DumpInput(const StringRef &Filename) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DILineInfo dli = DICtx->getLineInfoForAddress(Address, SpecFlags);
|
||||
DILineInfo dli = DICtx->getLineInfoForAddress(Address, Spec);
|
||||
PrintDILineInfo(dli);
|
||||
}
|
||||
}
|
||||
|
@ -35,13 +35,12 @@ static bool error(error_code ec) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
getDILineInfoSpecifierFlags(const LLVMSymbolizer::Options &Opts) {
|
||||
uint32_t Flags = llvm::DILineInfoSpecifier::FileLineInfo |
|
||||
llvm::DILineInfoSpecifier::AbsoluteFilePath;
|
||||
if (Opts.PrintFunctions)
|
||||
Flags |= llvm::DILineInfoSpecifier::FunctionName;
|
||||
return Flags;
|
||||
static DILineInfoSpecifier
|
||||
getDILineInfoSpecifier(const LLVMSymbolizer::Options &Opts) {
|
||||
return DILineInfoSpecifier(
|
||||
DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
|
||||
Opts.PrintFunctions ? DILineInfoSpecifier::FunctionNameKind::LinkageName
|
||||
: DILineInfoSpecifier::FunctionNameKind::None);
|
||||
}
|
||||
|
||||
ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
|
||||
@ -115,7 +114,7 @@ DILineInfo ModuleInfo::symbolizeCode(
|
||||
DILineInfo LineInfo;
|
||||
if (DebugInfoContext) {
|
||||
LineInfo = DebugInfoContext->getLineInfoForAddress(
|
||||
ModuleOffset, getDILineInfoSpecifierFlags(Opts));
|
||||
ModuleOffset, getDILineInfoSpecifier(Opts));
|
||||
}
|
||||
// Override function name from symbol table if necessary.
|
||||
if (Opts.PrintFunctions && Opts.UseSymbolTable) {
|
||||
@ -134,7 +133,7 @@ DIInliningInfo ModuleInfo::symbolizeInlinedCode(
|
||||
DIInliningInfo InlinedContext;
|
||||
if (DebugInfoContext) {
|
||||
InlinedContext = DebugInfoContext->getInliningInfoForAddress(
|
||||
ModuleOffset, getDILineInfoSpecifierFlags(Opts));
|
||||
ModuleOffset, getDILineInfoSpecifier(Opts));
|
||||
}
|
||||
// Make sure there is at least one frame in context.
|
||||
if (InlinedContext.getNumberOfFrames() == 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user