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