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)
Set the start value for the range, and keep the same size.
BaseType GetRangeEnd() const