aboutsummaryrefslogtreecommitdiff
path: root/include/lldb/Target/Memory.h
blob: bf1cc1878784370edf15e929279a6b7e25154c5a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
//===-- Memory.h ------------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_Memory_h_
#define liblldb_Memory_h_

// C Includes
// C++ Includes
#include <map>
#include <vector>

// Other libraries and framework includes

// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Core/RangeMap.h"
#include "lldb/Host/Mutex.h"

namespace lldb_private {
    //----------------------------------------------------------------------
    // A class to track memory that was read from a live process between 
    // runs. 
    //----------------------------------------------------------------------
    class MemoryCache
    {
    public:
        //------------------------------------------------------------------
        // Constructors and Destructors
        //------------------------------------------------------------------
        MemoryCache (Process &process);
        
        ~MemoryCache ();
        
        void
        Clear(bool clear_invalid_ranges = false);
        
        void
        Flush (lldb::addr_t addr, size_t size);
        
        size_t
        Read (lldb::addr_t addr, 
              void *dst, 
              size_t dst_len,
              Error &error);
        
        uint32_t
        GetMemoryCacheLineSize() const
        {
            return m_L2_cache_line_byte_size ;
        }
        
        void
        AddInvalidRange (lldb::addr_t base_addr, lldb::addr_t byte_size);

        bool
        RemoveInvalidRange (lldb::addr_t base_addr, lldb::addr_t byte_size);

        // Allow external sources to populate data into the L1 memory cache
        void
        AddL1CacheData(lldb::addr_t addr, const void *src, size_t src_len);

        void
        AddL1CacheData(lldb::addr_t addr, const lldb::DataBufferSP &data_buffer_sp);

    protected:
        typedef std::map<lldb::addr_t, lldb::DataBufferSP> BlockMap;
        typedef RangeArray<lldb::addr_t, lldb::addr_t, 4> InvalidRanges;
        typedef Range<lldb::addr_t, lldb::addr_t> AddrRange;
        //------------------------------------------------------------------
        // Classes that inherit from MemoryCache can see and modify these
        //------------------------------------------------------------------
        Mutex m_mutex;
        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
        BlockMap m_L2_cache; // A memory cache of fixed size chinks (m_L2_cache_line_byte_size bytes in size each)
        InvalidRanges m_invalid_ranges;
        Process &m_process;
        uint32_t m_L2_cache_line_byte_size;
    private:
        DISALLOW_COPY_AND_ASSIGN (MemoryCache);
    };

    
    class AllocatedBlock
    {
    public:
        AllocatedBlock (lldb::addr_t addr, 
                        uint32_t byte_size, 
                        uint32_t permissions,
                        uint32_t chunk_size);
        
        ~AllocatedBlock ();
        
        lldb::addr_t
        ReserveBlock (uint32_t size);
        
        bool
        FreeBlock (lldb::addr_t addr);
        
        lldb::addr_t
        GetBaseAddress () const
        {
            return m_addr;
        }
        
        uint32_t
        GetByteSize () const
        {
            return m_byte_size;
        }

        uint32_t
        GetPermissions () const
        {
            return m_permissions;
        }

        uint32_t
        GetChunkSize () const
        {
            return m_chunk_size;
        }

        bool
        Contains (lldb::addr_t addr) const
        {
            return ((addr >= m_addr) && addr < (m_addr + m_byte_size));
        }
    protected:
        uint32_t
        TotalChunks () const
        {
            return m_byte_size / m_chunk_size;
        }
        
        uint32_t 
        CalculateChunksNeededForSize (uint32_t size) const
        {
            return (size + m_chunk_size - 1) / m_chunk_size;
        }
        const lldb::addr_t m_addr;    // Base address of this block of memory
        const uint32_t m_byte_size;   // 4GB of chunk should be enough...
        const uint32_t m_permissions; // Permissions for this memory (logical OR of lldb::Permissions bits)
        const uint32_t m_chunk_size;  // The size of chunks that the memory at m_addr is divied up into
        typedef std::map<uint32_t, uint32_t> OffsetToChunkSize;
        OffsetToChunkSize m_offset_to_chunk_size;
    };
    

    //----------------------------------------------------------------------
    // A class that can track allocated memory and give out allocated memory
    // without us having to make an allocate/deallocate call every time we
    // need some memory in a process that is being debugged.
    //----------------------------------------------------------------------
    class AllocatedMemoryCache
    {
    public:
        //------------------------------------------------------------------
        // Constructors and Destructors
        //------------------------------------------------------------------
        AllocatedMemoryCache (Process &process);
        
        ~AllocatedMemoryCache ();
        
        void
        Clear();

        lldb::addr_t
        AllocateMemory (size_t byte_size, 
                        uint32_t permissions, 
                        Error &error);

        bool
        DeallocateMemory (lldb::addr_t ptr);
        
    protected:
        typedef std::shared_ptr<AllocatedBlock> AllocatedBlockSP;

        AllocatedBlockSP
        AllocatePage (uint32_t byte_size, 
                      uint32_t permissions, 
                      uint32_t chunk_size, 
                      Error &error);


        //------------------------------------------------------------------
        // Classes that inherit from MemoryCache can see and modify these
        //------------------------------------------------------------------
        Process &m_process;
        Mutex m_mutex;
        typedef std::multimap<uint32_t, AllocatedBlockSP> PermissionsToBlockMap;
        PermissionsToBlockMap m_memory_map;
        
    private:
        DISALLOW_COPY_AND_ASSIGN (AllocatedMemoryCache);
    };

} // namespace lldb_private

#endif  // liblldb_Memory_h_