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