summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/test/CodeGen/asan-static-odr.cpp17
-rw-r--r--compiler-rt/lib/asan/asan_globals.cc13
-rw-r--r--compiler-rt/test/asan/TestCases/Linux/odr_indicators.cc26
-rw-r--r--llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp8
-rw-r--r--llvm/test/Instrumentation/AddressSanitizer/do-not-touch-odr-global.ll2
-rw-r--r--llvm/test/Instrumentation/AddressSanitizer/global_metadata.ll2
-rw-r--r--llvm/test/Instrumentation/AddressSanitizer/local_alias.ll11
-rw-r--r--llvm/test/Instrumentation/AddressSanitizer/odr-check-ignore.ll17
-rw-r--r--llvm/test/Instrumentation/AddressSanitizer/win-string-literal.ll2
9 files changed, 89 insertions, 9 deletions
diff --git a/clang/test/CodeGen/asan-static-odr.cpp b/clang/test/CodeGen/asan-static-odr.cpp
new file mode 100644
index 00000000000..6b23b62e16f
--- /dev/null
+++ b/clang/test/CodeGen/asan-static-odr.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefixes=CHECK,ALIAS1
+
+// No alias on Windows but indicators should work.
+// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-windows-msvc %s | FileCheck %s --check-prefixes=CHECK,ALIAS0
+
+static int global;
+
+int main() {
+ return global;
+}
+
+// CHECK-NOT: __odr_asan_gen
+// CHECK-NOT: private alias
+// CHECK: [[VAR:@.*global.*]] ={{.*}} global { i32, [60 x i8] } zeroinitializer, align 32
+// CHECK: @0 = internal global {{.*}} [[VAR]] to i64), {{.*}}, i64 -1 }]
+// CHECK: call void @__asan_register_globals(i64 ptrtoint ([1 x { i64, i64, i64, i64, i64, i64, i64, i64 }]* @0 to i64), i64 1)
+// CHECK: call void @__asan_unregister_globals(i64 ptrtoint ([1 x { i64, i64, i64, i64, i64, i64, i64, i64 }]* @0 to i64), i64 1)
diff --git a/compiler-rt/lib/asan/asan_globals.cc b/compiler-rt/lib/asan/asan_globals.cc
index febbdb5af35..146234ac6c6 100644
--- a/compiler-rt/lib/asan/asan_globals.cc
+++ b/compiler-rt/lib/asan/asan_globals.cc
@@ -83,9 +83,11 @@ static bool IsAddressNearGlobal(uptr addr, const __asan_global &g) {
}
static void ReportGlobal(const Global &g, const char *prefix) {
- Report("%s Global[%p]: beg=%p size=%zu/%zu name=%s module=%s dyn_init=%zu\n",
- prefix, &g, (void *)g.beg, g.size, g.size_with_redzone, g.name,
- g.module_name, g.has_dynamic_init);
+ Report(
+ "%s Global[%p]: beg=%p size=%zu/%zu name=%s module=%s dyn_init=%zu "
+ "odr_indicator=%p\n",
+ prefix, &g, (void *)g.beg, g.size, g.size_with_redzone, g.name,
+ g.module_name, g.has_dynamic_init, (void *)g.odr_indicator);
if (g.location) {
Report(" location (%p): name=%s[%p], %d %d\n", g.location,
g.location->filename, g.location->filename, g.location->line_no,
@@ -133,6 +135,9 @@ enum GlobalSymbolState {
// this method in case compiler instruments global variables through their
// local aliases.
static void CheckODRViolationViaIndicator(const Global *g) {
+ // Instrumentation requests to skip ODR check.
+ if (g->odr_indicator == UINTPTR_MAX)
+ return;
u8 *odr_indicator = reinterpret_cast<u8 *>(g->odr_indicator);
if (*odr_indicator == UNREGISTERED) {
*odr_indicator = REGISTERED;
@@ -246,7 +251,7 @@ static void UnregisterGlobal(const Global *g) {
// implementation. It might not be worth doing anyway.
// Release ODR indicator.
- if (UseODRIndicator(g)) {
+ if (UseODRIndicator(g) && g->odr_indicator != UINTPTR_MAX) {
u8 *odr_indicator = reinterpret_cast<u8 *>(g->odr_indicator);
*odr_indicator = UNREGISTERED;
}
diff --git a/compiler-rt/test/asan/TestCases/Linux/odr_indicators.cc b/compiler-rt/test/asan/TestCases/Linux/odr_indicators.cc
new file mode 100644
index 00000000000..36176b55290
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/Linux/odr_indicators.cc
@@ -0,0 +1,26 @@
+// RUN: %clangxx_asan -fPIC %s -o %t
+// RUN: %env_asan_opts=report_globals=2 %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK,INDICATOR0
+
+// RUN: %clangxx_asan -fsanitize-address-use-odr-indicator -fPIC %s -o %t
+// RUN: %env_asan_opts=report_globals=2 %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK,INDICATOR1
+
+#include <stdio.h>
+
+int test_global_1;
+// INDICATOR0-DAG: Added Global{{.*}} name=test_global_1{{.*}} odr_indicator={{0x0+$}}
+// INDICATOR1-DAG: Added Global{{.*}} name=test_global_1{{.*}} odr_indicator={{0x0*[^0]+.*$}}
+
+static int test_global_2;
+// CHECK-DAG: Added Global{{.*}} name=test_global_2{{.*}} odr_indicator={{0xf+$}}
+
+namespace {
+static int test_global_3;
+// CHECK-DAG: Added Global{{.*}} name={{.*}}::test_global_3{{.*}} odr_indicator={{0xf+$}}
+} // namespace
+
+int main() {
+ const char f[] = "%d %d %d\n";
+ // CHECK-DAG: Added Global{{.*}} name=__const.main.f{{.*}} odr_indicator={{0xf+$}}
+ printf(f, test_global_1, test_global_2, test_global_3);
+ return 0;
+}
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index cd7652d3c3a..87288388853 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -2190,7 +2190,13 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M, bool
GlobalAlias::create(GlobalValue::PrivateLinkage, "", NewGlobal);
}
- if (UseOdrIndicator) {
+ // ODR check is not useful for the following, but we see false reports
+ // caused by linker optimizations.
+ if (NewGlobal->hasLocalLinkage() || NewGlobal->hasGlobalUnnamedAddr() ||
+ NewGlobal->hasLinkOnceODRLinkage() || NewGlobal->hasWeakODRLinkage()) {
+ ODRIndicator = ConstantExpr::getIntToPtr(ConstantInt::get(IntptrTy, -1),
+ IRB.getInt8PtrTy());
+ } else if (UseOdrIndicator) {
// With local aliases, we need to provide another externally visible
// symbol __odr_asan_XXX to detect ODR violation.
auto *ODRIndicatorSym =
diff --git a/llvm/test/Instrumentation/AddressSanitizer/do-not-touch-odr-global.ll b/llvm/test/Instrumentation/AddressSanitizer/do-not-touch-odr-global.ll
index 97752612297..bdcd6595a0f 100644
--- a/llvm/test/Instrumentation/AddressSanitizer/do-not-touch-odr-global.ll
+++ b/llvm/test/Instrumentation/AddressSanitizer/do-not-touch-odr-global.ll
@@ -5,7 +5,9 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
target triple = "x86_64-unknown-linux-gnu"
; no action should be taken for these globals
@global_noinst = linkonce_odr constant [2 x i8] [i8 1, i8 2]
+@global_weak_noinst = weak_odr constant [2 x i8] [i8 1, i8 2]
@global_inst = private constant [2 x i8] [i8 1, i8 2]
; CHECK-NOT: {{asan_gen.*global_noinst}}
+; CHECK-NOT: {{asan_gen.*global_weak_noinst}}
; CHECK: {{asan_gen.*global_inst}}
; CHECK: @asan.module_ctor
diff --git a/llvm/test/Instrumentation/AddressSanitizer/global_metadata.ll b/llvm/test/Instrumentation/AddressSanitizer/global_metadata.ll
index ec3d4b680f9..ee42f1cef97 100644
--- a/llvm/test/Instrumentation/AddressSanitizer/global_metadata.ll
+++ b/llvm/test/Instrumentation/AddressSanitizer/global_metadata.ll
@@ -22,7 +22,7 @@ target triple = "x86_64-unknown-linux-gnu"
; CHECK: [[FILENAME:@___asan_gen_.[0-9]+]] = private unnamed_addr constant [22 x i8] c"/tmp/asan-globals.cpp\00", align 1
; CHECK: [[LOCDESCR:@___asan_gen_.[0-9]+]] = private unnamed_addr constant { [22 x i8]*, i32, i32 } { [22 x i8]* [[FILENAME]], i32 5, i32 5 }
; CHECK: @__asan_global_global = {{.*}}i64 ptrtoint ({ i32, [60 x i8] }* @global to i64){{.*}} section "asan_globals"{{.*}}, !associated
-; CHECK: @__asan_global_.str = {{.*}}i64 ptrtoint ({ [14 x i8], [50 x i8] }* @.str to i64){{.*}} section "asan_globals"{{.*}}, !associated
+; CHECK: @__asan_global_.str = {{.*}}i64 ptrtoint ({ [14 x i8], [50 x i8] }* @{{.str|1}} to i64){{.*}} section "asan_globals"{{.*}}, !associated
; The metadata has to be inserted to llvm.compiler.used to avoid being stripped
; during LTO.
diff --git a/llvm/test/Instrumentation/AddressSanitizer/local_alias.ll b/llvm/test/Instrumentation/AddressSanitizer/local_alias.ll
index 9d573df461f..9b95bb3fa6b 100644
--- a/llvm/test/Instrumentation/AddressSanitizer/local_alias.ll
+++ b/llvm/test/Instrumentation/AddressSanitizer/local_alias.ll
@@ -6,14 +6,21 @@
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
-@a = internal global [2 x i32] zeroinitializer, align 4
+@a = dso_local global [2 x i32] zeroinitializer, align 4
+@b = private global [2 x i32] zeroinitializer, align 4
+@c = internal global [2 x i32] zeroinitializer, align 4
+@d = unnamed_addr global [2 x i32] zeroinitializer, align 4
; Check that we generate internal alias and odr indicator symbols for global to be protected.
; CHECK-NOINDICATOR-NOT: __odr_asan_gen_a
; CHECK-NOALIAS-NOT: private alias
-; CHECK-INDICATOR: @__odr_asan_gen_a = internal global i8 0, align 1
+; CHECK-INDICATOR: @__odr_asan_gen_a = global i8 0, align 1
; CHECK-ALIAS: @0 = private alias { [2 x i32], [56 x i8] }, { [2 x i32], [56 x i8] }* @a
+; CHECK-ALIAS: @1 = private alias { [2 x i32], [56 x i8] }, { [2 x i32], [56 x i8] }* @b
+; CHECK-ALIAS: @2 = private alias { [2 x i32], [56 x i8] }, { [2 x i32], [56 x i8] }* @c
+; CHECK-ALIAS: @3 = private alias { [2 x i32], [56 x i8] }, { [2 x i32], [56 x i8] }* @d
+
; Function Attrs: nounwind sanitize_address uwtable
define i32 @foo(i32 %M) #0 {
entry:
diff --git a/llvm/test/Instrumentation/AddressSanitizer/odr-check-ignore.ll b/llvm/test/Instrumentation/AddressSanitizer/odr-check-ignore.ll
new file mode 100644
index 00000000000..3a9e614c9ea
--- /dev/null
+++ b/llvm/test/Instrumentation/AddressSanitizer/odr-check-ignore.ll
@@ -0,0 +1,17 @@
+; RUN: opt < %s -asan -asan-module -S | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@a = global [2 x i32] zeroinitializer, align 4
+@b = private global [2 x i32] zeroinitializer, align 4
+@c = internal global [2 x i32] zeroinitializer, align 4
+@d = unnamed_addr global [2 x i32] zeroinitializer, align 4
+
+; CHECK: @__asan_global_a = private global { i64, i64, i64, i64, i64, i64, i64, i64 } { i64 ptrtoint ({ [2 x i32], [56 x i8] }* @a to i64), i64 8, i64 64, i64 ptrtoint ([2 x i8]* @___asan_gen_.1 to i64), i64 ptrtoint ([8 x i8]* @___asan_gen_ to i64), i64 0, i64 0, i64 0 }
+
+; CHECK: @__asan_global_b = private global { i64, i64, i64, i64, i64, i64, i64, i64 } { i64 ptrtoint ({ [2 x i32], [56 x i8] }* @b to i64), i64 8, i64 64, i64 ptrtoint ([2 x i8]* @___asan_gen_.2 to i64), i64 ptrtoint ([8 x i8]* @___asan_gen_ to i64), i64 0, i64 0, i64 -1 }
+
+; CHECK: @__asan_global_c = private global { i64, i64, i64, i64, i64, i64, i64, i64 } { i64 ptrtoint ({ [2 x i32], [56 x i8] }* @c to i64), i64 8, i64 64, i64 ptrtoint ([2 x i8]* @___asan_gen_.3 to i64), i64 ptrtoint ([8 x i8]* @___asan_gen_ to i64), i64 0, i64 0, i64 -1 }
+
+; CHECK: @__asan_global_d = private global { i64, i64, i64, i64, i64, i64, i64, i64 } { i64 ptrtoint ({ [2 x i32], [56 x i8] }* @d to i64), i64 8, i64 64, i64 ptrtoint ([2 x i8]* @___asan_gen_.4 to i64), i64 ptrtoint ([8 x i8]* @___asan_gen_ to i64), i64 0, i64 0, i64 -1 }
diff --git a/llvm/test/Instrumentation/AddressSanitizer/win-string-literal.ll b/llvm/test/Instrumentation/AddressSanitizer/win-string-literal.ll
index 4fef094832a..a86581c1e8e 100644
--- a/llvm/test/Instrumentation/AddressSanitizer/win-string-literal.ll
+++ b/llvm/test/Instrumentation/AddressSanitizer/win-string-literal.ll
@@ -15,7 +15,7 @@
; CHECK-SAME: { i64 ptrtoint ({ [5 x i8], [59 x i8] }* @"??_C@_04JIHMPGLA@asdf?$AA@" to i64),
; CHECK-SAME: i64 5, i64 64, i64 ptrtoint ([17 x i8]* @___asan_gen_.1 to i64),
; CHECK-SAME: i64 ptrtoint ([8 x i8]* @___asan_gen_ to i64), i64 0,
-; CHECK-SAME: i64 ptrtoint ({ [6 x i8]*, i32, i32 }* @___asan_gen_.3 to i64), i64 0 },
+; CHECK-SAME: i64 ptrtoint ({ [6 x i8]*, i32, i32 }* @___asan_gen_.3 to i64), i64 -1 },
; CHECK-SAME: section ".ASAN$GL", comdat($"??_C@_04JIHMPGLA@asdf?$AA@"), align 64
; ModuleID = 't.cpp'
OpenPOWER on IntegriCloud