mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-20 10:24:12 +00:00
[DWARF parser] Teach DIContext to fetch short (non-linkage) function names for a given address.
Change --functions option in llvm-symbolizer tool to accept values "none", "short" or "linkage". Update the tests and docs accordingly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209050 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -61,11 +61,14 @@ OPTIONS
|
|||||||
-------
|
-------
|
||||||
|
|
||||||
.. option:: -obj
|
.. option:: -obj
|
||||||
|
|
||||||
Path to object file to be symbolized.
|
Path to object file to be symbolized.
|
||||||
|
|
||||||
.. option:: -functions
|
.. option:: -functions=[none|short|linkage]
|
||||||
|
|
||||||
Print function names as well as source file/line locations. Defaults to true.
|
Specify the way function names are printed (omit function name,
|
||||||
|
print short function name, or print full linkage name, respectively).
|
||||||
|
Defaults to ``linkage``.
|
||||||
|
|
||||||
.. option:: -use-symbol-table
|
.. option:: -use-symbol-table
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ class DIInliningInfo {
|
|||||||
/// should be filled with data.
|
/// should be filled with data.
|
||||||
struct DILineInfoSpecifier {
|
struct DILineInfoSpecifier {
|
||||||
enum class FileLineInfoKind { None, Default, AbsoluteFilePath };
|
enum class FileLineInfoKind { None, Default, AbsoluteFilePath };
|
||||||
enum class FunctionNameKind { None, LinkageName };
|
enum class FunctionNameKind { None, ShortName, LinkageName };
|
||||||
|
|
||||||
FileLineInfoKind FLIKind;
|
FileLineInfoKind FLIKind;
|
||||||
FunctionNameKind FNKind;
|
FunctionNameKind FNKind;
|
||||||
|
@ -277,13 +277,15 @@ DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U,
|
|||||||
FunctionNameKind Kind) const {
|
FunctionNameKind Kind) const {
|
||||||
if (!isSubroutineDIE() || Kind == FunctionNameKind::None)
|
if (!isSubroutineDIE() || Kind == FunctionNameKind::None)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
// Try to get mangled name if possible.
|
// Try to get mangled name only if it was asked for.
|
||||||
if (const char *name =
|
if (Kind == FunctionNameKind::LinkageName) {
|
||||||
getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, nullptr))
|
if (const char *name =
|
||||||
return name;
|
getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, nullptr))
|
||||||
if (const char *name = getAttributeValueAsString(U, DW_AT_linkage_name,
|
return name;
|
||||||
nullptr))
|
if (const char *name =
|
||||||
return name;
|
getAttributeValueAsString(U, DW_AT_linkage_name, nullptr))
|
||||||
|
return name;
|
||||||
|
}
|
||||||
if (const char *name = getAttributeValueAsString(U, DW_AT_name, nullptr))
|
if (const char *name = getAttributeValueAsString(U, DW_AT_name, nullptr))
|
||||||
return name;
|
return name;
|
||||||
// Try to get name from specification DIE.
|
// Try to get name from specification DIE.
|
||||||
|
@ -10,7 +10,7 @@ RUN: echo "%p/Inputs/macho-universal:i386 0x1f67" >> %t.input
|
|||||||
RUN: echo "%p/Inputs/macho-universal:x86_64 0x100000f05" >> %t.input
|
RUN: echo "%p/Inputs/macho-universal:x86_64 0x100000f05" >> %t.input
|
||||||
RUN: echo "%p/Inputs/llvm-symbolizer-dwo-test 0x400514" >> %t.input
|
RUN: echo "%p/Inputs/llvm-symbolizer-dwo-test 0x400514" >> %t.input
|
||||||
|
|
||||||
RUN: llvm-symbolizer --functions --inlining --demangle=false \
|
RUN: llvm-symbolizer --functions=linkage --inlining --demangle=false \
|
||||||
RUN: --default-arch=i386 < %t.input | FileCheck %s
|
RUN: --default-arch=i386 < %t.input | FileCheck %s
|
||||||
|
|
||||||
CHECK: main
|
CHECK: main
|
||||||
@ -87,3 +87,9 @@ RUN: llvm-symbolizer --obj %p/Inputs/shared-object-stripped.elf-i386 < %t.input6
|
|||||||
RUN: | FileCheck %s --check-prefix=STRIPPED
|
RUN: | FileCheck %s --check-prefix=STRIPPED
|
||||||
|
|
||||||
STRIPPED: global_func
|
STRIPPED: global_func
|
||||||
|
|
||||||
|
RUN: echo "%p/Inputs/dwarfdump-test4.elf-x86-64 0x62c" > %t.input7
|
||||||
|
RUN: llvm-symbolizer --functions=short --use-symbol-table=false --demangle=false < %t.input7 \
|
||||||
|
RUN: | FileCheck %s --check-prefix=SHORT_FUNCTION_NAME
|
||||||
|
|
||||||
|
SHORT_FUNCTION_NAME-NOT: _Z1cv
|
||||||
|
@ -39,8 +39,7 @@ static DILineInfoSpecifier
|
|||||||
getDILineInfoSpecifier(const LLVMSymbolizer::Options &Opts) {
|
getDILineInfoSpecifier(const LLVMSymbolizer::Options &Opts) {
|
||||||
return DILineInfoSpecifier(
|
return DILineInfoSpecifier(
|
||||||
DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
|
DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
|
||||||
Opts.PrintFunctions ? DILineInfoSpecifier::FunctionNameKind::LinkageName
|
Opts.PrintFunctions);
|
||||||
: DILineInfoSpecifier::FunctionNameKind::None);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
|
ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
|
||||||
@ -117,7 +116,7 @@ DILineInfo ModuleInfo::symbolizeCode(
|
|||||||
ModuleOffset, getDILineInfoSpecifier(Opts));
|
ModuleOffset, getDILineInfoSpecifier(Opts));
|
||||||
}
|
}
|
||||||
// Override function name from symbol table if necessary.
|
// Override function name from symbol table if necessary.
|
||||||
if (Opts.PrintFunctions && Opts.UseSymbolTable) {
|
if (Opts.PrintFunctions != FunctionNameKind::None && Opts.UseSymbolTable) {
|
||||||
std::string FunctionName;
|
std::string FunctionName;
|
||||||
uint64_t Start, Size;
|
uint64_t Start, Size;
|
||||||
if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset,
|
if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset,
|
||||||
@ -140,7 +139,7 @@ DIInliningInfo ModuleInfo::symbolizeInlinedCode(
|
|||||||
InlinedContext.addFrame(DILineInfo());
|
InlinedContext.addFrame(DILineInfo());
|
||||||
}
|
}
|
||||||
// Override the function name in lower frame with name from symbol table.
|
// Override the function name in lower frame with name from symbol table.
|
||||||
if (Opts.PrintFunctions && Opts.UseSymbolTable) {
|
if (Opts.PrintFunctions != FunctionNameKind::None && Opts.UseSymbolTable) {
|
||||||
DIInliningInfo PatchedInlinedContext;
|
DIInliningInfo PatchedInlinedContext;
|
||||||
for (uint32_t i = 0, n = InlinedContext.getNumberOfFrames(); i < n; i++) {
|
for (uint32_t i = 0, n = InlinedContext.getNumberOfFrames(); i < n; i++) {
|
||||||
DILineInfo LineInfo = InlinedContext.getFrame(i);
|
DILineInfo LineInfo = InlinedContext.getFrame(i);
|
||||||
@ -398,7 +397,7 @@ std::string LLVMSymbolizer::printDILineInfo(DILineInfo LineInfo) const {
|
|||||||
// cannot fetch. We replace it to "??" to make our output closer to addr2line.
|
// cannot fetch. We replace it to "??" to make our output closer to addr2line.
|
||||||
static const std::string kDILineInfoBadString = "<invalid>";
|
static const std::string kDILineInfoBadString = "<invalid>";
|
||||||
std::stringstream Result;
|
std::stringstream Result;
|
||||||
if (Opts.PrintFunctions) {
|
if (Opts.PrintFunctions != FunctionNameKind::None) {
|
||||||
std::string FunctionName = LineInfo.FunctionName;
|
std::string FunctionName = LineInfo.FunctionName;
|
||||||
if (FunctionName == kDILineInfoBadString)
|
if (FunctionName == kDILineInfoBadString)
|
||||||
FunctionName = kBadString;
|
FunctionName = kBadString;
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
|
typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
|
||||||
using namespace object;
|
using namespace object;
|
||||||
|
|
||||||
namespace symbolize {
|
namespace symbolize {
|
||||||
@ -34,17 +35,17 @@ class LLVMSymbolizer {
|
|||||||
public:
|
public:
|
||||||
struct Options {
|
struct Options {
|
||||||
bool UseSymbolTable : 1;
|
bool UseSymbolTable : 1;
|
||||||
bool PrintFunctions : 1;
|
FunctionNameKind PrintFunctions;
|
||||||
bool PrintInlining : 1;
|
bool PrintInlining : 1;
|
||||||
bool Demangle : 1;
|
bool Demangle : 1;
|
||||||
std::string DefaultArch;
|
std::string DefaultArch;
|
||||||
Options(bool UseSymbolTable = true, bool PrintFunctions = true,
|
Options(bool UseSymbolTable = true,
|
||||||
|
FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName,
|
||||||
bool PrintInlining = true, bool Demangle = true,
|
bool PrintInlining = true, bool Demangle = true,
|
||||||
std::string DefaultArch = "")
|
std::string DefaultArch = "")
|
||||||
: UseSymbolTable(UseSymbolTable), PrintFunctions(PrintFunctions),
|
: UseSymbolTable(UseSymbolTable), PrintFunctions(PrintFunctions),
|
||||||
PrintInlining(PrintInlining), Demangle(Demangle),
|
PrintInlining(PrintInlining), Demangle(Demangle),
|
||||||
DefaultArch(DefaultArch) {
|
DefaultArch(DefaultArch) {}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
LLVMSymbolizer(const Options &Opts = Options()) : Opts(Opts) {}
|
LLVMSymbolizer(const Options &Opts = Options()) : Opts(Opts) {}
|
||||||
|
@ -35,10 +35,15 @@ ClUseSymbolTable("use-symbol-table", cl::init(true),
|
|||||||
cl::desc("Prefer names in symbol table to names "
|
cl::desc("Prefer names in symbol table to names "
|
||||||
"in debug info"));
|
"in debug info"));
|
||||||
|
|
||||||
static cl::opt<bool>
|
static cl::opt<FunctionNameKind> ClPrintFunctions(
|
||||||
ClPrintFunctions("functions", cl::init(true),
|
"functions", cl::init(FunctionNameKind::LinkageName),
|
||||||
cl::desc("Print function names as well as line "
|
cl::desc("Print function name for a given address:"),
|
||||||
"information for a given address"));
|
cl::values(clEnumValN(FunctionNameKind::None, "none", "omit function name"),
|
||||||
|
clEnumValN(FunctionNameKind::ShortName, "short",
|
||||||
|
"print short function name"),
|
||||||
|
clEnumValN(FunctionNameKind::LinkageName, "linkage",
|
||||||
|
"print function linkage name"),
|
||||||
|
clEnumValEnd));
|
||||||
|
|
||||||
static cl::opt<bool>
|
static cl::opt<bool>
|
||||||
ClPrintInlining("inlining", cl::init(true),
|
ClPrintInlining("inlining", cl::init(true),
|
||||||
|
Reference in New Issue
Block a user