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/lldb-private.h" 23 #include "lldb/Core/RangeMap.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 { 32 public: 33 //------------------------------------------------------------------ 34 // Constructors and Destructors 35 //------------------------------------------------------------------ 36 MemoryCache (Process &process); 37 38 ~MemoryCache (); 39 40 void 41 Clear(bool clear_invalid_ranges = false); 42 43 void 44 Flush (lldb::addr_t addr, size_t size); 45 46 size_t 47 Read (lldb::addr_t addr, 48 void *dst, 49 size_t dst_len, 50 Error &error); 51 52 uint32_t 53 GetMemoryCacheLineSize() const 54 { 55 return m_L2_cache_line_byte_size ; 56 } 57 58 void 59 AddInvalidRange (lldb::addr_t base_addr, lldb::addr_t byte_size); 60 61 bool 62 RemoveInvalidRange (lldb::addr_t base_addr, lldb::addr_t byte_size); 63 64 // Allow external sources to populate data into the L1 memory cache 65 void 66 AddL1CacheData(lldb::addr_t addr, const void *src, size_t src_len); 67 68 void 69 AddL1CacheData(lldb::addr_t addr, const lldb::DataBufferSP &data_buffer_sp); 70 71 protected: 72 typedef std::map<lldb::addr_t, lldb::DataBufferSP> BlockMap; 73 typedef RangeArray<lldb::addr_t, lldb::addr_t, 4> InvalidRanges; 74 typedef Range<lldb::addr_t, lldb::addr_t> AddrRange; 75 //------------------------------------------------------------------ 76 // Classes that inherit from MemoryCache can see and modify these 77 //------------------------------------------------------------------ 78 std::recursive_mutex m_mutex; 79 BlockMap m_L1_cache; // A first level memory cache whose chunk sizes vary that will be used only if the memory read fits entirely in a chunk 80 BlockMap m_L2_cache; // A memory cache of fixed size chinks (m_L2_cache_line_byte_size bytes in size each) 81 InvalidRanges m_invalid_ranges; 82 Process &m_process; 83 uint32_t m_L2_cache_line_byte_size; 84 private: 85 DISALLOW_COPY_AND_ASSIGN (MemoryCache); 86 }; 87 88 89 class AllocatedBlock 90 { 91 public: 92 AllocatedBlock (lldb::addr_t addr, 93 uint32_t byte_size, 94 uint32_t permissions, 95 uint32_t chunk_size); 96 97 ~AllocatedBlock (); 98 99 lldb::addr_t 100 ReserveBlock (uint32_t size); 101 102 bool 103 FreeBlock (lldb::addr_t addr); 104 105 lldb::addr_t 106 GetBaseAddress () const 107 { 108 return m_addr; 109 } 110 111 uint32_t 112 GetByteSize () const 113 { 114 return m_byte_size; 115 } 116 117 uint32_t 118 GetPermissions () const 119 { 120 return m_permissions; 121 } 122 123 uint32_t 124 GetChunkSize () const 125 { 126 return m_chunk_size; 127 } 128 129 bool 130 Contains (lldb::addr_t addr) const 131 { 132 return ((addr >= m_addr) && addr < (m_addr + m_byte_size)); 133 } 134 protected: 135 uint32_t 136 TotalChunks () const 137 { 138 return m_byte_size / m_chunk_size; 139 } 140 141 uint32_t 142 CalculateChunksNeededForSize (uint32_t size) const 143 { 144 return (size + m_chunk_size - 1) / m_chunk_size; 145 } 146 const lldb::addr_t m_addr; // Base address of this block of memory 147 const uint32_t m_byte_size; // 4GB of chunk should be enough... 148 const uint32_t m_permissions; // Permissions for this memory (logical OR of lldb::Permissions bits) 149 const uint32_t m_chunk_size; // The size of chunks that the memory at m_addr is divied up into 150 typedef std::map<uint32_t, uint32_t> OffsetToChunkSize; 151 OffsetToChunkSize m_offset_to_chunk_size; 152 }; 153 154 155 //---------------------------------------------------------------------- 156 // A class that can track allocated memory and give out allocated memory 157 // without us having to make an allocate/deallocate call every time we 158 // need some memory in a process that is being debugged. 159 //---------------------------------------------------------------------- 160 class AllocatedMemoryCache 161 { 162 public: 163 //------------------------------------------------------------------ 164 // Constructors and Destructors 165 //------------------------------------------------------------------ 166 AllocatedMemoryCache (Process &process); 167 168 ~AllocatedMemoryCache (); 169 170 void 171 Clear(); 172 173 lldb::addr_t 174 AllocateMemory (size_t byte_size, 175 uint32_t permissions, 176 Error &error); 177 178 bool 179 DeallocateMemory (lldb::addr_t ptr); 180 181 protected: 182 typedef std::shared_ptr<AllocatedBlock> AllocatedBlockSP; 183 184 AllocatedBlockSP 185 AllocatePage (uint32_t byte_size, 186 uint32_t permissions, 187 uint32_t chunk_size, 188 Error &error); 189 190 191 //------------------------------------------------------------------ 192 // Classes that inherit from MemoryCache can see and modify these 193 //------------------------------------------------------------------ 194 Process &m_process; 195 std::recursive_mutex m_mutex; 196 typedef std::multimap<uint32_t, AllocatedBlockSP> PermissionsToBlockMap; 197 PermissionsToBlockMap m_memory_map; 198 199 private: 200 DISALLOW_COPY_AND_ASSIGN (AllocatedMemoryCache); 201 }; 202 203 } // namespace lldb_private 204 205 #endif // liblldb_Memory_h_ 206