1 //===-- DynamicLoaderDarwinKernel.h -----------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef liblldb_DynamicLoaderDarwinKernel_h_ 11 #define liblldb_DynamicLoaderDarwinKernel_h_ 12 13 // C Includes 14 // C++ Includes 15 #include <map> 16 #include <vector> 17 #include <string> 18 19 // Other libraries and framework includes 20 #include "llvm/Support/MachO.h" 21 22 #include "lldb/Target/DynamicLoader.h" 23 #include "lldb/Host/FileSpec.h" 24 #include "lldb/Host/TimeValue.h" 25 #include "lldb/Core/UUID.h" 26 #include "lldb/Host/Mutex.h" 27 #include "lldb/Target/Process.h" 28 29 class DynamicLoaderDarwinKernel : public lldb_private::DynamicLoader 30 { 31 public: 32 //------------------------------------------------------------------ 33 // Static Functions 34 //------------------------------------------------------------------ 35 static void 36 Initialize(); 37 38 static void 39 Terminate(); 40 41 static const char * 42 GetPluginNameStatic(); 43 44 static const char * 45 GetPluginDescriptionStatic(); 46 47 static lldb_private::DynamicLoader * 48 CreateInstance (lldb_private::Process *process, bool force); 49 50 DynamicLoaderDarwinKernel (lldb_private::Process *process); 51 52 virtual 53 ~DynamicLoaderDarwinKernel (); 54 //------------------------------------------------------------------ 55 /// Called after attaching a process. 56 /// 57 /// Allow DynamicLoader plug-ins to execute some code after 58 /// attaching to a process. 59 //------------------------------------------------------------------ 60 virtual void 61 DidAttach (); 62 63 virtual void 64 DidLaunch (); 65 66 virtual lldb::ThreadPlanSP 67 GetStepThroughTrampolinePlan (lldb_private::Thread &thread, 68 bool stop_others); 69 70 virtual lldb_private::Error 71 CanLoadImage (); 72 73 //------------------------------------------------------------------ 74 // PluginInterface protocol 75 //------------------------------------------------------------------ 76 virtual const char * 77 GetPluginName(); 78 79 virtual const char * 80 GetShortPluginName(); 81 82 virtual uint32_t 83 GetPluginVersion(); 84 85 protected: 86 void 87 PrivateInitialize (lldb_private::Process *process); 88 89 void 90 PrivateProcessStateChanged (lldb_private::Process *process, 91 lldb::StateType state); 92 93 void 94 UpdateIfNeeded(); 95 96 void 97 LoadKernelModuleIfNeeded (); 98 99 void 100 Clear (bool clear_process); 101 102 void 103 PutToLog (lldb_private::Log *log) const; 104 105 static bool 106 BreakpointHitCallback (void *baton, 107 lldb_private::StoppointCallbackContext *context, 108 lldb::user_id_t break_id, 109 lldb::user_id_t break_loc_id); 110 111 bool 112 BreakpointHit (lldb_private::StoppointCallbackContext *context, 113 lldb::user_id_t break_id, 114 lldb::user_id_t break_loc_id); 115 uint32_t 116 GetAddrByteSize() 117 { 118 return m_kernel.GetAddressByteSize(); 119 } 120 121 static lldb::ByteOrder 122 GetByteOrderFromMagic (uint32_t magic) 123 { 124 switch (magic) 125 { 126 case llvm::MachO::HeaderMagic32: 127 case llvm::MachO::HeaderMagic64: 128 return lldb::endian::InlHostByteOrder(); 129 130 case llvm::MachO::HeaderMagic32Swapped: 131 case llvm::MachO::HeaderMagic64Swapped: 132 if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig) 133 return lldb::eByteOrderLittle; 134 else 135 return lldb::eByteOrderBig; 136 137 default: 138 break; 139 } 140 return lldb::eByteOrderInvalid; 141 } 142 enum 143 { 144 KERNEL_MODULE_MAX_NAME = 64u, 145 // Versions less than 2 didn't have an entry size, 146 // they had a 64 bit name, 16 byte UUID, 8 byte addr, 147 // 8 byte size, 8 byte version, 4 byte load tag, and 148 // 4 byte flags 149 KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u 150 }; 151 152 struct OSKextLoadedKextSummary 153 { 154 char name[KERNEL_MODULE_MAX_NAME]; 155 lldb::ModuleSP module_sp; 156 uint32_t load_process_stop_id; 157 lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros 158 lldb_private::Address so_address; // The section offset address for this kext in case it can be read from object files 159 uint64_t address; 160 uint64_t size; 161 uint64_t version; 162 uint32_t load_tag; 163 uint32_t flags; 164 uint64_t reference_list; 165 166 OSKextLoadedKextSummary() : 167 module_sp (), 168 load_process_stop_id (UINT32_MAX), 169 uuid (), 170 so_address (), 171 address (LLDB_INVALID_ADDRESS), 172 size (0), 173 version (0), 174 load_tag (0), 175 flags (0), 176 reference_list (0) 177 { 178 name[0] = '\0'; 179 } 180 181 bool 182 IsLoaded () 183 { 184 return load_process_stop_id != UINT32_MAX; 185 } 186 187 void 188 Clear (bool load_cmd_data_only) 189 { 190 if (!load_cmd_data_only) 191 { 192 so_address.Clear(); 193 address = LLDB_INVALID_ADDRESS; 194 size = 0; 195 version = 0; 196 load_tag = 0; 197 flags = 0; 198 reference_list = 0; 199 name[0] = '\0'; 200 } 201 module_sp.reset(); 202 load_process_stop_id = UINT32_MAX; 203 } 204 205 bool 206 LoadImageAtFileAddress (lldb_private::Process *process); 207 208 bool 209 LoadImageUsingMemoryModule (lldb_private::Process *process); 210 211 // bool 212 // operator == (const OSKextLoadedKextSummary& rhs) const 213 // { 214 // return address == rhs.address 215 // && size == rhs.size 216 // //&& module_sp.get() == rhs.module_sp.get() 217 // && uuid == rhs.uuid 218 // && version == rhs.version 219 // && load_tag == rhs.load_tag 220 // && flags == rhs.flags 221 // && reference_list == rhs.reference_list 222 // && strncmp (name, rhs.name, KERNEL_MODULE_MAX_NAME) == 0; 223 // } 224 // 225 bool 226 UUIDValid() const 227 { 228 return uuid.IsValid(); 229 } 230 231 uint32_t 232 GetAddressByteSize () 233 { 234 if (module_sp) 235 return module_sp->GetArchitecture().GetAddressByteSize(); 236 return 0; 237 } 238 239 lldb::ByteOrder 240 GetByteOrder() 241 { 242 if (module_sp) 243 return module_sp->GetArchitecture().GetByteOrder(); 244 return lldb::endian::InlHostByteOrder(); 245 } 246 247 lldb_private::ArchSpec 248 GetArchitecture () const 249 { 250 if (module_sp) 251 return module_sp->GetArchitecture(); 252 return lldb_private::ArchSpec (); 253 } 254 255 void 256 PutToLog (lldb_private::Log *log) const; 257 258 typedef std::vector<OSKextLoadedKextSummary> collection; 259 typedef collection::iterator iterator; 260 typedef collection::const_iterator const_iterator; 261 }; 262 263 struct OSKextLoadedKextSummaryHeader 264 { 265 uint32_t version; 266 uint32_t entry_size; 267 uint32_t entry_count; 268 lldb::addr_t image_infos_addr; 269 270 OSKextLoadedKextSummaryHeader() : 271 version (0), 272 entry_size (0), 273 entry_count (0), 274 image_infos_addr (LLDB_INVALID_ADDRESS) 275 { 276 } 277 278 uint32_t 279 GetSize() 280 { 281 switch (version) 282 { 283 case 0: return 0; // Can't know the size without a valid version 284 case 1: return 8; // Version 1 only had a version + entry_count 285 default: break; 286 } 287 // Version 2 and above has version, entry_size, entry_count, and reserved 288 return 16; 289 } 290 291 void 292 Clear() 293 { 294 version = 0; 295 entry_size = 0; 296 entry_count = 0; 297 image_infos_addr = LLDB_INVALID_ADDRESS; 298 } 299 300 bool 301 IsValid() const 302 { 303 return version >= 1 || version <= 2; 304 } 305 }; 306 307 void 308 RegisterNotificationCallbacks(); 309 310 void 311 UnregisterNotificationCallbacks(); 312 313 void 314 SetNotificationBreakpointIfNeeded (); 315 316 bool 317 ReadAllKextSummaries (); 318 319 bool 320 ReadKextSummaryHeader (); 321 322 bool 323 ParseKextSummaries (const lldb_private::Address &kext_summary_addr, 324 uint32_t count); 325 326 bool 327 AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos); 328 329 void 330 UpdateImageInfosHeaderAndLoadCommands(OSKextLoadedKextSummary::collection &image_infos, 331 uint32_t infos_count, 332 bool update_executable); 333 334 uint32_t 335 ReadKextSummaries (const lldb_private::Address &kext_summary_addr, 336 uint32_t image_infos_count, 337 OSKextLoadedKextSummary::collection &image_infos); 338 339 OSKextLoadedKextSummary m_kernel; // Info about the current kernel image being used 340 lldb_private::Address m_kext_summary_header_ptr_addr; 341 lldb_private::Address m_kext_summary_header_addr; 342 OSKextLoadedKextSummaryHeader m_kext_summary_header; 343 OSKextLoadedKextSummary::collection m_kext_summaries; 344 mutable lldb_private::Mutex m_mutex; 345 lldb::user_id_t m_break_id; 346 347 private: 348 DISALLOW_COPY_AND_ASSIGN (DynamicLoaderDarwinKernel); 349 }; 350 351 #endif // liblldb_DynamicLoaderDarwinKernel_h_ 352