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
12using namespace lldb_private;
13
14MemoryTagMap::MemoryTagMap(const MemoryTagManager *manager)
15 : m_manager(manager) {
16 assert(m_manager && "valid tag manager required to construct a MemoryTagMap");
17}
18
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
29bool MemoryTagMap::Empty() const { return m_addr_to_tag.empty(); }
30
31std::vector<std::optional<lldb::addr_t>>
32MemoryTagMap::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(x: 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
58std::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(x: addr);
62 if (found == m_addr_to_tag.end())
63 return std::nullopt;
64 return found->second;
65}
66

source code of lldb/source/Target/MemoryTagMap.cpp