msan_chained_origin_depot.cc revision 2d1fdb26e458c4ddc04155c1d421bced3ba90cd0
1//===-- msan_chained_origin_depot.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// A storage for chained origins.
11//===----------------------------------------------------------------------===//
12
13#include "msan_chained_origin_depot.h"
14
15#include "sanitizer_common/sanitizer_stackdepotbase.h"
16
17namespace __msan {
18
19struct ChainedOriginDepotDesc {
20  u32 here_id;
21  u32 prev_id;
22  u32 hash() const { return here_id ^ prev_id; }
23  bool is_valid() { return true; }
24};
25
26struct ChainedOriginDepotNode {
27  ChainedOriginDepotNode *link;
28  u32 id;
29  u32 here_id;
30  u32 prev_id;
31
32  typedef ChainedOriginDepotDesc args_type;
33  bool eq(u32 hash, const args_type &args) const {
34    return here_id == args.here_id && prev_id == args.prev_id;
35  }
36  static uptr storage_size(const args_type &args) {
37    return sizeof(ChainedOriginDepotNode);
38  }
39  void store(const args_type &args, u32 other_hash) {
40    here_id = args.here_id;
41    prev_id = args.prev_id;
42  }
43  args_type load() const {
44    args_type ret = {here_id, prev_id};
45    return ret;
46  }
47  struct Handle {
48    ChainedOriginDepotNode *node_;
49    Handle() : node_(0) {}
50    explicit Handle(ChainedOriginDepotNode *node) : node_(node) {}
51    bool valid() { return node_; }
52    u32 id() { return node_->id; }
53    int here_id() { return node_->here_id; }
54    int prev_id() { return node_->prev_id; }
55  };
56  Handle get_handle() { return Handle(this); }
57
58  typedef Handle handle_type;
59};
60
61static StackDepotBase<ChainedOriginDepotNode, 3> chainedOriginDepot;
62
63StackDepotStats *ChainedOriginDepotGetStats() {
64  return chainedOriginDepot.GetStats();
65}
66
67bool ChainedOriginDepotPut(u32 here_id, u32 prev_id, u32 *new_id) {
68  ChainedOriginDepotDesc desc = {here_id, prev_id};
69  bool inserted;
70  ChainedOriginDepotNode::Handle h = chainedOriginDepot.Put(desc, &inserted);
71  *new_id = h.valid() ? h.id() : 0;
72  return inserted;
73}
74
75// Retrieves a stored stack trace by the id.
76u32 ChainedOriginDepotGet(u32 id, u32 *other) {
77  ChainedOriginDepotDesc desc = chainedOriginDepot.Get(id);
78  *other = desc.prev_id;
79  return desc.here_id;
80}
81
82}  // namespace __msan
83