[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
diff --git a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
index e40c3d8..b512d48 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 @@
_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 @@
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