diff options
-rw-r--r-- | lld/include/lld/ReaderWriter/ELFLinkingContext.h | 6 | ||||
-rw-r--r-- | lld/lib/Driver/GnuLdDriver.cpp | 8 | ||||
-rw-r--r-- | lld/lib/Driver/GnuLdOptions.td | 12 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp | 41 | ||||
-rw-r--r-- | lld/test/elf/X86_64/Inputs/undefcpp.c | 1 | ||||
-rw-r--r-- | lld/test/elf/X86_64/Inputs/undefcpp.o | bin | 0 -> 1344 bytes | |||
-rw-r--r-- | lld/test/elf/X86_64/demangle.test | 10 |
7 files changed, 72 insertions, 6 deletions
diff --git a/lld/include/lld/ReaderWriter/ELFLinkingContext.h b/lld/include/lld/ReaderWriter/ELFLinkingContext.h index eda445ba2a9..225d3cabef1 100644 --- a/lld/include/lld/ReaderWriter/ELFLinkingContext.h +++ b/lld/include/lld/ReaderWriter/ELFLinkingContext.h @@ -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; diff --git a/lld/lib/Driver/GnuLdDriver.cpp b/lld/lib/Driver/GnuLdDriver.cpp index 0d2dea3bd77..542b1bda3f8 100644 --- a/lld/lib/Driver/GnuLdDriver.cpp +++ b/lld/lib/Driver/GnuLdDriver.cpp @@ -305,6 +305,14 @@ bool GnuLdDriver::parse(int argc, const char *argv[], 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, diff --git a/lld/lib/Driver/GnuLdOptions.td b/lld/lib/Driver/GnuLdOptions.td index 590ce9509aa..0abb7e5652b 100644 --- a/lld/lib/Driver/GnuLdOptions.td +++ b/lld/lib/Driver/GnuLdOptions.td @@ -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">, diff --git a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp index e3428fbba46..9dba86a9b8e 100644 --- a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp +++ b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp @@ -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::notifySymbolTableCoalesce(const Atom *existingAtom, _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 diff --git a/lld/test/elf/X86_64/Inputs/undefcpp.c b/lld/test/elf/X86_64/Inputs/undefcpp.c new file mode 100644 index 00000000000..ce84c2a592b --- /dev/null +++ b/lld/test/elf/X86_64/Inputs/undefcpp.c @@ -0,0 +1 @@ +int foo() { return _Z3fooPKc(); } diff --git a/lld/test/elf/X86_64/Inputs/undefcpp.o b/lld/test/elf/X86_64/Inputs/undefcpp.o Binary files differnew file mode 100644 index 00000000000..6b8ebf5b6ab --- /dev/null +++ b/lld/test/elf/X86_64/Inputs/undefcpp.o diff --git a/lld/test/elf/X86_64/demangle.test b/lld/test/elf/X86_64/demangle.test new file mode 100644 index 00000000000..820e6be9e03 --- /dev/null +++ b/lld/test/elf/X86_64/demangle.test @@ -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 |