[asan] get rid of std::map. No STL and almost no libstdc++ left.

llvm-svn: 145706
This commit is contained in:
Kostya Serebryany 2011-12-02 21:02:20 +00:00
parent dbf20b8aaa
commit e4bada2c94
3 changed files with 46 additions and 14 deletions

View File

@ -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

View File

@ -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);

View File

@ -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);