[lld] r220184 - [ELF] Implement demangle.

Shankar Easwaran shankarke at gmail.com
Sun Oct 19 22:04:53 PDT 2014


Author: shankare
Date: Mon Oct 20 00:04:53 2014
New Revision: 220184

URL: http://llvm.org/viewvc/llvm-project?rev=220184&view=rev
Log:
[ELF] Implement demangle.

This adds functionality in the GNU flavor to demangle symbols when
undefined symbols are displayed to the user.

Added:
    lld/trunk/test/elf/X86_64/Inputs/undefcpp.c
    lld/trunk/test/elf/X86_64/Inputs/undefcpp.o
    lld/trunk/test/elf/X86_64/demangle.test
Modified:
    lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
    lld/trunk/lib/Driver/GnuLdDriver.cpp
    lld/trunk/lib/Driver/GnuLdOptions.td
    lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp

Modified: lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h?rev=220184&r1=220183&r2=220184&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h Mon Oct 20 00:04:53 2014
@@ -275,6 +275,11 @@ public:
     return _dynamicallyExportedSymbols.count(name) != 0;
   }
 
+  /// \brief Demangle symbols.
+  std::string demangle(StringRef symbolName) const override;
+  bool demangleSymbols() const { return _demangle; }
+  void setDemangleSymbols(bool d) { _demangle = d; }
+
 private:
   ELFLinkingContext() LLVM_DELETED_FUNCTION;
 
@@ -299,6 +304,7 @@ protected:
   bool _dynamicLinkerArg;
   bool _noAllowDynamicLibraries;
   bool _mergeRODataToTextSegment;
+  bool _demangle;
   OutputMagic _outputMagic;
   StringRefVector _inputSearchPaths;
   std::unique_ptr<Writer> _writer;

Modified: lld/trunk/lib/Driver/GnuLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=220184&r1=220183&r2=220184&view=diff
==============================================================================
--- lld/trunk/lib/Driver/GnuLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/GnuLdDriver.cpp Mon Oct 20 00:04:53 2014
@@ -305,6 +305,14 @@ bool GnuLdDriver::parse(int argc, const
   if (!parsedArgs->hasArg(OPT_nostdlib))
     addPlatformSearchDirs(*ctx, triple, baseTriple);
 
+  // Handle --demangle option(For compatibility)
+  if (parsedArgs->getLastArg(OPT_demangle))
+    ctx->setDemangleSymbols(true);
+
+  // Handle --no-demangle option.
+  if (parsedArgs->getLastArg(OPT_no_demangle))
+    ctx->setDemangleSymbols(false);
+
   // Figure out output kind ( -r, -static, -shared)
   if (llvm::opt::Arg *kind =
           parsedArgs->getLastArg(OPT_relocatable, OPT_static, OPT_shared,

Modified: lld/trunk/lib/Driver/GnuLdOptions.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdOptions.td?rev=220184&r1=220183&r2=220184&view=diff
==============================================================================
--- lld/trunk/lib/Driver/GnuLdOptions.td (original)
+++ lld/trunk/lib/Driver/GnuLdOptions.td Mon Oct 20 00:04:53 2014
@@ -215,6 +215,18 @@ def z : Separate<["-"], "z">,
      Group<grp_customopts>;
 
 //===----------------------------------------------------------------------===//
+/// Symbol options
+//===----------------------------------------------------------------------===//
+def grp_symbolopts : OptionGroup<"opts">,
+     HelpText<"SYMBOL OPTIONS">;
+def demangle : Flag<["--"], "demangle">,
+     HelpText<"Demangle C++ symbols">,
+     Group<grp_symbolopts>;
+def no_demangle : Flag<["--"], "no-demangle">,
+     HelpText<"Dont demangle C++ symbols">,
+     Group<grp_symbolopts>;
+
+//===----------------------------------------------------------------------===//
 /// Optimization Options
 //===----------------------------------------------------------------------===//
 def grp_opts : OptionGroup<"opts">,

Modified: lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp?rev=220184&r1=220183&r2=220184&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp Mon Oct 20 00:04:53 2014
@@ -16,11 +16,16 @@
 #include "lld/Passes/LayoutPass.h"
 #include "lld/Passes/RoundTripYAMLPass.h"
 #include "llvm/ADT/Triple.h"
+#include "llvm/Config/config.h"
 #include "llvm/Support/ELF.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 
+#if HAVE_CXXABI_H
+#include <cxxabi.h>
+#endif
+
 namespace lld {
 
 class CommandLineAbsoluteAtom : public AbsoluteAtom {
@@ -53,12 +58,11 @@ ELFLinkingContext::ELFLinkingContext(
     llvm::Triple triple, std::unique_ptr<TargetHandlerBase> targetHandler)
     : _outputELFType(elf::ET_EXEC), _triple(triple),
       _targetHandler(std::move(targetHandler)), _baseAddress(0),
-      _isStaticExecutable(false), _noInhibitExec(false),
-      _exportDynamic(false), _mergeCommonStrings(false),
-      _runLayoutPass(true), _useShlibUndefines(true),
-      _dynamicLinkerArg(false), _noAllowDynamicLibraries(false),
-      _mergeRODataToTextSegment(true), _outputMagic(OutputMagic::DEFAULT),
-      _sysrootPath("") {}
+      _isStaticExecutable(false), _noInhibitExec(false), _exportDynamic(false),
+      _mergeCommonStrings(false), _runLayoutPass(true),
+      _useShlibUndefines(true), _dynamicLinkerArg(false),
+      _noAllowDynamicLibraries(false), _mergeRODataToTextSegment(true),
+      _demangle(true), _outputMagic(OutputMagic::DEFAULT), _sysrootPath("") {}
 
 bool ELFLinkingContext::is64Bits() const { return getTriple().isArch64Bit(); }
 
@@ -260,4 +264,29 @@ void ELFLinkingContext::notifySymbolTabl
     _dynamicallyExportedSymbols.insert(ua->name());
 }
 
+std::string ELFLinkingContext::demangle(StringRef symbolName) const {
+  if (!_demangle)
+    return symbolName;
+
+  // Only try to demangle symbols that look like C++ symbols
+  if (!symbolName.startswith("_Z"))
+    return symbolName;
+
+#if HAVE_CXXABI_H
+  SmallString<256> symBuff;
+  StringRef nullTermSym = Twine(symbolName).toNullTerminatedStringRef(symBuff);
+  const char *cstr = nullTermSym.data();
+  int status;
+  char *demangled = abi::__cxa_demangle(cstr, nullptr, nullptr, &status);
+  if (demangled != NULL) {
+    std::string result(demangled);
+    // __cxa_demangle() always uses a malloc'ed buffer to return the result.
+    free(demangled);
+    return result;
+  }
+#endif
+
+  return symbolName;
+}
+
 } // end namespace lld

Added: lld/trunk/test/elf/X86_64/Inputs/undefcpp.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/undefcpp.c?rev=220184&view=auto
==============================================================================
--- lld/trunk/test/elf/X86_64/Inputs/undefcpp.c (added)
+++ lld/trunk/test/elf/X86_64/Inputs/undefcpp.c Mon Oct 20 00:04:53 2014
@@ -0,0 +1 @@
+int foo() { return _Z3fooPKc(); }

Added: lld/trunk/test/elf/X86_64/Inputs/undefcpp.o
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/undefcpp.o?rev=220184&view=auto
==============================================================================
Binary files lld/trunk/test/elf/X86_64/Inputs/undefcpp.o (added) and lld/trunk/test/elf/X86_64/Inputs/undefcpp.o Mon Oct 20 00:04:53 2014 differ

Added: lld/trunk/test/elf/X86_64/demangle.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/demangle.test?rev=220184&view=auto
==============================================================================
--- lld/trunk/test/elf/X86_64/demangle.test (added)
+++ lld/trunk/test/elf/X86_64/demangle.test Mon Oct 20 00:04:53 2014
@@ -0,0 +1,10 @@
+# Check that the linker is able to demangle strings properly.
+# Once there is a way to add undefined symbols using yaml2obj, the test will be
+# changed.
+#
+RUN: lld -flavor gnu -target x86_64 %p/Inputs/undefcpp.o --noinhibit-exec 2>&1 | FileCheck -check-prefix=DEMANGLE %s
+RUN: lld -flavor gnu -target x86_64 %p/Inputs/undefcpp.o --noinhibit-exec --no-demangle 2>&1 | FileCheck -check-prefix=NODEMANGLE %s
+RUN: lld -flavor gnu -target x86_64 %p/Inputs/undefcpp.o --noinhibit-exec --demangle 2>&1 | FileCheck -check-prefix=DEMANGLE %s
+
+#DEMANGLE: undefcpp.o: foo(char const*)
+#NODEMANGLE: undefcpp.o: _Z3fooPKc





More information about the llvm-commits mailing list