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 AddrByteSize() 117 { 118 switch (m_kernel.header.magic) 119 { 120 case llvm::MachO::HeaderMagic32: 121 case llvm::MachO::HeaderMagic32Swapped: 122 return 4; 123 124 case llvm::MachO::HeaderMagic64: 125 case llvm::MachO::HeaderMagic64Swapped: 126 return 8; 127 128 default: 129 break; 130 } 131 return 0; 132 } 133 134 static lldb::ByteOrder 135 GetByteOrderFromMagic (uint32_t magic) 136 { 137 switch (magic) 138 { 139 case llvm::MachO::HeaderMagic32: 140 case llvm::MachO::HeaderMagic64: 141 return lldb::endian::InlHostByteOrder(); 142 143 case llvm::MachO::HeaderMagic32Swapped: 144 case llvm::MachO::HeaderMagic64Swapped: 145 if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig) 146 return lldb::eByteOrderLittle; 147 else 148 return lldb::eByteOrderBig; 149 150 default: 151 break; 152 } 153 return lldb::eByteOrderInvalid; 154 } 155 156 class Segment 157 { 158 public: 159 160 Segment() : 161 name(), 162 vmaddr(LLDB_INVALID_ADDRESS), 163 vmsize(0), 164 fileoff(0), 165 filesize(0), 166 maxprot(0), 167 initprot(0), 168 nsects(0), 169 flags(0) 170 { 171 } 172 173 lldb_private::ConstString name; 174 lldb::addr_t vmaddr; 175 lldb::addr_t vmsize; 176 lldb::addr_t fileoff; 177 lldb::addr_t filesize; 178 uint32_t maxprot; 179 uint32_t initprot; 180 uint32_t nsects; 181 uint32_t flags; 182 183 bool 184 operator==(const Segment& rhs) const 185 { 186 return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize; 187 } 188 189 void 190 PutToLog (lldb_private::Log *log, 191 lldb::addr_t slide) const; 192 193 }; 194 195 enum 196 { 197 KERNEL_MODULE_MAX_NAME = 64u, 198 // Versions less than 2 didn't have an entry size, 199 // they had a 64 bit name, 16 byte UUID, 8 byte addr, 200 // 8 byte size, 8 byte version, 4 byte load tag, and 201 // 4 byte flags 202 KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u 203 }; 204 205 struct OSKextLoadedKextSummary 206 { 207 char name[KERNEL_MODULE_MAX_NAME]; 208 lldb::ModuleSP module_sp; 209 uint32_t module_create_stop_id; 210 lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros 211 lldb_private::Address so_address; // The section offset address for this kext in case it can be read from object files 212 uint64_t address; 213 uint64_t size; 214 uint64_t version; 215 uint32_t load_tag; 216 uint32_t flags; 217 uint64_t reference_list; 218 llvm::MachO::mach_header header; // The mach header for this image 219 std::vector<Segment> segments; // All segment vmaddr and vmsize pairs for this executable (from memory of inferior) 220 221 OSKextLoadedKextSummary() : 222 module_sp (), 223 module_create_stop_id (UINT32_MAX), 224 uuid (), 225 so_address (), 226 address (LLDB_INVALID_ADDRESS), 227 size (0), 228 version (0), 229 load_tag (0), 230 flags (0), 231 reference_list (0), 232 header(), 233 segments() 234 { 235 name[0] = '\0'; 236 } 237 238 void 239 Clear (bool load_cmd_data_only) 240 { 241 if (!load_cmd_data_only) 242 { 243 so_address.Clear(); 244 address = LLDB_INVALID_ADDRESS; 245 size = 0; 246 version = 0; 247 load_tag = 0; 248 flags = 0; 249 reference_list = 0; 250 name[0] = '\0'; 251 ::memset (&header, 0, sizeof(header)); 252 } 253 module_sp.reset(); 254 module_create_stop_id = UINT32_MAX; 255 uuid.Clear(); 256 segments.clear(); 257 } 258 259 bool 260 operator == (const OSKextLoadedKextSummary& rhs) const 261 { 262 return address == rhs.address 263 && size == rhs.size 264 //&& module_sp.get() == rhs.module_sp.get() 265 && uuid == rhs.uuid 266 && version == rhs.version 267 && load_tag == rhs.load_tag 268 && flags == rhs.flags 269 && reference_list == rhs.reference_list 270 && strncmp (name, rhs.name, KERNEL_MODULE_MAX_NAME) == 0 271 && memcmp(&header, &rhs.header, sizeof(header)) == 0 272 && segments == rhs.segments; 273 } 274 275 bool 276 UUIDValid() const 277 { 278 return uuid.IsValid(); 279 } 280 281 uint32_t 282 GetAddressByteSize () 283 { 284 if (header.cputype) 285 { 286 if (header.cputype & llvm::MachO::CPUArchABI64) 287 return 8; 288 else 289 return 4; 290 } 291 return 0; 292 } 293 294 lldb::ByteOrder 295 GetByteOrder() 296 { 297 switch (header.magic) 298 { 299 case llvm::MachO::HeaderMagic32: // MH_MAGIC 300 case llvm::MachO::HeaderMagic64: // MH_MAGIC_64 301 return lldb::endian::InlHostByteOrder(); 302 303 case llvm::MachO::HeaderMagic32Swapped: // MH_CIGAM 304 case llvm::MachO::HeaderMagic64Swapped: // MH_CIGAM_64 305 if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderLittle) 306 return lldb::eByteOrderBig; 307 else 308 return lldb::eByteOrderLittle; 309 default: 310 assert (!"invalid header.magic value"); 311 break; 312 } 313 return lldb::endian::InlHostByteOrder(); 314 } 315 316 lldb_private::ArchSpec 317 GetArchitecture () const 318 { 319 return lldb_private::ArchSpec (lldb_private::eArchTypeMachO, header.cputype, header.cpusubtype); 320 } 321 322 const Segment * 323 FindSegment (const lldb_private::ConstString &name) const; 324 325 void 326 PutToLog (lldb_private::Log *log) const; 327 328 typedef std::vector<OSKextLoadedKextSummary> collection; 329 typedef collection::iterator iterator; 330 typedef collection::const_iterator const_iterator; 331 }; 332 333 struct OSKextLoadedKextSummaryHeader 334 { 335 uint32_t version; 336 uint32_t entry_size; 337 uint32_t entry_count; 338 lldb::addr_t image_infos_addr; 339 340 OSKextLoadedKextSummaryHeader() : 341 version (0), 342 entry_size (0), 343 entry_count (0), 344 image_infos_addr (LLDB_INVALID_ADDRESS) 345 { 346 } 347 348 uint32_t 349 GetSize() 350 { 351 switch (version) 352 { 353 case 0: return 0; // Can't know the size without a valid version 354 case 1: return 8; // Version 1 only had a version + entry_count 355 default: break; 356 } 357 // Version 2 and above has version, entry_size, entry_count, and reserved 358 return 16; 359 } 360 361 void 362 Clear() 363 { 364 version = 0; 365 entry_size = 0; 366 entry_count = 0; 367 image_infos_addr = LLDB_INVALID_ADDRESS; 368 } 369 370 bool 371 IsValid() const 372 { 373 return version >= 1 || version <= 2; 374 } 375 }; 376 377 bool 378 ReadMachHeader (OSKextLoadedKextSummary& kext_summary, 379 lldb_private::DataExtractor *load_command_data); 380 381 void 382 RegisterNotificationCallbacks(); 383 384 void 385 UnregisterNotificationCallbacks(); 386 387 uint32_t 388 ParseLoadCommands (const lldb_private::DataExtractor& data, 389 OSKextLoadedKextSummary& dylib_info); 390 391 bool 392 UpdateImageLoadAddress(OSKextLoadedKextSummary& info); 393 394 bool 395 FindTargetModule (OSKextLoadedKextSummary &image_info, 396 bool can_create, 397 bool *did_create_ptr); 398 399 void 400 SetNotificationBreakpointIfNeeded (); 401 402 bool 403 ReadAllKextSummaries (); 404 405 bool 406 ReadKextSummaryHeader (); 407 408 bool 409 ParseKextSummaries (const lldb_private::Address &kext_summary_addr, 410 uint32_t count); 411 412 bool 413 AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos); 414 415 void 416 UpdateImageInfosHeaderAndLoadCommands(OSKextLoadedKextSummary::collection &image_infos, 417 uint32_t infos_count, 418 bool update_executable); 419 420 bool 421 UpdateCommPageLoadAddress (lldb_private::Module *module); 422 423 uint32_t 424 ReadKextSummaries (const lldb_private::Address &kext_summary_addr, 425 uint32_t image_infos_count, 426 OSKextLoadedKextSummary::collection &image_infos); 427 428 bool 429 UnloadImageLoadAddress (OSKextLoadedKextSummary& info); 430 431 OSKextLoadedKextSummary m_kernel; // Info about the current kernel image being used 432 lldb_private::Address m_kext_summary_header_ptr_addr; 433 lldb_private::Address m_kext_summary_header_addr; 434 OSKextLoadedKextSummaryHeader m_kext_summary_header; 435 OSKextLoadedKextSummary::collection m_kext_summaries; 436 mutable lldb_private::Mutex m_mutex; 437 lldb::user_id_t m_break_id; 438 439 private: 440 DISALLOW_COPY_AND_ASSIGN (DynamicLoaderDarwinKernel); 441 }; 442 443 #endif // liblldb_DynamicLoaderDarwinKernel_h_ 444