sanitizer_stackdepot.cc revision ff35f1d82b4f145b3477ef27a7a2e7b63c486988
1//===-- sanitizer_stackdepot.cc -------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file is shared between AddressSanitizer and ThreadSanitizer 11// run-time libraries. 12//===----------------------------------------------------------------------===// 13 14#include "sanitizer_stackdepot.h" 15#include "sanitizer_common.h" 16#include "sanitizer_mutex.h" 17 18namespace __sanitizer { 19 20struct StackDesc { 21 StackDesc *link; 22 u32 id; 23 uptr hash; 24 uptr size; 25 uptr stack[1]; 26}; 27 28static struct { 29 StaticSpinMutex mtx; 30 StackDesc *head; 31 u8 *region_pos; 32 u8 *region_end; 33 u32 seq; 34} depot; 35 36static uptr hash(const uptr *stack, uptr size) { 37 return 0; 38} 39 40static StackDesc *allocDesc(uptr size) { 41 uptr memsz = sizeof(StackDesc) + (size - 1) * sizeof(uptr); 42 if (depot.region_pos + memsz > depot.region_end) { 43 uptr allocsz = 64*1024; 44 if (allocsz < memsz) 45 allocsz = memsz; 46 depot.region_pos = (u8*)MmapOrDie(allocsz, "stack depot"); 47 depot.region_end = depot.region_pos + allocsz; 48 } 49 StackDesc *s = (StackDesc*)depot.region_pos; 50 depot.region_pos += memsz; 51 return s; 52} 53 54u32 StackDepotPut(const uptr *stack, uptr size) { 55 if (stack == 0 || size == 0) 56 return 0; 57 uptr h = hash(stack, size); 58 SpinMutexLock l(&depot.mtx); 59 for (StackDesc *s = depot.head; s; s = s->link) { 60 if (s->hash == h && s->size == size 61 && internal_memcmp(s->stack, stack, size * sizeof(uptr)) == 0) 62 return s->id; 63 } 64 StackDesc *s = allocDesc(size); 65 s->id = ++depot.seq; 66 s->hash = h; 67 s->size = size; 68 internal_memcpy(s->stack, stack, size * sizeof(uptr)); 69 s->link = depot.head; 70 depot.head = s; 71 return s->id; 72} 73 74const uptr *StackDepotGet(u32 id, uptr *size) { 75 if (id == 0) 76 return 0; 77 SpinMutexLock l(&depot.mtx); 78 for (StackDesc *s = depot.head; s; s = s->link) { 79 if (s->id == id) { 80 *size = s->size; 81 return s->stack; 82 } 83 } 84 return 0; 85} 86 87} // namespace __sanitizer 88