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

Shankar Easwaran shankare at codeaurora.org
Tue Sep 30 18:26:32 PDT 2014


The linking context changes are applicable for ELFLinkingContext as 
well, I cant think of any other option than duplicating the code in 
MachOLinkingContext in ELFLinkingContext.

What do you think ?

Shankar Easwaran

On 9/30/2014 6:15 PM, Nick Kledzik wrote:
> 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
> +
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>


-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by the Linux Foundation




More information about the llvm-commits mailing list