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); GetAddrByteSize()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: KextImageInfo()128 KextImageInfo() 129 : m_name(), m_module_sp(), m_memory_module_sp(), 130 m_load_process_stop_id(UINT32_MAX), m_uuid(), 131 m_load_address(LLDB_INVALID_ADDRESS), m_size(0), 132 m_kernel_image(false) {} 133 Clear()134 void Clear() { 135 m_load_address = LLDB_INVALID_ADDRESS; 136 m_size = 0; 137 m_name.clear(); 138 m_uuid.Clear(); 139 m_module_sp.reset(); 140 m_memory_module_sp.reset(); 141 m_load_process_stop_id = UINT32_MAX; 142 } 143 144 bool LoadImageAtFileAddress(lldb_private::Process *process); 145 146 bool LoadImageUsingMemoryModule(lldb_private::Process *process); 147 IsLoaded()148 bool IsLoaded() { return m_load_process_stop_id != UINT32_MAX; } 149 150 void SetLoadAddress( 151 lldb::addr_t load_addr); // Address of the Mach-O header for this binary 152 153 lldb::addr_t 154 GetLoadAddress() const; // Address of the Mach-O header for this binary 155 156 lldb_private::UUID GetUUID() const; 157 158 void SetUUID(const lldb_private::UUID &uuid); 159 160 void SetName(const char *); 161 162 std::string GetName() const; 163 164 void SetModule(lldb::ModuleSP module); 165 166 lldb::ModuleSP GetModule(); 167 168 // try to fill in m_memory_module_sp from memory based on the m_load_address 169 bool ReadMemoryModule(lldb_private::Process *process); 170 171 bool IsKernel() 172 const; // true if this is the mach_kernel; false if this is a kext 173 174 void SetIsKernel(bool is_kernel); 175 176 uint64_t GetSize() const; 177 178 void SetSize(uint64_t size); 179 180 uint32_t 181 GetProcessStopId() const; // the stop-id when this binary was first noticed 182 183 void SetProcessStopId(uint32_t stop_id); 184 185 bool operator==(const KextImageInfo &rhs); 186 187 uint32_t GetAddressByteSize(); // as determined by Mach-O header 188 189 lldb::ByteOrder GetByteOrder(); // as determined by Mach-O header 190 191 lldb_private::ArchSpec 192 GetArchitecture() const; // as determined by Mach-O header 193 194 void PutToLog(lldb_private::Log *log) const; 195 196 typedef std::vector<KextImageInfo> collection; 197 typedef collection::iterator iterator; 198 typedef collection::const_iterator const_iterator; 199 200 private: 201 std::string m_name; 202 lldb::ModuleSP m_module_sp; 203 lldb::ModuleSP m_memory_module_sp; 204 uint32_t m_load_process_stop_id; // the stop-id when this module was added 205 // to the Target 206 lldb_private::UUID 207 m_uuid; // UUID for this dylib if it has one, else all zeros 208 lldb::addr_t m_load_address; 209 uint64_t m_size; 210 bool m_kernel_image; // true if this is the kernel, false if this is a kext 211 }; 212 213 struct OSKextLoadedKextSummaryHeader { 214 uint32_t version; 215 uint32_t entry_size; 216 uint32_t entry_count; 217 lldb::addr_t image_infos_addr; 218 OSKextLoadedKextSummaryHeaderOSKextLoadedKextSummaryHeader219 OSKextLoadedKextSummaryHeader() 220 : version(0), entry_size(0), entry_count(0), 221 image_infos_addr(LLDB_INVALID_ADDRESS) {} 222 GetSizeOSKextLoadedKextSummaryHeader223 uint32_t GetSize() { 224 switch (version) { 225 case 0: 226 return 0; // Can't know the size without a valid version 227 case 1: 228 return 8; // Version 1 only had a version + entry_count 229 default: 230 break; 231 } 232 // Version 2 and above has version, entry_size, entry_count, and reserved 233 return 16; 234 } 235 ClearOSKextLoadedKextSummaryHeader236 void Clear() { 237 version = 0; 238 entry_size = 0; 239 entry_count = 0; 240 image_infos_addr = LLDB_INVALID_ADDRESS; 241 } 242 IsValidOSKextLoadedKextSummaryHeader243 bool IsValid() const { return version >= 1 && version <= 2; } 244 }; 245 246 void RegisterNotificationCallbacks(); 247 248 void UnregisterNotificationCallbacks(); 249 250 void SetNotificationBreakpointIfNeeded(); 251 252 bool ReadAllKextSummaries(); 253 254 bool ReadKextSummaryHeader(); 255 256 bool ParseKextSummaries(const lldb_private::Address &kext_summary_addr, 257 uint32_t count); 258 259 void 260 UpdateImageInfosHeaderAndLoadCommands(KextImageInfo::collection &image_infos, 261 uint32_t infos_count, 262 bool update_executable); 263 264 uint32_t ReadKextSummaries(const lldb_private::Address &kext_summary_addr, 265 uint32_t image_infos_count, 266 KextImageInfo::collection &image_infos); 267 268 static lldb::addr_t 269 SearchForKernelAtSameLoadAddr(lldb_private::Process *process); 270 271 static lldb::addr_t 272 SearchForKernelWithDebugHints(lldb_private::Process *process); 273 274 static lldb::addr_t SearchForKernelNearPC(lldb_private::Process *process); 275 276 static lldb::addr_t 277 SearchForKernelViaExhaustiveSearch(lldb_private::Process *process); 278 279 static bool 280 ReadMachHeader(lldb::addr_t addr, lldb_private::Process *process, llvm::MachO::mach_header &mh, 281 bool *read_error = nullptr); 282 283 static lldb_private::UUID 284 CheckForKernelImageAtAddress(lldb::addr_t addr, 285 lldb_private::Process *process, 286 bool *read_error = nullptr); 287 288 lldb::addr_t m_kernel_load_address; 289 KextImageInfo m_kernel; // Info about the current kernel image being used 290 291 lldb_private::Address m_kext_summary_header_ptr_addr; 292 lldb_private::Address m_kext_summary_header_addr; 293 OSKextLoadedKextSummaryHeader m_kext_summary_header; 294 KextImageInfo::collection m_known_kexts; 295 mutable std::recursive_mutex m_mutex; 296 lldb::user_id_t m_break_id; 297 298 private: 299 DynamicLoaderDarwinKernel(const DynamicLoaderDarwinKernel &) = delete; 300 const DynamicLoaderDarwinKernel & 301 operator=(const DynamicLoaderDarwinKernel &) = delete; 302 }; 303 304 #endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_DARWIN_KERNEL_DYNAMICLOADERDARWINKERNEL_H 305