If a .syms file is available alongside a sanitizer runtime, pass it to the
linker via --dynamic-list instead of using --export-dynamic. This reduces the
size of the dynamic symbol table, and thus of the binary (in some cases by up
to ~30%).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177783 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index cc5b016..3167e03 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -287,7 +287,9 @@
   // ccc-install-dir) can change 'Dir'.
   StringRef ClangResourceDir(CLANG_RESOURCE_DIR);
   SmallString<128> P(Dir);
-  if (!ClangResourceDir.empty())
+  if (const Arg *A = Args->getLastArg(options::OPT_resource_dir))
+    P = A->getValue();
+  else if (!ClangResourceDir.empty())
     llvm::sys::path::append(P, ClangResourceDir);
   else
     llvm::sys::path::append(P, "..", "lib", "clang", CLANG_VERSION_STRING);
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index cb84e0a..2581ae3 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -1575,7 +1575,8 @@
 
 static void addSanitizerRTLinkFlagsLinux(
     const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs,
-    const StringRef Sanitizer, bool BeforeLibStdCXX) {
+    const StringRef Sanitizer, bool BeforeLibStdCXX,
+    bool ExportSymbols = true) {
   // Sanitizer runtime is located in the Linux library directory and
   // has name "libclang_rt.<Sanitizer>-<ArchName>.a".
   SmallString<128> LibSanitizer(TC.getDriver().ResourceDir);
@@ -1599,7 +1600,17 @@
 
   CmdArgs.push_back("-lpthread");
   CmdArgs.push_back("-ldl");
-  CmdArgs.push_back("-export-dynamic");
+
+  // If possible, use a dynamic symbols file to export the symbols from the
+  // runtime library. If we can't do so, use -export-dynamic instead to export
+  // all symbols from the binary.
+  if (ExportSymbols) {
+    if (llvm::sys::fs::exists(LibSanitizer + ".syms"))
+      CmdArgs.push_back(
+          Args.MakeArgString("--dynamic-list=" + LibSanitizer + ".syms"));
+    else
+      CmdArgs.push_back("-export-dynamic");
+  }
 }
 
 /// If AddressSanitizer is enabled, add appropriate linker flags (Linux).
@@ -1666,7 +1677,7 @@
   // Need a copy of sanitizer_common. This could come from another sanitizer
   // runtime; if we're not including one, include our own copy.
   if (!HasOtherSanitizerRt)
-    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "san", true);
+    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "san", true, false);
 
   addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "ubsan", false);