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 liblldb_DynamicLoaderDarwinKernel_h_ 10 #define liblldb_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 //------------------------------------------------------------------ 32 // Static Functions 33 //------------------------------------------------------------------ 34 static void Initialize(); 35 36 static void Terminate(); 37 38 static lldb_private::ConstString GetPluginNameStatic(); 39 40 static const char *GetPluginDescriptionStatic(); 41 42 static lldb_private::DynamicLoader * 43 CreateInstance(lldb_private::Process *process, bool force); 44 45 static void DebuggerInitialize(lldb_private::Debugger &debugger); 46 47 static lldb::addr_t SearchForDarwinKernel(lldb_private::Process *process); 48 49 //------------------------------------------------------------------ 50 /// Called after attaching a process. 51 /// 52 /// Allow DynamicLoader plug-ins to execute some code after 53 /// attaching to a process. 54 //------------------------------------------------------------------ 55 void DidAttach() override; 56 57 void DidLaunch() override; 58 59 lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread, 60 bool stop_others) override; 61 62 lldb_private::Status CanLoadImage() override; 63 64 //------------------------------------------------------------------ 65 // PluginInterface protocol 66 //------------------------------------------------------------------ 67 lldb_private::ConstString GetPluginName() override; 68 69 uint32_t GetPluginVersion() override; 70 71 protected: 72 void PrivateInitialize(lldb_private::Process *process); 73 74 void PrivateProcessStateChanged(lldb_private::Process *process, 75 lldb::StateType state); 76 77 void UpdateIfNeeded(); 78 79 void LoadKernelModuleIfNeeded(); 80 81 void Clear(bool clear_process); 82 83 void PutToLog(lldb_private::Log *log) const; 84 85 static bool 86 BreakpointHitCallback(void *baton, 87 lldb_private::StoppointCallbackContext *context, 88 lldb::user_id_t break_id, lldb::user_id_t break_loc_id); 89 90 bool BreakpointHit(lldb_private::StoppointCallbackContext *context, 91 lldb::user_id_t break_id, lldb::user_id_t break_loc_id); 92 uint32_t GetAddrByteSize() { return m_kernel.GetAddressByteSize(); } 93 94 static lldb::ByteOrder GetByteOrderFromMagic(uint32_t magic); 95 96 enum { 97 KERNEL_MODULE_MAX_NAME = 64u, 98 // Versions less than 2 didn't have an entry size, 99 // they had a 64 bit name, 16 byte UUID, 8 byte addr, 100 // 8 byte size, 8 byte version, 4 byte load tag, and 101 // 4 byte flags 102 KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u 103 }; 104 105 // class KextImageInfo represents a single kext or kernel binary image. 106 // The class was designed to hold the information from the 107 // OSKextLoadedKextSummary 108 // structure (in libkern/libkern/OSKextLibPrivate.h from xnu). The kernel 109 // maintains 110 // a list of loded kexts in memory (the OSKextLoadedKextSummaryHeader 111 // structure, 112 // which points to an array of OSKextLoadedKextSummary's). 113 // 114 // A KextImageInfos may have - 115 // 116 // 1. The load address, name, UUID, and size of a kext/kernel binary in memory 117 // (read straight out of the kernel's list-of-kexts loaded) 118 // 2. A ModuleSP based on a MemoryModule read out of the kernel's memory 119 // (very unlikely to have any symbolic information) 120 // 3. A ModuleSP for an on-disk copy of the kext binary, possibly with debug 121 // info 122 // or a dSYM 123 // 124 // For performance reasons, the developer may prefer that lldb not load the 125 // kexts out 126 // of memory at the start of a kernel session. But we should build up / 127 // maintain a 128 // list of kexts that the kernel has told us about so we can relocate a kext 129 // module 130 // later if the user explicitly adds it to the target. 131 132 class KextImageInfo { 133 public: 134 KextImageInfo() 135 : m_name(), m_module_sp(), m_memory_module_sp(), 136 m_load_process_stop_id(UINT32_MAX), m_uuid(), 137 m_load_address(LLDB_INVALID_ADDRESS), m_size(0), 138 m_kernel_image(false) {} 139 140 void Clear() { 141 m_load_address = LLDB_INVALID_ADDRESS; 142 m_size = 0; 143 m_name.clear(); 144 m_uuid.Clear(); 145 m_module_sp.reset(); 146 m_memory_module_sp.reset(); 147 m_load_process_stop_id = UINT32_MAX; 148 } 149 150 bool LoadImageAtFileAddress(lldb_private::Process *process); 151 152 bool LoadImageUsingMemoryModule(lldb_private::Process *process); 153 154 bool IsLoaded() { return m_load_process_stop_id != UINT32_MAX; } 155 156 void SetLoadAddress( 157 lldb::addr_t load_addr); // Address of the Mach-O header for this binary 158 159 lldb::addr_t 160 GetLoadAddress() const; // Address of the Mach-O header for this binary 161 162 lldb_private::UUID GetUUID() const; 163 164 void SetUUID(const lldb_private::UUID &uuid); 165 166 void SetName(const char *); 167 168 std::string GetName() const; 169 170 void SetModule(lldb::ModuleSP module); 171 172 lldb::ModuleSP GetModule(); 173 174 // try to fill in m_memory_module_sp from memory based on the m_load_address 175 bool ReadMemoryModule(lldb_private::Process *process); 176 177 bool IsKernel() 178 const; // true if this is the mach_kernel; false if this is a kext 179 180 void SetIsKernel(bool is_kernel); 181 182 uint64_t GetSize() const; 183 184 void SetSize(uint64_t size); 185 186 uint32_t 187 GetProcessStopId() const; // the stop-id when this binary was first noticed 188 189 void SetProcessStopId(uint32_t stop_id); 190 191 bool operator==(const KextImageInfo &rhs); 192 193 uint32_t GetAddressByteSize(); // as determined by Mach-O header 194 195 lldb::ByteOrder GetByteOrder(); // as determined by Mach-O header 196 197 lldb_private::ArchSpec 198 GetArchitecture() const; // as determined by Mach-O header 199 200 void PutToLog(lldb_private::Log *log) const; 201 202 typedef std::vector<KextImageInfo> collection; 203 typedef collection::iterator iterator; 204 typedef collection::const_iterator const_iterator; 205 206 private: 207 std::string m_name; 208 lldb::ModuleSP m_module_sp; 209 lldb::ModuleSP m_memory_module_sp; 210 uint32_t m_load_process_stop_id; // the stop-id when this module was added 211 // to the Target 212 lldb_private::UUID 213 m_uuid; // UUID for this dylib if it has one, else all zeros 214 lldb::addr_t m_load_address; 215 uint64_t m_size; 216 bool m_kernel_image; // true if this is the kernel, false if this is a kext 217 }; 218 219 struct OSKextLoadedKextSummaryHeader { 220 uint32_t version; 221 uint32_t entry_size; 222 uint32_t entry_count; 223 lldb::addr_t image_infos_addr; 224 225 OSKextLoadedKextSummaryHeader() 226 : version(0), entry_size(0), entry_count(0), 227 image_infos_addr(LLDB_INVALID_ADDRESS) {} 228 229 uint32_t GetSize() { 230 switch (version) { 231 case 0: 232 return 0; // Can't know the size without a valid version 233 case 1: 234 return 8; // Version 1 only had a version + entry_count 235 default: 236 break; 237 } 238 // Version 2 and above has version, entry_size, entry_count, and reserved 239 return 16; 240 } 241 242 void Clear() { 243 version = 0; 244 entry_size = 0; 245 entry_count = 0; 246 image_infos_addr = LLDB_INVALID_ADDRESS; 247 } 248 249 bool IsValid() const { return version >= 1 || version <= 2; } 250 }; 251 252 void RegisterNotificationCallbacks(); 253 254 void UnregisterNotificationCallbacks(); 255 256 void SetNotificationBreakpointIfNeeded(); 257 258 bool ReadAllKextSummaries(); 259 260 bool ReadKextSummaryHeader(); 261 262 bool ParseKextSummaries(const lldb_private::Address &kext_summary_addr, 263 uint32_t count); 264 265 void 266 UpdateImageInfosHeaderAndLoadCommands(KextImageInfo::collection &image_infos, 267 uint32_t infos_count, 268 bool update_executable); 269 270 uint32_t ReadKextSummaries(const lldb_private::Address &kext_summary_addr, 271 uint32_t image_infos_count, 272 KextImageInfo::collection &image_infos); 273 274 static lldb::addr_t 275 SearchForKernelAtSameLoadAddr(lldb_private::Process *process); 276 277 static lldb::addr_t 278 SearchForKernelWithDebugHints(lldb_private::Process *process); 279 280 static lldb::addr_t SearchForKernelNearPC(lldb_private::Process *process); 281 282 static lldb::addr_t 283 SearchForKernelViaExhaustiveSearch(lldb_private::Process *process); 284 285 static bool 286 ReadMachHeader(lldb::addr_t addr, lldb_private::Process *process, llvm::MachO::mach_header &mh, 287 bool *read_error = nullptr); 288 289 static lldb_private::UUID 290 CheckForKernelImageAtAddress(lldb::addr_t addr, 291 lldb_private::Process *process, 292 bool *read_error = nullptr); 293 294 lldb::addr_t m_kernel_load_address; 295 KextImageInfo m_kernel; // Info about the current kernel image being used 296 297 lldb_private::Address m_kext_summary_header_ptr_addr; 298 lldb_private::Address m_kext_summary_header_addr; 299 OSKextLoadedKextSummaryHeader m_kext_summary_header; 300 KextImageInfo::collection m_known_kexts; 301 mutable std::recursive_mutex m_mutex; 302 lldb::user_id_t m_break_id; 303 304 private: 305 DISALLOW_COPY_AND_ASSIGN(DynamicLoaderDarwinKernel); 306 }; 307 308 #endif // liblldb_DynamicLoaderDarwinKernel_h_ 309