|
|
|||
File indexing completed on 2026-05-10 08:42:53
0001 //===-- MemoryTagManager.h --------------------------------------*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 0009 #ifndef LLDB_TARGET_MEMORYTAGMANAGER_H 0010 #define LLDB_TARGET_MEMORYTAGMANAGER_H 0011 0012 #include "lldb/Target/MemoryRegionInfo.h" 0013 #include "lldb/Utility/RangeMap.h" 0014 #include "lldb/lldb-private.h" 0015 #include "llvm/Support/Error.h" 0016 0017 namespace lldb_private { 0018 0019 // This interface allows high level commands to handle memory tags 0020 // in a generic way. 0021 // 0022 // Definitions: 0023 // logical tag - the tag stored in a pointer 0024 // allocation tag - the tag stored in hardware 0025 // (e.g. special memory, cache line bits) 0026 // granule - number of bytes of memory a single tag applies to 0027 0028 class MemoryTagManager { 0029 public: 0030 typedef Range<lldb::addr_t, lldb::addr_t> TagRange; 0031 0032 // Extract the logical tag from a pointer 0033 // The tag is returned as a plain value, with any shifts removed. 0034 // For example if your tags are stored in bits 56-60 then the logical tag 0035 // you get will have been shifted down 56 before being returned. 0036 virtual lldb::addr_t GetLogicalTag(lldb::addr_t addr) const = 0; 0037 0038 // Remove tag bits from a pointer 0039 virtual lldb::addr_t RemoveTagBits(lldb::addr_t addr) const = 0; 0040 0041 // Return the difference between two addresses, ignoring any logical tags they 0042 // have. If your tags are just part of a larger set of ignored bits, this 0043 // should ignore all those bits. 0044 virtual ptrdiff_t AddressDiff(lldb::addr_t addr1, 0045 lldb::addr_t addr2) const = 0; 0046 0047 // Return the number of bytes a single tag covers 0048 virtual lldb::addr_t GetGranuleSize() const = 0; 0049 0050 // Align an address range to granule boundaries. 0051 // So that reading memory tags for the new range returns 0052 // tags that will cover the original range. 0053 // 0054 // Say your granules are 16 bytes and you want 0055 // tags for 16 bytes of memory starting from address 8. 0056 // 1 granule isn't enough because it only covers addresses 0057 // 0-16, we want addresses 8-24. So the range must be 0058 // expanded to 2 granules. 0059 virtual TagRange ExpandToGranule(TagRange range) const = 0; 0060 0061 // Given a range addr to end_addr, check that: 0062 // * end_addr >= addr (when memory tags are removed) 0063 // * the granule aligned range is completely covered by tagged memory 0064 // (which may include one or more memory regions) 0065 // 0066 // If so, return a modified range which will have been expanded 0067 // to be granule aligned. Otherwise return an error. 0068 // 0069 // Tags in the input addresses are ignored and not present 0070 // in the returned range. 0071 virtual llvm::Expected<TagRange> MakeTaggedRange( 0072 lldb::addr_t addr, lldb::addr_t end_addr, 0073 const lldb_private::MemoryRegionInfos &memory_regions) const = 0; 0074 0075 // Given a range addr to end_addr, check that end_addr >= addr. 0076 // If it is not, return an error saying so. 0077 // Otherwise, granule align it and return a set of ranges representing 0078 // subsections of the aligned range that have memory tagging enabled. 0079 // 0080 // Basically a sparse version of MakeTaggedRange. Use this when you 0081 // want to know which parts of a larger range have memory tagging. 0082 // 0083 // Regions in memory_regions should be sorted in ascending order and 0084 // not overlap. (use Process GetMemoryRegions) 0085 // 0086 // Tags in the input addresses are ignored and not present 0087 // in the returned ranges. 0088 virtual llvm::Expected<std::vector<TagRange>> MakeTaggedRanges( 0089 lldb::addr_t addr, lldb::addr_t end_addr, 0090 const lldb_private::MemoryRegionInfos &memory_regions) const = 0; 0091 0092 // Return the type value to use in GDB protocol qMemTags packets to read 0093 // allocation tags. This is named "Allocation" specifically because the spec 0094 // allows for logical tags to be read the same way, though we do not use that. 0095 // 0096 // This value is unique within a given architecture. Meaning that different 0097 // tagging schemes within the same architecture should use unique values, 0098 // but other architectures can overlap those values. 0099 virtual int32_t GetAllocationTagType() const = 0; 0100 0101 // Return the number of bytes a single tag will be packed into during 0102 // transport. For example an MTE tag is 4 bits but occupies 1 byte during 0103 // transport. 0104 virtual size_t GetTagSizeInBytes() const = 0; 0105 0106 // Unpack tags from their stored format (e.g. gdb qMemTags data) into separate 0107 // tags. 0108 // 0109 // Checks that each tag is within the expected value range and if granules is 0110 // set to non-zero, that the number of tags found matches the number of 0111 // granules we expected to cover. 0112 virtual llvm::Expected<std::vector<lldb::addr_t>> 0113 UnpackTagsData(const std::vector<uint8_t> &tags, 0114 size_t granules = 0) const = 0; 0115 0116 // Unpack tags from a corefile segment containing compressed tags 0117 // (compression that may be different from the one used for GDB transport). 0118 // 0119 // This method asumes that: 0120 // * addr and len have been granule aligned by a tag manager 0121 // * addr >= tag_segment_virtual_address 0122 // 0123 // 'reader' will always be a wrapper around a CoreFile in real use 0124 // but allows testing without having to mock a CoreFile. 0125 typedef std::function<size_t(lldb::offset_t, size_t, void *)> CoreReaderFn; 0126 std::vector<lldb::addr_t> virtual UnpackTagsFromCoreFileSegment( 0127 CoreReaderFn reader, lldb::addr_t tag_segment_virtual_address, 0128 lldb::addr_t tag_segment_data_address, lldb::addr_t addr, 0129 size_t len) const = 0; 0130 0131 // Pack uncompressed tags into their storage format (e.g. for gdb QMemTags). 0132 // Checks that each tag is within the expected value range. 0133 // We do not check the number of tags or range they apply to because 0134 // it is up to the remote to repeat them as needed. 0135 virtual llvm::Expected<std::vector<uint8_t>> 0136 PackTags(const std::vector<lldb::addr_t> &tags) const = 0; 0137 0138 // Take a set of tags and repeat them as much as needed to cover the given 0139 // range. We assume that this range has been previously expanded/aligned to 0140 // granules. (this method is used by lldb-server to implement QMemTags 0141 // packet handling) 0142 // 0143 // If the range is empty, zero tags are returned. 0144 // If the range is not empty and... 0145 // * there are no tags, an error is returned. 0146 // * there are fewer tags than granules, the tags are repeated to fill the 0147 // range. 0148 // * there are more tags than granules, only the tags required to cover 0149 // the range are returned. 0150 // 0151 // When repeating tags it will not always return a multiple of the original 0152 // list. For example if your range is 3 granules and your tags are 1 and 2. 0153 // You will get tags 1, 2 and 1 returned. Rather than getting 1, 2, 1, 2, 0154 // which would be one too many tags for the range. 0155 // 0156 // A single tag will just be repeated as you'd expected. Tag 1 over 3 granules 0157 // would return 1, 1, 1. 0158 virtual llvm::Expected<std::vector<lldb::addr_t>> 0159 RepeatTagsForRange(const std::vector<lldb::addr_t> &tags, 0160 TagRange range) const = 0; 0161 0162 virtual ~MemoryTagManager() = default; 0163 }; 0164 0165 } // namespace lldb_private 0166 0167 #endif // LLDB_TARGET_MEMORYTAGMANAGER_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|