Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -827,6 +827,9 @@ Group, Flags<[CoreOption, DriverOption]>, HelpText<"Disable use-after-scope detection in AddressSanitizer">; +def fsanitize_address_globals_live_support : Flag<["-"], "fsanitize-address-globals-live-support">, + Group, + HelpText<"Enable linker dead stripping of globals in AddressSanitizer">; def fsanitize_recover : Flag<["-"], "fsanitize-recover">, Group; def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">, Flags<[CoreOption, DriverOption]>, Index: include/clang/Driver/SanitizerArgs.h =================================================================== --- include/clang/Driver/SanitizerArgs.h +++ include/clang/Driver/SanitizerArgs.h @@ -35,6 +35,7 @@ int AsanFieldPadding = 0; bool AsanSharedRuntime = false; bool AsanUseAfterScope = true; + bool AsanGlobalsLiveSupport = false; bool LinkCXXRuntimes = false; bool NeedPIE = false; bool Stats = false; Index: include/clang/Frontend/CodeGenOptions.def =================================================================== --- include/clang/Frontend/CodeGenOptions.def +++ include/clang/Frontend/CodeGenOptions.def @@ -137,6 +137,8 @@ CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels. CODEGENOPT(SanitizeAddressUseAfterScope , 1, 0) ///< Enable use-after-scope detection ///< in AddressSanitizer +CODEGENOPT(SanitizeAddressGlobalsLiveSupport , 1, 0) ///< Enable linker dead stripping + ///< of globals in AddressSanitizer CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in ///< MemorySanitizer CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0) ///< Enable use-after-delete detection Index: lib/CodeGen/BackendUtil.cpp =================================================================== --- lib/CodeGen/BackendUtil.cpp +++ lib/CodeGen/BackendUtil.cpp @@ -193,6 +193,8 @@ // where this is not a factor). Also, on ELF this feature requires an assembler // extension that only works with -integrated-as at the moment. static bool asanUseGlobalsGC(const Triple &T, const CodeGenOptions &CGOpts) { + if (!CGOpts.SanitizeAddressGlobalsLiveSupport) + return false; switch (T.getObjectFormat()) { case Triple::MachO: case Triple::COFF: Index: lib/Driver/SanitizerArgs.cpp =================================================================== --- lib/Driver/SanitizerArgs.cpp +++ lib/Driver/SanitizerArgs.cpp @@ -568,6 +568,12 @@ AsanUseAfterScope = A->getOption().getID() == options::OPT_fsanitize_address_use_after_scope; } + + // This is a workaround for a bug in gold and enabled by default for non-ELF + // targets. + AsanGlobalsLiveSupport = + !TC.getTriple().isOSBinFormatELF() || + Args.hasArg(options::OPT_fsanitize_address_globals_live_support); } // Parse -link-cxx-sanitizer flag. @@ -716,6 +722,9 @@ if (AsanUseAfterScope) CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-use-after-scope")); + if (AsanGlobalsLiveSupport) + CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-globals-live-support")); + // MSan: Workaround for PR16386. // ASan: This is mainly to help LSan with cases such as // https://code.google.com/p/address-sanitizer/issues/detail?id=373 Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -777,6 +777,8 @@ Opts.SanitizeAddressUseAfterScope = A->getOption().getID() == OPT_fsanitize_address_use_after_scope; } + Opts.SanitizeAddressGlobalsLiveSupport = + Args.hasArg(OPT_fsanitize_address_globals_live_support); Opts.SSPBufferSize = getLastArgIntValue(Args, OPT_stack_protector_buffer_size, 8, Diags); Opts.StackRealignment = Args.hasArg(OPT_mstackrealign); Index: test/CodeGen/asan-globals-gc.cpp =================================================================== --- test/CodeGen/asan-globals-gc.cpp +++ test/CodeGen/asan-globals-gc.cpp @@ -1,5 +1,16 @@ -// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-windows-msvc %s | FileCheck %s --check-prefix=WITH-GC -// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-windows-msvc -fdata-sections %s | FileCheck %s --check-prefix=WITH-GC +// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-globals-live-support -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefix=WITHOUT-GC +// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-globals-live-support -fdata-sections -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefix=WITH-GC +// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-globals-live-support -fno-integrated-as -fdata-sections -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefix=WITHOUT-GC +// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-globals-live-support -fno-integrated-as -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefix=WITHOUT-GC +// RUN: %clang_cc1 -fsanitize=address -fdata-sections -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefix=WITHOUT-GC + +// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-globals-live-support -fno-data-sections -emit-llvm -o - -triple x86_64-windows-msvc %s | FileCheck %s --check-prefix=WITH-GC +// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-globals-live-support -fdata-sections -emit-llvm -o - -triple x86_64-windows-msvc %s | FileCheck %s --check-prefix=WITH-GC +// RUN: %clang_cc1 -fsanitize=address -fdata-sections -emit-llvm -o - -triple x86_64-windows-msvc %s | FileCheck %s --check-prefix=WITHOUT-GC + +// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-globals-live-support -fno-data-sections -emit-llvm -o - -triple x86_64-apple-macosx11 %s | FileCheck %s --check-prefix=WITH-GC +// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-globals-live-support -fdata-sections -emit-llvm -o - -triple x86_64-apple-macosx11 %s | FileCheck %s --check-prefix=WITH-GC +// RUN: %clang_cc1 -fsanitize=address -fdata-sections -emit-llvm -o - -triple x86_64-apple-macosx11 %s | FileCheck %s --check-prefix=WITHOUT-GC int global; Index: test/Driver/fsanitize.c =================================================================== --- test/Driver/fsanitize.c +++ test/Driver/fsanitize.c @@ -126,6 +126,13 @@ // RUN: %clang -target x86_64-linux-gnu -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-WITHOUT-USE-AFTER-SCOPE // CHECK-ASAN-WITHOUT-USE-AFTER-SCOPE: -cc1{{.*}}address-use-after-scope +// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-globals-live-support %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-GLOBALS +// RUN: %clang -target x86_64-linux-gnu -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ASAN-GLOBALS +// RUN: %clang_cl -target x86_64-windows-msvc -fsanitize=address -fsanitize-address-globals-live-support -### -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-GLOBALS +// RUN: %clang_cl -target x86_64-windows-msvc -fsanitize=address -### -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-GLOBALS +// CHECK-ASAN-GLOBALS: -cc1{{.*}}-fsanitize-address-globals-live-support +// CHECK-NO-ASAN-GLOBALS-NOT: -cc1{{.*}}-fsanitize-address-globals-live-support + // RUN: %clang -target x86_64-linux-gnu -fsanitize-memory-track-origins -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ONLY-TRACK-ORIGINS // CHECK-ONLY-TRACK-ORIGINS: warning: argument unused during compilation: '-fsanitize-memory-track-origins'