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