summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/include/lld/ReaderWriter/ELFLinkingContext.h6
-rw-r--r--lld/lib/Driver/GnuLdDriver.cpp8
-rw-r--r--lld/lib/Driver/GnuLdOptions.td12
-rw-r--r--lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp41
-rw-r--r--lld/test/elf/X86_64/Inputs/undefcpp.c1
-rw-r--r--lld/test/elf/X86_64/Inputs/undefcpp.obin0 -> 1344 bytes
-rw-r--r--lld/test/elf/X86_64/demangle.test10
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
new file mode 100644
index 00000000000..6b8ebf5b6ab
--- /dev/null
+++ b/lld/test/elf/X86_64/Inputs/undefcpp.o
Binary files differ
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
OpenPOWER on IntegriCloud