summaryrefslogtreecommitdiffstats
path: root/compiler-rt
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2014-04-25 08:58:28 +0000
committerKostya Serebryany <kcc@google.com>2014-04-25 08:58:28 +0000
commite91930a7e6786e0f3fa314c66203996210ea2929 (patch)
tree0d361808759f0ca2ae3984b3962b47a58768cb3d /compiler-rt
parent56a18f02ea5fcb3f03f23cdb670b3a0412c9c89f (diff)
downloadbcm5719-llvm-e91930a7e6786e0f3fa314c66203996210ea2929.tar.gz
bcm5719-llvm-e91930a7e6786e0f3fa314c66203996210ea2929.zip
[asan] implement an experimental detector of ODR violations. Not tested yet outside of a tiny test, may need tuning.
llvm-svn: 207210
Diffstat (limited to 'compiler-rt')
-rw-r--r--compiler-rt/lib/asan/asan_flags.h1
-rw-r--r--compiler-rt/lib/asan/asan_globals.cc12
-rw-r--r--compiler-rt/lib/asan/asan_report.cc13
-rw-r--r--compiler-rt/lib/asan/asan_report.h3
-rw-r--r--compiler-rt/lib/asan/asan_rtl.cc4
-rw-r--r--compiler-rt/test/asan/TestCases/Linux/odr-violation.cc23
6 files changed, 56 insertions, 0 deletions
diff --git a/compiler-rt/lib/asan/asan_flags.h b/compiler-rt/lib/asan/asan_flags.h
index 7dc78158189..3601aff461e 100644
--- a/compiler-rt/lib/asan/asan_flags.h
+++ b/compiler-rt/lib/asan/asan_flags.h
@@ -64,6 +64,7 @@ struct Flags {
bool start_deactivated;
int detect_invalid_pointer_pairs;
bool detect_container_overflow;
+ bool detect_odr_violation;
};
extern Flags asan_flags_dont_use_directly;
diff --git a/compiler-rt/lib/asan/asan_globals.cc b/compiler-rt/lib/asan/asan_globals.cc
index 81699676b57..8bb2e3b26ec 100644
--- a/compiler-rt/lib/asan/asan_globals.cc
+++ b/compiler-rt/lib/asan/asan_globals.cc
@@ -92,6 +92,18 @@ static void RegisterGlobal(const Global *g) {
CHECK(AddrIsInMem(g->beg));
CHECK(AddrIsAlignedByGranularity(g->beg));
CHECK(AddrIsAlignedByGranularity(g->size_with_redzone));
+ if (flags()->detect_odr_violation) {
+ // Try detecting ODR (One Definition Rule) violation, i.e. the situation
+ // where two globals with the same name are defined in different modules.
+ if (__asan_region_is_poisoned(g->beg, g->size_with_redzone)) {
+ // This check may not be enough: if the first global is much larger
+ // the entire redzone of the second global may be within the first global.
+ for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
+ if (g->beg == l->g->beg)
+ ReportODRViolation(g, l->g);
+ }
+ }
+ }
if (flags()->poison_heap)
PoisonRedZones(*g);
ListOfGlobals *l = new(allocator_for_globals) ListOfGlobals;
diff --git a/compiler-rt/lib/asan/asan_report.cc b/compiler-rt/lib/asan/asan_report.cc
index bece6eab36f..af6f7705383 100644
--- a/compiler-rt/lib/asan/asan_report.cc
+++ b/compiler-rt/lib/asan/asan_report.cc
@@ -729,6 +729,19 @@ void ReportBadParamsToAnnotateContiguousContainer(uptr beg, uptr end,
ReportErrorSummary("bad-__sanitizer_annotate_contiguous_container", stack);
}
+void ReportODRViolation(const __asan_global *g1, const __asan_global *g2) {
+ ScopedInErrorReport in_report;
+ Decorator d;
+ Printf("%s", d.Warning());
+ Report("ERROR: AddressSanitizer: odr-violation (%p):\n", g1->beg);
+ Printf("%s", d.EndWarning());
+ Printf(" [1] size=%zd %s %s\n", g1->size, g1->name, g1->module_name);
+ Printf(" [2] size=%zd %s %s\n", g2->size, g2->name, g2->module_name);
+ Report("HINT: if you don't care about these warnings you may set "
+ "ASAN_OPTIONS=detect_odr_violation=0\n");
+ ReportErrorSummary("odr-violation", g1->module_name, 0, g1->name);
+}
+
// ----------------------- CheckForInvalidPointerPair ----------- {{{1
static NOINLINE void
ReportInvalidPointerPair(uptr pc, uptr bp, uptr sp, uptr a1, uptr a2) {
diff --git a/compiler-rt/lib/asan/asan_report.h b/compiler-rt/lib/asan/asan_report.h
index 3843a2ea2cd..1cf7c59b82d 100644
--- a/compiler-rt/lib/asan/asan_report.h
+++ b/compiler-rt/lib/asan/asan_report.h
@@ -54,6 +54,9 @@ void NORETURN
ReportBadParamsToAnnotateContiguousContainer(uptr beg, uptr end, uptr old_mid,
uptr new_mid, StackTrace *stack);
+void NORETURN
+ReportODRViolation(const __asan_global *g1, const __asan_global *g2);
+
// Mac-specific errors and warnings.
void WarnMacFreeUnallocated(
uptr addr, uptr zone_ptr, const char *zone_name, StackTrace *stack);
diff --git a/compiler-rt/lib/asan/asan_rtl.cc b/compiler-rt/lib/asan/asan_rtl.cc
index 2bac66907c9..38416677239 100644
--- a/compiler-rt/lib/asan/asan_rtl.cc
+++ b/compiler-rt/lib/asan/asan_rtl.cc
@@ -225,6 +225,10 @@ static void ParseFlagsFromString(Flags *f, const char *str) {
"detect_container_overflow",
"If true, honor the container overflow annotations. "
"See https://code.google.com/p/address-sanitizer/wiki/ContainerOverflow");
+
+ ParseFlag(str, &f->detect_odr_violation,
+ "detect_odr_violation",
+ "If true, detect violation of One-Definition-Rule (ODR) ");
}
void InitializeFlags(Flags *f, const char *env) {
diff --git a/compiler-rt/test/asan/TestCases/Linux/odr-violation.cc b/compiler-rt/test/asan/TestCases/Linux/odr-violation.cc
new file mode 100644
index 00000000000..7e53e4885ca
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/Linux/odr-violation.cc
@@ -0,0 +1,23 @@
+// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t.so
+// RUN: %clangxx_asan %s %t.so -Wl,-R. -o %t
+// RUN: ASAN_OPTIONS=detect_odr_violation=1 not %t 2>&1 | FileCheck %s
+// RUN: ASAN_OPTIONS=detect_odr_violation=0 %t 2>&1 | FileCheck %s --check-prefix=DISABLED
+// RUN: %t 2>&1 | FileCheck %s --check-prefix=DISABLED
+
+#ifndef SZ
+# define SZ 4
+#endif
+
+#if BUILD_SO
+char G[SZ];
+#else
+#include <stdio.h>
+char G[100];
+int main(int argc, char **argv) {
+ printf("PASS: %p\n", &G);
+}
+#endif
+
+// CHECK: ERROR: AddressSanitizer: odr-violation
+// CHECK: size=100 G
+// DISABLED: PASS
OpenPOWER on IntegriCloud