blob: 9eeee9bc3f61351c2be0587cc4ca9e3433732d1d [file] [log] [blame]
Dmitry Vyukovf4792872012-08-30 10:02:48 +00001//===-- 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
Dmitry Vyukov191f2f72012-08-30 13:02:30 +000036static uptr hash(const uptr *stack, uptr size) {
Dmitry Vyukovf4792872012-08-30 10:02:48 +000037 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
Dmitry Vyukov191f2f72012-08-30 13:02:30 +000054u32 StackDepotPut(const uptr *stack, uptr size) {
Dmitry Vyukovf4792872012-08-30 10:02:48 +000055 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
Dmitry Vyukov191f2f72012-08-30 13:02:30 +000074const uptr *StackDepotGet(u32 id, uptr *size) {
Dmitry Vyukovf4792872012-08-30 10:02:48 +000075 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