[lld] r218718 - [mach-o] Implement -demangle.

Nick Kledzik kledzik at apple.com
Tue Sep 30 16:15:39 PDT 2014


Author: kledzik
Date: Tue Sep 30 18:15:39 2014
New Revision: 218718

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

The darwin linker has the -demangle option which directs it to demangle C++
(and soon Swift) mangled symbol names. Long term we need some Diagnostics object
for formatting errors and warnings. But for now we have the Core linker just
writing messages to llvm::errs(). So, to enable demangling, I changed the
Resolver to call a LinkingContext method on the symbol name.

To make this more interesting, the demangling code is done via __cxa_demangle()
which is part of the C++ ABI, which is only supported on some platforms, so I
had to conditionalize the code with the config generated HAVE_CXXABI_H.

Added:
    lld/trunk/test/mach-o/demangle.yaml
Modified:
    lld/trunk/include/lld/Core/LinkingContext.h
    lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
    lld/trunk/lib/Core/Resolver.cpp
    lld/trunk/lib/Driver/DarwinLdDriver.cpp
    lld/trunk/lib/Driver/DarwinLdOptions.td
    lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp

Modified: lld/trunk/include/lld/Core/LinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/LinkingContext.h?rev=218718&r1=218717&r2=218718&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/LinkingContext.h (original)
+++ lld/trunk/include/lld/Core/LinkingContext.h Tue Sep 30 18:15:39 2014
@@ -270,6 +270,11 @@ public:
   /// \returns true if there is an error with the current settings.
   bool validate(raw_ostream &diagnostics);
 
+  /// Formats symbol name for use in error messages.
+  virtual std::string demangle(StringRef symbolName) const {
+    return symbolName;
+  }
+
   /// @}
   /// \name Methods used by Driver::link()
   /// @{

Modified: lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h?rev=218718&r1=218717&r2=218718&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h Tue Sep 30 18:15:39 2014
@@ -66,6 +66,8 @@ public:
 
   void addPasses(PassManager &pm) override;
   bool validateImpl(raw_ostream &diagnostics) override;
+  std::string demangle(StringRef symbolName) const override;
+
   bool createImplicitFiles(std::vector<std::unique_ptr<File>> &) const override;
 
   uint32_t getCPUType() const;
@@ -95,6 +97,9 @@ public:
 
   bool keepPrivateExterns() const { return _keepPrivateExterns; }
   void setKeepPrivateExterns(bool v) { _keepPrivateExterns = v; }
+  bool demangleSymbols() const { return _demangle; }
+  void setDemangleSymbols(bool d) { _demangle = d; }
+
 
   bool minOS(StringRef mac, StringRef iOS) const;
   void setDoNothing(bool value) { _doNothing = value; }
@@ -289,6 +294,7 @@ private:
   bool _printAtoms;
   bool _testingFileUsage;
   bool _keepPrivateExterns;
+  bool _demangle;
   StringRef _bundleLoader;
   mutable std::unique_ptr<mach_o::ArchHandler> _archHandler;
   mutable std::unique_ptr<Writer> _writer;

Modified: lld/trunk/lib/Core/Resolver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Resolver.cpp?rev=218718&r1=218717&r2=218718&view=diff
==============================================================================
--- lld/trunk/lib/Core/Resolver.cpp (original)
+++ lld/trunk/lib/Core/Resolver.cpp Tue Sep 30 18:15:39 2014
@@ -393,7 +393,8 @@ bool Resolver::checkUndefines() {
       foundUndefines = true;
       if (_context.printRemainingUndefines()) {
         llvm::errs() << "Undefined symbol: " << undefAtom->file().path()
-                     << ": " << undefAtom->name() << "\n";
+                     << ": " << _context.demangle(undefAtom->name())
+                     << "\n";
       }
     }
     if (foundUndefines) {

Modified: lld/trunk/lib/Driver/DarwinLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/DarwinLdDriver.cpp?rev=218718&r1=218717&r2=218718&view=diff
==============================================================================
--- lld/trunk/lib/Driver/DarwinLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/DarwinLdDriver.cpp Tue Sep 30 18:15:39 2014
@@ -425,6 +425,10 @@ bool DarwinLdDriver::parse(int argc, con
   if (parsedArgs->getLastArg(OPT_t))
     ctx.setLogInputFiles(true);
 
+  // Handle -demangle option.
+  if (parsedArgs->getLastArg(OPT_demangle))
+    ctx.setDemangleSymbols(true);
+
   // Handle -keep_private_externs
   if (parsedArgs->getLastArg(OPT_keep_private_externs)) {
     ctx.setKeepPrivateExterns(true);

Modified: lld/trunk/lib/Driver/DarwinLdOptions.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/DarwinLdOptions.td?rev=218718&r1=218717&r2=218718&view=diff
==============================================================================
--- lld/trunk/lib/Driver/DarwinLdOptions.td (original)
+++ lld/trunk/lib/Driver/DarwinLdOptions.td Tue Sep 30 18:15:39 2014
@@ -144,6 +144,8 @@ def sectalign : MultiArg<["-"], "sectali
      HelpText<"alignment for segment/section">;
 def image_base : Separate<["-"], "image_base">;
 def seg1addr : Separate<["-"], "seg1addr">, Alias<image_base>;
+def demangle : Flag<["-"], "demangle">,
+     HelpText<"Demangles symbol names in errors and warnings">;
 
 def t : Flag<["-"], "t">,
      HelpText<"Print the names of the input files as ld processes them">;

Modified: lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp?rev=218718&r1=218717&r2=218718&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp Tue Sep 30 18:15:39 2014
@@ -23,6 +23,7 @@
 
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/Triple.h"
+#include "llvm/Config/config.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/MachO.h"
@@ -30,6 +31,10 @@
 
 #include <algorithm>
 
+#if HAVE_CXXABI_H
+#include <cxxabi.h>
+#endif
+
 using lld::mach_o::ArchHandler;
 using lld::mach_o::MachODylibFile;
 using namespace llvm::MachO;
@@ -137,7 +142,8 @@ MachOLinkingContext::MachOLinkingContext
       _osMinVersion(0), _pageZeroSize(0), _pageSize(4096), _baseAddress(0),
       _compatibilityVersion(0), _currentVersion(0), _deadStrippableDylib(false),
       _printAtoms(false), _testingFileUsage(false), _keepPrivateExterns(false),
-      _archHandler(nullptr), _exportMode(ExportMode::globals) {}
+      _demangle(false), _archHandler(nullptr),
+      _exportMode(ExportMode::globals) {}
 
 MachOLinkingContext::~MachOLinkingContext() {}
 
@@ -659,5 +665,32 @@ bool MachOLinkingContext::exportSymbolNa
   llvm_unreachable("_exportMode unknown enum value");
 }
 
+std::string MachOLinkingContext::demangle(StringRef symbolName) const {
+  // Only try to demangle symbols if -demangle on command line
+  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);
+  // Mach-O has extra leading underscore that needs to be removed.
+  const char *cstr = nullTermSym.data() + 1;
+  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/mach-o/demangle.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/demangle.yaml?rev=218718&view=auto
==============================================================================
--- lld/trunk/test/mach-o/demangle.yaml (added)
+++ lld/trunk/test/mach-o/demangle.yaml Tue Sep 30 18:15:39 2014
@@ -0,0 +1,74 @@
+# REQUIRES: system-linker-mach-o
+#
+# RUN: not lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s  \
+# RUN:     -dylib -o %t %p/Inputs/libSystem.yaml  2> %t.err
+# RUN: FileCheck %s < %t.err
+#
+# RUN: not lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s \
+# RUN:     -dylib -o %t %p/Inputs/libSystem.yaml -demangle 2> %t.err2
+# RUN: FileCheck %s --check-prefix=DCHECK < %t.err2
+#
+# Test -demangle option works on undefined symbol errors.
+#
+
+--- !mach-o
+arch:            x86_64
+file-type:       MH_OBJECT
+flags:           [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+sections:
+  - segment:         __TEXT
+    section:         __text
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+    address:         0x0000000000000000
+    content:         [ 0xE8, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x00, 0x00, 
+                       0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00 ]
+    relocations:
+      - offset:          0x0000000B
+        type:            X86_64_RELOC_BRANCH
+        length:          2
+        pc-rel:          true
+        extern:          true
+        symbol:          2
+      - offset:          0x00000006
+        type:            X86_64_RELOC_BRANCH
+        length:          2
+        pc-rel:          true
+        extern:          true
+        symbol:          3
+      - offset:          0x00000001
+        type:            X86_64_RELOC_BRANCH
+        length:          2
+        pc-rel:          true
+        extern:          true
+        symbol:          1
+global-symbols:
+  - name:            __Z1xv
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000000
+undefined-symbols:
+  - name:            __Znam
+    type:            N_UNDF
+    scope:           [ N_EXT ]
+    value:           0x0000000000000000
+  - name:            __Znotcpp
+    type:            N_UNDF
+    scope:           [ N_EXT ]
+    value:           0x0000000000000000
+  - name:            _foo
+    type:            N_UNDF
+    scope:           [ N_EXT ]
+    value:           0x0000000000000000
+
+...
+
+# CHECK:  __Znotcpp
+# CHECK:  __Znam
+# CHECK:  _foo
+
+# DCHECK:  __Znotcpp
+# DCHECK: operator new[](unsigned long)
+# DCHECK:  _foo
+





More information about the llvm-commits mailing list