1 //===-- MemoryTagMap.cpp --------------------------------------------------===// 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 #include "lldb/Target/MemoryTagMap.h" 10 #include <optional> 11 12 using namespace lldb_private; 13 MemoryTagMap(const MemoryTagManager * manager)14MemoryTagMap::MemoryTagMap(const MemoryTagManager *manager) 15 : m_manager(manager) { 16 assert(m_manager && "valid tag manager required to construct a MemoryTagMap"); 17 } 18 InsertTags(lldb::addr_t addr,const std::vector<lldb::addr_t> tags)19void MemoryTagMap::InsertTags(lldb::addr_t addr, 20 const std::vector<lldb::addr_t> tags) { 21 // We're assuming that addr has no non address bits and is granule aligned. 22 size_t granule_size = m_manager->GetGranuleSize(); 23 for (auto tag : tags) { 24 m_addr_to_tag[addr] = tag; 25 addr += granule_size; 26 } 27 } 28 Empty() const29bool MemoryTagMap::Empty() const { return m_addr_to_tag.empty(); } 30 31 std::vector<std::optional<lldb::addr_t>> GetTags(lldb::addr_t addr,size_t len) const32MemoryTagMap::GetTags(lldb::addr_t addr, size_t len) const { 33 // Addr and len might be unaligned 34 addr = m_manager->RemoveTagBits(addr); 35 MemoryTagManager::TagRange range(addr, len); 36 range = m_manager->ExpandToGranule(range); 37 38 std::vector<std::optional<lldb::addr_t>> tags; 39 lldb::addr_t end_addr = range.GetRangeEnd(); 40 addr = range.GetRangeBase(); 41 bool got_valid_tags = false; 42 size_t granule_size = m_manager->GetGranuleSize(); 43 44 for (; addr < end_addr; addr += granule_size) { 45 std::optional<lldb::addr_t> tag = GetTag(addr); 46 tags.push_back(tag); 47 if (tag) 48 got_valid_tags = true; 49 } 50 51 // To save the caller checking if every item is std::nullopt, 52 // we return an empty vector if we got no tags at all. 53 if (got_valid_tags) 54 return tags; 55 return {}; 56 } 57 GetTag(lldb::addr_t addr) const58std::optional<lldb::addr_t> MemoryTagMap::GetTag(lldb::addr_t addr) const { 59 // Here we assume that addr is granule aligned, just like when the tags 60 // were inserted. 61 auto found = m_addr_to_tag.find(addr); 62 if (found == m_addr_to_tag.end()) 63 return std::nullopt; 64 return found->second; 65 } 66