15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===-- Memory.h ------------------------------------------------*- C++ -*-===//
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef liblldb_Memory_h_
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define liblldb_Memory_h_
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// C Includes
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// C++ Includes
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Other libraries and framework includes
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Project includes
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lldb/lldb-private.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lldb/Core/RangeMap.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lldb/Host/Mutex.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace lldb_private {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //----------------------------------------------------------------------
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // A class to track memory that was read from a live process between
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // runs.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //----------------------------------------------------------------------
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    class MemoryCache
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public:
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        //------------------------------------------------------------------
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Constructors and Destructors
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        //------------------------------------------------------------------
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MemoryCache (Process &process);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ~MemoryCache ();
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        void
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Clear(bool clear_invalid_ranges = false);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        void
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Flush (lldb::addr_t addr, size_t size);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        size_t
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Read (lldb::addr_t addr,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              void *dst,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              size_t dst_len,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              Error &error);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        uint32_t
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetMemoryCacheLineSize() const
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return m_cache_line_byte_size ;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        void
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AddInvalidRange (lldb::addr_t base_addr, lldb::addr_t byte_size);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        bool
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        RemoveInvalidRange (lldb::addr_t base_addr, lldb::addr_t byte_size);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    protected:
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        typedef std::map<lldb::addr_t, lldb::DataBufferSP> BlockMap;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        typedef RangeArray<lldb::addr_t, lldb::addr_t, 4> InvalidRanges;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        //------------------------------------------------------------------
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Classes that inherit from MemoryCache can see and modify these
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        //------------------------------------------------------------------
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Process &m_process;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        uint32_t m_cache_line_byte_size;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Mutex m_mutex;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BlockMap m_cache;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        InvalidRanges m_invalid_ranges;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private:
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DISALLOW_COPY_AND_ASSIGN (MemoryCache);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    class AllocatedBlock
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public:
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AllocatedBlock (lldb::addr_t addr,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        uint32_t byte_size,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        uint32_t permissions,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        uint32_t chunk_size);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ~AllocatedBlock ();
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        lldb::addr_t
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ReserveBlock (uint32_t size);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        bool
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FreeBlock (lldb::addr_t addr);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        lldb::addr_t
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetBaseAddress () const
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return m_addr;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        uint32_t
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetByteSize () const
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return m_byte_size;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        uint32_t
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetPermissions () const
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return m_permissions;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        uint32_t
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetChunkSize () const
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return m_chunk_size;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        bool
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Contains (lldb::addr_t addr) const
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return ((addr >= m_addr) && addr < (m_addr + m_byte_size));
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    protected:
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        uint32_t
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TotalChunks () const
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return m_byte_size / m_chunk_size;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        uint32_t
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CalculateChunksNeededForSize (uint32_t size) const
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return (size + m_chunk_size - 1) / m_chunk_size;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const lldb::addr_t m_addr;    // Base address of this block of memory
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const uint32_t m_byte_size;   // 4GB of chunk should be enough...
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const uint32_t m_permissions; // Permissions for this memory (logical OR of lldb::Permissions bits)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const uint32_t m_chunk_size;  // The size of chunks that the memory at m_addr is divied up into
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        typedef std::map<uint32_t, uint32_t> OffsetToChunkSize;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        OffsetToChunkSize m_offset_to_chunk_size;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //----------------------------------------------------------------------
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // A class that can track allocated memory and give out allocated memory
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // without us having to make an allocate/deallocate call every time we
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // need some memory in a process that is being debugged.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //----------------------------------------------------------------------
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    class AllocatedMemoryCache
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public:
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        //------------------------------------------------------------------
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Constructors and Destructors
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        //------------------------------------------------------------------
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AllocatedMemoryCache (Process &process);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ~AllocatedMemoryCache ();
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        void
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Clear();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        lldb::addr_t
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AllocateMemory (size_t byte_size,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        uint32_t permissions,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        Error &error);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        bool
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DeallocateMemory (lldb::addr_t ptr);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    protected:
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        typedef std::shared_ptr<AllocatedBlock> AllocatedBlockSP;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AllocatedBlockSP
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AllocatePage (uint32_t byte_size,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      uint32_t permissions,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      uint32_t chunk_size,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      Error &error);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        //------------------------------------------------------------------
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Classes that inherit from MemoryCache can see and modify these
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        //------------------------------------------------------------------
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Process &m_process;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Mutex m_mutex;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        typedef std::multimap<uint32_t, AllocatedBlockSP> PermissionsToBlockMap;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PermissionsToBlockMap m_memory_map;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private:
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DISALLOW_COPY_AND_ASSIGN (AllocatedMemoryCache);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace lldb_private
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // liblldb_Memory_h_
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)