[PATCH] D15644: [asan] Use private aliases for global variables (compiler-rt part).
Maxim Ostapenko via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 18 08:23:33 PST 2015
m.ostapenko created this revision.
m.ostapenko added reviewers: kcc, eugenis, samsonov.
m.ostapenko added subscribers: ygribov, llvm-commits.
m.ostapenko set the repository for this revision to rL LLVM.
This is a compiler-rt part of this http://reviews.llvm.org/differential/diff/43231/ patch. Here, we change the way how we detect ODR violation. Instead of using __asan_region_is_poisoned(g->beg, g->size_with_redzone) on global address (that would be false now due to using private alias), we use new globally visible indicator symbol to perform the check.
Does this look like a reasonable approach?
Repository:
rL LLVM
http://reviews.llvm.org/D15644
Files:
lib/asan/asan_globals.cc
lib/asan/asan_interface_internal.h
test/asan/TestCases/Linux/local_alias.cc
Index: test/asan/TestCases/Linux/local_alias.cc
===================================================================
--- /dev/null
+++ test/asan/TestCases/Linux/local_alias.cc
@@ -0,0 +1,30 @@
+// RUN: %clangxx_asan -DBUILD_FOO_SO=1 -fPIC -shared %s -o %t-FOO-SO.so
+// RUN: %clangxx -DBUILD_BAR_SO=1 -fPIC -shared %s -o %t-BAR-SO.so
+// RUN: %clangxx %s -c -o %t.o
+// RUN: %clangxx_asan %t.o %t-BAR-SO.so %t-FOO-SO.so -o %t-EXE
+// RUN: %run %t-EXE
+
+#if defined (BUILD_FOO_SO)
+long h = 15;
+long f = 4;
+long foo(long *p) {
+ return *p;
+}
+#elif defined (BUILD_BAR_SO)
+long foo(long *);
+long h = 12;
+long i = 13;
+long f = 5;
+
+int bar() {
+ if (foo(&f) != 5 || foo(&h) != 12 || foo(&i) != 13)
+ return 1;
+ return 0;
+}
+#else
+extern int bar();
+
+int main() {
+ return bar();
+}
+#endif
Index: lib/asan/asan_interface_internal.h
===================================================================
--- lib/asan/asan_interface_internal.h
+++ lib/asan/asan_interface_internal.h
@@ -45,7 +45,8 @@
// This structure describes an instrumented global variable.
struct __asan_global {
- uptr beg; // The address of the global.
+ uptr beg; // The private address of the global.
+ uptr odr_indicator; // The address of the ODR indicator symbol.
uptr size; // The original size of the global.
uptr size_with_redzone; // The size with the redzone.
const char *name; // Name as a C string.
Index: lib/asan/asan_globals.cc
===================================================================
--- lib/asan/asan_globals.cc
+++ lib/asan/asan_globals.cc
@@ -149,17 +149,21 @@
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)) {
+ u8 *odr_indicator = reinterpret_cast<u8 *>(g->odr_indicator);
+ // If *odr_indicator is not zero, some module have already registred
+ // externally visible symbol with the same name. This is an ODR vioation.
+ if (*odr_indicator != 0) {
// 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 &&
+ if (g->odr_indicator == l->g->odr_indicator &&
(flags()->detect_odr_violation >= 2 || g->size != l->g->size) &&
!IsODRViolationSuppressed(g->name))
ReportODRViolation(g, FindRegistrationSite(g),
l->g, FindRegistrationSite(l->g));
}
}
+ *odr_indicator = 1;
}
if (CanPoisonMemory())
PoisonRedZones(*g);
@@ -190,6 +194,10 @@
// We unpoison the shadow memory for the global but we do not remove it from
// the list because that would require O(n^2) time with the current list
// implementation. It might not be worth doing anyway.
+
+ // Release ODR indicator.
+ u8 *odr_indicator = reinterpret_cast<u8 *>(g->odr_indicator);
+ *odr_indicator = 0;
}
void StopInitOrderChecking() {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D15644.43231.patch
Type: text/x-patch
Size: 3239 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151218/f12f7605/attachment.bin>
More information about the llvm-commits
mailing list