1613b8739a4d489b7f1c571288d5786768c024205Greg Clayton//===-- Memory.h ------------------------------------------------*- C++ -*-===//
2613b8739a4d489b7f1c571288d5786768c024205Greg Clayton//
3613b8739a4d489b7f1c571288d5786768c024205Greg Clayton//                     The LLVM Compiler Infrastructure
4613b8739a4d489b7f1c571288d5786768c024205Greg Clayton//
5613b8739a4d489b7f1c571288d5786768c024205Greg Clayton// This file is distributed under the University of Illinois Open Source
6613b8739a4d489b7f1c571288d5786768c024205Greg Clayton// License. See LICENSE.TXT for details.
7613b8739a4d489b7f1c571288d5786768c024205Greg Clayton//
8613b8739a4d489b7f1c571288d5786768c024205Greg Clayton//===----------------------------------------------------------------------===//
9613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
10613b8739a4d489b7f1c571288d5786768c024205Greg Clayton#ifndef liblldb_Memory_h_
11613b8739a4d489b7f1c571288d5786768c024205Greg Clayton#define liblldb_Memory_h_
12613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
13613b8739a4d489b7f1c571288d5786768c024205Greg Clayton// C Includes
14613b8739a4d489b7f1c571288d5786768c024205Greg Clayton// C++ Includes
15613b8739a4d489b7f1c571288d5786768c024205Greg Clayton#include <map>
16613b8739a4d489b7f1c571288d5786768c024205Greg Clayton#include <vector>
17613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
18613b8739a4d489b7f1c571288d5786768c024205Greg Clayton// Other libraries and framework includes
19613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
20613b8739a4d489b7f1c571288d5786768c024205Greg Clayton// Project includes
21613b8739a4d489b7f1c571288d5786768c024205Greg Clayton#include "lldb/lldb-private.h"
22761133029ba2d5bb0c21c3a871dede340b2775fcGreg Clayton#include "lldb/Core/RangeMap.h"
23613b8739a4d489b7f1c571288d5786768c024205Greg Clayton#include "lldb/Host/Mutex.h"
24613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
25613b8739a4d489b7f1c571288d5786768c024205Greg Claytonnamespace lldb_private {
26613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    //----------------------------------------------------------------------
27613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    // A class to track memory that was read from a live process between
28613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    // runs.
29613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    //----------------------------------------------------------------------
30613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    class MemoryCache
31613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    {
32613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    public:
33613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        //------------------------------------------------------------------
34613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        // Constructors and Destructors
35613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        //------------------------------------------------------------------
36613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        MemoryCache (Process &process);
37613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
38613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        ~MemoryCache ();
39613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
40613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        void
414d4ff9e8f7746ba1b1d597512b7cb711350c0206Greg Clayton        Clear(bool clear_invalid_ranges = false);
42613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
43613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        void
44613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        Flush (lldb::addr_t addr, size_t size);
45613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
46613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        size_t
47613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        Read (lldb::addr_t addr,
48613b8739a4d489b7f1c571288d5786768c024205Greg Clayton              void *dst,
49613b8739a4d489b7f1c571288d5786768c024205Greg Clayton              size_t dst_len,
50613b8739a4d489b7f1c571288d5786768c024205Greg Clayton              Error &error);
51613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
52613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        uint32_t
53613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        GetMemoryCacheLineSize() const
54613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        {
55613b8739a4d489b7f1c571288d5786768c024205Greg Clayton            return m_cache_line_byte_size ;
56613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        }
57761133029ba2d5bb0c21c3a871dede340b2775fcGreg Clayton
58761133029ba2d5bb0c21c3a871dede340b2775fcGreg Clayton        void
59761133029ba2d5bb0c21c3a871dede340b2775fcGreg Clayton        AddInvalidRange (lldb::addr_t base_addr, lldb::addr_t byte_size);
60761133029ba2d5bb0c21c3a871dede340b2775fcGreg Clayton
61761133029ba2d5bb0c21c3a871dede340b2775fcGreg Clayton        bool
62761133029ba2d5bb0c21c3a871dede340b2775fcGreg Clayton        RemoveInvalidRange (lldb::addr_t base_addr, lldb::addr_t byte_size);
63761133029ba2d5bb0c21c3a871dede340b2775fcGreg Clayton
64613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    protected:
65761133029ba2d5bb0c21c3a871dede340b2775fcGreg Clayton        typedef std::map<lldb::addr_t, lldb::DataBufferSP> BlockMap;
66761133029ba2d5bb0c21c3a871dede340b2775fcGreg Clayton        typedef RangeArray<lldb::addr_t, lldb::addr_t, 4> InvalidRanges;
67613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        //------------------------------------------------------------------
68613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        // Classes that inherit from MemoryCache can see and modify these
69613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        //------------------------------------------------------------------
70613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        Process &m_process;
71613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        uint32_t m_cache_line_byte_size;
72761133029ba2d5bb0c21c3a871dede340b2775fcGreg Clayton        Mutex m_mutex;
73761133029ba2d5bb0c21c3a871dede340b2775fcGreg Clayton        BlockMap m_cache;
74761133029ba2d5bb0c21c3a871dede340b2775fcGreg Clayton        InvalidRanges m_invalid_ranges;
75613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    private:
76613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        DISALLOW_COPY_AND_ASSIGN (MemoryCache);
77613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    };
78613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
79613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
80613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    class AllocatedBlock
81613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    {
82613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    public:
83613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        AllocatedBlock (lldb::addr_t addr,
84613b8739a4d489b7f1c571288d5786768c024205Greg Clayton                        uint32_t byte_size,
85613b8739a4d489b7f1c571288d5786768c024205Greg Clayton                        uint32_t permissions,
86613b8739a4d489b7f1c571288d5786768c024205Greg Clayton                        uint32_t chunk_size);
87613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
88613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        ~AllocatedBlock ();
89613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
90613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        lldb::addr_t
91613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        ReserveBlock (uint32_t size);
92613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
93613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        bool
94613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        FreeBlock (lldb::addr_t addr);
95613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
96613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        lldb::addr_t
97613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        GetBaseAddress () const
98613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        {
99613b8739a4d489b7f1c571288d5786768c024205Greg Clayton            return m_addr;
100613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        }
101613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
102613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        uint32_t
103613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        GetByteSize () const
104613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        {
105613b8739a4d489b7f1c571288d5786768c024205Greg Clayton            return m_byte_size;
106613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        }
107613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
108613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        uint32_t
109613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        GetPermissions () const
110613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        {
111613b8739a4d489b7f1c571288d5786768c024205Greg Clayton            return m_permissions;
112613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        }
113613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
114613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        uint32_t
115613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        GetChunkSize () const
116613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        {
117613b8739a4d489b7f1c571288d5786768c024205Greg Clayton            return m_chunk_size;
118613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        }
119613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
120613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        bool
121613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        Contains (lldb::addr_t addr) const
122613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        {
123613b8739a4d489b7f1c571288d5786768c024205Greg Clayton            return ((addr >= m_addr) && addr < (m_addr + m_byte_size));
124613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        }
125613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    protected:
126613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        uint32_t
127613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        TotalChunks () const
128613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        {
129613b8739a4d489b7f1c571288d5786768c024205Greg Clayton            return m_byte_size / m_chunk_size;
130613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        }
131613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
132613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        uint32_t
133613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        CalculateChunksNeededForSize (uint32_t size) const
134613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        {
135613b8739a4d489b7f1c571288d5786768c024205Greg Clayton            return (size + m_chunk_size - 1) / m_chunk_size;
136613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        }
137613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        const lldb::addr_t m_addr;    // Base address of this block of memory
138613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        const uint32_t m_byte_size;   // 4GB of chunk should be enough...
139613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        const uint32_t m_permissions; // Permissions for this memory (logical OR of lldb::Permissions bits)
140613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        const uint32_t m_chunk_size;  // The size of chunks that the memory at m_addr is divied up into
141613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        typedef std::map<uint32_t, uint32_t> OffsetToChunkSize;
142613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        OffsetToChunkSize m_offset_to_chunk_size;
143613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    };
144613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
145613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
146613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    //----------------------------------------------------------------------
147613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    // A class that can track allocated memory and give out allocated memory
148613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    // without us having to make an allocate/deallocate call every time we
149613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    // need some memory in a process that is being debugged.
150613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    //----------------------------------------------------------------------
151613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    class AllocatedMemoryCache
152613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    {
153613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    public:
154613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        //------------------------------------------------------------------
155613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        // Constructors and Destructors
156613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        //------------------------------------------------------------------
157613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        AllocatedMemoryCache (Process &process);
158613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
159613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        ~AllocatedMemoryCache ();
160613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
161613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        void
162613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        Clear();
163613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
164613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        lldb::addr_t
165613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        AllocateMemory (size_t byte_size,
166613b8739a4d489b7f1c571288d5786768c024205Greg Clayton                        uint32_t permissions,
167613b8739a4d489b7f1c571288d5786768c024205Greg Clayton                        Error &error);
168613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
169613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        bool
170613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        DeallocateMemory (lldb::addr_t ptr);
171613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
172613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    protected:
173102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton        typedef std::shared_ptr<AllocatedBlock> AllocatedBlockSP;
174613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
175613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        AllocatedBlockSP
176613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        AllocatePage (uint32_t byte_size,
177613b8739a4d489b7f1c571288d5786768c024205Greg Clayton                      uint32_t permissions,
178613b8739a4d489b7f1c571288d5786768c024205Greg Clayton                      uint32_t chunk_size,
179613b8739a4d489b7f1c571288d5786768c024205Greg Clayton                      Error &error);
180613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
181613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
182613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        //------------------------------------------------------------------
183613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        // Classes that inherit from MemoryCache can see and modify these
184613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        //------------------------------------------------------------------
185613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        Process &m_process;
186613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        Mutex m_mutex;
187613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        typedef std::multimap<uint32_t, AllocatedBlockSP> PermissionsToBlockMap;
188613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        PermissionsToBlockMap m_memory_map;
189613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
190613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    private:
191613b8739a4d489b7f1c571288d5786768c024205Greg Clayton        DISALLOW_COPY_AND_ASSIGN (AllocatedMemoryCache);
192613b8739a4d489b7f1c571288d5786768c024205Greg Clayton    };
193613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
194613b8739a4d489b7f1c571288d5786768c024205Greg Clayton} // namespace lldb_private
195613b8739a4d489b7f1c571288d5786768c024205Greg Clayton
196613b8739a4d489b7f1c571288d5786768c024205Greg Clayton#endif  // liblldb_Memory_h_
197