xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1061da546Spatrick //===-- DynamicLoaderDarwinKernel.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 
9dda28197Spatrick #ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_DARWIN_KERNEL_DYNAMICLOADERDARWINKERNEL_H
10dda28197Spatrick #define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_DARWIN_KERNEL_DYNAMICLOADERDARWINKERNEL_H
11061da546Spatrick 
12061da546Spatrick #include <mutex>
13061da546Spatrick #include <string>
14061da546Spatrick #include <vector>
15061da546Spatrick 
16061da546Spatrick 
17061da546Spatrick #include "lldb/Host/SafeMachO.h"
18061da546Spatrick 
19061da546Spatrick #include "lldb/Target/DynamicLoader.h"
20061da546Spatrick #include "lldb/Target/Process.h"
21061da546Spatrick #include "lldb/Utility/FileSpec.h"
22061da546Spatrick #include "lldb/Utility/UUID.h"
23061da546Spatrick 
24061da546Spatrick class DynamicLoaderDarwinKernel : public lldb_private::DynamicLoader {
25061da546Spatrick public:
26061da546Spatrick   DynamicLoaderDarwinKernel(lldb_private::Process *process,
27061da546Spatrick                             lldb::addr_t kernel_addr);
28061da546Spatrick 
29061da546Spatrick   ~DynamicLoaderDarwinKernel() override;
30061da546Spatrick 
31061da546Spatrick   // Static Functions
32061da546Spatrick   static void Initialize();
33061da546Spatrick 
34061da546Spatrick   static void Terminate();
35061da546Spatrick 
GetPluginNameStatic()36*f6aab3d8Srobert   static llvm::StringRef GetPluginNameStatic() { return "darwin-kernel"; }
37061da546Spatrick 
38*f6aab3d8Srobert   static llvm::StringRef GetPluginDescriptionStatic();
39061da546Spatrick 
40061da546Spatrick   static lldb_private::DynamicLoader *
41061da546Spatrick   CreateInstance(lldb_private::Process *process, bool force);
42061da546Spatrick 
43061da546Spatrick   static void DebuggerInitialize(lldb_private::Debugger &debugger);
44061da546Spatrick 
45061da546Spatrick   static lldb::addr_t SearchForDarwinKernel(lldb_private::Process *process);
46061da546Spatrick 
47061da546Spatrick   /// Called after attaching a process.
48061da546Spatrick   ///
49061da546Spatrick   /// Allow DynamicLoader plug-ins to execute some code after
50061da546Spatrick   /// attaching to a process.
51061da546Spatrick   void DidAttach() override;
52061da546Spatrick 
53061da546Spatrick   void DidLaunch() override;
54061da546Spatrick 
55061da546Spatrick   lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
56061da546Spatrick                                                   bool stop_others) override;
57061da546Spatrick 
58061da546Spatrick   lldb_private::Status CanLoadImage() override;
59061da546Spatrick 
60061da546Spatrick   // PluginInterface protocol
GetPluginName()61*f6aab3d8Srobert   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
62061da546Spatrick 
63061da546Spatrick protected:
64061da546Spatrick   void PrivateInitialize(lldb_private::Process *process);
65061da546Spatrick 
66061da546Spatrick   void PrivateProcessStateChanged(lldb_private::Process *process,
67061da546Spatrick                                   lldb::StateType state);
68061da546Spatrick 
69061da546Spatrick   void UpdateIfNeeded();
70061da546Spatrick 
71061da546Spatrick   void LoadKernelModuleIfNeeded();
72061da546Spatrick 
73061da546Spatrick   void Clear(bool clear_process);
74061da546Spatrick 
75061da546Spatrick   void PutToLog(lldb_private::Log *log) const;
76061da546Spatrick 
77061da546Spatrick   static bool
78061da546Spatrick   BreakpointHitCallback(void *baton,
79061da546Spatrick                         lldb_private::StoppointCallbackContext *context,
80061da546Spatrick                         lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
81061da546Spatrick 
82061da546Spatrick   bool BreakpointHit(lldb_private::StoppointCallbackContext *context,
83061da546Spatrick                      lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
GetAddrByteSize()84061da546Spatrick   uint32_t GetAddrByteSize() { return m_kernel.GetAddressByteSize(); }
85061da546Spatrick 
86061da546Spatrick   static lldb::ByteOrder GetByteOrderFromMagic(uint32_t magic);
87061da546Spatrick 
88061da546Spatrick   enum {
89061da546Spatrick     KERNEL_MODULE_MAX_NAME = 64u,
90061da546Spatrick     // Versions less than 2 didn't have an entry size,
91061da546Spatrick     // they had a 64 bit name, 16 byte UUID, 8 byte addr,
92061da546Spatrick     // 8 byte size, 8 byte version, 4 byte load tag, and
93061da546Spatrick     // 4 byte flags
94061da546Spatrick     KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u
95061da546Spatrick   };
96061da546Spatrick 
97061da546Spatrick   // class KextImageInfo represents a single kext or kernel binary image.
98061da546Spatrick   // The class was designed to hold the information from the
99061da546Spatrick   // OSKextLoadedKextSummary
100061da546Spatrick   // structure (in libkern/libkern/OSKextLibPrivate.h from xnu).  The kernel
101061da546Spatrick   // maintains
102061da546Spatrick   // a list of loded kexts in memory (the OSKextLoadedKextSummaryHeader
103061da546Spatrick   // structure,
104061da546Spatrick   // which points to an array of OSKextLoadedKextSummary's).
105061da546Spatrick   //
106061da546Spatrick   // A KextImageInfos may have -
107061da546Spatrick   //
108061da546Spatrick   // 1. The load address, name, UUID, and size of a kext/kernel binary in memory
109061da546Spatrick   //    (read straight out of the kernel's list-of-kexts loaded)
110061da546Spatrick   // 2. A ModuleSP based on a MemoryModule read out of the kernel's memory
111061da546Spatrick   //    (very unlikely to have any symbolic information)
112061da546Spatrick   // 3. A ModuleSP for an on-disk copy of the kext binary, possibly with debug
113061da546Spatrick   // info
114061da546Spatrick   //    or a dSYM
115061da546Spatrick   //
116061da546Spatrick   // For performance reasons, the developer may prefer that lldb not load the
117061da546Spatrick   // kexts out
118061da546Spatrick   // of memory at the start of a kernel session.  But we should build up /
119061da546Spatrick   // maintain a
120061da546Spatrick   // list of kexts that the kernel has told us about so we can relocate a kext
121061da546Spatrick   // module
122061da546Spatrick   // later if the user explicitly adds it to the target.
123061da546Spatrick 
124061da546Spatrick   class KextImageInfo {
125061da546Spatrick   public:
KextImageInfo()126be691f3bSpatrick     KextImageInfo() : m_name(), m_module_sp(), m_memory_module_sp(), m_uuid() {}
127061da546Spatrick 
Clear()128061da546Spatrick     void Clear() {
129061da546Spatrick       m_load_address = LLDB_INVALID_ADDRESS;
130061da546Spatrick       m_size = 0;
131061da546Spatrick       m_name.clear();
132061da546Spatrick       m_uuid.Clear();
133061da546Spatrick       m_module_sp.reset();
134061da546Spatrick       m_memory_module_sp.reset();
135061da546Spatrick       m_load_process_stop_id = UINT32_MAX;
136061da546Spatrick     }
137061da546Spatrick 
138061da546Spatrick     bool LoadImageAtFileAddress(lldb_private::Process *process);
139061da546Spatrick 
140061da546Spatrick     bool LoadImageUsingMemoryModule(lldb_private::Process *process);
141061da546Spatrick 
IsLoaded()142061da546Spatrick     bool IsLoaded() { return m_load_process_stop_id != UINT32_MAX; }
143061da546Spatrick 
144061da546Spatrick     void SetLoadAddress(
145061da546Spatrick         lldb::addr_t load_addr); // Address of the Mach-O header for this binary
146061da546Spatrick 
147061da546Spatrick     lldb::addr_t
148061da546Spatrick     GetLoadAddress() const; // Address of the Mach-O header for this binary
149061da546Spatrick 
150061da546Spatrick     lldb_private::UUID GetUUID() const;
151061da546Spatrick 
152061da546Spatrick     void SetUUID(const lldb_private::UUID &uuid);
153061da546Spatrick 
154061da546Spatrick     void SetName(const char *);
155061da546Spatrick 
156061da546Spatrick     std::string GetName() const;
157061da546Spatrick 
158061da546Spatrick     void SetModule(lldb::ModuleSP module);
159061da546Spatrick 
160061da546Spatrick     lldb::ModuleSP GetModule();
161061da546Spatrick 
162061da546Spatrick     // try to fill in m_memory_module_sp from memory based on the m_load_address
163061da546Spatrick     bool ReadMemoryModule(lldb_private::Process *process);
164061da546Spatrick 
165061da546Spatrick     bool IsKernel()
166061da546Spatrick         const; // true if this is the mach_kernel; false if this is a kext
167061da546Spatrick 
168061da546Spatrick     void SetIsKernel(bool is_kernel);
169061da546Spatrick 
170061da546Spatrick     uint64_t GetSize() const;
171061da546Spatrick 
172061da546Spatrick     void SetSize(uint64_t size);
173061da546Spatrick 
174061da546Spatrick     uint32_t
175061da546Spatrick     GetProcessStopId() const; // the stop-id when this binary was first noticed
176061da546Spatrick 
177061da546Spatrick     void SetProcessStopId(uint32_t stop_id);
178061da546Spatrick 
179061da546Spatrick     bool operator==(const KextImageInfo &rhs);
180061da546Spatrick 
181061da546Spatrick     uint32_t GetAddressByteSize(); // as determined by Mach-O header
182061da546Spatrick 
183061da546Spatrick     lldb::ByteOrder GetByteOrder(); // as determined by Mach-O header
184061da546Spatrick 
185061da546Spatrick     lldb_private::ArchSpec
186061da546Spatrick     GetArchitecture() const; // as determined by Mach-O header
187061da546Spatrick 
188061da546Spatrick     void PutToLog(lldb_private::Log *log) const;
189061da546Spatrick 
190061da546Spatrick     typedef std::vector<KextImageInfo> collection;
191061da546Spatrick     typedef collection::iterator iterator;
192061da546Spatrick     typedef collection::const_iterator const_iterator;
193061da546Spatrick 
194061da546Spatrick   private:
195061da546Spatrick     std::string m_name;
196061da546Spatrick     lldb::ModuleSP m_module_sp;
197061da546Spatrick     lldb::ModuleSP m_memory_module_sp;
198be691f3bSpatrick     uint32_t m_load_process_stop_id =
199be691f3bSpatrick         UINT32_MAX; // the stop-id when this module was added
200061da546Spatrick                     // to the Target
201061da546Spatrick     lldb_private::UUID
202061da546Spatrick         m_uuid; // UUID for this dylib if it has one, else all zeros
203be691f3bSpatrick     lldb::addr_t m_load_address = LLDB_INVALID_ADDRESS;
204be691f3bSpatrick     uint64_t m_size = 0;
205be691f3bSpatrick     bool m_kernel_image =
206be691f3bSpatrick         false; // true if this is the kernel, false if this is a kext
207061da546Spatrick   };
208061da546Spatrick 
209061da546Spatrick   struct OSKextLoadedKextSummaryHeader {
210be691f3bSpatrick     uint32_t version = 0;
211be691f3bSpatrick     uint32_t entry_size = 0;
212be691f3bSpatrick     uint32_t entry_count = 0;
213be691f3bSpatrick     lldb::addr_t image_infos_addr = LLDB_INVALID_ADDRESS;
214061da546Spatrick 
215be691f3bSpatrick     OSKextLoadedKextSummaryHeader() = default;
216061da546Spatrick 
GetSizeOSKextLoadedKextSummaryHeader217061da546Spatrick     uint32_t GetSize() {
218061da546Spatrick       switch (version) {
219061da546Spatrick       case 0:
220061da546Spatrick         return 0; // Can't know the size without a valid version
221061da546Spatrick       case 1:
222061da546Spatrick         return 8; // Version 1 only had a version + entry_count
223061da546Spatrick       default:
224061da546Spatrick         break;
225061da546Spatrick       }
226061da546Spatrick       // Version 2 and above has version, entry_size, entry_count, and reserved
227061da546Spatrick       return 16;
228061da546Spatrick     }
229061da546Spatrick 
ClearOSKextLoadedKextSummaryHeader230061da546Spatrick     void Clear() {
231061da546Spatrick       version = 0;
232061da546Spatrick       entry_size = 0;
233061da546Spatrick       entry_count = 0;
234061da546Spatrick       image_infos_addr = LLDB_INVALID_ADDRESS;
235061da546Spatrick     }
236061da546Spatrick 
IsValidOSKextLoadedKextSummaryHeader237061da546Spatrick     bool IsValid() const { return version >= 1 && version <= 2; }
238061da546Spatrick   };
239061da546Spatrick 
240061da546Spatrick   void RegisterNotificationCallbacks();
241061da546Spatrick 
242061da546Spatrick   void UnregisterNotificationCallbacks();
243061da546Spatrick 
244061da546Spatrick   void SetNotificationBreakpointIfNeeded();
245061da546Spatrick 
246061da546Spatrick   bool ReadAllKextSummaries();
247061da546Spatrick 
248061da546Spatrick   bool ReadKextSummaryHeader();
249061da546Spatrick 
250061da546Spatrick   bool ParseKextSummaries(const lldb_private::Address &kext_summary_addr,
251061da546Spatrick                           uint32_t count);
252061da546Spatrick 
253061da546Spatrick   void
254061da546Spatrick   UpdateImageInfosHeaderAndLoadCommands(KextImageInfo::collection &image_infos,
255061da546Spatrick                                         uint32_t infos_count,
256061da546Spatrick                                         bool update_executable);
257061da546Spatrick 
258061da546Spatrick   uint32_t ReadKextSummaries(const lldb_private::Address &kext_summary_addr,
259061da546Spatrick                              uint32_t image_infos_count,
260061da546Spatrick                              KextImageInfo::collection &image_infos);
261061da546Spatrick 
262061da546Spatrick   static lldb::addr_t
263061da546Spatrick   SearchForKernelAtSameLoadAddr(lldb_private::Process *process);
264061da546Spatrick 
265061da546Spatrick   static lldb::addr_t
266061da546Spatrick   SearchForKernelWithDebugHints(lldb_private::Process *process);
267061da546Spatrick 
268061da546Spatrick   static lldb::addr_t SearchForKernelNearPC(lldb_private::Process *process);
269061da546Spatrick 
270061da546Spatrick   static lldb::addr_t
271061da546Spatrick   SearchForKernelViaExhaustiveSearch(lldb_private::Process *process);
272061da546Spatrick 
273061da546Spatrick   static bool
274061da546Spatrick   ReadMachHeader(lldb::addr_t addr, lldb_private::Process *process, llvm::MachO::mach_header &mh,
275061da546Spatrick                  bool *read_error = nullptr);
276061da546Spatrick 
277061da546Spatrick   static lldb_private::UUID
278061da546Spatrick   CheckForKernelImageAtAddress(lldb::addr_t addr,
279061da546Spatrick                                lldb_private::Process *process,
280061da546Spatrick                                bool *read_error = nullptr);
281061da546Spatrick 
282061da546Spatrick   lldb::addr_t m_kernel_load_address;
283061da546Spatrick   KextImageInfo m_kernel; // Info about the current kernel image being used
284061da546Spatrick 
285061da546Spatrick   lldb_private::Address m_kext_summary_header_ptr_addr;
286061da546Spatrick   lldb_private::Address m_kext_summary_header_addr;
287061da546Spatrick   OSKextLoadedKextSummaryHeader m_kext_summary_header;
288061da546Spatrick   KextImageInfo::collection m_known_kexts;
289061da546Spatrick   mutable std::recursive_mutex m_mutex;
290061da546Spatrick   lldb::user_id_t m_break_id;
291061da546Spatrick 
292061da546Spatrick private:
293dda28197Spatrick   DynamicLoaderDarwinKernel(const DynamicLoaderDarwinKernel &) = delete;
294dda28197Spatrick   const DynamicLoaderDarwinKernel &
295dda28197Spatrick   operator=(const DynamicLoaderDarwinKernel &) = delete;
296061da546Spatrick };
297061da546Spatrick 
298dda28197Spatrick #endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_DARWIN_KERNEL_DYNAMICLOADERDARWINKERNEL_H
299