10#include "llvm/Support/Error.h"
59 new_start -= align_down_amount;
62 size_t new_len = range.
GetByteSize() + align_down_amount;
64 size_t align_up_amount = granule - (new_len % granule);
65 if (align_up_amount != granule)
66 new_len += align_up_amount;
73 return llvm::createStringError(
74 llvm::inconvertibleErrorCode(),
75 "End address (0x%" PRIx64
76 ") must be greater than the start address (0x%" PRIx64
")",
80llvm::Expected<MemoryTagManager::TagRange>
101 while (remaining_range.
IsValid()) {
103 MemoryRegionInfos::const_iterator region = std::find_if(
104 memory_regions.cbegin(), memory_regions.cend(),
106 return region.GetRange().Contains(remaining_range.GetRangeBase());
109 if (region == memory_regions.cend() ||
112 return llvm::createStringError(llvm::inconvertibleErrorCode(),
113 "Address range 0x%" PRIx64
":0x%" PRIx64
114 " is not in a memory tagged region",
124 remaining_range.
SetRangeBase(region->GetRange().GetRangeEnd());
132llvm::Expected<std::vector<MemoryTagManager::TagRange>>
143 std::vector<MemoryTagManager::TagRange> tagged_ranges;
145 if (memory_regions.empty())
146 return tagged_ranges;
150 assert(std::is_sorted(
151 memory_regions.begin(), memory_regions.end(),
153 return lhs.GetRange().GetRangeBase() < rhs.GetRange().GetRangeBase();
168 MemoryRegionInfos::const_iterator overlap = std::adjacent_find(
169 memory_regions.begin(), memory_regions.end(),
171 return rhs.GetRange().DoesIntersect(lhs.GetRange());
174 assert(overlap == memory_regions.end());
188 if (!region.GetRange().DoesIntersect(range))
193 if (region.GetMemoryTagged()) {
198 std::max(range.
GetRangeBase(), region.GetRange().GetRangeBase());
200 std::min(range.
GetRangeEnd(), region.GetRange().GetRangeEnd());
214 return tagged_ranges;
217llvm::Expected<std::vector<lldb::addr_t>>
219 size_t granules )
const {
223 if (num_tags != granules) {
224 return llvm::createStringError(
225 llvm::inconvertibleErrorCode(),
226 "Packed tag data size does not match expected number of tags. "
227 "Expected %zu tag(s) for %zu granule(s), got %zu tag(s).",
228 granules, granules, num_tags);
234 std::vector<lldb::addr_t> unpacked;
235 unpacked.reserve(tags.size());
236 for (
auto it = tags.begin(); it != tags.end(); ++it) {
239 return llvm::createStringError(
240 llvm::inconvertibleErrorCode(),
241 "Found tag 0x%x which is > max MTE tag value of 0x%x.", *it,
244 unpacked.push_back(*it);
250std::vector<lldb::addr_t>
259 const size_t two_granules = granule * 2;
261 size_t aligned_len = len;
264 if (aligned_addr % two_granules) {
265 assert(aligned_addr % two_granules == granule);
266 aligned_addr -= granule;
267 aligned_len += granule;
271 bool aligned_length_up =
false;
272 if (aligned_len % two_granules) {
273 assert(aligned_len % two_granules == granule);
274 aligned_len += granule;
275 aligned_length_up =
true;
279 assert(aligned_addr >= tag_segment_virtual_address);
282 const size_t offset_granules =
283 (aligned_addr - tag_segment_virtual_address) / granule;
285 const size_t file_offset_in_bytes = offset_granules / 2;
288 const size_t tag_bytes_to_read = aligned_len / granule / 2;
289 std::vector<uint8_t> tag_data(tag_bytes_to_read);
290 const size_t bytes_copied =
291 reader(tag_segment_data_address + file_offset_in_bytes, tag_bytes_to_read,
294 assert(bytes_copied == tag_bytes_to_read);
296 std::vector<lldb::addr_t> tags;
297 tags.reserve(2 * tag_data.size());
300 for (
auto tag_byte : tag_data) {
301 tags.push_back(tag_byte & 0xf);
302 tags.push_back(tag_byte >> 4);
306 if (addr != aligned_addr)
307 tags.erase(tags.begin());
309 if (aligned_length_up)
316 const std::vector<lldb::addr_t> &tags)
const {
317 std::vector<uint8_t> packed;
320 for (
auto tag : tags) {
322 return llvm::createStringError(llvm::inconvertibleErrorCode(),
323 "Found tag 0x%" PRIx64
324 " which is > max MTE tag value of 0x%x.",
327 packed.push_back(
static_cast<uint8_t
>(tag));
333llvm::Expected<std::vector<lldb::addr_t>>
335 const std::vector<lldb::addr_t> &tags,
TagRange range)
const {
336 std::vector<lldb::addr_t> new_tags;
341 return llvm::createStringError(
342 llvm::inconvertibleErrorCode(),
343 "Expected some tags to cover given range, got zero.");
348 new_tags.reserve(granules);
349 for (
size_t to_copy = 0; granules > 0; granules -= to_copy) {
350 to_copy = granules > tags.size() ? tags.size() : granules;
351 new_tags.insert(new_tags.end(), tags.begin(), tags.begin() + to_copy);
static const unsigned MTE_TAG_MAX
static const unsigned MTE_GRANULE_SIZE
static llvm::Error MakeInvalidRangeErr(lldb::addr_t addr, lldb::addr_t end_addr)
static const unsigned MTE_START_BIT
lldb::addr_t GetLogicalTag(lldb::addr_t addr) const override
llvm::Expected< std::vector< lldb::addr_t > > RepeatTagsForRange(const std::vector< lldb::addr_t > &tags, TagRange range) const override
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 override
ptrdiff_t AddressDiff(lldb::addr_t addr1, lldb::addr_t addr2) const override
lldb::addr_t RemoveTagBits(lldb::addr_t addr) const override
TagRange ExpandToGranule(TagRange range) const override
llvm::Expected< TagRange > MakeTaggedRange(lldb::addr_t addr, lldb::addr_t end_addr, const lldb_private::MemoryRegionInfos &memory_regions) const override
lldb::addr_t GetGranuleSize() const override
int32_t GetAllocationTagType() const override
llvm::Expected< std::vector< lldb::addr_t > > UnpackTagsData(const std::vector< uint8_t > &tags, size_t granules=0) const override
llvm::Expected< std::vector< uint8_t > > PackTags(const std::vector< lldb::addr_t > &tags) const override
size_t GetTagSizeInBytes() const override
llvm::Expected< std::vector< TagRange > > MakeTaggedRanges(lldb::addr_t addr, lldb::addr_t end_addr, const lldb_private::MemoryRegionInfos &memory_regions) const override
std::function< size_t(lldb::offset_t, size_t, void *)> CoreReaderFn
Range< lldb::addr_t, lldb::addr_t > TagRange
#define UNUSED_IF_ASSERT_DISABLED(x)
A class that represents a running process on the host machine.
BaseType GetRangeBase() const
void SetRangeEnd(BaseType end)
SizeType GetByteSize() const
void SetRangeBase(BaseType b)
BaseType GetRangeEnd() const