llvm.org GIT mirror llvm / bf6e3f9
[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 Alexey Samsonov 6 years ago
7 changed file(s) with 40 addition(s) and 24 deletion(s). Raw diff Collapse all Expand all
6060 -------
6161
6262 .. option:: -obj
63
6364 Path to object file to be symbolized.
6465
65 .. option:: -functions
66 .. option:: -functions=[none|short|linkage]
6667
67 Print function names as well as source file/line locations. Defaults to true.
68 Specify the way function names are printed (omit function name,
69 print short function name, or print full linkage name, respectively).
70 Defaults to ``linkage``.
6871
6972 .. option:: -use-symbol-table
7073
6969 /// should be filled with data.
7070 struct DILineInfoSpecifier {
7171 enum class FileLineInfoKind { None, Default, AbsoluteFilePath };
72 enum class FunctionNameKind { None, LinkageName };
72 enum class FunctionNameKind { None, ShortName, LinkageName };
7373
7474 FileLineInfoKind FLIKind;
7575 FunctionNameKind FNKind;
276276 FunctionNameKind Kind) const {
277277 if (!isSubroutineDIE() || Kind == FunctionNameKind::None)
278278 return nullptr;
279 // Try to get mangled name if possible.
280 if (const char *name =
281 getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, nullptr))
282 return name;
283 if (const char *name = getAttributeValueAsString(U, DW_AT_linkage_name,
284 nullptr))
285 return name;
279 // Try to get mangled name only if it was asked for.
280 if (Kind == FunctionNameKind::LinkageName) {
281 if (const char *name =
282 getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, nullptr))
283 return name;
284 if (const char *name =
285 getAttributeValueAsString(U, DW_AT_linkage_name, nullptr))
286 return name;
287 }
286288 if (const char *name = getAttributeValueAsString(U, DW_AT_name, nullptr))
287289 return name;
288290 // Try to get name from specification DIE.
99 RUN: echo "%p/Inputs/macho-universal:x86_64 0x100000f05" >> %t.input
1010 RUN: echo "%p/Inputs/llvm-symbolizer-dwo-test 0x400514" >> %t.input
1111
12 RUN: llvm-symbolizer --functions --inlining --demangle=false \
12 RUN: llvm-symbolizer --functions=linkage --inlining --demangle=false \
1313 RUN: --default-arch=i386 < %t.input | FileCheck %s
1414
1515 CHECK: main
8686 RUN: | FileCheck %s --check-prefix=STRIPPED
8787
8888 STRIPPED: global_func
89
90 RUN: echo "%p/Inputs/dwarfdump-test4.elf-x86-64 0x62c" > %t.input7
91 RUN: llvm-symbolizer --functions=short --use-symbol-table=false --demangle=false < %t.input7 \
92 RUN: | FileCheck %s --check-prefix=SHORT_FUNCTION_NAME
93
94 SHORT_FUNCTION_NAME-NOT: _Z1cv
3838 getDILineInfoSpecifier(const LLVMSymbolizer::Options &Opts) {
3939 return DILineInfoSpecifier(
4040 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
41 Opts.PrintFunctions ? DILineInfoSpecifier::FunctionNameKind::LinkageName
42 : DILineInfoSpecifier::FunctionNameKind::None);
41 Opts.PrintFunctions);
4342 }
4443
4544 ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
116115 ModuleOffset, getDILineInfoSpecifier(Opts));
117116 }
118117 // Override function name from symbol table if necessary.
119 if (Opts.PrintFunctions && Opts.UseSymbolTable) {
118 if (Opts.PrintFunctions != FunctionNameKind::None && Opts.UseSymbolTable) {
120119 std::string FunctionName;
121120 uint64_t Start, Size;
122121 if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset,
139138 InlinedContext.addFrame(DILineInfo());
140139 }
141140 // Override the function name in lower frame with name from symbol table.
142 if (Opts.PrintFunctions && Opts.UseSymbolTable) {
141 if (Opts.PrintFunctions != FunctionNameKind::None && Opts.UseSymbolTable) {
143142 DIInliningInfo PatchedInlinedContext;
144143 for (uint32_t i = 0, n = InlinedContext.getNumberOfFrames(); i < n; i++) {
145144 DILineInfo LineInfo = InlinedContext.getFrame(i);
397396 // cannot fetch. We replace it to "??" to make our output closer to addr2line.
398397 static const std::string kDILineInfoBadString = "";
399398 std::stringstream Result;
400 if (Opts.PrintFunctions) {
399 if (Opts.PrintFunctions != FunctionNameKind::None) {
401400 std::string FunctionName = LineInfo.FunctionName;
402401 if (FunctionName == kDILineInfoBadString)
403402 FunctionName = kBadString;
2323
2424 namespace llvm {
2525
26 typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
2627 using namespace object;
2728
2829 namespace symbolize {
3334 public:
3435 struct Options {
3536 bool UseSymbolTable : 1;
36 bool PrintFunctions : 1;
37 FunctionNameKind PrintFunctions;
3738 bool PrintInlining : 1;
3839 bool Demangle : 1;
3940 std::string DefaultArch;
40 Options(bool UseSymbolTable = true, bool PrintFunctions = true,
41 Options(bool UseSymbolTable = true,
42 FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName,
4143 bool PrintInlining = true, bool Demangle = true,
4244 std::string DefaultArch = "")
4345 : UseSymbolTable(UseSymbolTable), PrintFunctions(PrintFunctions),
4446 PrintInlining(PrintInlining), Demangle(Demangle),
45 DefaultArch(DefaultArch) {
46 }
47 DefaultArch(DefaultArch) {}
4748 };
4849
4950 LLVMSymbolizer(const Options &Opts = Options()) : Opts(Opts) {}
3434 cl::desc("Prefer names in symbol table to names "
3535 "in debug info"));
3636
37 static cl::opt
38 ClPrintFunctions("functions", cl::init(true),
39 cl::desc("Print function names as well as line "
40 "information for a given address"));
37 static cl::opt ClPrintFunctions(
38 "functions", cl::init(FunctionNameKind::LinkageName),
39 cl::desc("Print function name for a given address:"),
40 cl::values(clEnumValN(FunctionNameKind::None, "none", "omit function name"),
41 clEnumValN(FunctionNameKind::ShortName, "short",
42 "print short function name"),
43 clEnumValN(FunctionNameKind::LinkageName, "linkage",
44 "print function linkage name"),
45 clEnumValEnd));
4146
4247 static cl::opt
4348 ClPrintInlining("inlining", cl::init(true),