1 //===-- sanitizer_chained_origin_depot.h ------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // A storage for chained origins.
10 //===----------------------------------------------------------------------===//
11 
12 #ifndef SANITIZER_CHAINED_ORIGIN_DEPOT_H
13 #define SANITIZER_CHAINED_ORIGIN_DEPOT_H
14 
15 #include "sanitizer_common.h"
16 #include "sanitizer_stackdepotbase.h"
17 
18 namespace __sanitizer {
19 
20 class ChainedOriginDepot {
21  public:
22   ChainedOriginDepot();
23 
24   // Gets the statistic of the origin chain storage.
25   StackDepotStats *GetStats();
26 
27   // Stores a chain with StackDepot ID here_id and previous chain ID prev_id.
28   // If successful, returns true and the new chain id new_id.
29   // If the same element already exists, returns false and sets new_id to the
30   // existing ID.
31   bool Put(u32 here_id, u32 prev_id, u32 *new_id);
32 
33   // Retrieves the stored StackDepot ID for the given origin ID.
34   u32 Get(u32 id, u32 *other);
35 
36   void LockAll();
37   void UnlockAll();
38 
39  private:
40   struct ChainedOriginDepotDesc {
41     u32 here_id;
42     u32 prev_id;
43   };
44 
45   struct ChainedOriginDepotNode {
46     ChainedOriginDepotNode *link;
47     u32 id;
48     u32 here_id;
49     u32 prev_id;
50 
51     typedef ChainedOriginDepotDesc args_type;
52 
53     bool eq(u32 hash, const args_type &args) const;
54 
55     static uptr storage_size(const args_type &args);
56 
57     static u32 hash(const args_type &args);
58 
59     static bool is_valid(const args_type &args);
60 
61     void store(const args_type &args, u32 other_hash);
62 
63     args_type load() const;
64 
65     struct Handle {
66       ChainedOriginDepotNode *node_;
67       Handle() : node_(nullptr) {}
68       explicit Handle(ChainedOriginDepotNode *node) : node_(node) {}
69       bool valid() { return node_; }
70       u32 id() { return node_->id; }
71       int here_id() { return node_->here_id; }
72       int prev_id() { return node_->prev_id; }
73     };
74 
75     Handle get_handle();
76 
77     typedef Handle handle_type;
78   };
79 
80   StackDepotBase<ChainedOriginDepotNode, 4, 20> depot;
81 
82   ChainedOriginDepot(const ChainedOriginDepot &) = delete;
83   void operator=(const ChainedOriginDepot &) = delete;
84 };
85 
86 }  // namespace __sanitizer
87 
88 #endif  // SANITIZER_CHAINED_ORIGIN_DEPOT_H
89