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;