1 //===-- Memory.h ------------------------------------------------*- C++ -*-===// 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 #ifndef liblldb_Memory_h_ 10 #define liblldb_Memory_h_ 11 12 #include "lldb/Utility/RangeMap.h" 13 #include "lldb/lldb-private.h" 14 #include <map> 15 #include <mutex> 16 #include <vector> 17 18 namespace lldb_private { 19 // A class to track memory that was read from a live process between 20 // runs. 21 class MemoryCache { 22 public: 23 // Constructors and Destructors 24 MemoryCache(Process &process); 25 26 ~MemoryCache(); 27 28 void Clear(bool clear_invalid_ranges = false); 29 30 void Flush(lldb::addr_t addr, size_t size); 31 32 size_t Read(lldb::addr_t addr, void *dst, size_t dst_len, Status &error); 33 34 uint32_t GetMemoryCacheLineSize() const { return m_L2_cache_line_byte_size; } 35 36 void AddInvalidRange(lldb::addr_t base_addr, lldb::addr_t byte_size); 37 38 bool RemoveInvalidRange(lldb::addr_t base_addr, lldb::addr_t byte_size); 39 40 // Allow external sources to populate data into the L1 memory cache 41 void AddL1CacheData(lldb::addr_t addr, const void *src, size_t src_len); 42 43 void AddL1CacheData(lldb::addr_t addr, 44 const lldb::DataBufferSP &data_buffer_sp); 45 46 protected: 47 typedef std::map<lldb::addr_t, lldb::DataBufferSP> BlockMap; 48 typedef RangeArray<lldb::addr_t, lldb::addr_t, 4> InvalidRanges; 49 typedef Range<lldb::addr_t, lldb::addr_t> AddrRange; 50 // Classes that inherit from MemoryCache can see and modify these 51 std::recursive_mutex m_mutex; 52 BlockMap m_L1_cache; // A first level memory cache whose chunk sizes vary that 53 // will be used only if the memory read fits entirely in 54 // a chunk 55 BlockMap m_L2_cache; // A memory cache of fixed size chinks 56 // (m_L2_cache_line_byte_size bytes in size each) 57 InvalidRanges m_invalid_ranges; 58 Process &m_process; 59 uint32_t m_L2_cache_line_byte_size; 60 61 private: 62 DISALLOW_COPY_AND_ASSIGN(MemoryCache); 63 }; 64 65 66 67 class AllocatedBlock { 68 public: 69 AllocatedBlock(lldb::addr_t addr, uint32_t byte_size, uint32_t permissions, 70 uint32_t chunk_size); 71 72 ~AllocatedBlock(); 73 74 lldb::addr_t ReserveBlock(uint32_t size); 75 76 bool FreeBlock(lldb::addr_t addr); 77 78 lldb::addr_t GetBaseAddress() const { return m_range.GetRangeBase(); } 79 80 uint32_t GetByteSize() const { return m_range.GetByteSize(); } 81 82 uint32_t GetPermissions() const { return m_permissions; } 83 84 uint32_t GetChunkSize() const { return m_chunk_size; } 85 86 bool Contains(lldb::addr_t addr) const { 87 return m_range.Contains(addr); 88 } 89 90 protected: 91 uint32_t TotalChunks() const { return GetByteSize() / GetChunkSize(); } 92 93 uint32_t CalculateChunksNeededForSize(uint32_t size) const { 94 return (size + m_chunk_size - 1) / m_chunk_size; 95 } 96 // Base address of this block of memory 4GB of chunk should be enough. 97 Range<lldb::addr_t, uint32_t> m_range; 98 // Permissions for this memory (logical OR of lldb::Permissions bits) 99 const uint32_t m_permissions; 100 // The size of chunks that the memory at m_addr is divied up into. 101 const uint32_t m_chunk_size; 102 // A sorted list of free address ranges. 103 RangeVector<lldb::addr_t, uint32_t> m_free_blocks; 104 // A sorted list of reserved address. 105 RangeVector<lldb::addr_t, uint32_t> m_reserved_blocks; 106 }; 107 108 // A class that can track allocated memory and give out allocated memory 109 // without us having to make an allocate/deallocate call every time we need 110 // some memory in a process that is being debugged. 111 class AllocatedMemoryCache { 112 public: 113 // Constructors and Destructors 114 AllocatedMemoryCache(Process &process); 115 116 ~AllocatedMemoryCache(); 117 118 void Clear(); 119 120 lldb::addr_t AllocateMemory(size_t byte_size, uint32_t permissions, 121 Status &error); 122 123 bool DeallocateMemory(lldb::addr_t ptr); 124 125 protected: 126 typedef std::shared_ptr<AllocatedBlock> AllocatedBlockSP; 127 128 AllocatedBlockSP AllocatePage(uint32_t byte_size, uint32_t permissions, 129 uint32_t chunk_size, Status &error); 130 131 // Classes that inherit from MemoryCache can see and modify these 132 Process &m_process; 133 std::recursive_mutex m_mutex; 134 typedef std::multimap<uint32_t, AllocatedBlockSP> PermissionsToBlockMap; 135 PermissionsToBlockMap m_memory_map; 136 137 private: 138 DISALLOW_COPY_AND_ASSIGN(AllocatedMemoryCache); 139 }; 140 141 } // namespace lldb_private 142 143 #endif // liblldb_Memory_h_ 144