1254721Semaste//===-- Memory.h ------------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#ifndef liblldb_Memory_h_
11254721Semaste#define liblldb_Memory_h_
12254721Semaste
13254721Semaste// C Includes
14254721Semaste// C++ Includes
15254721Semaste#include <map>
16254721Semaste#include <vector>
17254721Semaste
18254721Semaste// Other libraries and framework includes
19254721Semaste
20254721Semaste// Project includes
21254721Semaste#include "lldb/lldb-private.h"
22254721Semaste#include "lldb/Core/RangeMap.h"
23254721Semaste#include "lldb/Host/Mutex.h"
24254721Semaste
25254721Semastenamespace lldb_private {
26254721Semaste    //----------------------------------------------------------------------
27254721Semaste    // A class to track memory that was read from a live process between
28254721Semaste    // runs.
29254721Semaste    //----------------------------------------------------------------------
30254721Semaste    class MemoryCache
31254721Semaste    {
32254721Semaste    public:
33254721Semaste        //------------------------------------------------------------------
34254721Semaste        // Constructors and Destructors
35254721Semaste        //------------------------------------------------------------------
36254721Semaste        MemoryCache (Process &process);
37254721Semaste
38254721Semaste        ~MemoryCache ();
39254721Semaste
40254721Semaste        void
41254721Semaste        Clear(bool clear_invalid_ranges = false);
42254721Semaste
43254721Semaste        void
44254721Semaste        Flush (lldb::addr_t addr, size_t size);
45254721Semaste
46254721Semaste        size_t
47254721Semaste        Read (lldb::addr_t addr,
48254721Semaste              void *dst,
49254721Semaste              size_t dst_len,
50254721Semaste              Error &error);
51254721Semaste
52254721Semaste        uint32_t
53254721Semaste        GetMemoryCacheLineSize() const
54254721Semaste        {
55254721Semaste            return m_cache_line_byte_size ;
56254721Semaste        }
57254721Semaste
58254721Semaste        void
59254721Semaste        AddInvalidRange (lldb::addr_t base_addr, lldb::addr_t byte_size);
60254721Semaste
61254721Semaste        bool
62254721Semaste        RemoveInvalidRange (lldb::addr_t base_addr, lldb::addr_t byte_size);
63254721Semaste
64254721Semaste    protected:
65254721Semaste        typedef std::map<lldb::addr_t, lldb::DataBufferSP> BlockMap;
66254721Semaste        typedef RangeArray<lldb::addr_t, lldb::addr_t, 4> InvalidRanges;
67254721Semaste        //------------------------------------------------------------------
68254721Semaste        // Classes that inherit from MemoryCache can see and modify these
69254721Semaste        //------------------------------------------------------------------
70254721Semaste        Process &m_process;
71254721Semaste        uint32_t m_cache_line_byte_size;
72254721Semaste        Mutex m_mutex;
73254721Semaste        BlockMap m_cache;
74254721Semaste        InvalidRanges m_invalid_ranges;
75254721Semaste    private:
76254721Semaste        DISALLOW_COPY_AND_ASSIGN (MemoryCache);
77254721Semaste    };
78254721Semaste
79254721Semaste
80254721Semaste    class AllocatedBlock
81254721Semaste    {
82254721Semaste    public:
83254721Semaste        AllocatedBlock (lldb::addr_t addr,
84254721Semaste                        uint32_t byte_size,
85254721Semaste                        uint32_t permissions,
86254721Semaste                        uint32_t chunk_size);
87254721Semaste
88254721Semaste        ~AllocatedBlock ();
89254721Semaste
90254721Semaste        lldb::addr_t
91254721Semaste        ReserveBlock (uint32_t size);
92254721Semaste
93254721Semaste        bool
94254721Semaste        FreeBlock (lldb::addr_t addr);
95254721Semaste
96254721Semaste        lldb::addr_t
97254721Semaste        GetBaseAddress () const
98254721Semaste        {
99254721Semaste            return m_addr;
100254721Semaste        }
101254721Semaste
102254721Semaste        uint32_t
103254721Semaste        GetByteSize () const
104254721Semaste        {
105254721Semaste            return m_byte_size;
106254721Semaste        }
107254721Semaste
108254721Semaste        uint32_t
109254721Semaste        GetPermissions () const
110254721Semaste        {
111254721Semaste            return m_permissions;
112254721Semaste        }
113254721Semaste
114254721Semaste        uint32_t
115254721Semaste        GetChunkSize () const
116254721Semaste        {
117254721Semaste            return m_chunk_size;
118254721Semaste        }
119254721Semaste
120254721Semaste        bool
121254721Semaste        Contains (lldb::addr_t addr) const
122254721Semaste        {
123254721Semaste            return ((addr >= m_addr) && addr < (m_addr + m_byte_size));
124254721Semaste        }
125254721Semaste    protected:
126254721Semaste        uint32_t
127254721Semaste        TotalChunks () const
128254721Semaste        {
129254721Semaste            return m_byte_size / m_chunk_size;
130254721Semaste        }
131254721Semaste
132254721Semaste        uint32_t
133254721Semaste        CalculateChunksNeededForSize (uint32_t size) const
134254721Semaste        {
135254721Semaste            return (size + m_chunk_size - 1) / m_chunk_size;
136254721Semaste        }
137254721Semaste        const lldb::addr_t m_addr;    // Base address of this block of memory
138254721Semaste        const uint32_t m_byte_size;   // 4GB of chunk should be enough...
139254721Semaste        const uint32_t m_permissions; // Permissions for this memory (logical OR of lldb::Permissions bits)
140254721Semaste        const uint32_t m_chunk_size;  // The size of chunks that the memory at m_addr is divied up into
141254721Semaste        typedef std::map<uint32_t, uint32_t> OffsetToChunkSize;
142254721Semaste        OffsetToChunkSize m_offset_to_chunk_size;
143254721Semaste    };
144254721Semaste
145254721Semaste
146254721Semaste    //----------------------------------------------------------------------
147254721Semaste    // A class that can track allocated memory and give out allocated memory
148254721Semaste    // without us having to make an allocate/deallocate call every time we
149254721Semaste    // need some memory in a process that is being debugged.
150254721Semaste    //----------------------------------------------------------------------
151254721Semaste    class AllocatedMemoryCache
152254721Semaste    {
153254721Semaste    public:
154254721Semaste        //------------------------------------------------------------------
155254721Semaste        // Constructors and Destructors
156254721Semaste        //------------------------------------------------------------------
157254721Semaste        AllocatedMemoryCache (Process &process);
158254721Semaste
159254721Semaste        ~AllocatedMemoryCache ();
160254721Semaste
161254721Semaste        void
162254721Semaste        Clear();
163254721Semaste
164254721Semaste        lldb::addr_t
165254721Semaste        AllocateMemory (size_t byte_size,
166254721Semaste                        uint32_t permissions,
167254721Semaste                        Error &error);
168254721Semaste
169254721Semaste        bool
170254721Semaste        DeallocateMemory (lldb::addr_t ptr);
171254721Semaste
172254721Semaste    protected:
173254721Semaste        typedef std::shared_ptr<AllocatedBlock> AllocatedBlockSP;
174254721Semaste
175254721Semaste        AllocatedBlockSP
176254721Semaste        AllocatePage (uint32_t byte_size,
177254721Semaste                      uint32_t permissions,
178254721Semaste                      uint32_t chunk_size,
179254721Semaste                      Error &error);
180254721Semaste
181254721Semaste
182254721Semaste        //------------------------------------------------------------------
183254721Semaste        // Classes that inherit from MemoryCache can see and modify these
184254721Semaste        //------------------------------------------------------------------
185254721Semaste        Process &m_process;
186254721Semaste        Mutex m_mutex;
187254721Semaste        typedef std::multimap<uint32_t, AllocatedBlockSP> PermissionsToBlockMap;
188254721Semaste        PermissionsToBlockMap m_memory_map;
189254721Semaste
190254721Semaste    private:
191254721Semaste        DISALLOW_COPY_AND_ASSIGN (AllocatedMemoryCache);
192254721Semaste    };
193254721Semaste
194254721Semaste} // namespace lldb_private
195254721Semaste
196254721Semaste#endif  // liblldb_Memory_h_
197