1944b828aSGreg Clayton //===-- DynamicLoaderDarwinKernel.cpp -----------------------------*- C++ -*-===// 2d4bfbc9aSGreg Clayton // 3d4bfbc9aSGreg Clayton // The LLVM Compiler Infrastructure 4d4bfbc9aSGreg Clayton // 5d4bfbc9aSGreg Clayton // This file is distributed under the University of Illinois Open Source 6d4bfbc9aSGreg Clayton // License. See LICENSE.TXT for details. 7d4bfbc9aSGreg Clayton // 8d4bfbc9aSGreg Clayton //===----------------------------------------------------------------------===// 9d4bfbc9aSGreg Clayton 10d4bfbc9aSGreg Clayton #include "lldb/Breakpoint/StoppointCallbackContext.h" 11d4bfbc9aSGreg Clayton #include "lldb/Core/DataBuffer.h" 12d4bfbc9aSGreg Clayton #include "lldb/Core/DataBufferHeap.h" 13d4bfbc9aSGreg Clayton #include "lldb/Core/Debugger.h" 14d4bfbc9aSGreg Clayton #include "lldb/Core/Log.h" 15d4bfbc9aSGreg Clayton #include "lldb/Core/Module.h" 16d4bfbc9aSGreg Clayton #include "lldb/Core/PluginManager.h" 17d4bfbc9aSGreg Clayton #include "lldb/Core/State.h" 18d4bfbc9aSGreg Clayton #include "lldb/Symbol/ObjectFile.h" 19d4bfbc9aSGreg Clayton #include "lldb/Target/ObjCLanguageRuntime.h" 20d4bfbc9aSGreg Clayton #include "lldb/Target/RegisterContext.h" 21d4bfbc9aSGreg Clayton #include "lldb/Target/Target.h" 22d4bfbc9aSGreg Clayton #include "lldb/Target/Thread.h" 23d4bfbc9aSGreg Clayton #include "lldb/Target/ThreadPlanRunToAddress.h" 24d4bfbc9aSGreg Clayton #include "lldb/Target/StackFrame.h" 25d4bfbc9aSGreg Clayton 26944b828aSGreg Clayton #include "DynamicLoaderDarwinKernel.h" 27d4bfbc9aSGreg Clayton 28d4bfbc9aSGreg Clayton //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN 29d4bfbc9aSGreg Clayton #ifdef ENABLE_DEBUG_PRINTF 30d4bfbc9aSGreg Clayton #include <stdio.h> 31d4bfbc9aSGreg Clayton #define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__) 32d4bfbc9aSGreg Clayton #else 33d4bfbc9aSGreg Clayton #define DEBUG_PRINTF(fmt, ...) 34d4bfbc9aSGreg Clayton #endif 35d4bfbc9aSGreg Clayton 36d4bfbc9aSGreg Clayton using namespace lldb; 37d4bfbc9aSGreg Clayton using namespace lldb_private; 38d4bfbc9aSGreg Clayton 39d4bfbc9aSGreg Clayton /// FIXME - The ObjC Runtime trampoline handler doesn't really belong here. 40d4bfbc9aSGreg Clayton /// I am putting it here so I can invoke it in the Trampoline code here, but 41d4bfbc9aSGreg Clayton /// it should be moved to the ObjC Runtime support when it is set up. 42d4bfbc9aSGreg Clayton 43d4bfbc9aSGreg Clayton 44d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 45d4bfbc9aSGreg Clayton // Create an instance of this class. This function is filled into 46d4bfbc9aSGreg Clayton // the plugin info class that gets handed out by the plugin factory and 47d4bfbc9aSGreg Clayton // allows the lldb to instantiate an instance of this class. 48d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 49d4bfbc9aSGreg Clayton DynamicLoader * 50944b828aSGreg Clayton DynamicLoaderDarwinKernel::CreateInstance (Process* process, bool force) 51d4bfbc9aSGreg Clayton { 52d4bfbc9aSGreg Clayton bool create = force; 53d4bfbc9aSGreg Clayton if (!create) 54d4bfbc9aSGreg Clayton { 55d4bfbc9aSGreg Clayton Module* exe_module = process->GetTarget().GetExecutableModulePointer(); 56d4bfbc9aSGreg Clayton if (exe_module) 57d4bfbc9aSGreg Clayton { 58d4bfbc9aSGreg Clayton ObjectFile *object_file = exe_module->GetObjectFile(); 59d4bfbc9aSGreg Clayton if (object_file) 60d4bfbc9aSGreg Clayton { 6149bce8ecSSean Callanan create = (object_file->GetStrata() == ObjectFile::eStrataKernel); 62d4bfbc9aSGreg Clayton } 63d4bfbc9aSGreg Clayton } 64d4bfbc9aSGreg Clayton 65d4bfbc9aSGreg Clayton if (create) 66d4bfbc9aSGreg Clayton { 67d4bfbc9aSGreg Clayton const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple(); 68d4bfbc9aSGreg Clayton create = triple_ref.getOS() == llvm::Triple::Darwin && triple_ref.getVendor() == llvm::Triple::Apple; 69d4bfbc9aSGreg Clayton } 70d4bfbc9aSGreg Clayton } 71d4bfbc9aSGreg Clayton 72d4bfbc9aSGreg Clayton if (create) 7390539456SSean Callanan { 7490539456SSean Callanan process->SetCanJIT(false); 75944b828aSGreg Clayton return new DynamicLoaderDarwinKernel (process); 7690539456SSean Callanan } 77d4bfbc9aSGreg Clayton return NULL; 78d4bfbc9aSGreg Clayton } 79d4bfbc9aSGreg Clayton 80d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 81d4bfbc9aSGreg Clayton // Constructor 82d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 83944b828aSGreg Clayton DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel (Process* process) : 84d4bfbc9aSGreg Clayton DynamicLoader(process), 85d4bfbc9aSGreg Clayton m_kernel(), 86d4bfbc9aSGreg Clayton m_kext_summary_header_ptr_addr (), 87d4bfbc9aSGreg Clayton m_kext_summary_header_addr (), 88d4bfbc9aSGreg Clayton m_kext_summary_header (), 89d4bfbc9aSGreg Clayton m_kext_summaries(), 90a08823fdSDaniel Dunbar m_mutex(Mutex::eMutexTypeRecursive), 91a08823fdSDaniel Dunbar m_break_id (LLDB_INVALID_BREAK_ID) 92d4bfbc9aSGreg Clayton { 93d4bfbc9aSGreg Clayton } 94d4bfbc9aSGreg Clayton 95d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 96d4bfbc9aSGreg Clayton // Destructor 97d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 98944b828aSGreg Clayton DynamicLoaderDarwinKernel::~DynamicLoaderDarwinKernel() 99d4bfbc9aSGreg Clayton { 100d4bfbc9aSGreg Clayton Clear(true); 101d4bfbc9aSGreg Clayton } 102d4bfbc9aSGreg Clayton 103d4bfbc9aSGreg Clayton void 104944b828aSGreg Clayton DynamicLoaderDarwinKernel::UpdateIfNeeded() 105d4bfbc9aSGreg Clayton { 106d4bfbc9aSGreg Clayton LoadKernelModuleIfNeeded(); 107d4bfbc9aSGreg Clayton SetNotificationBreakpointIfNeeded (); 108d4bfbc9aSGreg Clayton } 109d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 110d4bfbc9aSGreg Clayton /// Called after attaching a process. 111d4bfbc9aSGreg Clayton /// 112d4bfbc9aSGreg Clayton /// Allow DynamicLoader plug-ins to execute some code after 113d4bfbc9aSGreg Clayton /// attaching to a process. 114d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 115d4bfbc9aSGreg Clayton void 116944b828aSGreg Clayton DynamicLoaderDarwinKernel::DidAttach () 117d4bfbc9aSGreg Clayton { 118d4bfbc9aSGreg Clayton PrivateInitialize(m_process); 119d4bfbc9aSGreg Clayton UpdateIfNeeded(); 120d4bfbc9aSGreg Clayton } 121d4bfbc9aSGreg Clayton 122d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 123d4bfbc9aSGreg Clayton /// Called after attaching a process. 124d4bfbc9aSGreg Clayton /// 125d4bfbc9aSGreg Clayton /// Allow DynamicLoader plug-ins to execute some code after 126d4bfbc9aSGreg Clayton /// attaching to a process. 127d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 128d4bfbc9aSGreg Clayton void 129944b828aSGreg Clayton DynamicLoaderDarwinKernel::DidLaunch () 130d4bfbc9aSGreg Clayton { 131d4bfbc9aSGreg Clayton PrivateInitialize(m_process); 132d4bfbc9aSGreg Clayton UpdateIfNeeded(); 133d4bfbc9aSGreg Clayton } 134d4bfbc9aSGreg Clayton 135d4bfbc9aSGreg Clayton 136d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 137d4bfbc9aSGreg Clayton // Clear out the state of this class. 138d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 139d4bfbc9aSGreg Clayton void 140944b828aSGreg Clayton DynamicLoaderDarwinKernel::Clear (bool clear_process) 141d4bfbc9aSGreg Clayton { 142d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 143d4bfbc9aSGreg Clayton 144d4bfbc9aSGreg Clayton if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id)) 145d4bfbc9aSGreg Clayton m_process->ClearBreakpointSiteByID(m_break_id); 146d4bfbc9aSGreg Clayton 147d4bfbc9aSGreg Clayton if (clear_process) 148d4bfbc9aSGreg Clayton m_process = NULL; 149d4bfbc9aSGreg Clayton m_kernel.Clear(false); 150d4bfbc9aSGreg Clayton m_kext_summary_header_ptr_addr.Clear(); 151d4bfbc9aSGreg Clayton m_kext_summary_header_addr.Clear(); 152d4bfbc9aSGreg Clayton m_kext_summaries.clear(); 153d4bfbc9aSGreg Clayton m_break_id = LLDB_INVALID_BREAK_ID; 154d4bfbc9aSGreg Clayton } 155d4bfbc9aSGreg Clayton 156d4bfbc9aSGreg Clayton 157c859e2d5SGreg Clayton bool 158c859e2d5SGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageUsingMemoryModule (Process *process) 159c859e2d5SGreg Clayton { 160c859e2d5SGreg Clayton if (IsLoaded()) 161c859e2d5SGreg Clayton return true; 162c859e2d5SGreg Clayton 163c859e2d5SGreg Clayton bool uuid_is_valid = uuid.IsValid(); 164c859e2d5SGreg Clayton 165c859e2d5SGreg Clayton Target &target = process->GetTarget(); 166c859e2d5SGreg Clayton ModuleSP memory_module_sp; 167c859e2d5SGreg Clayton // Use the memory module as the module if we have one... 168c859e2d5SGreg Clayton if (address != LLDB_INVALID_ADDRESS) 169c859e2d5SGreg Clayton { 170c859e2d5SGreg Clayton FileSpec file_spec; 171c859e2d5SGreg Clayton if (module_sp) 172c859e2d5SGreg Clayton file_spec = module_sp->GetFileSpec(); 173c859e2d5SGreg Clayton else 174c859e2d5SGreg Clayton file_spec.SetFile (name, false); 175c859e2d5SGreg Clayton 176c859e2d5SGreg Clayton memory_module_sp = process->ReadModuleFromMemory (file_spec, address, false, false); 177c859e2d5SGreg Clayton if (memory_module_sp && !uuid_is_valid) 178c859e2d5SGreg Clayton { 179c859e2d5SGreg Clayton uuid = memory_module_sp->GetUUID(); 180c859e2d5SGreg Clayton uuid_is_valid = uuid.IsValid(); 181c859e2d5SGreg Clayton } 182c859e2d5SGreg Clayton } 183c859e2d5SGreg Clayton 184c859e2d5SGreg Clayton if (!module_sp) 185c859e2d5SGreg Clayton { 186c859e2d5SGreg Clayton bool uuid_is_valid = uuid.IsValid(); 187c859e2d5SGreg Clayton if (uuid_is_valid) 188c859e2d5SGreg Clayton { 189c859e2d5SGreg Clayton ModuleList &target_images = target.GetImages(); 190c859e2d5SGreg Clayton module_sp = target_images.FindModule(uuid); 191c859e2d5SGreg Clayton 192c859e2d5SGreg Clayton if (!module_sp) 193c859e2d5SGreg Clayton module_sp = target.GetSharedModule (FileSpec(), target.GetArchitecture(), &uuid); 194c859e2d5SGreg Clayton } 195c859e2d5SGreg Clayton } 196c859e2d5SGreg Clayton 197c859e2d5SGreg Clayton 198c859e2d5SGreg Clayton if (memory_module_sp) 199c859e2d5SGreg Clayton { 200c859e2d5SGreg Clayton // Someone already supplied a file, make sure it is the right one. 201c859e2d5SGreg Clayton if (module_sp) 202c859e2d5SGreg Clayton { 203c859e2d5SGreg Clayton if (module_sp->GetUUID() == memory_module_sp->GetUUID()) 204c859e2d5SGreg Clayton { 205c859e2d5SGreg Clayton ObjectFile *ondisk_object_file = module_sp->GetObjectFile(); 206c859e2d5SGreg Clayton ObjectFile *memory_object_file = memory_module_sp->GetObjectFile(); 207c859e2d5SGreg Clayton if (memory_object_file && ondisk_object_file) 208c859e2d5SGreg Clayton { 209c859e2d5SGreg Clayton SectionList *ondisk_section_list = ondisk_object_file->GetSectionList (); 210c859e2d5SGreg Clayton SectionList *memory_section_list = memory_object_file->GetSectionList (); 211c859e2d5SGreg Clayton if (memory_section_list && ondisk_section_list) 212c859e2d5SGreg Clayton { 213*bae2f2f8SGreg Clayton const uint32_t num_ondisk_sections = ondisk_section_list->GetSize(); 214c859e2d5SGreg Clayton // There may be CTF sections in the memory image so we can't 215c859e2d5SGreg Clayton // always just compare the number of sections (which are actually 216c859e2d5SGreg Clayton // segments in mach-o parlance) 217c859e2d5SGreg Clayton uint32_t sect_idx = 0; 218*bae2f2f8SGreg Clayton 219*bae2f2f8SGreg Clayton 220*bae2f2f8SGreg Clayton // We now iterate through all sections in the file module 221*bae2f2f8SGreg Clayton // and look to see if the memory module has a load address 222*bae2f2f8SGreg Clayton // for that section. 223*bae2f2f8SGreg Clayton uint32_t num_sections_loaded = 0; 224*bae2f2f8SGreg Clayton for (sect_idx=0; sect_idx<num_ondisk_sections; ++sect_idx) 225c859e2d5SGreg Clayton { 226*bae2f2f8SGreg Clayton const Section *ondisk_section = ondisk_section_list->GetSectionAtIndex(sect_idx).get(); 227*bae2f2f8SGreg Clayton if (ondisk_section) 228c859e2d5SGreg Clayton { 229*bae2f2f8SGreg Clayton const Section *memory_section = memory_section_list->FindSectionByName(ondisk_section->GetName()).get(); 230*bae2f2f8SGreg Clayton if (memory_section) 231c859e2d5SGreg Clayton { 232c859e2d5SGreg Clayton target.GetSectionLoadList().SetSectionLoadAddress (ondisk_section, memory_section->GetFileAddress()); 233*bae2f2f8SGreg Clayton ++num_sections_loaded; 234c859e2d5SGreg Clayton } 235*bae2f2f8SGreg Clayton } 236*bae2f2f8SGreg Clayton } 237*bae2f2f8SGreg Clayton if (num_sections_loaded > 0) 238c859e2d5SGreg Clayton load_process_stop_id = process->GetStopID(); 239*bae2f2f8SGreg Clayton else 240*bae2f2f8SGreg Clayton module_sp.reset(); // No sections were loaded 241c859e2d5SGreg Clayton } 242c859e2d5SGreg Clayton else 243c859e2d5SGreg Clayton module_sp.reset(); // One or both section lists 244c859e2d5SGreg Clayton } 245c859e2d5SGreg Clayton else 246c859e2d5SGreg Clayton module_sp.reset(); // One or both object files missing 247c859e2d5SGreg Clayton } 248c859e2d5SGreg Clayton else 249c859e2d5SGreg Clayton module_sp.reset(); // UUID mismatch 250c859e2d5SGreg Clayton } 251c859e2d5SGreg Clayton 252c859e2d5SGreg Clayton // Use the memory module as the module if we didn't like the file 253c859e2d5SGreg Clayton // module we either found or were supplied with 254c859e2d5SGreg Clayton if (!module_sp) 255c859e2d5SGreg Clayton { 256c859e2d5SGreg Clayton module_sp = memory_module_sp; 257c859e2d5SGreg Clayton // Load the memory image in the target as all adresses are already correct 258c859e2d5SGreg Clayton bool changed = false; 259c859e2d5SGreg Clayton target.GetImages().Append (memory_module_sp); 260c859e2d5SGreg Clayton if (module_sp->SetLoadAddress (target, 0, changed)) 261c859e2d5SGreg Clayton load_process_stop_id = process->GetStopID(); 262c859e2d5SGreg Clayton } 263c859e2d5SGreg Clayton } 264c859e2d5SGreg Clayton bool is_loaded = IsLoaded(); 265c859e2d5SGreg Clayton 266c859e2d5SGreg Clayton if (so_address.IsValid()) 267c859e2d5SGreg Clayton { 268c859e2d5SGreg Clayton if (is_loaded) 269c859e2d5SGreg Clayton so_address.SetLoadAddress (address, &target); 270c859e2d5SGreg Clayton else 271c859e2d5SGreg Clayton target.GetImages().ResolveFileAddress (address, so_address); 272c859e2d5SGreg Clayton 273c859e2d5SGreg Clayton } 274c859e2d5SGreg Clayton return is_loaded; 275c859e2d5SGreg Clayton } 276c859e2d5SGreg Clayton 277d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 278d4bfbc9aSGreg Clayton // Load the kernel module and initialize the "m_kernel" member. Return 279d4bfbc9aSGreg Clayton // true _only_ if the kernel is loaded the first time through (subsequent 280d4bfbc9aSGreg Clayton // calls to this function should return false after the kernel has been 281d4bfbc9aSGreg Clayton // already loaded). 282d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 283d4bfbc9aSGreg Clayton void 284944b828aSGreg Clayton DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() 285d4bfbc9aSGreg Clayton { 286d4bfbc9aSGreg Clayton if (!m_kext_summary_header_ptr_addr.IsValid()) 287d4bfbc9aSGreg Clayton { 288d4bfbc9aSGreg Clayton m_kernel.Clear(false); 289d4bfbc9aSGreg Clayton m_kernel.module_sp = m_process->GetTarget().GetExecutableModule(); 290c859e2d5SGreg Clayton strncpy(m_kernel.name, "mach_kernel", sizeof(m_kernel.name)); 291c859e2d5SGreg Clayton if (m_kernel.address == LLDB_INVALID_ADDRESS) 292d4bfbc9aSGreg Clayton { 293c859e2d5SGreg Clayton m_kernel.address = m_process->GetImageInfoAddress (); 294c859e2d5SGreg Clayton if (m_kernel.address == LLDB_INVALID_ADDRESS && m_kernel.module_sp) 295c859e2d5SGreg Clayton { 296c859e2d5SGreg Clayton // We didn't get a hint from the process, so we will 297c859e2d5SGreg Clayton // try the kernel at the address that it exists at in 298c859e2d5SGreg Clayton // the file if we have one 299c859e2d5SGreg Clayton ObjectFile *kernel_object_file = m_kernel.module_sp->GetObjectFile(); 300c859e2d5SGreg Clayton if (kernel_object_file) 301c859e2d5SGreg Clayton m_kernel.address = kernel_object_file->GetHeaderAddress().GetFileAddress(); 302c859e2d5SGreg Clayton } 303c859e2d5SGreg Clayton } 304c859e2d5SGreg Clayton 305c859e2d5SGreg Clayton if (m_kernel.address != LLDB_INVALID_ADDRESS) 306c859e2d5SGreg Clayton m_kernel.LoadImageUsingMemoryModule (m_process); 307c859e2d5SGreg Clayton 308c859e2d5SGreg Clayton if (m_kernel.IsLoaded()) 309c859e2d5SGreg Clayton { 310d4bfbc9aSGreg Clayton static ConstString kext_summary_symbol ("gLoadedKextSummaries"); 311c859e2d5SGreg Clayton const Symbol *symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData); 312d4bfbc9aSGreg Clayton if (symbol) 313c859e2d5SGreg Clayton { 314d4bfbc9aSGreg Clayton m_kext_summary_header_ptr_addr = symbol->GetValue(); 315d4bfbc9aSGreg Clayton // Update all image infos 316d4bfbc9aSGreg Clayton ReadAllKextSummaries (); 317d4bfbc9aSGreg Clayton } 318d4bfbc9aSGreg Clayton } 319d4bfbc9aSGreg Clayton else 320d4bfbc9aSGreg Clayton { 321d4bfbc9aSGreg Clayton m_kernel.Clear(false); 322d4bfbc9aSGreg Clayton } 323d4bfbc9aSGreg Clayton } 324d4bfbc9aSGreg Clayton } 325d4bfbc9aSGreg Clayton 326d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 327d4bfbc9aSGreg Clayton // Static callback function that gets called when our DYLD notification 328d4bfbc9aSGreg Clayton // breakpoint gets hit. We update all of our image infos and then 329d4bfbc9aSGreg Clayton // let our super class DynamicLoader class decide if we should stop 330d4bfbc9aSGreg Clayton // or not (based on global preference). 331d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 332d4bfbc9aSGreg Clayton bool 333944b828aSGreg Clayton DynamicLoaderDarwinKernel::BreakpointHitCallback (void *baton, 334d4bfbc9aSGreg Clayton StoppointCallbackContext *context, 335d4bfbc9aSGreg Clayton user_id_t break_id, 336d4bfbc9aSGreg Clayton user_id_t break_loc_id) 337d4bfbc9aSGreg Clayton { 338944b828aSGreg Clayton return static_cast<DynamicLoaderDarwinKernel*>(baton)->BreakpointHit (context, break_id, break_loc_id); 339d4bfbc9aSGreg Clayton } 340d4bfbc9aSGreg Clayton 341d4bfbc9aSGreg Clayton bool 342944b828aSGreg Clayton DynamicLoaderDarwinKernel::BreakpointHit (StoppointCallbackContext *context, 343d4bfbc9aSGreg Clayton user_id_t break_id, 344d4bfbc9aSGreg Clayton user_id_t break_loc_id) 345d4bfbc9aSGreg Clayton { 346d4bfbc9aSGreg Clayton LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 347d4bfbc9aSGreg Clayton if (log) 348944b828aSGreg Clayton log->Printf ("DynamicLoaderDarwinKernel::BreakpointHit (...)\n"); 349d4bfbc9aSGreg Clayton 350d4bfbc9aSGreg Clayton ReadAllKextSummaries (); 351d4bfbc9aSGreg Clayton 352d4bfbc9aSGreg Clayton if (log) 353d4bfbc9aSGreg Clayton PutToLog(log.get()); 354d4bfbc9aSGreg Clayton 355d4bfbc9aSGreg Clayton return GetStopWhenImagesChange(); 356d4bfbc9aSGreg Clayton } 357d4bfbc9aSGreg Clayton 358d4bfbc9aSGreg Clayton 359d4bfbc9aSGreg Clayton bool 360944b828aSGreg Clayton DynamicLoaderDarwinKernel::ReadKextSummaryHeader () 361d4bfbc9aSGreg Clayton { 362d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 363d4bfbc9aSGreg Clayton 364d4bfbc9aSGreg Clayton // the all image infos is already valid for this process stop ID 365d4bfbc9aSGreg Clayton 366d4bfbc9aSGreg Clayton m_kext_summaries.clear(); 367d4bfbc9aSGreg Clayton if (m_kext_summary_header_ptr_addr.IsValid()) 368d4bfbc9aSGreg Clayton { 369d4bfbc9aSGreg Clayton const uint32_t addr_size = m_kernel.GetAddressByteSize (); 370d4bfbc9aSGreg Clayton const ByteOrder byte_order = m_kernel.GetByteOrder(); 371d4bfbc9aSGreg Clayton Error error; 372d4bfbc9aSGreg Clayton // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure 373d4bfbc9aSGreg Clayton // which is currenty 4 uint32_t and a pointer. 374d4bfbc9aSGreg Clayton uint8_t buf[24]; 375d4bfbc9aSGreg Clayton DataExtractor data (buf, sizeof(buf), byte_order, addr_size); 376d4bfbc9aSGreg Clayton const size_t count = 4 * sizeof(uint32_t) + addr_size; 377d4bfbc9aSGreg Clayton const bool prefer_file_cache = false; 378d4bfbc9aSGreg Clayton if (m_process->GetTarget().ReadPointerFromMemory (m_kext_summary_header_ptr_addr, 379d4bfbc9aSGreg Clayton prefer_file_cache, 380d4bfbc9aSGreg Clayton error, 381d4bfbc9aSGreg Clayton m_kext_summary_header_addr)) 382d4bfbc9aSGreg Clayton { 383d4bfbc9aSGreg Clayton // We got a valid address for our kext summary header and make sure it isn't NULL 384d4bfbc9aSGreg Clayton if (m_kext_summary_header_addr.IsValid() && 385d4bfbc9aSGreg Clayton m_kext_summary_header_addr.GetFileAddress() != 0) 386d4bfbc9aSGreg Clayton { 387d4bfbc9aSGreg Clayton const size_t bytes_read = m_process->GetTarget().ReadMemory (m_kext_summary_header_addr, prefer_file_cache, buf, count, error); 388d4bfbc9aSGreg Clayton if (bytes_read == count) 389d4bfbc9aSGreg Clayton { 390d4bfbc9aSGreg Clayton uint32_t offset = 0; 391d4bfbc9aSGreg Clayton m_kext_summary_header.version = data.GetU32(&offset); 392d4bfbc9aSGreg Clayton if (m_kext_summary_header.version >= 2) 393d4bfbc9aSGreg Clayton { 394d4bfbc9aSGreg Clayton m_kext_summary_header.entry_size = data.GetU32(&offset); 395d4bfbc9aSGreg Clayton } 396d4bfbc9aSGreg Clayton else 397d4bfbc9aSGreg Clayton { 398d4bfbc9aSGreg Clayton // Versions less than 2 didn't have an entry size, it was hard coded 399d4bfbc9aSGreg Clayton m_kext_summary_header.entry_size = KERNEL_MODULE_ENTRY_SIZE_VERSION_1; 400d4bfbc9aSGreg Clayton } 401d4bfbc9aSGreg Clayton m_kext_summary_header.entry_count = data.GetU32(&offset); 402d4bfbc9aSGreg Clayton return true; 403d4bfbc9aSGreg Clayton } 404d4bfbc9aSGreg Clayton } 405d4bfbc9aSGreg Clayton } 406d4bfbc9aSGreg Clayton } 407d4bfbc9aSGreg Clayton m_kext_summary_header_addr.Clear(); 408d4bfbc9aSGreg Clayton return false; 409d4bfbc9aSGreg Clayton } 410d4bfbc9aSGreg Clayton 411d4bfbc9aSGreg Clayton 412d4bfbc9aSGreg Clayton bool 413944b828aSGreg Clayton DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr, 414d4bfbc9aSGreg Clayton uint32_t count) 415d4bfbc9aSGreg Clayton { 416d4bfbc9aSGreg Clayton OSKextLoadedKextSummary::collection kext_summaries; 417d4bfbc9aSGreg Clayton LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 418d4bfbc9aSGreg Clayton if (log) 419fd54b368SJason Molenda log->Printf ("Adding %d modules.\n", count); 420d4bfbc9aSGreg Clayton 421d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 422d4bfbc9aSGreg Clayton 423d4bfbc9aSGreg Clayton if (!ReadKextSummaries (kext_summary_addr, count, kext_summaries)) 424d4bfbc9aSGreg Clayton return false; 425d4bfbc9aSGreg Clayton 426d4bfbc9aSGreg Clayton Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream(); 427d4bfbc9aSGreg Clayton for (uint32_t i = 0; i < count; i++) 428d4bfbc9aSGreg Clayton { 429d4bfbc9aSGreg Clayton if (s) 430d4bfbc9aSGreg Clayton { 431d4bfbc9aSGreg Clayton const uint8_t *u = (const uint8_t *)kext_summaries[i].uuid.GetBytes(); 432d4bfbc9aSGreg Clayton if (u) 433d4bfbc9aSGreg Clayton { 4340ca4f8bbSJason Molenda s->Printf("Loading kext: %2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X 0x%16.16llx \"%s\"...", 435d4bfbc9aSGreg Clayton u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7], 436d4bfbc9aSGreg Clayton u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15], 437d4bfbc9aSGreg Clayton kext_summaries[i].address, kext_summaries[i].name); 438d4bfbc9aSGreg Clayton } 439d4bfbc9aSGreg Clayton else 440d4bfbc9aSGreg Clayton { 4410ca4f8bbSJason Molenda s->Printf("0x%16.16llx \"%s\"...", kext_summaries[i].address, kext_summaries[i].name); 442d4bfbc9aSGreg Clayton } 443d4bfbc9aSGreg Clayton } 444d4bfbc9aSGreg Clayton 445c859e2d5SGreg Clayton kext_summaries[i].LoadImageUsingMemoryModule (m_process); 446d4bfbc9aSGreg Clayton 447d4bfbc9aSGreg Clayton if (s) 448d4bfbc9aSGreg Clayton { 449d4bfbc9aSGreg Clayton if (kext_summaries[i].module_sp) 450c859e2d5SGreg Clayton { 451c859e2d5SGreg Clayton if (kext_summaries[i].module_sp->GetFileSpec().GetDirectory()) 4520ca4f8bbSJason Molenda s->Printf("\n found kext: %s/%s\n", 453d4bfbc9aSGreg Clayton kext_summaries[i].module_sp->GetFileSpec().GetDirectory().AsCString(), 454d4bfbc9aSGreg Clayton kext_summaries[i].module_sp->GetFileSpec().GetFilename().AsCString()); 4550ca4f8bbSJason Molenda else 456c859e2d5SGreg Clayton s->Printf("\n found kext: %s\n", 457c859e2d5SGreg Clayton kext_summaries[i].module_sp->GetFileSpec().GetFilename().AsCString()); 458c859e2d5SGreg Clayton } 459c859e2d5SGreg Clayton else 4600ca4f8bbSJason Molenda s->Printf (" failed to locate/load.\n"); 461d4bfbc9aSGreg Clayton } 462d4bfbc9aSGreg Clayton 463d4bfbc9aSGreg Clayton if (log) 464d4bfbc9aSGreg Clayton kext_summaries[i].PutToLog (log.get()); 465d4bfbc9aSGreg Clayton } 466d4bfbc9aSGreg Clayton bool return_value = AddModulesUsingImageInfos (kext_summaries); 467d4bfbc9aSGreg Clayton return return_value; 468d4bfbc9aSGreg Clayton } 469d4bfbc9aSGreg Clayton 470d4bfbc9aSGreg Clayton // Adds the modules in image_infos to m_kext_summaries. 471d4bfbc9aSGreg Clayton // NB don't call this passing in m_kext_summaries. 472d4bfbc9aSGreg Clayton 473d4bfbc9aSGreg Clayton bool 474944b828aSGreg Clayton DynamicLoaderDarwinKernel::AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos) 475d4bfbc9aSGreg Clayton { 476d4bfbc9aSGreg Clayton // Now add these images to the main list. 477d4bfbc9aSGreg Clayton ModuleList loaded_module_list; 478d4bfbc9aSGreg Clayton 479d4bfbc9aSGreg Clayton for (uint32_t idx = 0; idx < image_infos.size(); ++idx) 480d4bfbc9aSGreg Clayton { 481c859e2d5SGreg Clayton OSKextLoadedKextSummary &image_info = image_infos[idx]; 482c859e2d5SGreg Clayton m_kext_summaries.push_back(image_info); 483d4bfbc9aSGreg Clayton 484c859e2d5SGreg Clayton if (image_info.module_sp && m_process->GetStopID() == image_info.load_process_stop_id) 485d4bfbc9aSGreg Clayton loaded_module_list.AppendIfNeeded (image_infos[idx].module_sp); 486d4bfbc9aSGreg Clayton } 487d4bfbc9aSGreg Clayton 488d4bfbc9aSGreg Clayton if (loaded_module_list.GetSize() > 0) 489d4bfbc9aSGreg Clayton { 490d4bfbc9aSGreg Clayton // FIXME: This should really be in the Runtime handlers class, which should get 491d4bfbc9aSGreg Clayton // called by the target's ModulesDidLoad, but we're doing it all locally for now 492d4bfbc9aSGreg Clayton // to save time. 493d4bfbc9aSGreg Clayton // Also, I'm assuming there can be only one libobjc dylib loaded... 494d4bfbc9aSGreg Clayton 495d4bfbc9aSGreg Clayton ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime(); 496d4bfbc9aSGreg Clayton if (objc_runtime != NULL && !objc_runtime->HasReadObjCLibrary()) 497d4bfbc9aSGreg Clayton { 498d4bfbc9aSGreg Clayton size_t num_modules = loaded_module_list.GetSize(); 499d4bfbc9aSGreg Clayton for (int i = 0; i < num_modules; i++) 500d4bfbc9aSGreg Clayton { 501d4bfbc9aSGreg Clayton if (objc_runtime->IsModuleObjCLibrary (loaded_module_list.GetModuleAtIndex (i))) 502d4bfbc9aSGreg Clayton { 503d4bfbc9aSGreg Clayton objc_runtime->ReadObjCLibrary (loaded_module_list.GetModuleAtIndex (i)); 504d4bfbc9aSGreg Clayton break; 505d4bfbc9aSGreg Clayton } 506d4bfbc9aSGreg Clayton } 507d4bfbc9aSGreg Clayton } 508d4bfbc9aSGreg Clayton // if (log) 509944b828aSGreg Clayton // loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderDarwinKernel::ModulesDidLoad"); 510d4bfbc9aSGreg Clayton m_process->GetTarget().ModulesDidLoad (loaded_module_list); 511d4bfbc9aSGreg Clayton } 512d4bfbc9aSGreg Clayton return true; 513d4bfbc9aSGreg Clayton } 514d4bfbc9aSGreg Clayton 515d4bfbc9aSGreg Clayton 516d4bfbc9aSGreg Clayton uint32_t 517944b828aSGreg Clayton DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr, 518d4bfbc9aSGreg Clayton uint32_t image_infos_count, 519d4bfbc9aSGreg Clayton OSKextLoadedKextSummary::collection &image_infos) 520d4bfbc9aSGreg Clayton { 521d4bfbc9aSGreg Clayton const ByteOrder endian = m_kernel.GetByteOrder(); 522d4bfbc9aSGreg Clayton const uint32_t addr_size = m_kernel.GetAddressByteSize(); 523d4bfbc9aSGreg Clayton 524d4bfbc9aSGreg Clayton image_infos.resize(image_infos_count); 525d4bfbc9aSGreg Clayton const size_t count = image_infos.size() * m_kext_summary_header.entry_size; 526d4bfbc9aSGreg Clayton DataBufferHeap data(count, 0); 527d4bfbc9aSGreg Clayton Error error; 528d4bfbc9aSGreg Clayton 529d4bfbc9aSGreg Clayton Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream(); 530d4bfbc9aSGreg Clayton 531d4bfbc9aSGreg Clayton if (s) 532d4bfbc9aSGreg Clayton s->Printf ("Reading %u kext summaries...\n", image_infos_count); 533d4bfbc9aSGreg Clayton const bool prefer_file_cache = false; 534d4bfbc9aSGreg Clayton const size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary_addr, 535d4bfbc9aSGreg Clayton prefer_file_cache, 536d4bfbc9aSGreg Clayton data.GetBytes(), 537d4bfbc9aSGreg Clayton data.GetByteSize(), 538d4bfbc9aSGreg Clayton error); 539d4bfbc9aSGreg Clayton if (bytes_read == count) 540d4bfbc9aSGreg Clayton { 541d4bfbc9aSGreg Clayton 542d4bfbc9aSGreg Clayton DataExtractor extractor (data.GetBytes(), data.GetByteSize(), endian, addr_size); 543d4bfbc9aSGreg Clayton uint32_t i=0; 544d4bfbc9aSGreg Clayton for (uint32_t kext_summary_offset = 0; 545d4bfbc9aSGreg Clayton i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size); 546d4bfbc9aSGreg Clayton ++i, kext_summary_offset += m_kext_summary_header.entry_size) 547d4bfbc9aSGreg Clayton { 548d4bfbc9aSGreg Clayton uint32_t offset = kext_summary_offset; 549d4bfbc9aSGreg Clayton const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME); 550d4bfbc9aSGreg Clayton if (name_data == NULL) 551d4bfbc9aSGreg Clayton break; 552d4bfbc9aSGreg Clayton memcpy (image_infos[i].name, name_data, KERNEL_MODULE_MAX_NAME); 553d4bfbc9aSGreg Clayton image_infos[i].uuid.SetBytes(extractor.GetData (&offset, 16)); 554d4bfbc9aSGreg Clayton image_infos[i].address = extractor.GetU64(&offset); 555d4bfbc9aSGreg Clayton if (!image_infos[i].so_address.SetLoadAddress (image_infos[i].address, &m_process->GetTarget())) 556d4bfbc9aSGreg Clayton m_process->GetTarget().GetImages().ResolveFileAddress (image_infos[i].address, image_infos[i].so_address); 557d4bfbc9aSGreg Clayton image_infos[i].size = extractor.GetU64(&offset); 558d4bfbc9aSGreg Clayton image_infos[i].version = extractor.GetU64(&offset); 559d4bfbc9aSGreg Clayton image_infos[i].load_tag = extractor.GetU32(&offset); 560d4bfbc9aSGreg Clayton image_infos[i].flags = extractor.GetU32(&offset); 561d4bfbc9aSGreg Clayton if ((offset - kext_summary_offset) < m_kext_summary_header.entry_size) 562d4bfbc9aSGreg Clayton { 563d4bfbc9aSGreg Clayton image_infos[i].reference_list = extractor.GetU64(&offset); 564d4bfbc9aSGreg Clayton } 565d4bfbc9aSGreg Clayton else 566d4bfbc9aSGreg Clayton { 567d4bfbc9aSGreg Clayton image_infos[i].reference_list = 0; 568d4bfbc9aSGreg Clayton } 569*bae2f2f8SGreg Clayton // printf ("[%3u] %*.*s: address=0x%16.16llx, size=0x%16.16llx, version=0x%16.16llx, load_tag=0x%8.8x, flags=0x%8.8x\n", 570*bae2f2f8SGreg Clayton // i, 571*bae2f2f8SGreg Clayton // KERNEL_MODULE_MAX_NAME, KERNEL_MODULE_MAX_NAME, (char *)name_data, 572*bae2f2f8SGreg Clayton // image_infos[i].address, 573*bae2f2f8SGreg Clayton // image_infos[i].size, 574*bae2f2f8SGreg Clayton // image_infos[i].version, 575*bae2f2f8SGreg Clayton // image_infos[i].load_tag, 576*bae2f2f8SGreg Clayton // image_infos[i].flags); 577d4bfbc9aSGreg Clayton } 578d4bfbc9aSGreg Clayton if (i < image_infos.size()) 579d4bfbc9aSGreg Clayton image_infos.resize(i); 580d4bfbc9aSGreg Clayton } 581d4bfbc9aSGreg Clayton else 582d4bfbc9aSGreg Clayton { 583d4bfbc9aSGreg Clayton image_infos.clear(); 584d4bfbc9aSGreg Clayton } 585d4bfbc9aSGreg Clayton return image_infos.size(); 586d4bfbc9aSGreg Clayton } 587d4bfbc9aSGreg Clayton 588d4bfbc9aSGreg Clayton bool 589944b828aSGreg Clayton DynamicLoaderDarwinKernel::ReadAllKextSummaries () 590d4bfbc9aSGreg Clayton { 591d4bfbc9aSGreg Clayton LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 592d4bfbc9aSGreg Clayton 593d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 594d4bfbc9aSGreg Clayton 595d4bfbc9aSGreg Clayton if (ReadKextSummaryHeader ()) 596d4bfbc9aSGreg Clayton { 597d4bfbc9aSGreg Clayton if (m_kext_summary_header.entry_count > 0 && m_kext_summary_header_addr.IsValid()) 598d4bfbc9aSGreg Clayton { 599d4bfbc9aSGreg Clayton Address summary_addr (m_kext_summary_header_addr); 600d4bfbc9aSGreg Clayton summary_addr.Slide(m_kext_summary_header.GetSize()); 601d4bfbc9aSGreg Clayton if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count)) 602d4bfbc9aSGreg Clayton { 603d4bfbc9aSGreg Clayton m_kext_summaries.clear(); 604d4bfbc9aSGreg Clayton } 605d4bfbc9aSGreg Clayton return true; 606d4bfbc9aSGreg Clayton } 607d4bfbc9aSGreg Clayton } 608d4bfbc9aSGreg Clayton return false; 609d4bfbc9aSGreg Clayton } 610d4bfbc9aSGreg Clayton 611d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 612d4bfbc9aSGreg Clayton // Dump an image info structure to the file handle provided. 613d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 614d4bfbc9aSGreg Clayton void 615944b828aSGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::PutToLog (Log *log) const 616d4bfbc9aSGreg Clayton { 617d4bfbc9aSGreg Clayton if (log == NULL) 618d4bfbc9aSGreg Clayton return; 619d4bfbc9aSGreg Clayton const uint8_t *u = (uint8_t *)uuid.GetBytes(); 620d4bfbc9aSGreg Clayton 621d4bfbc9aSGreg Clayton if (address == LLDB_INVALID_ADDRESS) 622d4bfbc9aSGreg Clayton { 623d4bfbc9aSGreg Clayton if (u) 624d4bfbc9aSGreg Clayton { 625d4bfbc9aSGreg Clayton log->Printf("\tuuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\" (UNLOADED)", 626d4bfbc9aSGreg Clayton u[ 0], u[ 1], u[ 2], u[ 3], 627d4bfbc9aSGreg Clayton u[ 4], u[ 5], u[ 6], u[ 7], 628d4bfbc9aSGreg Clayton u[ 8], u[ 9], u[10], u[11], 629d4bfbc9aSGreg Clayton u[12], u[13], u[14], u[15], 630d4bfbc9aSGreg Clayton name); 631d4bfbc9aSGreg Clayton } 632d4bfbc9aSGreg Clayton else 633d4bfbc9aSGreg Clayton log->Printf("\tname=\"%s\" (UNLOADED)", name); 634d4bfbc9aSGreg Clayton } 635d4bfbc9aSGreg Clayton else 636d4bfbc9aSGreg Clayton { 637d4bfbc9aSGreg Clayton if (u) 638d4bfbc9aSGreg Clayton { 639d4bfbc9aSGreg Clayton log->Printf("\taddr=0x%16.16llx size=0x%16.16llx version=0x%16.16llx load-tag=0x%8.8x flags=0x%8.8x ref-list=0x%16.16llx uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\"", 640d4bfbc9aSGreg Clayton address, size, version, load_tag, flags, reference_list, 641d4bfbc9aSGreg Clayton u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7], 642d4bfbc9aSGreg Clayton u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15], 643d4bfbc9aSGreg Clayton name); 644d4bfbc9aSGreg Clayton } 645d4bfbc9aSGreg Clayton else 646d4bfbc9aSGreg Clayton { 647d4bfbc9aSGreg Clayton log->Printf("\t[0x%16.16llx - 0x%16.16llx) version=0x%16.16llx load-tag=0x%8.8x flags=0x%8.8x ref-list=0x%16.16llx name=\"%s\"", 648d4bfbc9aSGreg Clayton address, address+size, version, load_tag, flags, reference_list, 649d4bfbc9aSGreg Clayton name); 650d4bfbc9aSGreg Clayton } 651d4bfbc9aSGreg Clayton } 652d4bfbc9aSGreg Clayton } 653d4bfbc9aSGreg Clayton 654d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 655d4bfbc9aSGreg Clayton // Dump the _dyld_all_image_infos members and all current image infos 656d4bfbc9aSGreg Clayton // that we have parsed to the file handle provided. 657d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 658d4bfbc9aSGreg Clayton void 659944b828aSGreg Clayton DynamicLoaderDarwinKernel::PutToLog(Log *log) const 660d4bfbc9aSGreg Clayton { 661d4bfbc9aSGreg Clayton if (log == NULL) 662d4bfbc9aSGreg Clayton return; 663d4bfbc9aSGreg Clayton 664d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 665d4bfbc9aSGreg Clayton log->Printf("gLoadedKextSummaries = 0x%16.16llx { version=%u, entry_size=%u, entry_count=%u }", 666d4bfbc9aSGreg Clayton m_kext_summary_header_addr.GetFileAddress(), 667d4bfbc9aSGreg Clayton m_kext_summary_header.version, 668d4bfbc9aSGreg Clayton m_kext_summary_header.entry_size, 669d4bfbc9aSGreg Clayton m_kext_summary_header.entry_count); 670d4bfbc9aSGreg Clayton 671d4bfbc9aSGreg Clayton size_t i; 672d4bfbc9aSGreg Clayton const size_t count = m_kext_summaries.size(); 673d4bfbc9aSGreg Clayton if (count > 0) 674d4bfbc9aSGreg Clayton { 675d4bfbc9aSGreg Clayton log->PutCString("Loaded:"); 676d4bfbc9aSGreg Clayton for (i = 0; i<count; i++) 677d4bfbc9aSGreg Clayton m_kext_summaries[i].PutToLog(log); 678d4bfbc9aSGreg Clayton } 679d4bfbc9aSGreg Clayton } 680d4bfbc9aSGreg Clayton 681d4bfbc9aSGreg Clayton void 682944b828aSGreg Clayton DynamicLoaderDarwinKernel::PrivateInitialize(Process *process) 683d4bfbc9aSGreg Clayton { 684944b828aSGreg Clayton DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); 685d4bfbc9aSGreg Clayton Clear(true); 686d4bfbc9aSGreg Clayton m_process = process; 687d4bfbc9aSGreg Clayton m_process->GetTarget().GetSectionLoadList().Clear(); 688d4bfbc9aSGreg Clayton } 689d4bfbc9aSGreg Clayton 690d4bfbc9aSGreg Clayton void 691944b828aSGreg Clayton DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded () 692d4bfbc9aSGreg Clayton { 693c859e2d5SGreg Clayton if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.module_sp) 694d4bfbc9aSGreg Clayton { 695944b828aSGreg Clayton DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); 696d4bfbc9aSGreg Clayton 697d4bfbc9aSGreg Clayton 698d4bfbc9aSGreg Clayton const bool internal_bp = false; 699d4bfbc9aSGreg Clayton const LazyBool skip_prologue = eLazyBoolNo; 700969795f1SJim Ingham FileSpecList module_spec_list; 701969795f1SJim Ingham module_spec_list.Append (m_kernel.module_sp->GetFileSpec()); 702969795f1SJim Ingham Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&module_spec_list, 70387df91b8SJim Ingham NULL, 704d4bfbc9aSGreg Clayton "OSKextLoadedKextSummariesUpdated", 705d4bfbc9aSGreg Clayton eFunctionNameTypeFull, 706d4bfbc9aSGreg Clayton internal_bp, 707d4bfbc9aSGreg Clayton skip_prologue).get(); 708d4bfbc9aSGreg Clayton 709944b828aSGreg Clayton bp->SetCallback (DynamicLoaderDarwinKernel::BreakpointHitCallback, this, true); 710d4bfbc9aSGreg Clayton m_break_id = bp->GetID(); 711d4bfbc9aSGreg Clayton } 712d4bfbc9aSGreg Clayton } 713d4bfbc9aSGreg Clayton 714d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 715d4bfbc9aSGreg Clayton // Member function that gets called when the process state changes. 716d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 717d4bfbc9aSGreg Clayton void 718944b828aSGreg Clayton DynamicLoaderDarwinKernel::PrivateProcessStateChanged (Process *process, StateType state) 719d4bfbc9aSGreg Clayton { 720944b828aSGreg Clayton DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__, StateAsCString(state)); 721d4bfbc9aSGreg Clayton switch (state) 722d4bfbc9aSGreg Clayton { 723d4bfbc9aSGreg Clayton case eStateConnected: 724d4bfbc9aSGreg Clayton case eStateAttaching: 725d4bfbc9aSGreg Clayton case eStateLaunching: 726d4bfbc9aSGreg Clayton case eStateInvalid: 727d4bfbc9aSGreg Clayton case eStateUnloaded: 728d4bfbc9aSGreg Clayton case eStateExited: 729d4bfbc9aSGreg Clayton case eStateDetached: 730d4bfbc9aSGreg Clayton Clear(false); 731d4bfbc9aSGreg Clayton break; 732d4bfbc9aSGreg Clayton 733d4bfbc9aSGreg Clayton case eStateStopped: 734d4bfbc9aSGreg Clayton UpdateIfNeeded(); 735d4bfbc9aSGreg Clayton break; 736d4bfbc9aSGreg Clayton 737d4bfbc9aSGreg Clayton case eStateRunning: 738d4bfbc9aSGreg Clayton case eStateStepping: 739d4bfbc9aSGreg Clayton case eStateCrashed: 740d4bfbc9aSGreg Clayton case eStateSuspended: 741d4bfbc9aSGreg Clayton break; 742d4bfbc9aSGreg Clayton 743d4bfbc9aSGreg Clayton default: 744d4bfbc9aSGreg Clayton break; 745d4bfbc9aSGreg Clayton } 746d4bfbc9aSGreg Clayton } 747d4bfbc9aSGreg Clayton 748d4bfbc9aSGreg Clayton ThreadPlanSP 749944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) 750d4bfbc9aSGreg Clayton { 751d4bfbc9aSGreg Clayton ThreadPlanSP thread_plan_sp; 752d4bfbc9aSGreg Clayton LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 753d4bfbc9aSGreg Clayton if (log) 754d4bfbc9aSGreg Clayton log->Printf ("Could not find symbol for step through."); 755d4bfbc9aSGreg Clayton return thread_plan_sp; 756d4bfbc9aSGreg Clayton } 757d4bfbc9aSGreg Clayton 758d4bfbc9aSGreg Clayton Error 759944b828aSGreg Clayton DynamicLoaderDarwinKernel::CanLoadImage () 760d4bfbc9aSGreg Clayton { 761d4bfbc9aSGreg Clayton Error error; 762d4bfbc9aSGreg Clayton error.SetErrorString("always unsafe to load or unload shared libraries in the darwin kernel"); 763d4bfbc9aSGreg Clayton return error; 764d4bfbc9aSGreg Clayton } 765d4bfbc9aSGreg Clayton 766d4bfbc9aSGreg Clayton void 767944b828aSGreg Clayton DynamicLoaderDarwinKernel::Initialize() 768d4bfbc9aSGreg Clayton { 769d4bfbc9aSGreg Clayton PluginManager::RegisterPlugin (GetPluginNameStatic(), 770d4bfbc9aSGreg Clayton GetPluginDescriptionStatic(), 771d4bfbc9aSGreg Clayton CreateInstance); 772d4bfbc9aSGreg Clayton } 773d4bfbc9aSGreg Clayton 774d4bfbc9aSGreg Clayton void 775944b828aSGreg Clayton DynamicLoaderDarwinKernel::Terminate() 776d4bfbc9aSGreg Clayton { 777d4bfbc9aSGreg Clayton PluginManager::UnregisterPlugin (CreateInstance); 778d4bfbc9aSGreg Clayton } 779d4bfbc9aSGreg Clayton 780d4bfbc9aSGreg Clayton 781d4bfbc9aSGreg Clayton const char * 782944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetPluginNameStatic() 783d4bfbc9aSGreg Clayton { 784d4bfbc9aSGreg Clayton return "dynamic-loader.macosx-kernel"; 785d4bfbc9aSGreg Clayton } 786d4bfbc9aSGreg Clayton 787d4bfbc9aSGreg Clayton const char * 788944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetPluginDescriptionStatic() 789d4bfbc9aSGreg Clayton { 790d4bfbc9aSGreg Clayton return "Dynamic loader plug-in that watches for shared library loads/unloads in the MacOSX kernel."; 791d4bfbc9aSGreg Clayton } 792d4bfbc9aSGreg Clayton 793d4bfbc9aSGreg Clayton 794d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 795d4bfbc9aSGreg Clayton // PluginInterface protocol 796d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 797d4bfbc9aSGreg Clayton const char * 798944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetPluginName() 799d4bfbc9aSGreg Clayton { 800944b828aSGreg Clayton return "DynamicLoaderDarwinKernel"; 801d4bfbc9aSGreg Clayton } 802d4bfbc9aSGreg Clayton 803d4bfbc9aSGreg Clayton const char * 804944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetShortPluginName() 805d4bfbc9aSGreg Clayton { 806d4bfbc9aSGreg Clayton return GetPluginNameStatic(); 807d4bfbc9aSGreg Clayton } 808d4bfbc9aSGreg Clayton 809d4bfbc9aSGreg Clayton uint32_t 810944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetPluginVersion() 811d4bfbc9aSGreg Clayton { 812d4bfbc9aSGreg Clayton return 1; 813d4bfbc9aSGreg Clayton } 814d4bfbc9aSGreg Clayton 815