blob: acf3825bfb3f3d9b0120ffb941dc186842e74738 [file] [log] [blame]
//===-- MemoryTagMap.h ------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLDB_TARGET_MEMORYTAGMAP_H
#define LLDB_TARGET_MEMORYTAGMAP_H
#include "lldb/Target/MemoryTagManager.h"
#include "lldb/lldb-private.h"
#include "llvm/ADT/Optional.h"
#include <map>
namespace lldb_private {
/// MemoryTagMap provides a way to give a sparse read result
/// when reading memory tags for a range. This is useful when
/// you want to annotate some large memory dump that might include
/// tagged memory but you don't know that it is all tagged.
class MemoryTagMap {
public:
/// Init an empty tag map
///
/// \param [in] manager
/// Non-null pointer to a memory tag manager.
MemoryTagMap(const MemoryTagManager *manager);
/// Insert tags into the map starting from addr.
///
/// \param [in] addr
/// Start address of the range to insert tags for.
/// This address should be granule aligned and have had
/// any non address bits removed.
/// (ideally you would use the base of the range you used
/// to read the tags in the first place)
///
/// \param [in] tags
/// Vector of tags to insert. The first tag will be inserted
/// at addr, the next at addr+granule size and so on until
/// all tags have been inserted.
void InsertTags(lldb::addr_t addr, const std::vector<lldb::addr_t> tags);
bool Empty() const;
/// Lookup memory tags for a range of memory from addr to addr+len.
///
/// \param [in] addr
/// The start of the range. This may include non address bits and
/// does not have to be granule aligned.
///
/// \param [in] len
/// The length in bytes of the range to read tags for. This does
/// not need to be multiple of the granule size.
///
/// \return
/// A vector containing the tags found for the granules in the
/// range. (which is the result of granule aligning the given range)
///
/// Each item in the vector is an optional tag. Meaning that if
/// it is valid then the granule had a tag and if not, it didn't.
///
/// If the range had no tags at all, the vector will be empty.
/// If some of the range was tagged it will have items and some
/// of them may be llvm::None.
/// (this saves the caller checking whether all items are llvm::None)
std::vector<llvm::Optional<lldb::addr_t>> GetTags(lldb::addr_t addr,
size_t len) const;
private:
/// Lookup the tag for address
///
/// \param [in] address
/// The address to lookup a tag for. This should be aligned
/// to a granule boundary.
///
/// \return
/// The tag for the granule that address refers to, or llvm::None
/// if it has no memory tag.
llvm::Optional<lldb::addr_t> GetTag(lldb::addr_t addr) const;
// A map of granule aligned addresses to their memory tag
std::map<lldb::addr_t, lldb::addr_t> m_addr_to_tag;
// Memory tag manager used to align addresses and get granule size.
// Ideally this would be a const& but only certain architectures will
// have a memory tag manager class to provide here. So for a method
// returning a MemoryTagMap, Optional<MemoryTagMap> allows it to handle
// architectures without memory tagging. Optionals cannot hold references
// so we go with a pointer that we assume will be not be null.
const MemoryTagManager *m_manager;
};
} // namespace lldb_private
#endif // LLDB_TARGET_MEMORYTAGMAP_H