aboutsummaryrefslogtreecommitdiff
path: root/lib/asan/asan_globals.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/asan/asan_globals.cc')
-rw-r--r--lib/asan/asan_globals.cc76
1 files changed, 29 insertions, 47 deletions
diff --git a/lib/asan/asan_globals.cc b/lib/asan/asan_globals.cc
index 06140bbb360a..c34b1d3cedf2 100644
--- a/lib/asan/asan_globals.cc
+++ b/lib/asan/asan_globals.cc
@@ -18,6 +18,7 @@
#include "asan_report.h"
#include "asan_stack.h"
#include "asan_stats.h"
+#include "asan_suppressions.h"
#include "asan_thread.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_mutex.h"
@@ -73,7 +74,7 @@ ALWAYS_INLINE void PoisonRedZones(const Global &g) {
const uptr kMinimalDistanceFromAnotherGlobal = 64;
-bool IsAddressNearGlobal(uptr addr, const __asan_global &g) {
+static bool IsAddressNearGlobal(uptr addr, const __asan_global &g) {
if (addr <= g.beg - kMinimalDistanceFromAnotherGlobal) return false;
if (addr >= g.beg + g.size_with_redzone) return false;
return true;
@@ -90,36 +91,40 @@ static void ReportGlobal(const Global &g, const char *prefix) {
}
}
-static bool DescribeOrGetInfoIfGlobal(uptr addr, uptr size, bool print,
- Global *output_global) {
- if (!flags()->report_globals) return false;
+static u32 FindRegistrationSite(const Global *g) {
+ mu_for_globals.CheckLocked();
+ CHECK(global_registration_site_vector);
+ for (uptr i = 0, n = global_registration_site_vector->size(); i < n; i++) {
+ GlobalRegistrationSite &grs = (*global_registration_site_vector)[i];
+ if (g >= grs.g_first && g <= grs.g_last)
+ return grs.stack_id;
+ }
+ return 0;
+}
+
+int GetGlobalsForAddress(uptr addr, Global *globals, u32 *reg_sites,
+ int max_globals) {
+ if (!flags()->report_globals) return 0;
BlockingMutexLock lock(&mu_for_globals);
- bool res = false;
+ int res = 0;
for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
const Global &g = *l->g;
- if (print) {
- if (flags()->report_globals >= 2)
- ReportGlobal(g, "Search");
- res |= DescribeAddressRelativeToGlobal(addr, size, g);
- } else {
- if (IsAddressNearGlobal(addr, g)) {
- CHECK(output_global);
- *output_global = g;
- return true;
- }
+ if (flags()->report_globals >= 2)
+ ReportGlobal(g, "Search");
+ if (IsAddressNearGlobal(addr, g)) {
+ globals[res] = g;
+ if (reg_sites)
+ reg_sites[res] = FindRegistrationSite(&g);
+ res++;
+ if (res == max_globals) break;
}
}
return res;
}
-bool DescribeAddressIfGlobal(uptr addr, uptr size) {
- return DescribeOrGetInfoIfGlobal(addr, size, /* print */ true,
- /* output_global */ nullptr);
-}
-
bool GetInfoForAddressIfGlobal(uptr addr, AddressDescription *descr) {
Global g = {};
- if (DescribeOrGetInfoIfGlobal(addr, /* size */ 1, /* print */ false, &g)) {
+ if (GetGlobalsForAddress(addr, &g, nullptr, 1)) {
internal_strncpy(descr->name, g.name, descr->name_size);
descr->region_address = g.beg;
descr->region_size = g.size;
@@ -129,16 +134,6 @@ bool GetInfoForAddressIfGlobal(uptr addr, AddressDescription *descr) {
return false;
}
-u32 FindRegistrationSite(const Global *g) {
- CHECK(global_registration_site_vector);
- for (uptr i = 0, n = global_registration_site_vector->size(); i < n; i++) {
- GlobalRegistrationSite &grs = (*global_registration_site_vector)[i];
- if (g >= grs.g_first && g <= grs.g_last)
- return grs.stack_id;
- }
- return 0;
-}
-
// Register a global variable.
// This function may be called more than once for every global
// so we store the globals in a map.
@@ -158,7 +153,8 @@ static void RegisterGlobal(const Global *g) {
// 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 &&
- (flags()->detect_odr_violation >= 2 || g->size != l->g->size))
+ (flags()->detect_odr_violation >= 2 || g->size != l->g->size) &&
+ !IsODRViolationSuppressed(g->name))
ReportODRViolation(g, FindRegistrationSite(g),
l->g, FindRegistrationSite(l->g));
}
@@ -210,20 +206,6 @@ void StopInitOrderChecking() {
}
}
-#if SANITIZER_WINDOWS // Should only be called on Windows.
-SANITIZER_INTERFACE_ATTRIBUTE
-void UnregisterGlobalsInRange(void *beg, void *end) {
- if (!flags()->report_globals)
- return;
- BlockingMutexLock lock(&mu_for_globals);
- for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
- void *address = (void *)l->g->beg;
- if (beg <= address && address < end)
- UnregisterGlobal(l->g);
- }
-}
-#endif
-
} // namespace __asan
// ---------------------- Interface ---------------- {{{1
@@ -232,7 +214,7 @@ using namespace __asan; // NOLINT
// Register an array of globals.
void __asan_register_globals(__asan_global *globals, uptr n) {
if (!flags()->report_globals) return;
- GET_STACK_TRACE_FATAL_HERE;
+ GET_STACK_TRACE_MALLOC;
u32 stack_id = StackDepotPut(stack);
BlockingMutexLock lock(&mu_for_globals);
if (!global_registration_site_vector)