diff --git a/docs/CommandGuide/llvm-symbolizer.rst b/docs/CommandGuide/llvm-symbolizer.rst index dfbdb3ac434..ce2d9c00435 100644 --- a/docs/CommandGuide/llvm-symbolizer.rst +++ b/docs/CommandGuide/llvm-symbolizer.rst @@ -61,11 +61,14 @@ OPTIONS ------- .. option:: -obj + 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 diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h index 3f3e3792d54..c1aba01fbf7 100644 --- a/include/llvm/DebugInfo/DIContext.h +++ b/include/llvm/DebugInfo/DIContext.h @@ -70,7 +70,7 @@ class DIInliningInfo { /// should be filled with data. struct DILineInfoSpecifier { enum class FileLineInfoKind { None, Default, AbsoluteFilePath }; - enum class FunctionNameKind { None, LinkageName }; + enum class FunctionNameKind { None, ShortName, LinkageName }; FileLineInfoKind FLIKind; FunctionNameKind FNKind; diff --git a/lib/DebugInfo/DWARFDebugInfoEntry.cpp b/lib/DebugInfo/DWARFDebugInfoEntry.cpp index d2b529346fb..b811ed70644 100644 --- a/lib/DebugInfo/DWARFDebugInfoEntry.cpp +++ b/lib/DebugInfo/DWARFDebugInfoEntry.cpp @@ -277,13 +277,15 @@ 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 = - getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, nullptr)) - return name; - if (const char *name = getAttributeValueAsString(U, DW_AT_linkage_name, - nullptr)) - return name; + // Try to get mangled name only if it was asked for. + if (Kind == FunctionNameKind::LinkageName) { + if (const char *name = + getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, nullptr)) + return name; + if (const char *name = + getAttributeValueAsString(U, DW_AT_linkage_name, nullptr)) + return name; + } if (const char *name = getAttributeValueAsString(U, DW_AT_name, nullptr)) return name; // Try to get name from specification DIE. diff --git a/test/DebugInfo/llvm-symbolizer.test b/test/DebugInfo/llvm-symbolizer.test index 6d51fe96c48..ed42cc3cf9c 100644 --- a/test/DebugInfo/llvm-symbolizer.test +++ b/test/DebugInfo/llvm-symbolizer.test @@ -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/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 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 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 diff --git a/tools/llvm-symbolizer/LLVMSymbolize.cpp b/tools/llvm-symbolizer/LLVMSymbolize.cpp index 7018ebed731..3e71111b009 100644 --- a/tools/llvm-symbolizer/LLVMSymbolize.cpp +++ b/tools/llvm-symbolizer/LLVMSymbolize.cpp @@ -39,8 +39,7 @@ static DILineInfoSpecifier getDILineInfoSpecifier(const LLVMSymbolizer::Options &Opts) { return DILineInfoSpecifier( DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, - Opts.PrintFunctions ? DILineInfoSpecifier::FunctionNameKind::LinkageName - : DILineInfoSpecifier::FunctionNameKind::None); + Opts.PrintFunctions); } ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx) @@ -117,7 +116,7 @@ DILineInfo ModuleInfo::symbolizeCode( ModuleOffset, getDILineInfoSpecifier(Opts)); } // Override function name from symbol table if necessary. - if (Opts.PrintFunctions && Opts.UseSymbolTable) { + if (Opts.PrintFunctions != FunctionNameKind::None && Opts.UseSymbolTable) { std::string FunctionName; uint64_t Start, Size; if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset, @@ -140,7 +139,7 @@ DIInliningInfo ModuleInfo::symbolizeInlinedCode( InlinedContext.addFrame(DILineInfo()); } // 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; for (uint32_t i = 0, n = InlinedContext.getNumberOfFrames(); i < n; 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. static const std::string kDILineInfoBadString = ""; std::stringstream Result; - if (Opts.PrintFunctions) { + if (Opts.PrintFunctions != FunctionNameKind::None) { std::string FunctionName = LineInfo.FunctionName; if (FunctionName == kDILineInfoBadString) FunctionName = kBadString; diff --git a/tools/llvm-symbolizer/LLVMSymbolize.h b/tools/llvm-symbolizer/LLVMSymbolize.h index a1283a511af..45febe07847 100644 --- a/tools/llvm-symbolizer/LLVMSymbolize.h +++ b/tools/llvm-symbolizer/LLVMSymbolize.h @@ -24,6 +24,7 @@ namespace llvm { +typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind; using namespace object; namespace symbolize { @@ -34,17 +35,17 @@ class LLVMSymbolizer { public: struct Options { bool UseSymbolTable : 1; - bool PrintFunctions : 1; + FunctionNameKind PrintFunctions; bool PrintInlining : 1; bool Demangle : 1; std::string DefaultArch; - Options(bool UseSymbolTable = true, bool PrintFunctions = true, + Options(bool UseSymbolTable = true, + FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName, bool PrintInlining = true, bool Demangle = true, std::string DefaultArch = "") : UseSymbolTable(UseSymbolTable), PrintFunctions(PrintFunctions), PrintInlining(PrintInlining), Demangle(Demangle), - DefaultArch(DefaultArch) { - } + DefaultArch(DefaultArch) {} }; LLVMSymbolizer(const Options &Opts = Options()) : Opts(Opts) {} diff --git a/tools/llvm-symbolizer/llvm-symbolizer.cpp b/tools/llvm-symbolizer/llvm-symbolizer.cpp index 1680470f855..29db172531b 100644 --- a/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ b/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -35,10 +35,15 @@ ClUseSymbolTable("use-symbol-table", cl::init(true), cl::desc("Prefer names in symbol table to names " "in debug info")); -static cl::opt -ClPrintFunctions("functions", cl::init(true), - cl::desc("Print function names as well as line " - "information for a given address")); +static cl::opt ClPrintFunctions( + "functions", cl::init(FunctionNameKind::LinkageName), + cl::desc("Print function name 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 ClPrintInlining("inlining", cl::init(true),