xref: /openbsd-src/gnu/llvm/lldb/include/lldb/Expression/IRMemoryMap.h (revision dda2819751e49c83612958492e38917049128b41)
1061da546Spatrick //===-- IRMemoryMap.h -------------------------------------------*- C++ -*-===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9*dda28197Spatrick #ifndef LLDB_EXPRESSION_IRMEMORYMAP_H
10*dda28197Spatrick #define LLDB_EXPRESSION_IRMEMORYMAP_H
11061da546Spatrick 
12061da546Spatrick #include "lldb/Utility/DataBufferHeap.h"
13061da546Spatrick #include "lldb/Utility/UserID.h"
14061da546Spatrick #include "lldb/lldb-public.h"
15061da546Spatrick 
16061da546Spatrick #include <map>
17061da546Spatrick 
18061da546Spatrick namespace lldb_private {
19061da546Spatrick 
20061da546Spatrick /// \class IRMemoryMap IRMemoryMap.h "lldb/Expression/IRMemoryMap.h"
21061da546Spatrick /// Encapsulates memory that may exist in the process but must
22061da546Spatrick ///     also be available in the host process.
23061da546Spatrick ///
24061da546Spatrick /// This class encapsulates a group of memory objects that must be readable or
25061da546Spatrick /// writable from the host process regardless of whether the process exists.
26061da546Spatrick /// This allows the IR interpreter as well as JITted code to access the same
27061da546Spatrick /// memory.  All allocations made by this class are represented as disjoint
28061da546Spatrick /// intervals.
29061da546Spatrick ///
30061da546Spatrick /// Point queries against this group of memory objects can be made by the
31061da546Spatrick /// address in the tar at which they reside.  If the inferior does not exist,
32061da546Spatrick /// allocations still get made-up addresses.  If an inferior appears at some
33061da546Spatrick /// point, then those addresses need to be re-mapped.
34061da546Spatrick class IRMemoryMap {
35061da546Spatrick public:
36061da546Spatrick   IRMemoryMap(lldb::TargetSP target_sp);
37061da546Spatrick   ~IRMemoryMap();
38061da546Spatrick 
39061da546Spatrick   enum AllocationPolicy : uint8_t {
40061da546Spatrick     eAllocationPolicyInvalid =
41061da546Spatrick         0, ///< It is an error for an allocation to have this policy.
42061da546Spatrick     eAllocationPolicyHostOnly, ///< This allocation was created in the host and
43061da546Spatrick                                ///will never make it into the process.
44061da546Spatrick     ///< It is an error to create other types of allocations while such
45061da546Spatrick     ///allocations exist.
46061da546Spatrick     eAllocationPolicyMirror, ///< The intent is that this allocation exist both
47061da546Spatrick                              ///in the host and the process and have
48061da546Spatrick                              ///< the same content in both.
49061da546Spatrick     eAllocationPolicyProcessOnly ///< The intent is that this allocation exist
50061da546Spatrick                                  ///only in the process.
51061da546Spatrick   };
52061da546Spatrick 
53061da546Spatrick   lldb::addr_t Malloc(size_t size, uint8_t alignment, uint32_t permissions,
54061da546Spatrick                       AllocationPolicy policy, bool zero_memory, Status &error);
55061da546Spatrick   void Leak(lldb::addr_t process_address, Status &error);
56061da546Spatrick   void Free(lldb::addr_t process_address, Status &error);
57061da546Spatrick 
58061da546Spatrick   void WriteMemory(lldb::addr_t process_address, const uint8_t *bytes,
59061da546Spatrick                    size_t size, Status &error);
60061da546Spatrick   void WriteScalarToMemory(lldb::addr_t process_address, Scalar &scalar,
61061da546Spatrick                            size_t size, Status &error);
62061da546Spatrick   void WritePointerToMemory(lldb::addr_t process_address, lldb::addr_t address,
63061da546Spatrick                             Status &error);
64061da546Spatrick   void ReadMemory(uint8_t *bytes, lldb::addr_t process_address, size_t size,
65061da546Spatrick                   Status &error);
66061da546Spatrick   void ReadScalarFromMemory(Scalar &scalar, lldb::addr_t process_address,
67061da546Spatrick                             size_t size, Status &error);
68061da546Spatrick   void ReadPointerFromMemory(lldb::addr_t *address,
69061da546Spatrick                              lldb::addr_t process_address, Status &error);
70061da546Spatrick   bool GetAllocSize(lldb::addr_t address, size_t &size);
71061da546Spatrick   void GetMemoryData(DataExtractor &extractor, lldb::addr_t process_address,
72061da546Spatrick                      size_t size, Status &error);
73061da546Spatrick 
74061da546Spatrick   lldb::ByteOrder GetByteOrder();
75061da546Spatrick   uint32_t GetAddressByteSize();
76061da546Spatrick 
77061da546Spatrick   // This function can return NULL.
78061da546Spatrick   ExecutionContextScope *GetBestExecutionContextScope() const;
79061da546Spatrick 
GetTarget()80061da546Spatrick   lldb::TargetSP GetTarget() { return m_target_wp.lock(); }
81061da546Spatrick 
82061da546Spatrick protected:
83061da546Spatrick   // This function should only be used if you know you are using the JIT. Any
84061da546Spatrick   // other cases should use GetBestExecutionContextScope().
85061da546Spatrick 
GetProcessWP()86061da546Spatrick   lldb::ProcessWP &GetProcessWP() { return m_process_wp; }
87061da546Spatrick 
88061da546Spatrick private:
89061da546Spatrick   struct Allocation {
90061da546Spatrick     lldb::addr_t
91061da546Spatrick         m_process_alloc; ///< The (unaligned) base for the remote allocation.
92061da546Spatrick     lldb::addr_t
93061da546Spatrick         m_process_start; ///< The base address of the allocation in the process.
94061da546Spatrick     size_t m_size;       ///< The size of the requested allocation.
95061da546Spatrick     DataBufferHeap m_data;
96061da546Spatrick 
97061da546Spatrick     /// Flags. Keep these grouped together to avoid structure padding.
98061da546Spatrick     AllocationPolicy m_policy;
99061da546Spatrick     bool m_leak;
100061da546Spatrick     uint8_t m_permissions; ///< The access permissions on the memory in the
101061da546Spatrick                            /// process. In the host, the memory is always
102061da546Spatrick                            /// read/write.
103061da546Spatrick     uint8_t m_alignment;   ///< The alignment of the requested allocation.
104061da546Spatrick 
105061da546Spatrick   public:
106061da546Spatrick     Allocation(lldb::addr_t process_alloc, lldb::addr_t process_start,
107061da546Spatrick                size_t size, uint32_t permissions, uint8_t alignment,
108061da546Spatrick                AllocationPolicy m_policy);
109061da546Spatrick 
110*dda28197Spatrick     Allocation(const Allocation &) = delete;
111*dda28197Spatrick     const Allocation &operator=(const Allocation &) = delete;
112061da546Spatrick   };
113061da546Spatrick 
114061da546Spatrick   static_assert(sizeof(Allocation) <=
115061da546Spatrick                     (4 * sizeof(lldb::addr_t)) + sizeof(DataBufferHeap),
116061da546Spatrick                 "IRMemoryMap::Allocation is larger than expected");
117061da546Spatrick 
118061da546Spatrick   lldb::ProcessWP m_process_wp;
119061da546Spatrick   lldb::TargetWP m_target_wp;
120061da546Spatrick   typedef std::map<lldb::addr_t, Allocation> AllocationMap;
121061da546Spatrick   AllocationMap m_allocations;
122061da546Spatrick 
123061da546Spatrick   lldb::addr_t FindSpace(size_t size);
124061da546Spatrick   bool ContainsHostOnlyAllocations();
125061da546Spatrick   AllocationMap::iterator FindAllocation(lldb::addr_t addr, size_t size);
126061da546Spatrick 
127061da546Spatrick   // Returns true if the given allocation intersects any allocation in the
128061da546Spatrick   // memory map.
129061da546Spatrick   bool IntersectsAllocation(lldb::addr_t addr, size_t size) const;
130061da546Spatrick 
131061da546Spatrick   // Returns true if the two given allocations intersect each other.
132061da546Spatrick   static bool AllocationsIntersect(lldb::addr_t addr1, size_t size1,
133061da546Spatrick                                    lldb::addr_t addr2, size_t size2);
134061da546Spatrick };
135061da546Spatrick }
136061da546Spatrick 
137061da546Spatrick #endif
138