LLDB mainline
MemoryTagManager.h
Go to the documentation of this file.
1//===-- MemoryTagManager.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_MEMORYTAGMANAGER_H
10#define LLDB_TARGET_MEMORYTAGMANAGER_H
11
14#include "lldb/lldb-private.h"
15#include "llvm/Support/Error.h"
16
17namespace lldb_private {
18
19// This interface allows high level commands to handle memory tags
20// in a generic way.
21//
22// Definitions:
23// logical tag - the tag stored in a pointer
24// allocation tag - the tag stored in hardware
25// (e.g. special memory, cache line bits)
26// granule - number of bytes of memory a single tag applies to
27
29public:
31
32 // Extract the logical tag from a pointer
33 // The tag is returned as a plain value, with any shifts removed.
34 // For example if your tags are stored in bits 56-60 then the logical tag
35 // you get will have been shifted down 56 before being returned.
36 virtual lldb::addr_t GetLogicalTag(lldb::addr_t addr) const = 0;
37
38 // Remove tag bits from a pointer
39 virtual lldb::addr_t RemoveTagBits(lldb::addr_t addr) const = 0;
40
41 // Return the difference between two addresses, ignoring any logical tags they
42 // have. If your tags are just part of a larger set of ignored bits, this
43 // should ignore all those bits.
44 virtual ptrdiff_t AddressDiff(lldb::addr_t addr1,
45 lldb::addr_t addr2) const = 0;
46
47 // Return the number of bytes a single tag covers
48 virtual lldb::addr_t GetGranuleSize() const = 0;
49
50 // Align an address range to granule boundaries.
51 // So that reading memory tags for the new range returns
52 // tags that will cover the original range.
53 //
54 // Say your granules are 16 bytes and you want
55 // tags for 16 bytes of memory starting from address 8.
56 // 1 granule isn't enough because it only covers addresses
57 // 0-16, we want addresses 8-24. So the range must be
58 // expanded to 2 granules.
59 virtual TagRange ExpandToGranule(TagRange range) const = 0;
60
61 // Given a range addr to end_addr, check that:
62 // * end_addr >= addr (when memory tags are removed)
63 // * the granule aligned range is completely covered by tagged memory
64 // (which may include one or more memory regions)
65 //
66 // If so, return a modified range which will have been expanded
67 // to be granule aligned. Otherwise return an error.
68 //
69 // Tags in the input addresses are ignored and not present
70 // in the returned range.
71 virtual llvm::Expected<TagRange> MakeTaggedRange(
72 lldb::addr_t addr, lldb::addr_t end_addr,
73 const lldb_private::MemoryRegionInfos &memory_regions) const = 0;
74
75 // Given a range addr to end_addr, check that end_addr >= addr.
76 // If it is not, return an error saying so.
77 // Otherwise, granule align it and return a set of ranges representing
78 // subsections of the aligned range that have memory tagging enabled.
79 //
80 // Basically a sparse version of MakeTaggedRange. Use this when you
81 // want to know which parts of a larger range have memory tagging.
82 //
83 // Regions in memory_regions should be sorted in ascending order and
84 // not overlap. (use Process GetMemoryRegions)
85 //
86 // Tags in the input addresses are ignored and not present
87 // in the returned ranges.
88 virtual llvm::Expected<std::vector<TagRange>> MakeTaggedRanges(
89 lldb::addr_t addr, lldb::addr_t end_addr,
90 const lldb_private::MemoryRegionInfos &memory_regions) const = 0;
91
92 // Return the type value to use in GDB protocol qMemTags packets to read
93 // allocation tags. This is named "Allocation" specifically because the spec
94 // allows for logical tags to be read the same way, though we do not use that.
95 //
96 // This value is unique within a given architecture. Meaning that different
97 // tagging schemes within the same architecture should use unique values,
98 // but other architectures can overlap those values.
99 virtual int32_t GetAllocationTagType() const = 0;
100
101 // Return the number of bytes a single tag will be packed into during
102 // transport. For example an MTE tag is 4 bits but occupies 1 byte during
103 // transport.
104 virtual size_t GetTagSizeInBytes() const = 0;
105
106 // Unpack tags from their stored format (e.g. gdb qMemTags data) into separate
107 // tags.
108 //
109 // Checks that each tag is within the expected value range and if granules is
110 // set to non-zero, that the number of tags found matches the number of
111 // granules we expected to cover.
112 virtual llvm::Expected<std::vector<lldb::addr_t>>
113 UnpackTagsData(const std::vector<uint8_t> &tags,
114 size_t granules = 0) const = 0;
115
116 // Unpack tags from a corefile segment containing compressed tags
117 // (compression that may be different from the one used for GDB transport).
118 //
119 // This method asumes that:
120 // * addr and len have been granule aligned by a tag manager
121 // * addr >= tag_segment_virtual_address
122 //
123 // 'reader' will always be a wrapper around a CoreFile in real use
124 // but allows testing without having to mock a CoreFile.
125 typedef std::function<size_t(lldb::offset_t, size_t, void *)> CoreReaderFn;
126 std::vector<lldb::addr_t> virtual UnpackTagsFromCoreFileSegment(
127 CoreReaderFn reader, lldb::addr_t tag_segment_virtual_address,
128 lldb::addr_t tag_segment_data_address, lldb::addr_t addr,
129 size_t len) const = 0;
130
131 // Pack uncompressed tags into their storage format (e.g. for gdb QMemTags).
132 // Checks that each tag is within the expected value range.
133 // We do not check the number of tags or range they apply to because
134 // it is up to the remote to repeat them as needed.
135 virtual llvm::Expected<std::vector<uint8_t>>
136 PackTags(const std::vector<lldb::addr_t> &tags) const = 0;
137
138 // Take a set of tags and repeat them as much as needed to cover the given
139 // range. We assume that this range has been previously expanded/aligned to
140 // granules. (this method is used by lldb-server to implement QMemTags
141 // packet handling)
142 //
143 // If the range is empty, zero tags are returned.
144 // If the range is not empty and...
145 // * there are no tags, an error is returned.
146 // * there are fewer tags than granules, the tags are repeated to fill the
147 // range.
148 // * there are more tags than granules, only the tags required to cover
149 // the range are returned.
150 //
151 // When repeating tags it will not always return a multiple of the original
152 // list. For example if your range is 3 granules and your tags are 1 and 2.
153 // You will get tags 1, 2 and 1 returned. Rather than getting 1, 2, 1, 2,
154 // which would be one too many tags for the range.
155 //
156 // A single tag will just be repeated as you'd expected. Tag 1 over 3 granules
157 // would return 1, 1, 1.
158 virtual llvm::Expected<std::vector<lldb::addr_t>>
159 RepeatTagsForRange(const std::vector<lldb::addr_t> &tags,
160 TagRange range) const = 0;
161
162 virtual ~MemoryTagManager() = default;
163};
164
165} // namespace lldb_private
166
167#endif // LLDB_TARGET_MEMORYTAGMANAGER_H
virtual std::vector< lldb::addr_t > UnpackTagsFromCoreFileSegment(CoreReaderFn reader, lldb::addr_t tag_segment_virtual_address, lldb::addr_t tag_segment_data_address, lldb::addr_t addr, size_t len) const =0
std::function< size_t(lldb::offset_t, size_t, void *)> CoreReaderFn
virtual ~MemoryTagManager()=default
virtual TagRange ExpandToGranule(TagRange range) const =0
virtual llvm::Expected< TagRange > MakeTaggedRange(lldb::addr_t addr, lldb::addr_t end_addr, const lldb_private::MemoryRegionInfos &memory_regions) const =0
virtual llvm::Expected< std::vector< lldb::addr_t > > UnpackTagsData(const std::vector< uint8_t > &tags, size_t granules=0) const =0
Range< lldb::addr_t, lldb::addr_t > TagRange
virtual ptrdiff_t AddressDiff(lldb::addr_t addr1, lldb::addr_t addr2) const =0
virtual size_t GetTagSizeInBytes() const =0
virtual lldb::addr_t GetGranuleSize() const =0
virtual llvm::Expected< std::vector< lldb::addr_t > > RepeatTagsForRange(const std::vector< lldb::addr_t > &tags, TagRange range) const =0
virtual llvm::Expected< std::vector< uint8_t > > PackTags(const std::vector< lldb::addr_t > &tags) const =0
virtual int32_t GetAllocationTagType() const =0
virtual lldb::addr_t RemoveTagBits(lldb::addr_t addr) const =0
virtual llvm::Expected< std::vector< TagRange > > MakeTaggedRanges(lldb::addr_t addr, lldb::addr_t end_addr, const lldb_private::MemoryRegionInfos &memory_regions) const =0
virtual lldb::addr_t GetLogicalTag(lldb::addr_t addr) const =0
A class that represents a running process on the host machine.
uint64_t offset_t
Definition: lldb-types.h:85
uint64_t addr_t
Definition: lldb-types.h:80