diff options
-rw-r--r-- | compiler-rt/lib/asan/asan_globals.cc | 30 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_internal.h | 13 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_rtl.cc | 17 |
3 files changed, 46 insertions, 14 deletions
diff --git a/compiler-rt/lib/asan/asan_globals.cc b/compiler-rt/lib/asan/asan_globals.cc index ac89d755e44..317d939fc83 100644 --- a/compiler-rt/lib/asan/asan_globals.cc +++ b/compiler-rt/lib/asan/asan_globals.cc @@ -21,15 +21,19 @@ #include "asan_thread.h" #include <ctype.h> -#include <map> namespace __asan { typedef __asan_global Global; +struct ListOfGlobals { + const Global *g; + ListOfGlobals *next; +}; + static AsanLock mu_for_globals(LINKER_INITIALIZED); -typedef std::map<uintptr_t, Global> MapOfGlobals; -static MapOfGlobals *g_all_globals = NULL; +static ListOfGlobals *list_of_globals; +static LowLevelAllocator allocator_for_globals(LINKER_INITIALIZED); void PoisonRedZones(const Global &g) { size_t shadow_rz_size = kGlobalAndStackRedzone >> SHADOW_SCALE; @@ -86,13 +90,9 @@ bool DescribeAddrIfMyRedZone(const Global &g, uintptr_t addr) { bool DescribeAddrIfGlobal(uintptr_t addr) { if (!FLAG_report_globals) return false; ScopedLock lock(&mu_for_globals); - if (!g_all_globals) return false; bool res = false; - // Just iterate. May want to use binary search instead. - for (MapOfGlobals::iterator i = g_all_globals->begin(), - end = g_all_globals->end(); i != end; ++i) { - Global &g = i->second; - CHECK(i->first == g.beg); + for (ListOfGlobals *l = list_of_globals; l; l = l->next) { + const Global &g = *l->g; if (FLAG_report_globals >= 2) Printf("Search Global: beg=%p size=%ld name=%s\n", g.beg, g.size, g.name); @@ -108,15 +108,17 @@ static void RegisterGlobal(const Global *g) { CHECK(asan_inited); if (!FLAG_report_globals) return; ScopedLock lock(&mu_for_globals); - if (!g_all_globals) - g_all_globals = new MapOfGlobals; CHECK(AddrIsInMem(g->beg)); + CHECK(AddrIsAlignedByGranularity(g->beg)); + PoisonRedZones(*g); + ListOfGlobals *l = + (ListOfGlobals*)allocator_for_globals.Allocate(sizeof(ListOfGlobals)); + l->g = g; + l->next = list_of_globals; + list_of_globals = l; if (FLAG_report_globals >= 2) Printf("Added Global: beg=%p size=%ld name=%s\n", g->beg, g->size, g->name); - CHECK(AddrIsAlignedByGranularity(g->beg)); - PoisonRedZones(*g); - (*g_all_globals)[g->beg] = *g; } } // namespace __asan diff --git a/compiler-rt/lib/asan/asan_internal.h b/compiler-rt/lib/asan/asan_internal.h index c722feb7b42..4ae68e78eca 100644 --- a/compiler-rt/lib/asan/asan_internal.h +++ b/compiler-rt/lib/asan/asan_internal.h @@ -163,6 +163,19 @@ const int kAsanGlobalRedzoneMagic = 0xf9; static const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3; static const uintptr_t kRetiredStackFrameMagic = 0x45E0360E; +// -------------------------- LowLevelAllocator ----- {{{1 +// A simple low-level memory allocator for internal use. +class LowLevelAllocator { + public: + explicit LowLevelAllocator(LinkerInitialized) {} + // 'size' must be a power of two. + // Requires an external lock. + void *Allocate(size_t size); + private: + char *allocated_end_; + char *allocated_current_; +}; + // -------------------------- Atomic ---------------- {{{1 static inline int AtomicInc(int *a) { if (!FLAG_mt) return ++(*a); diff --git a/compiler-rt/lib/asan/asan_rtl.cc b/compiler-rt/lib/asan/asan_rtl.cc index 5518641a67d..609c007cc52 100644 --- a/compiler-rt/lib/asan/asan_rtl.cc +++ b/compiler-rt/lib/asan/asan_rtl.cc @@ -174,6 +174,23 @@ static void protect_range(uintptr_t beg, uintptr_t end) { CHECK(res == (void*)beg); } +// ---------------------- LowLevelAllocator ------------- {{{1 +void *LowLevelAllocator::Allocate(size_t size) { + CHECK((size & (size - 1)) == 0 && "size must be a power of two"); + if (allocated_end_ - allocated_current_ < size) { + size_t size_to_allocate = Max(size, kPageSize); + allocated_current_ = (char*)asan_mmap(0, size_to_allocate, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + CHECK((allocated_current_ != (char*)-1) && "Can't mmap"); + allocated_end_ = allocated_current_ + size_to_allocate; + } + CHECK(allocated_end_ - allocated_current_ >= size); + void *res = allocated_current_; + allocated_current_ += size; + return res; +} + // ---------------------- DescribeAddress -------------------- {{{1 static bool DescribeStackAddress(uintptr_t addr, uintptr_t access_size) { AsanThread *t = asanThreadRegistry().FindThreadByStackAddress(addr); |