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