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 <vector>
17 
18 // Other libraries and framework includes
19 
20 // Project includes
21 #include "lldb/lldb-private.h"
22 #include "lldb/Core/RangeMap.h"
23 #include "lldb/Host/Mutex.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
GetMemoryCacheLineSize()53         GetMemoryCacheLineSize() const
54         {
55             return m_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     protected:
65         typedef std::map<lldb::addr_t, lldb::DataBufferSP> BlockMap;
66         typedef RangeArray<lldb::addr_t, lldb::addr_t, 4> InvalidRanges;
67         //------------------------------------------------------------------
68         // Classes that inherit from MemoryCache can see and modify these
69         //------------------------------------------------------------------
70         Process &m_process;
71         uint32_t m_cache_line_byte_size;
72         Mutex m_mutex;
73         BlockMap m_cache;
74         InvalidRanges m_invalid_ranges;
75     private:
76         DISALLOW_COPY_AND_ASSIGN (MemoryCache);
77     };
78 
79 
80     class AllocatedBlock
81     {
82     public:
83         AllocatedBlock (lldb::addr_t addr,
84                         uint32_t byte_size,
85                         uint32_t permissions,
86                         uint32_t chunk_size);
87 
88         ~AllocatedBlock ();
89 
90         lldb::addr_t
91         ReserveBlock (uint32_t size);
92 
93         bool
94         FreeBlock (lldb::addr_t addr);
95 
96         lldb::addr_t
GetBaseAddress()97         GetBaseAddress () const
98         {
99             return m_addr;
100         }
101 
102         uint32_t
GetByteSize()103         GetByteSize () const
104         {
105             return m_byte_size;
106         }
107 
108         uint32_t
GetPermissions()109         GetPermissions () const
110         {
111             return m_permissions;
112         }
113 
114         uint32_t
GetChunkSize()115         GetChunkSize () const
116         {
117             return m_chunk_size;
118         }
119 
120         bool
Contains(lldb::addr_t addr)121         Contains (lldb::addr_t addr) const
122         {
123             return ((addr >= m_addr) && addr < (m_addr + m_byte_size));
124         }
125     protected:
126         uint32_t
TotalChunks()127         TotalChunks () const
128         {
129             return m_byte_size / m_chunk_size;
130         }
131 
132         uint32_t
CalculateChunksNeededForSize(uint32_t size)133         CalculateChunksNeededForSize (uint32_t size) const
134         {
135             return (size + m_chunk_size - 1) / m_chunk_size;
136         }
137         const lldb::addr_t m_addr;    // Base address of this block of memory
138         const uint32_t m_byte_size;   // 4GB of chunk should be enough...
139         const uint32_t m_permissions; // Permissions for this memory (logical OR of lldb::Permissions bits)
140         const uint32_t m_chunk_size;  // The size of chunks that the memory at m_addr is divied up into
141         typedef std::map<uint32_t, uint32_t> OffsetToChunkSize;
142         OffsetToChunkSize m_offset_to_chunk_size;
143     };
144 
145 
146     //----------------------------------------------------------------------
147     // A class that can track allocated memory and give out allocated memory
148     // without us having to make an allocate/deallocate call every time we
149     // need some memory in a process that is being debugged.
150     //----------------------------------------------------------------------
151     class AllocatedMemoryCache
152     {
153     public:
154         //------------------------------------------------------------------
155         // Constructors and Destructors
156         //------------------------------------------------------------------
157         AllocatedMemoryCache (Process &process);
158 
159         ~AllocatedMemoryCache ();
160 
161         void
162         Clear();
163 
164         lldb::addr_t
165         AllocateMemory (size_t byte_size,
166                         uint32_t permissions,
167                         Error &error);
168 
169         bool
170         DeallocateMemory (lldb::addr_t ptr);
171 
172     protected:
173         typedef std::shared_ptr<AllocatedBlock> AllocatedBlockSP;
174 
175         AllocatedBlockSP
176         AllocatePage (uint32_t byte_size,
177                       uint32_t permissions,
178                       uint32_t chunk_size,
179                       Error &error);
180 
181 
182         //------------------------------------------------------------------
183         // Classes that inherit from MemoryCache can see and modify these
184         //------------------------------------------------------------------
185         Process &m_process;
186         Mutex m_mutex;
187         typedef std::multimap<uint32_t, AllocatedBlockSP> PermissionsToBlockMap;
188         PermissionsToBlockMap m_memory_map;
189 
190     private:
191         DISALLOW_COPY_AND_ASSIGN (AllocatedMemoryCache);
192     };
193 
194 } // namespace lldb_private
195 
196 #endif  // liblldb_Memory_h_
197