Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:53

0001 //===-- Memory.h ------------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLDB_TARGET_MEMORY_H
0010 #define LLDB_TARGET_MEMORY_H
0011 
0012 #include "lldb/Utility/RangeMap.h"
0013 #include "lldb/lldb-private.h"
0014 #include <map>
0015 #include <mutex>
0016 #include <vector>
0017 
0018 namespace lldb_private {
0019 // A class to track memory that was read from a live process between
0020 // runs.
0021 class MemoryCache {
0022 public:
0023   // Constructors and Destructors
0024   MemoryCache(Process &process);
0025 
0026   ~MemoryCache();
0027 
0028   void Clear(bool clear_invalid_ranges = false);
0029 
0030   void Flush(lldb::addr_t addr, size_t size);
0031 
0032   size_t Read(lldb::addr_t addr, void *dst, size_t dst_len, Status &error);
0033 
0034   uint32_t GetMemoryCacheLineSize() const { return m_L2_cache_line_byte_size; }
0035 
0036   void AddInvalidRange(lldb::addr_t base_addr, lldb::addr_t byte_size);
0037 
0038   bool RemoveInvalidRange(lldb::addr_t base_addr, lldb::addr_t byte_size);
0039 
0040   // Allow external sources to populate data into the L1 memory cache
0041   void AddL1CacheData(lldb::addr_t addr, const void *src, size_t src_len);
0042 
0043   void AddL1CacheData(lldb::addr_t addr,
0044                       const lldb::DataBufferSP &data_buffer_sp);
0045 
0046 protected:
0047   typedef std::map<lldb::addr_t, lldb::DataBufferSP> BlockMap;
0048   typedef RangeVector<lldb::addr_t, lldb::addr_t, 4> InvalidRanges;
0049   typedef Range<lldb::addr_t, lldb::addr_t> AddrRange;
0050   // Classes that inherit from MemoryCache can see and modify these
0051   std::recursive_mutex m_mutex;
0052   BlockMap m_L1_cache; // A first level memory cache whose chunk sizes vary that
0053                        // will be used only if the memory read fits entirely in
0054                        // a chunk
0055   BlockMap m_L2_cache; // A memory cache of fixed size chinks
0056                        // (m_L2_cache_line_byte_size bytes in size each)
0057   InvalidRanges m_invalid_ranges;
0058   Process &m_process;
0059   uint32_t m_L2_cache_line_byte_size;
0060 
0061 private:
0062   MemoryCache(const MemoryCache &) = delete;
0063   const MemoryCache &operator=(const MemoryCache &) = delete;
0064 
0065   lldb::DataBufferSP GetL2CacheLine(lldb::addr_t addr, Status &error);
0066 };
0067 
0068     
0069 
0070 class AllocatedBlock {
0071 public:
0072   AllocatedBlock(lldb::addr_t addr, uint32_t byte_size, uint32_t permissions,
0073                  uint32_t chunk_size);
0074 
0075   ~AllocatedBlock();
0076 
0077   lldb::addr_t ReserveBlock(uint32_t size);
0078 
0079   bool FreeBlock(lldb::addr_t addr);
0080 
0081   lldb::addr_t GetBaseAddress() const { return m_range.GetRangeBase(); }
0082 
0083   uint32_t GetByteSize() const { return m_range.GetByteSize(); }
0084 
0085   uint32_t GetPermissions() const { return m_permissions; }
0086 
0087   uint32_t GetChunkSize() const { return m_chunk_size; }
0088 
0089   bool Contains(lldb::addr_t addr) const {
0090     return m_range.Contains(addr);
0091   }
0092 
0093 protected:
0094   uint32_t TotalChunks() const { return GetByteSize() / GetChunkSize(); }
0095 
0096   uint32_t CalculateChunksNeededForSize(uint32_t size) const {
0097     return (size + m_chunk_size - 1) / m_chunk_size;
0098   }
0099   // Base address of this block of memory 4GB of chunk should be enough.
0100   Range<lldb::addr_t, uint32_t> m_range;
0101   // Permissions for this memory (logical OR of lldb::Permissions bits)
0102   const uint32_t m_permissions;
0103   // The size of chunks that the memory at m_addr is divied up into.
0104   const uint32_t m_chunk_size;
0105   // A sorted list of free address ranges.
0106   RangeVector<lldb::addr_t, uint32_t> m_free_blocks;
0107   // A sorted list of reserved address.
0108   RangeVector<lldb::addr_t, uint32_t> m_reserved_blocks;
0109 };
0110 
0111 // A class that can track allocated memory and give out allocated memory
0112 // without us having to make an allocate/deallocate call every time we need
0113 // some memory in a process that is being debugged.
0114 class AllocatedMemoryCache {
0115 public:
0116   // Constructors and Destructors
0117   AllocatedMemoryCache(Process &process);
0118 
0119   ~AllocatedMemoryCache();
0120 
0121   void Clear(bool deallocate_memory);
0122 
0123   lldb::addr_t AllocateMemory(size_t byte_size, uint32_t permissions,
0124                               Status &error);
0125 
0126   bool DeallocateMemory(lldb::addr_t ptr);
0127 
0128 protected:
0129   typedef std::shared_ptr<AllocatedBlock> AllocatedBlockSP;
0130 
0131   AllocatedBlockSP AllocatePage(uint32_t byte_size, uint32_t permissions,
0132                                 uint32_t chunk_size, Status &error);
0133 
0134   // Classes that inherit from MemoryCache can see and modify these
0135   Process &m_process;
0136   std::recursive_mutex m_mutex;
0137   typedef std::multimap<uint32_t, AllocatedBlockSP> PermissionsToBlockMap;
0138   PermissionsToBlockMap m_memory_map;
0139 
0140 private:
0141   AllocatedMemoryCache(const AllocatedMemoryCache &) = delete;
0142   const AllocatedMemoryCache &operator=(const AllocatedMemoryCache &) = delete;
0143 };
0144 
0145 } // namespace lldb_private
0146 
0147 #endif // LLDB_TARGET_MEMORY_H