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