1 | //===-- MemoryTagMap.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 | #ifndef LLDB_TARGET_MEMORYTAGMAP_H |
10 | #define LLDB_TARGET_MEMORYTAGMAP_H |
11 | |
12 | #include "lldb/Target/MemoryTagManager.h" |
13 | #include "lldb/lldb-private.h" |
14 | #include <map> |
15 | #include <optional> |
16 | |
17 | namespace lldb_private { |
18 | |
19 | /// MemoryTagMap provides a way to give a sparse read result |
20 | /// when reading memory tags for a range. This is useful when |
21 | /// you want to annotate some large memory dump that might include |
22 | /// tagged memory but you don't know that it is all tagged. |
23 | class MemoryTagMap { |
24 | public: |
25 | /// Init an empty tag map |
26 | /// |
27 | /// \param [in] manager |
28 | /// Non-null pointer to a memory tag manager. |
29 | MemoryTagMap(const MemoryTagManager *manager); |
30 | |
31 | /// Insert tags into the map starting from addr. |
32 | /// |
33 | /// \param [in] addr |
34 | /// Start address of the range to insert tags for. |
35 | /// This address should be granule aligned and have had |
36 | /// any non address bits removed. |
37 | /// (ideally you would use the base of the range you used |
38 | /// to read the tags in the first place) |
39 | /// |
40 | /// \param [in] tags |
41 | /// Vector of tags to insert. The first tag will be inserted |
42 | /// at addr, the next at addr+granule size and so on until |
43 | /// all tags have been inserted. |
44 | void InsertTags(lldb::addr_t addr, const std::vector<lldb::addr_t> tags); |
45 | |
46 | bool Empty() const; |
47 | |
48 | /// Lookup memory tags for a range of memory from addr to addr+len. |
49 | /// |
50 | /// \param [in] addr |
51 | /// The start of the range. This may include non address bits and |
52 | /// does not have to be granule aligned. |
53 | /// |
54 | /// \param [in] len |
55 | /// The length in bytes of the range to read tags for. This does |
56 | /// not need to be multiple of the granule size. |
57 | /// |
58 | /// \return |
59 | /// A vector containing the tags found for the granules in the |
60 | /// range. (which is the result of granule aligning the given range) |
61 | /// |
62 | /// Each item in the vector is an optional tag. Meaning that if |
63 | /// it is valid then the granule had a tag and if not, it didn't. |
64 | /// |
65 | /// If the range had no tags at all, the vector will be empty. |
66 | /// If some of the range was tagged it will have items and some |
67 | /// of them may be std::nullopt. |
68 | /// (this saves the caller checking whether all items are std::nullopt) |
69 | std::vector<std::optional<lldb::addr_t>> GetTags(lldb::addr_t addr, |
70 | size_t len) const; |
71 | |
72 | private: |
73 | /// Lookup the tag for address |
74 | /// |
75 | /// \param [in] address |
76 | /// The address to lookup a tag for. This should be aligned |
77 | /// to a granule boundary. |
78 | /// |
79 | /// \return |
80 | /// The tag for the granule that address refers to, or std::nullopt |
81 | /// if it has no memory tag. |
82 | std::optional<lldb::addr_t> GetTag(lldb::addr_t addr) const; |
83 | |
84 | // A map of granule aligned addresses to their memory tag |
85 | std::map<lldb::addr_t, lldb::addr_t> m_addr_to_tag; |
86 | |
87 | // Memory tag manager used to align addresses and get granule size. |
88 | // Ideally this would be a const& but only certain architectures will |
89 | // have a memory tag manager class to provide here. So for a method |
90 | // returning a MemoryTagMap, std::optional<MemoryTagMap> allows it to handle |
91 | // architectures without memory tagging. Optionals cannot hold references |
92 | // so we go with a pointer that we assume will be not be null. |
93 | const MemoryTagManager *m_manager; |
94 | }; |
95 | |
96 | } // namespace lldb_private |
97 | |
98 | #endif // LLDB_TARGET_MEMORYTAGMAP_H |
99 | |