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