xref: /llvm-project/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h (revision 86ef699060394c82dcda7e86ff70d8cabeabcc2a)
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/Core/Progress.h"
20 #include "lldb/Target/DynamicLoader.h"
21 #include "lldb/Target/Process.h"
22 #include "lldb/Utility/FileSpec.h"
23 #include "lldb/Utility/UUID.h"
24 
25 class DynamicLoaderDarwinKernel : public lldb_private::DynamicLoader {
26 public:
27   DynamicLoaderDarwinKernel(lldb_private::Process *process,
28                             lldb::addr_t kernel_addr);
29 
30   ~DynamicLoaderDarwinKernel() override;
31 
32   // Static Functions
33   static void Initialize();
34 
35   static void Terminate();
36 
37   static llvm::StringRef GetPluginNameStatic() { return "darwin-kernel"; }
38 
39   static llvm::StringRef GetPluginDescriptionStatic();
40 
41   static lldb_private::DynamicLoader *
42   CreateInstance(lldb_private::Process *process, bool force);
43 
44   static void DebuggerInitialize(lldb_private::Debugger &debugger);
45 
46   static lldb::addr_t SearchForDarwinKernel(lldb_private::Process *process);
47 
48   /// Called after attaching a process.
49   ///
50   /// Allow DynamicLoader plug-ins to execute some code after
51   /// attaching to a process.
52   void DidAttach() override;
53 
54   void DidLaunch() override;
55 
56   lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
57                                                   bool stop_others) override;
58 
59   lldb_private::Status CanLoadImage() override;
60 
61   // PluginInterface protocol
62   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
63 
64 protected:
65   void PrivateInitialize(lldb_private::Process *process);
66 
67   void PrivateProcessStateChanged(lldb_private::Process *process,
68                                   lldb::StateType state);
69 
70   void UpdateIfNeeded();
71 
72   void LoadKernelModuleIfNeeded();
73 
74   void Clear(bool clear_process);
75 
76   void PutToLog(lldb_private::Log *log) const;
77 
78   static bool
79   BreakpointHitCallback(void *baton,
80                         lldb_private::StoppointCallbackContext *context,
81                         lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
82 
83   bool BreakpointHit(lldb_private::StoppointCallbackContext *context,
84                      lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
85   uint32_t GetAddrByteSize() { return m_kernel.GetAddressByteSize(); }
86 
87   static lldb::ByteOrder GetByteOrderFromMagic(uint32_t magic);
88 
89   enum {
90     KERNEL_MODULE_MAX_NAME = 64u,
91     // Versions less than 2 didn't have an entry size,
92     // they had a 64 bit name, 16 byte UUID, 8 byte addr,
93     // 8 byte size, 8 byte version, 4 byte load tag, and
94     // 4 byte flags
95     KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u
96   };
97 
98   // class KextImageInfo represents a single kext or kernel binary image.
99   // The class was designed to hold the information from the
100   // OSKextLoadedKextSummary
101   // structure (in libkern/libkern/OSKextLibPrivate.h from xnu).  The kernel
102   // maintains
103   // a list of loded kexts in memory (the OSKextLoadedKextSummaryHeader
104   // structure,
105   // which points to an array of OSKextLoadedKextSummary's).
106   //
107   // A KextImageInfos may have -
108   //
109   // 1. The load address, name, UUID, and size of a kext/kernel binary in memory
110   //    (read straight out of the kernel's list-of-kexts loaded)
111   // 2. A ModuleSP based on a MemoryModule read out of the kernel's memory
112   //    (very unlikely to have any symbolic information)
113   // 3. A ModuleSP for an on-disk copy of the kext binary, possibly with debug
114   // info
115   //    or a dSYM
116   //
117   // For performance reasons, the developer may prefer that lldb not load the
118   // kexts out
119   // of memory at the start of a kernel session.  But we should build up /
120   // maintain a
121   // list of kexts that the kernel has told us about so we can relocate a kext
122   // module
123   // later if the user explicitly adds it to the target.
124 
125   class KextImageInfo {
126   public:
127     KextImageInfo() : m_name(), m_module_sp(), m_memory_module_sp(), m_uuid() {}
128 
129     void Clear() {
130       m_load_address = LLDB_INVALID_ADDRESS;
131       m_size = 0;
132       m_name.clear();
133       m_uuid.Clear();
134       m_module_sp.reset();
135       m_memory_module_sp.reset();
136       m_load_process_stop_id = UINT32_MAX;
137     }
138 
139     bool LoadImageAtFileAddress(lldb_private::Process *process);
140 
141     bool LoadImageUsingMemoryModule(lldb_private::Process *process,
142                                     lldb_private::Progress *progress = nullptr);
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) const;
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