From f3e624ca73b007552554b31358f4abde9eb2d3b7 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Sat, 23 Mar 2013 00:30:08 +0000 Subject: [PATCH] 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%). llvm-svn: 177783 --- clang/include/clang/Driver/CC1Options.td | 2 -- clang/include/clang/Driver/Options.td | 5 +++++ clang/lib/Driver/Driver.cpp | 4 +++- clang/lib/Driver/Tools.cpp | 17 ++++++++++++++--- .../lib/linux/libclang_rt.asan-i386.a.syms | 0 .../lib/linux/libclang_rt.asan-x86_64.a.syms | 0 .../lib/linux/libclang_rt.msan-x86_64.a.syms | 0 .../lib/linux/libclang_rt.tsan-x86_64.a.syms | 0 .../lib/linux/libclang_rt.ubsan-i386.a.syms | 0 .../lib/linux/libclang_rt.ubsan-x86_64.a.syms | 0 .../lib/linux/libclang_rt.ubsan_cxx-i386.a.syms | 0 .../linux/libclang_rt.ubsan_cxx-x86_64.a.syms | 0 clang/test/Driver/sanitizer-ld.c | 14 +++++++++++--- 13 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.asan-i386.a.syms create mode 100644 clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.asan-x86_64.a.syms create mode 100644 clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.msan-x86_64.a.syms create mode 100644 clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.tsan-x86_64.a.syms create mode 100644 clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan-i386.a.syms create mode 100644 clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan-x86_64.a.syms create mode 100644 clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan_cxx-i386.a.syms create mode 100644 clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan_cxx-x86_64.a.syms diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td index c2ac1cfe512a..65326c67ba48 100644 --- a/clang/include/clang/Driver/CC1Options.td +++ b/clang/include/clang/Driver/CC1Options.td @@ -282,8 +282,6 @@ def plugin_arg : JoinedAndSeparate<["-"], "plugin-arg-">, HelpText<"Pass to plugin ">; def add_plugin : Separate<["-"], "add-plugin">, MetaVarName<"">, HelpText<"Use the named plugin action in addition to the default action">; -def resource_dir : Separate<["-"], "resource-dir">, - HelpText<"The directory which holds the compiler resource files">; def version : Flag<["-"], "version">, HelpText<"Print the compiler version">; def ast_dump_filter : Separate<["-"], "ast-dump-filter">, diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index bdd398d57026..a6ede0f450a0 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1016,6 +1016,11 @@ def rewrite_objc : Flag<["-"], "rewrite-objc">, Flags<[DriverOption,CC1Option]>, def rewrite_legacy_objc : Flag<["-"], "rewrite-legacy-objc">, Flags<[DriverOption]>, HelpText<"Rewrite Legacy Objective-C source to C++">; def rdynamic : Flag<["-"], "rdynamic">; +def resource_dir : Separate<["-"], "resource-dir">, + Flags<[DriverOption, CC1Option, HelpHidden]>, + HelpText<"The directory which holds the compiler resource files">; +def resource_dir_EQ : Joined<["-"], "resource-dir=">, Flags<[DriverOption]>, + Alias; def rpath : Separate<["-"], "rpath">, Flags<[LinkerInput]>; def rtlib_EQ : Joined<["-", "--"], "rtlib=">; def r : Flag<["-"], "r">; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index cc5b016b03bd..3167e03ca449 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -287,7 +287,9 @@ Compilation *Driver::BuildCompilation(ArrayRef ArgList) { // 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/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index cb84e0a547cf..2581ae36f712 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -1575,7 +1575,8 @@ SanitizerArgs::SanitizerArgs(const Driver &D, const ArgList &Args) 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.-.a". SmallString<128> LibSanitizer(TC.getDriver().ResourceDir); @@ -1599,7 +1600,17 @@ static void addSanitizerRTLinkFlagsLinux( 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 @@ static void addUbsanRTLinux(const ToolChain &TC, const ArgList &Args, // 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); diff --git a/clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.asan-i386.a.syms b/clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.asan-i386.a.syms new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.asan-x86_64.a.syms b/clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.asan-x86_64.a.syms new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.msan-x86_64.a.syms b/clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.msan-x86_64.a.syms new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.tsan-x86_64.a.syms b/clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.tsan-x86_64.a.syms new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan-i386.a.syms b/clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan-i386.a.syms new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan-x86_64.a.syms b/clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan-x86_64.a.syms new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan_cxx-i386.a.syms b/clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan_cxx-i386.a.syms new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan_cxx-x86_64.a.syms b/clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.ubsan_cxx-x86_64.a.syms new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/sanitizer-ld.c b/clang/test/Driver/sanitizer-ld.c index 89cbb6b284fd..fd68b579a105 100644 --- a/clang/test/Driver/sanitizer-ld.c +++ b/clang/test/Driver/sanitizer-ld.c @@ -2,6 +2,7 @@ // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target i386-unknown-linux -fsanitize=address \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-ASAN-LINUX %s // @@ -10,10 +11,12 @@ // CHECK-ASAN-LINUX: libclang_rt.asan-i386.a" // CHECK-ASAN-LINUX: "-lpthread" // CHECK-ASAN-LINUX: "-ldl" -// CHECK-ASAN-LINUX: "-export-dynamic" +// CHECK-ASAN-LINUX-NOT: "-export-dynamic" +// CHECK-ASAN-LINUX: "--dynamic-list={{.*}}libclang_rt.asan-i386.a.syms" // RUN: %clangxx -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target i386-unknown-linux -fsanitize=address \ +// RUN: -resource-dir=%S/Inputs/empty_resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-ASAN-LINUX-CXX %s // @@ -23,6 +26,7 @@ // CHECK-ASAN-LINUX-CXX: "-lpthread" // CHECK-ASAN-LINUX-CXX: "-ldl" // CHECK-ASAN-LINUX-CXX: "-export-dynamic" +// CHECK-ASAN-LINUX-CXX-NOT: "--dynamic-list" // CHECK-ASAN-LINUX-CXX: stdc++ // RUN: %clang -no-canonical-prefixes %s -### -o /dev/null -fsanitize=address \ @@ -58,6 +62,7 @@ // RUN: %clangxx -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target x86_64-unknown-linux -lstdc++ -fsanitize=thread \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-TSAN-LINUX-CXX %s // @@ -66,11 +71,13 @@ // CHECK-TSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.tsan-x86_64.a" "-no-whole-archive" // CHECK-TSAN-LINUX-CXX: "-lpthread" // CHECK-TSAN-LINUX-CXX: "-ldl" -// CHECK-TSAN-LINUX-CXX: "-export-dynamic" +// CHECK-TSAN-LINUX-CXX-NOT: "-export-dynamic" +// CHECK-TSAN-LINUX-CXX: "--dynamic-list={{.*}}libclang_rt.tsan-x86_64.a.syms" // CHECK-TSAN-LINUX-CXX: stdc++ // RUN: %clangxx -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target x86_64-unknown-linux -lstdc++ -fsanitize=memory \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-MSAN-LINUX-CXX %s // @@ -79,7 +86,8 @@ // CHECK-MSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.msan-x86_64.a" "-no-whole-archive" // CHECK-MSAN-LINUX-CXX: "-lpthread" // CHECK-MSAN-LINUX-CXX: "-ldl" -// CHECK-MSAN-LINUX-CXX: "-export-dynamic" +// CHECK-MSAN-LINUX-CXX-NOT: "-export-dynamic" +// CHECK-MSAN-LINUX-CXX: "--dynamic-list={{.*}}libclang_rt.msan-x86_64.a.syms" // CHECK-MSAN-LINUX-CXX: stdc++ // RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \