diff options
| author | Nick Kledzik <kledzik@apple.com> | 2014-09-30 23:15:39 +0000 |
|---|---|---|
| committer | Nick Kledzik <kledzik@apple.com> | 2014-09-30 23:15:39 +0000 |
| commit | be43d7ef29a6034a54c374ec619b251f18d4161a (patch) | |
| tree | 3417c3a9d546256545eb3357617151d3e8309674 | |
| parent | ffb650856d48262ac78c1eb61f634f528c6a35d1 (diff) | |
| download | bcm5719-llvm-be43d7ef29a6034a54c374ec619b251f18d4161a.tar.gz bcm5719-llvm-be43d7ef29a6034a54c374ec619b251f18d4161a.zip | |
[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.
llvm-svn: 218718
| -rw-r--r-- | lld/include/lld/Core/LinkingContext.h | 5 | ||||
| -rw-r--r-- | lld/include/lld/ReaderWriter/MachOLinkingContext.h | 6 | ||||
| -rw-r--r-- | lld/lib/Core/Resolver.cpp | 3 | ||||
| -rw-r--r-- | lld/lib/Driver/DarwinLdDriver.cpp | 4 | ||||
| -rw-r--r-- | lld/lib/Driver/DarwinLdOptions.td | 2 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp | 35 | ||||
| -rw-r--r-- | lld/test/mach-o/demangle.yaml | 74 |
7 files changed, 127 insertions, 2 deletions
diff --git a/lld/include/lld/Core/LinkingContext.h b/lld/include/lld/Core/LinkingContext.h index edb62dd98f6..b0048cc7f8e 100644 --- a/lld/include/lld/Core/LinkingContext.h +++ b/lld/include/lld/Core/LinkingContext.h @@ -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() /// @{ diff --git a/lld/include/lld/ReaderWriter/MachOLinkingContext.h b/lld/include/lld/ReaderWriter/MachOLinkingContext.h index 68a003a29d2..a2968047d74 100644 --- a/lld/include/lld/ReaderWriter/MachOLinkingContext.h +++ b/lld/include/lld/ReaderWriter/MachOLinkingContext.h @@ -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; diff --git a/lld/lib/Core/Resolver.cpp b/lld/lib/Core/Resolver.cpp index 85ecad0c127..417442de0f2 100644 --- a/lld/lib/Core/Resolver.cpp +++ b/lld/lib/Core/Resolver.cpp @@ -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) { diff --git a/lld/lib/Driver/DarwinLdDriver.cpp b/lld/lib/Driver/DarwinLdDriver.cpp index 3f9f7012b42..407bd19fe61 100644 --- a/lld/lib/Driver/DarwinLdDriver.cpp +++ b/lld/lib/Driver/DarwinLdDriver.cpp @@ -425,6 +425,10 @@ bool DarwinLdDriver::parse(int argc, const char *argv[], 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); diff --git a/lld/lib/Driver/DarwinLdOptions.td b/lld/lib/Driver/DarwinLdOptions.td index 1392eaae3cc..73672fdad8b 100644 --- a/lld/lib/Driver/DarwinLdOptions.td +++ b/lld/lib/Driver/DarwinLdOptions.td @@ -144,6 +144,8 @@ def sectalign : MultiArg<["-"], "sectalign", 3>, 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">; diff --git a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp index e40c3d8582c..b512d48943d 100644 --- a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp +++ b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp @@ -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::exportSymbolNamed(StringRef sym) const { 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 diff --git a/lld/test/mach-o/demangle.yaml b/lld/test/mach-o/demangle.yaml new file mode 100644 index 00000000000..64054580847 --- /dev/null +++ b/lld/test/mach-o/demangle.yaml @@ -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 + |

