[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