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