Index: test/CMakeLists.txt
===================================================================
--- test/CMakeLists.txt
+++ test/CMakeLists.txt
@@ -45,6 +45,7 @@
llc
lli
lli-child-target
+ llvm-addr2line
llvm-ar
llvm-as
llvm-bcanalyzer
Index: test/tools/llvm-symbolizer/demangle.s
===================================================================
--- test/tools/llvm-symbolizer/demangle.s
+++ test/tools/llvm-symbolizer/demangle.s
@@ -25,5 +25,11 @@
# RUN: llvm-symbolizer --no-demangle -C --obj %t.o 0 \
# RUN: | FileCheck %s --check-prefix=DEMANGLED_FUNCTION_NAME
+# Check that for llvm-addr2line the default is not to demangle.
+# RUN: llvm-addr2line -fe %t.o 0 \
+# RUN: | FileCheck %s --check-prefix=MANGLED_FUNCTION_NAME
+# RUN: llvm-addr2line -fCe %t.o 0 \
+# RUN: | FileCheck %s --check-prefix=DEMANGLED_FUNCTION_NAME
+
# MANGLED_FUNCTION_NAME: _Z1cv
# DEMANGLED_FUNCTION_NAME: c()
Index: test/tools/llvm-symbolizer/help.test
===================================================================
--- /dev/null
+++ test/tools/llvm-symbolizer/help.test
@@ -0,0 +1,8 @@
+RUN: llvm-symbolizer -help | FileCheck %s --check-prefix=SYMBOLIZER
+RUN: llvm-addr2line -help | FileCheck %s --check-prefix=ADDR2LINE
+
+SYMBOLIZER: OVERVIEW: llvm-symbolizer
+SYMBOLIZER: USAGE: llvm-symbolizer{{(.exe)?}} [options] ...
+
+ADDR2LINE: OVERVIEW: llvm-addr2line
+ADDR2LINE: USAGE: llvm-addr2line{{(.exe)?}} [options] ...
Index: test/tools/llvm-symbolizer/output-style.test
===================================================================
--- test/tools/llvm-symbolizer/output-style.test
+++ test/tools/llvm-symbolizer/output-style.test
@@ -7,5 +7,14 @@
RUN: llvm-symbolizer --output-style=LLVM -e %p/Inputs/addr.exe 0x40054d \
RUN: | FileCheck %s --check-prefix=LLVM
+RUN: llvm-addr2line -e %p/Inputs/addr.exe 0x40054d \
+RUN: | FileCheck %s --check-prefix=GNU
+
+RUN: llvm-addr2line --output-style=GNU -e %p/Inputs/addr.exe 0x40054d \
+RUN: | FileCheck %s --check-prefix=GNU
+
+RUN: llvm-addr2line --output-style=LLVM -e %p/Inputs/addr.exe 0x40054d \
+RUN: | FileCheck %s --check-prefix=LLVM
+
LLVM: {{^}}/tmp{{\\|/}}x.c:3:3{{$}}
GNU: {{^}}/tmp{{\\|/}}x.c:3{{$}}
Index: test/tools/llvm-symbolizer/sym.test
===================================================================
--- test/tools/llvm-symbolizer/sym.test
+++ test/tools/llvm-symbolizer/sym.test
@@ -29,6 +29,19 @@
RUN: echo "0x1" > %t.input
RUN: llvm-symbolizer -obj=%p/Inputs/zero < %t.input | FileCheck -check-prefix="ZERO" %s
+RUN: llvm-addr2line -obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck -check-prefix=A2L %s
+RUN: llvm-addr2line -a -obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck -check-prefixes=A2L,A2L_A %s
+RUN: llvm-addr2line -f -obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck -check-prefixes=A2L,A2L_F %s
+RUN: llvm-addr2line -i -obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck -check-prefixes=A2L,A2L_I %s
+RUN: llvm-addr2line -fi -obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck -check-prefixes=A2L,A2L_F,A2L_I,A2L_FI %s
+
+RUN: llvm-addr2line -pa -obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck -check-prefixes=A2LP,A2LP_A %s
+RUN: llvm-addr2line -pf -obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck -check-prefixes=A2LP,A2LP_F %s
+RUN: llvm-addr2line -paf -obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck -check-prefixes=A2LP,A2LP_AF %s
+RUN: llvm-addr2line -pai -obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck -check-prefixes=A2LP,A2LP_A,A2LP_I %s
+RUN: llvm-addr2line -pfi -obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck -check-prefixes=A2LP,A2LP_F,A2LP_FI %s
+RUN: llvm-addr2line -pafi -obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck -check-prefixes=A2LP,A2LP_AF,A2LP_FI %s
+
#CHECK: some text
#CHECK: 0x40054d
#CHECK: main
@@ -43,3 +56,23 @@
#
#ZERO: ??
#ZERO: ??:0:0
+#
+#A2L: some text
+#A2L_A-NEXT: 0x40054d
+#A2L_F-NEXT: inctwo
+#A2L-NEXT: {{[/\]+}}tmp{{[/\]+}}x.c:3
+#A2L_FI-NEXT: inc
+#A2L_I-NEXT: {{[/\]+}}tmp{{[/\]+}}x.c:7
+#A2L_FI-NEXT: main
+#A2L_I-NEXT: {{[/\]+}}tmp{{[/\]+}}x.c:14
+#A2L-NEXT: some text2
+
+#A2LP: some text
+#A2LP_A-NEXT: 0x40054d: {{[/\]+}}tmp{{[/\]+}}x.c:3
+#A2LP_F-NEXT: inctwo at {{[/\]+}}tmp{{[/\]+}}x.c:3
+#A2LP_AF-NEXT: 0x40054d: inctwo at {{[/\]+}}tmp{{[/\]+}}x.c:3
+#A2LP_I-NEXT: {{[/\]+}}tmp{{[/\]+}}x.c:7
+#A2LP_I-NEXT: {{[/\]+}}tmp{{[/\]+}}x.c:14
+#A2LP_FI-NEXT: (inlined by) inc at {{[/\]+}}tmp{{[/\]+}}x.c:7
+#A2LP_FI-NEXT: (inlined by) main at {{[/\]+}}tmp{{[/\]+}}x.c:14
+#A2LP-NEXT: some text2
Index: tools/llvm-symbolizer/CMakeLists.txt
===================================================================
--- tools/llvm-symbolizer/CMakeLists.txt
+++ tools/llvm-symbolizer/CMakeLists.txt
@@ -16,6 +16,8 @@
llvm-symbolizer.cpp
)
+add_llvm_tool_symlink(llvm-addr2line llvm-symbolizer)
+
if(LLVM_INSTALL_BINUTILS_SYMLINKS)
add_llvm_tool_symlink(addr2line llvm-symbolizer)
endif()
Index: tools/llvm-symbolizer/llvm-symbolizer.cpp
===================================================================
--- tools/llvm-symbolizer/llvm-symbolizer.cpp
+++ tools/llvm-symbolizer/llvm-symbolizer.cpp
@@ -43,7 +43,7 @@
clEnumValN(FunctionNameKind::ShortName, "short",
"print short function name"),
clEnumValN(FunctionNameKind::LinkageName, "linkage",
- "print function linkage name (default)"),
+ "print function linkage name"),
// Sentinel value for unspecified value.
clEnumValN(FunctionNameKind::LinkageName, "", "")));
static cl::alias ClPrintFunctionsShort("f", cl::desc("Alias for -functions"),
@@ -202,7 +202,7 @@
}
static void symbolizeInput(StringRef InputString, LLVMSymbolizer &Symbolizer,
- DIPrinter &Printer) {
+ DIPrinter &Printer, bool IsAddr2Line) {
bool IsData = false;
std::string ModuleName;
uint64_t Offset = 0;
@@ -227,21 +227,43 @@
ModuleName, {Offset, object::SectionedAddress::UndefSection},
ClDwpName);
Printer << (error(ResOrErr) ? DIInliningInfo() : ResOrErr.get());
+ } else if (IsAddr2Line) {
+ // With ClPrintFunctions == FunctionNameKind::LinkageName (default)
+ // and ClUseSymbolTable == true (also default), Symbolizer.symbolizeCode()
+ // may override the name of an inlined function with the name of the topmost
+ // caller function in the inlining chain. This contradicts the existing
+ // behavior of addr2line. Symbolizer.symbolizeInlinedCode() overrides only
+ // the topmost function, which suites our needs better.
+ auto ResOrErr = Symbolizer.symbolizeInlinedCode(
+ ModuleName, {Offset, object::SectionedAddress::UndefSection},
+ ClDwpName);
+ Printer << (error(ResOrErr) ? DILineInfo() : ResOrErr.get().getFrame(0));
} else {
auto ResOrErr = Symbolizer.symbolizeCode(
ModuleName, {Offset, object::SectionedAddress::UndefSection},
ClDwpName);
Printer << (error(ResOrErr) ? DILineInfo() : ResOrErr.get());
}
- outs() << "\n";
+ if (!IsAddr2Line)
+ outs() << "\n";
outs().flush();
}
int main(int argc, char **argv) {
InitLLVM X(argc, argv);
+ bool IsAddr2Line = sys::path::stem(argv[0]).contains("addr2line");
+
+ if (IsAddr2Line) {
+ ClDemangle.setInitialValue(false);
+ ClPrintFunctions.setInitialValue(FunctionNameKind::None);
+ ClPrintInlining.setInitialValue(false);
+ ClOutputStyle.setInitialValue(DIPrinter::OutputStyle::GNU);
+ }
+
llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded);
- cl::ParseCommandLineOptions(argc, argv, "llvm-symbolizer\n");
+ cl::ParseCommandLineOptions(argc, argv, IsAddr2Line ? "llvm-addr2line\n"
+ : "llvm-symbolizer\n");
// If both --demangle and --no-demangle are specified then pick the last one.
if (ClNoDemangle.getPosition() > ClDemangle.getPosition())
@@ -270,10 +292,10 @@
char InputString[kMaxInputStringLength];
while (fgets(InputString, sizeof(InputString), stdin))
- symbolizeInput(InputString, Symbolizer, Printer);
+ symbolizeInput(InputString, Symbolizer, Printer, IsAddr2Line);
} else {
for (StringRef Address : ClInputAddresses)
- symbolizeInput(Address, Symbolizer, Printer);
+ symbolizeInput(Address, Symbolizer, Printer, IsAddr2Line);
}
return 0;