1 //===-- DynamicLoaderDarwinKernel.h -----------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_DARWIN_KERNEL_DYNAMICLOADERDARWINKERNEL_H
10 #define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_DARWIN_KERNEL_DYNAMICLOADERDARWINKERNEL_H
11 
12 #include <mutex>
13 #include <string>
14 #include <vector>
15 
16 
17 #include "lldb/Host/SafeMachO.h"
18 
19 #include "lldb/Target/DynamicLoader.h"
20 #include "lldb/Target/Process.h"
21 #include "lldb/Utility/FileSpec.h"
22 #include "lldb/Utility/UUID.h"
23 
24 class DynamicLoaderDarwinKernel : public lldb_private::DynamicLoader {
25 public:
26   DynamicLoaderDarwinKernel(lldb_private::Process *process,
27                             lldb::addr_t kernel_addr);
28 
29   ~DynamicLoaderDarwinKernel() override;
30 
31   // Static Functions
32   static void Initialize();
33 
34   static void Terminate();
35 
36   static lldb_private::ConstString GetPluginNameStatic();
37 
38   static const char *GetPluginDescriptionStatic();
39 
40   static lldb_private::DynamicLoader *
41   CreateInstance(lldb_private::Process *process, bool force);
42 
43   static void DebuggerInitialize(lldb_private::Debugger &debugger);
44 
45   static lldb::addr_t SearchForDarwinKernel(lldb_private::Process *process);
46 
47   /// Called after attaching a process.
48   ///
49   /// Allow DynamicLoader plug-ins to execute some code after
50   /// attaching to a process.
51   void DidAttach() override;
52 
53   void DidLaunch() override;
54 
55   lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
56                                                   bool stop_others) override;
57 
58   lldb_private::Status CanLoadImage() override;
59 
60   // PluginInterface protocol
61   lldb_private::ConstString GetPluginName() override;
62 
63   uint32_t GetPluginVersion() override;
64 
65 protected:
66   void PrivateInitialize(lldb_private::Process *process);
67 
68   void PrivateProcessStateChanged(lldb_private::Process *process,
69                                   lldb::StateType state);
70 
71   void UpdateIfNeeded();
72 
73   void LoadKernelModuleIfNeeded();
74 
75   void Clear(bool clear_process);
76 
77   void PutToLog(lldb_private::Log *log) const;
78 
79   static bool
80   BreakpointHitCallback(void *baton,
81                         lldb_private::StoppointCallbackContext *context,
82                         lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
83 
84   bool BreakpointHit(lldb_private::StoppointCallbackContext *context,
85                      lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
86   uint32_t GetAddrByteSize() { return m_kernel.GetAddressByteSize(); }
87 
88   static lldb::ByteOrder GetByteOrderFromMagic(uint32_t magic);
89 
90   enum {
91     KERNEL_MODULE_MAX_NAME = 64u,
92     // Versions less than 2 didn't have an entry size,
93     // they had a 64 bit name, 16 byte UUID, 8 byte addr,
94     // 8 byte size, 8 byte version, 4 byte load tag, and
95     // 4 byte flags
96     KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u
97   };
98 
99   // class KextImageInfo represents a single kext or kernel binary image.
100   // The class was designed to hold the information from the
101   // OSKextLoadedKextSummary
102   // structure (in libkern/libkern/OSKextLibPrivate.h from xnu).  The kernel
103   // maintains
104   // a list of loded kexts in memory (the OSKextLoadedKextSummaryHeader
105   // structure,
106   // which points to an array of OSKextLoadedKextSummary's).
107   //
108   // A KextImageInfos may have -
109   //
110   // 1. The load address, name, UUID, and size of a kext/kernel binary in memory
111   //    (read straight out of the kernel's list-of-kexts loaded)
112   // 2. A ModuleSP based on a MemoryModule read out of the kernel's memory
113   //    (very unlikely to have any symbolic information)
114   // 3. A ModuleSP for an on-disk copy of the kext binary, possibly with debug
115   // info
116   //    or a dSYM
117   //
118   // For performance reasons, the developer may prefer that lldb not load the
119   // kexts out
120   // of memory at the start of a kernel session.  But we should build up /
121   // maintain a
122   // list of kexts that the kernel has told us about so we can relocate a kext
123   // module
124   // later if the user explicitly adds it to the target.
125 
126   class KextImageInfo {
127   public:
128     KextImageInfo() : m_name(), m_module_sp(), m_memory_module_sp(), m_uuid() {}
129 
130     void Clear() {
131       m_load_address = LLDB_INVALID_ADDRESS;
132       m_size = 0;
133       m_name.clear();
134       m_uuid.Clear();
135       m_module_sp.reset();
136       m_memory_module_sp.reset();
137       m_load_process_stop_id = UINT32_MAX;
138     }
139 
140     bool LoadImageAtFileAddress(lldb_private::Process *process);
141 
142     bool LoadImageUsingMemoryModule(lldb_private::Process *process);
143 
144     bool IsLoaded() { return m_load_process_stop_id != UINT32_MAX; }
145 
146     void SetLoadAddress(
147         lldb::addr_t load_addr); // Address of the Mach-O header for this binary
148 
149     lldb::addr_t
150     GetLoadAddress() const; // Address of the Mach-O header for this binary
151 
152     lldb_private::UUID GetUUID() const;
153 
154     void SetUUID(const lldb_private::UUID &uuid);
155 
156     void SetName(const char *);
157 
158     std::string GetName() const;
159 
160     void SetModule(lldb::ModuleSP module);
161 
162     lldb::ModuleSP GetModule();
163 
164     // try to fill in m_memory_module_sp from memory based on the m_load_address
165     bool ReadMemoryModule(lldb_private::Process *process);
166 
167     bool IsKernel()
168         const; // true if this is the mach_kernel; false if this is a kext
169 
170     void SetIsKernel(bool is_kernel);
171 
172     uint64_t GetSize() const;
173 
174     void SetSize(uint64_t size);
175 
176     uint32_t
177     GetProcessStopId() const; // the stop-id when this binary was first noticed
178 
179     void SetProcessStopId(uint32_t stop_id);
180 
181     bool operator==(const KextImageInfo &rhs);
182 
183     uint32_t GetAddressByteSize(); // as determined by Mach-O header
184 
185     lldb::ByteOrder GetByteOrder(); // as determined by Mach-O header
186 
187     lldb_private::ArchSpec
188     GetArchitecture() const; // as determined by Mach-O header
189 
190     void PutToLog(lldb_private::Log *log) const;
191 
192     typedef std::vector<KextImageInfo> collection;
193     typedef collection::iterator iterator;
194     typedef collection::const_iterator const_iterator;
195 
196   private:
197     std::string m_name;
198     lldb::ModuleSP m_module_sp;
199     lldb::ModuleSP m_memory_module_sp;
200     uint32_t m_load_process_stop_id =
201         UINT32_MAX; // the stop-id when this module was added
202                     // to the Target
203     lldb_private::UUID
204         m_uuid; // UUID for this dylib if it has one, else all zeros
205     lldb::addr_t m_load_address = LLDB_INVALID_ADDRESS;
206     uint64_t m_size = 0;
207     bool m_kernel_image =
208         false; // true if this is the kernel, false if this is a kext
209   };
210 
211   struct OSKextLoadedKextSummaryHeader {
212     uint32_t version = 0;
213     uint32_t entry_size = 0;
214     uint32_t entry_count = 0;
215     lldb::addr_t image_infos_addr = LLDB_INVALID_ADDRESS;
216 
217     OSKextLoadedKextSummaryHeader() = default;
218 
219     uint32_t GetSize() {
220       switch (version) {
221       case 0:
222         return 0; // Can't know the size without a valid version
223       case 1:
224         return 8; // Version 1 only had a version + entry_count
225       default:
226         break;
227       }
228       // Version 2 and above has version, entry_size, entry_count, and reserved
229       return 16;
230     }
231 
232     void Clear() {
233       version = 0;
234       entry_size = 0;
235       entry_count = 0;
236       image_infos_addr = LLDB_INVALID_ADDRESS;
237     }
238 
239     bool IsValid() const { return version >= 1 && version <= 2; }
240   };
241 
242   void RegisterNotificationCallbacks();
243 
244   void UnregisterNotificationCallbacks();
245 
246   void SetNotificationBreakpointIfNeeded();
247 
248   bool ReadAllKextSummaries();
249 
250   bool ReadKextSummaryHeader();
251 
252   bool ParseKextSummaries(const lldb_private::Address &kext_summary_addr,
253                           uint32_t count);
254 
255   void
256   UpdateImageInfosHeaderAndLoadCommands(KextImageInfo::collection &image_infos,
257                                         uint32_t infos_count,
258                                         bool update_executable);
259 
260   uint32_t ReadKextSummaries(const lldb_private::Address &kext_summary_addr,
261                              uint32_t image_infos_count,
262                              KextImageInfo::collection &image_infos);
263 
264   static lldb::addr_t
265   SearchForKernelAtSameLoadAddr(lldb_private::Process *process);
266 
267   static lldb::addr_t
268   SearchForKernelWithDebugHints(lldb_private::Process *process);
269 
270   static lldb::addr_t SearchForKernelNearPC(lldb_private::Process *process);
271 
272   static lldb::addr_t
273   SearchForKernelViaExhaustiveSearch(lldb_private::Process *process);
274 
275   static bool
276   ReadMachHeader(lldb::addr_t addr, lldb_private::Process *process, llvm::MachO::mach_header &mh,
277                  bool *read_error = nullptr);
278 
279   static lldb_private::UUID
280   CheckForKernelImageAtAddress(lldb::addr_t addr,
281                                lldb_private::Process *process,
282                                bool *read_error = nullptr);
283 
284   lldb::addr_t m_kernel_load_address;
285   KextImageInfo m_kernel; // Info about the current kernel image being used
286 
287   lldb_private::Address m_kext_summary_header_ptr_addr;
288   lldb_private::Address m_kext_summary_header_addr;
289   OSKextLoadedKextSummaryHeader m_kext_summary_header;
290   KextImageInfo::collection m_known_kexts;
291   mutable std::recursive_mutex m_mutex;
292   lldb::user_id_t m_break_id;
293 
294 private:
295   DynamicLoaderDarwinKernel(const DynamicLoaderDarwinKernel &) = delete;
296   const DynamicLoaderDarwinKernel &
297   operator=(const DynamicLoaderDarwinKernel &) = delete;
298 };
299 
300 #endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_DARWIN_KERNEL_DYNAMICLOADERDARWINKERNEL_H
301