10b57cec5SDimitry Andric //===-- MemoryRegionInfo.h ---------------------------------------*- C++ 20b57cec5SDimitry Andric //-*-===// 30b57cec5SDimitry Andric // 40b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 60b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70b57cec5SDimitry Andric // 80b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 90b57cec5SDimitry Andric 105ffd83dbSDimitry Andric #ifndef LLDB_TARGET_MEMORYREGIONINFO_H 115ffd83dbSDimitry Andric #define LLDB_TARGET_MEMORYREGIONINFO_H 120b57cec5SDimitry Andric 13bdd1243dSDimitry Andric #include <optional> 14fe6060f1SDimitry Andric #include <vector> 15fe6060f1SDimitry Andric 160b57cec5SDimitry Andric #include "lldb/Utility/ConstString.h" 170b57cec5SDimitry Andric #include "lldb/Utility/RangeMap.h" 180b57cec5SDimitry Andric #include "llvm/Support/FormatProviders.h" 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric namespace lldb_private { 210b57cec5SDimitry Andric class MemoryRegionInfo { 220b57cec5SDimitry Andric public: 230b57cec5SDimitry Andric typedef Range<lldb::addr_t, lldb::addr_t> RangeType; 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric enum OptionalBool { eDontKnow = -1, eNo = 0, eYes = 1 }; 260b57cec5SDimitry Andric 27480093f4SDimitry Andric MemoryRegionInfo() = default; MemoryRegionInfo(RangeType range,OptionalBool read,OptionalBool write,OptionalBool execute,OptionalBool shared,OptionalBool mapped,ConstString name,OptionalBool flash,lldb::offset_t blocksize,OptionalBool memory_tagged,OptionalBool stack_memory)28480093f4SDimitry Andric MemoryRegionInfo(RangeType range, OptionalBool read, OptionalBool write, 2981ad6265SDimitry Andric OptionalBool execute, OptionalBool shared, 3081ad6265SDimitry Andric OptionalBool mapped, ConstString name, 31e8d8bef9SDimitry Andric OptionalBool flash, lldb::offset_t blocksize, 32349cc55cSDimitry Andric OptionalBool memory_tagged, OptionalBool stack_memory) 33480093f4SDimitry Andric : m_range(range), m_read(read), m_write(write), m_execute(execute), 3481ad6265SDimitry Andric m_shared(shared), m_mapped(mapped), m_name(name), m_flash(flash), 3581ad6265SDimitry Andric m_blocksize(blocksize), m_memory_tagged(memory_tagged), 3681ad6265SDimitry Andric m_is_stack_memory(stack_memory) {} 370b57cec5SDimitry Andric GetRange()380b57cec5SDimitry Andric RangeType &GetRange() { return m_range; } 390b57cec5SDimitry Andric Clear()40fe6060f1SDimitry Andric void Clear() { *this = MemoryRegionInfo(); } 410b57cec5SDimitry Andric GetRange()420b57cec5SDimitry Andric const RangeType &GetRange() const { return m_range; } 430b57cec5SDimitry Andric GetReadable()440b57cec5SDimitry Andric OptionalBool GetReadable() const { return m_read; } 450b57cec5SDimitry Andric GetWritable()460b57cec5SDimitry Andric OptionalBool GetWritable() const { return m_write; } 470b57cec5SDimitry Andric GetExecutable()480b57cec5SDimitry Andric OptionalBool GetExecutable() const { return m_execute; } 490b57cec5SDimitry Andric GetShared()5081ad6265SDimitry Andric OptionalBool GetShared() const { return m_shared; } 5181ad6265SDimitry Andric GetMapped()520b57cec5SDimitry Andric OptionalBool GetMapped() const { return m_mapped; } 530b57cec5SDimitry Andric GetName()540b57cec5SDimitry Andric ConstString GetName() const { return m_name; } 550b57cec5SDimitry Andric GetMemoryTagged()56e8d8bef9SDimitry Andric OptionalBool GetMemoryTagged() const { return m_memory_tagged; } 57e8d8bef9SDimitry Andric SetReadable(OptionalBool val)580b57cec5SDimitry Andric void SetReadable(OptionalBool val) { m_read = val; } 590b57cec5SDimitry Andric SetWritable(OptionalBool val)600b57cec5SDimitry Andric void SetWritable(OptionalBool val) { m_write = val; } 610b57cec5SDimitry Andric SetExecutable(OptionalBool val)620b57cec5SDimitry Andric void SetExecutable(OptionalBool val) { m_execute = val; } 630b57cec5SDimitry Andric SetShared(OptionalBool val)6481ad6265SDimitry Andric void SetShared(OptionalBool val) { m_shared = val; } 6581ad6265SDimitry Andric SetMapped(OptionalBool val)660b57cec5SDimitry Andric void SetMapped(OptionalBool val) { m_mapped = val; } 670b57cec5SDimitry Andric SetName(const char * name)680b57cec5SDimitry Andric void SetName(const char *name) { m_name = ConstString(name); } 690b57cec5SDimitry Andric GetFlash()700b57cec5SDimitry Andric OptionalBool GetFlash() const { return m_flash; } 710b57cec5SDimitry Andric SetFlash(OptionalBool val)720b57cec5SDimitry Andric void SetFlash(OptionalBool val) { m_flash = val; } 730b57cec5SDimitry Andric GetBlocksize()740b57cec5SDimitry Andric lldb::offset_t GetBlocksize() const { return m_blocksize; } 750b57cec5SDimitry Andric SetBlocksize(lldb::offset_t blocksize)760b57cec5SDimitry Andric void SetBlocksize(lldb::offset_t blocksize) { m_blocksize = blocksize; } 770b57cec5SDimitry Andric SetMemoryTagged(OptionalBool val)78e8d8bef9SDimitry Andric void SetMemoryTagged(OptionalBool val) { m_memory_tagged = val; } 79e8d8bef9SDimitry Andric 800b57cec5SDimitry Andric // Get permissions as a uint32_t that is a mask of one or more bits from the 810b57cec5SDimitry Andric // lldb::Permissions GetLLDBPermissions()820b57cec5SDimitry Andric uint32_t GetLLDBPermissions() const { 830b57cec5SDimitry Andric uint32_t permissions = 0; 845f757f3fSDimitry Andric if (m_read == eYes) 850b57cec5SDimitry Andric permissions |= lldb::ePermissionsReadable; 865f757f3fSDimitry Andric if (m_write == eYes) 870b57cec5SDimitry Andric permissions |= lldb::ePermissionsWritable; 885f757f3fSDimitry Andric if (m_execute == eYes) 890b57cec5SDimitry Andric permissions |= lldb::ePermissionsExecutable; 900b57cec5SDimitry Andric return permissions; 910b57cec5SDimitry Andric } 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric // Set permissions from a uint32_t that contains one or more bits from the 940b57cec5SDimitry Andric // lldb::Permissions SetLLDBPermissions(uint32_t permissions)950b57cec5SDimitry Andric void SetLLDBPermissions(uint32_t permissions) { 960b57cec5SDimitry Andric m_read = (permissions & lldb::ePermissionsReadable) ? eYes : eNo; 970b57cec5SDimitry Andric m_write = (permissions & lldb::ePermissionsWritable) ? eYes : eNo; 980b57cec5SDimitry Andric m_execute = (permissions & lldb::ePermissionsExecutable) ? eYes : eNo; 990b57cec5SDimitry Andric } 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric bool operator==(const MemoryRegionInfo &rhs) const { 1020b57cec5SDimitry Andric return m_range == rhs.m_range && m_read == rhs.m_read && 1030b57cec5SDimitry Andric m_write == rhs.m_write && m_execute == rhs.m_execute && 10481ad6265SDimitry Andric m_shared == rhs.m_shared && 105480093f4SDimitry Andric m_mapped == rhs.m_mapped && m_name == rhs.m_name && 106e8d8bef9SDimitry Andric m_flash == rhs.m_flash && m_blocksize == rhs.m_blocksize && 107fe6060f1SDimitry Andric m_memory_tagged == rhs.m_memory_tagged && 108349cc55cSDimitry Andric m_pagesize == rhs.m_pagesize && 109349cc55cSDimitry Andric m_is_stack_memory == rhs.m_is_stack_memory; 1100b57cec5SDimitry Andric } 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric bool operator!=(const MemoryRegionInfo &rhs) const { return !(*this == rhs); } 1130b57cec5SDimitry Andric 114fe6060f1SDimitry Andric /// Get the target system's VM page size in bytes. 115fe6060f1SDimitry Andric /// \return 116fe6060f1SDimitry Andric /// 0 is returned if this information is unavailable. GetPageSize()11781ad6265SDimitry Andric int GetPageSize() const { return m_pagesize; } 118fe6060f1SDimitry Andric 119fe6060f1SDimitry Andric /// Get a vector of target VM pages that are dirty -- that have been 120fe6060f1SDimitry Andric /// modified -- within this memory region. This is an Optional return 121fe6060f1SDimitry Andric /// value; it will only be available if the remote stub was able to 122fe6060f1SDimitry Andric /// detail this. GetDirtyPageList()123bdd1243dSDimitry Andric const std::optional<std::vector<lldb::addr_t>> &GetDirtyPageList() const { 124fe6060f1SDimitry Andric return m_dirty_pages; 125fe6060f1SDimitry Andric } 126fe6060f1SDimitry Andric IsStackMemory()127349cc55cSDimitry Andric OptionalBool IsStackMemory() const { return m_is_stack_memory; } 128349cc55cSDimitry Andric SetIsStackMemory(OptionalBool val)129349cc55cSDimitry Andric void SetIsStackMemory(OptionalBool val) { m_is_stack_memory = val; } 130349cc55cSDimitry Andric SetPageSize(int pagesize)131fe6060f1SDimitry Andric void SetPageSize(int pagesize) { m_pagesize = pagesize; } 132fe6060f1SDimitry Andric SetDirtyPageList(std::vector<lldb::addr_t> pagelist)133fe6060f1SDimitry Andric void SetDirtyPageList(std::vector<lldb::addr_t> pagelist) { 13481ad6265SDimitry Andric if (m_dirty_pages) 135bdd1243dSDimitry Andric m_dirty_pages->clear(); 136fe6060f1SDimitry Andric m_dirty_pages = std::move(pagelist); 137fe6060f1SDimitry Andric } 138fe6060f1SDimitry Andric 1390b57cec5SDimitry Andric protected: 1400b57cec5SDimitry Andric RangeType m_range; 141480093f4SDimitry Andric OptionalBool m_read = eDontKnow; 142480093f4SDimitry Andric OptionalBool m_write = eDontKnow; 143480093f4SDimitry Andric OptionalBool m_execute = eDontKnow; 14481ad6265SDimitry Andric OptionalBool m_shared = eDontKnow; 145480093f4SDimitry Andric OptionalBool m_mapped = eDontKnow; 1460b57cec5SDimitry Andric ConstString m_name; 147480093f4SDimitry Andric OptionalBool m_flash = eDontKnow; 148480093f4SDimitry Andric lldb::offset_t m_blocksize = 0; 149e8d8bef9SDimitry Andric OptionalBool m_memory_tagged = eDontKnow; 150349cc55cSDimitry Andric OptionalBool m_is_stack_memory = eDontKnow; 151fe6060f1SDimitry Andric int m_pagesize = 0; 152bdd1243dSDimitry Andric std::optional<std::vector<lldb::addr_t>> m_dirty_pages; 1530b57cec5SDimitry Andric }; 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric inline bool operator<(const MemoryRegionInfo &lhs, 1560b57cec5SDimitry Andric const MemoryRegionInfo &rhs) { 1570b57cec5SDimitry Andric return lhs.GetRange() < rhs.GetRange(); 1580b57cec5SDimitry Andric } 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric inline bool operator<(const MemoryRegionInfo &lhs, lldb::addr_t rhs) { 1610b57cec5SDimitry Andric return lhs.GetRange().GetRangeBase() < rhs; 1620b57cec5SDimitry Andric } 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric inline bool operator<(lldb::addr_t lhs, const MemoryRegionInfo &rhs) { 1650b57cec5SDimitry Andric return lhs < rhs.GetRange().GetRangeBase(); 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric 168480093f4SDimitry Andric llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, 169480093f4SDimitry Andric const MemoryRegionInfo &Info); 170480093f4SDimitry Andric 1710b57cec5SDimitry Andric // Forward-declarable wrapper. 1720b57cec5SDimitry Andric class MemoryRegionInfos : public std::vector<lldb_private::MemoryRegionInfo> { 1730b57cec5SDimitry Andric public: 17481ad6265SDimitry Andric using std::vector<lldb_private::MemoryRegionInfo>::vector; 1750b57cec5SDimitry Andric }; 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric } 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric namespace llvm { 1800b57cec5SDimitry Andric template <> 181480093f4SDimitry Andric /// If Options is empty, prints a textual representation of the value. If 182480093f4SDimitry Andric /// Options is a single character, it uses that character for the "yes" value, 183480093f4SDimitry Andric /// while "no" is printed as "-", and "don't know" as "?". This can be used to 184480093f4SDimitry Andric /// print the permissions in the traditional "rwx" form. 1850b57cec5SDimitry Andric struct format_provider<lldb_private::MemoryRegionInfo::OptionalBool> { 1860b57cec5SDimitry Andric static void format(const lldb_private::MemoryRegionInfo::OptionalBool &B, 187480093f4SDimitry Andric raw_ostream &OS, StringRef Options); 1880b57cec5SDimitry Andric }; 1890b57cec5SDimitry Andric } 1900b57cec5SDimitry Andric 1915ffd83dbSDimitry Andric #endif // LLDB_TARGET_MEMORYREGIONINFO_H 192