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 157*c859e2d5SGreg Clayton bool 158*c859e2d5SGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageUsingMemoryModule (Process *process) 159*c859e2d5SGreg Clayton { 160*c859e2d5SGreg Clayton if (IsLoaded()) 161*c859e2d5SGreg Clayton return true; 162*c859e2d5SGreg Clayton 163*c859e2d5SGreg Clayton bool uuid_is_valid = uuid.IsValid(); 164*c859e2d5SGreg Clayton 165*c859e2d5SGreg Clayton Target &target = process->GetTarget(); 166*c859e2d5SGreg Clayton ModuleSP memory_module_sp; 167*c859e2d5SGreg Clayton // Use the memory module as the module if we have one... 168*c859e2d5SGreg Clayton if (address != LLDB_INVALID_ADDRESS) 169*c859e2d5SGreg Clayton { 170*c859e2d5SGreg Clayton FileSpec file_spec; 171*c859e2d5SGreg Clayton if (module_sp) 172*c859e2d5SGreg Clayton file_spec = module_sp->GetFileSpec(); 173*c859e2d5SGreg Clayton else 174*c859e2d5SGreg Clayton file_spec.SetFile (name, false); 175*c859e2d5SGreg Clayton 176*c859e2d5SGreg Clayton memory_module_sp = process->ReadModuleFromMemory (file_spec, address, false, false); 177*c859e2d5SGreg Clayton if (memory_module_sp && !uuid_is_valid) 178*c859e2d5SGreg Clayton { 179*c859e2d5SGreg Clayton uuid = memory_module_sp->GetUUID(); 180*c859e2d5SGreg Clayton uuid_is_valid = uuid.IsValid(); 181*c859e2d5SGreg Clayton } 182*c859e2d5SGreg Clayton } 183*c859e2d5SGreg Clayton 184*c859e2d5SGreg Clayton if (!module_sp) 185*c859e2d5SGreg Clayton { 186*c859e2d5SGreg Clayton bool uuid_is_valid = uuid.IsValid(); 187*c859e2d5SGreg Clayton if (uuid_is_valid) 188*c859e2d5SGreg Clayton { 189*c859e2d5SGreg Clayton ModuleList &target_images = target.GetImages(); 190*c859e2d5SGreg Clayton module_sp = target_images.FindModule(uuid); 191*c859e2d5SGreg Clayton 192*c859e2d5SGreg Clayton if (!module_sp) 193*c859e2d5SGreg Clayton module_sp = target.GetSharedModule (FileSpec(), target.GetArchitecture(), &uuid); 194*c859e2d5SGreg Clayton } 195*c859e2d5SGreg Clayton } 196*c859e2d5SGreg Clayton 197*c859e2d5SGreg Clayton 198*c859e2d5SGreg Clayton if (memory_module_sp) 199*c859e2d5SGreg Clayton { 200*c859e2d5SGreg Clayton // Someone already supplied a file, make sure it is the right one. 201*c859e2d5SGreg Clayton if (module_sp) 202*c859e2d5SGreg Clayton { 203*c859e2d5SGreg Clayton if (module_sp->GetUUID() == memory_module_sp->GetUUID()) 204*c859e2d5SGreg Clayton { 205*c859e2d5SGreg Clayton ObjectFile *ondisk_object_file = module_sp->GetObjectFile(); 206*c859e2d5SGreg Clayton ObjectFile *memory_object_file = memory_module_sp->GetObjectFile(); 207*c859e2d5SGreg Clayton if (memory_object_file && ondisk_object_file) 208*c859e2d5SGreg Clayton { 209*c859e2d5SGreg Clayton SectionList *ondisk_section_list = ondisk_object_file->GetSectionList (); 210*c859e2d5SGreg Clayton SectionList *memory_section_list = memory_object_file->GetSectionList (); 211*c859e2d5SGreg Clayton if (memory_section_list && ondisk_section_list) 212*c859e2d5SGreg Clayton { 213*c859e2d5SGreg Clayton const uint32_t num_sections = ondisk_section_list->GetSize(); 214*c859e2d5SGreg Clayton // There may be CTF sections in the memory image so we can't 215*c859e2d5SGreg Clayton // always just compare the number of sections (which are actually 216*c859e2d5SGreg Clayton // segments in mach-o parlance) 217*c859e2d5SGreg Clayton uint32_t sect_idx = 0; 218*c859e2d5SGreg Clayton const Section *memory_section; 219*c859e2d5SGreg Clayton const Section *ondisk_section; 220*c859e2d5SGreg Clayton // Always use the number of sections from the on disk file 221*c859e2d5SGreg Clayton // in case there are extra sections added to the memory image. 222*c859e2d5SGreg Clayton for (sect_idx=0; sect_idx<num_sections; ++sect_idx) 223*c859e2d5SGreg Clayton { 224*c859e2d5SGreg Clayton memory_section = memory_section_list->GetSectionAtIndex(sect_idx).get(); 225*c859e2d5SGreg Clayton ondisk_section = ondisk_section_list->GetSectionAtIndex(sect_idx).get(); 226*c859e2d5SGreg Clayton if (memory_section->GetName() != ondisk_section->GetName()) 227*c859e2d5SGreg Clayton { 228*c859e2d5SGreg Clayton // Section count was the same, but the sections themselves do not match 229*c859e2d5SGreg Clayton module_sp.reset(); 230*c859e2d5SGreg Clayton break; 231*c859e2d5SGreg Clayton } 232*c859e2d5SGreg Clayton } 233*c859e2d5SGreg Clayton if (module_sp) 234*c859e2d5SGreg Clayton { 235*c859e2d5SGreg Clayton for (sect_idx=0; sect_idx<num_sections; ++sect_idx) 236*c859e2d5SGreg Clayton { 237*c859e2d5SGreg Clayton memory_section = memory_section_list->GetSectionAtIndex(sect_idx).get(); 238*c859e2d5SGreg Clayton ondisk_section = ondisk_section_list->GetSectionAtIndex(sect_idx).get(); 239*c859e2d5SGreg Clayton target.GetSectionLoadList().SetSectionLoadAddress (ondisk_section, memory_section->GetFileAddress()); 240*c859e2d5SGreg Clayton } 241*c859e2d5SGreg Clayton if (num_sections > 0) 242*c859e2d5SGreg Clayton load_process_stop_id = process->GetStopID(); 243*c859e2d5SGreg Clayton } 244*c859e2d5SGreg Clayton } 245*c859e2d5SGreg Clayton else 246*c859e2d5SGreg Clayton module_sp.reset(); // One or both section lists 247*c859e2d5SGreg Clayton } 248*c859e2d5SGreg Clayton else 249*c859e2d5SGreg Clayton module_sp.reset(); // One or both object files missing 250*c859e2d5SGreg Clayton } 251*c859e2d5SGreg Clayton else 252*c859e2d5SGreg Clayton module_sp.reset(); // UUID mismatch 253*c859e2d5SGreg Clayton } 254*c859e2d5SGreg Clayton 255*c859e2d5SGreg Clayton // Use the memory module as the module if we didn't like the file 256*c859e2d5SGreg Clayton // module we either found or were supplied with 257*c859e2d5SGreg Clayton if (!module_sp) 258*c859e2d5SGreg Clayton { 259*c859e2d5SGreg Clayton module_sp = memory_module_sp; 260*c859e2d5SGreg Clayton // Load the memory image in the target as all adresses are already correct 261*c859e2d5SGreg Clayton bool changed = false; 262*c859e2d5SGreg Clayton target.GetImages().Append (memory_module_sp); 263*c859e2d5SGreg Clayton if (module_sp->SetLoadAddress (target, 0, changed)) 264*c859e2d5SGreg Clayton load_process_stop_id = process->GetStopID(); 265*c859e2d5SGreg Clayton } 266*c859e2d5SGreg Clayton } 267*c859e2d5SGreg Clayton bool is_loaded = IsLoaded(); 268*c859e2d5SGreg Clayton 269*c859e2d5SGreg Clayton if (so_address.IsValid()) 270*c859e2d5SGreg Clayton { 271*c859e2d5SGreg Clayton if (is_loaded) 272*c859e2d5SGreg Clayton so_address.SetLoadAddress (address, &target); 273*c859e2d5SGreg Clayton else 274*c859e2d5SGreg Clayton target.GetImages().ResolveFileAddress (address, so_address); 275*c859e2d5SGreg Clayton 276*c859e2d5SGreg Clayton } 277*c859e2d5SGreg Clayton return is_loaded; 278*c859e2d5SGreg Clayton } 279*c859e2d5SGreg Clayton 280d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 281d4bfbc9aSGreg Clayton // Load the kernel module and initialize the "m_kernel" member. Return 282d4bfbc9aSGreg Clayton // true _only_ if the kernel is loaded the first time through (subsequent 283d4bfbc9aSGreg Clayton // calls to this function should return false after the kernel has been 284d4bfbc9aSGreg Clayton // already loaded). 285d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 286d4bfbc9aSGreg Clayton void 287944b828aSGreg Clayton DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() 288d4bfbc9aSGreg Clayton { 289d4bfbc9aSGreg Clayton if (!m_kext_summary_header_ptr_addr.IsValid()) 290d4bfbc9aSGreg Clayton { 291d4bfbc9aSGreg Clayton m_kernel.Clear(false); 292d4bfbc9aSGreg Clayton m_kernel.module_sp = m_process->GetTarget().GetExecutableModule(); 293*c859e2d5SGreg Clayton strncpy(m_kernel.name, "mach_kernel", sizeof(m_kernel.name)); 294*c859e2d5SGreg Clayton if (m_kernel.address == LLDB_INVALID_ADDRESS) 295d4bfbc9aSGreg Clayton { 296*c859e2d5SGreg Clayton m_kernel.address = m_process->GetImageInfoAddress (); 297*c859e2d5SGreg Clayton if (m_kernel.address == LLDB_INVALID_ADDRESS && m_kernel.module_sp) 298*c859e2d5SGreg Clayton { 299*c859e2d5SGreg Clayton // We didn't get a hint from the process, so we will 300*c859e2d5SGreg Clayton // try the kernel at the address that it exists at in 301*c859e2d5SGreg Clayton // the file if we have one 302*c859e2d5SGreg Clayton ObjectFile *kernel_object_file = m_kernel.module_sp->GetObjectFile(); 303*c859e2d5SGreg Clayton if (kernel_object_file) 304*c859e2d5SGreg Clayton m_kernel.address = kernel_object_file->GetHeaderAddress().GetFileAddress(); 305*c859e2d5SGreg Clayton } 306*c859e2d5SGreg Clayton } 307*c859e2d5SGreg Clayton 308*c859e2d5SGreg Clayton if (m_kernel.address != LLDB_INVALID_ADDRESS) 309*c859e2d5SGreg Clayton m_kernel.LoadImageUsingMemoryModule (m_process); 310*c859e2d5SGreg Clayton 311*c859e2d5SGreg Clayton if (m_kernel.IsLoaded()) 312*c859e2d5SGreg Clayton { 313d4bfbc9aSGreg Clayton static ConstString kext_summary_symbol ("gLoadedKextSummaries"); 314*c859e2d5SGreg Clayton const Symbol *symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData); 315d4bfbc9aSGreg Clayton if (symbol) 316*c859e2d5SGreg Clayton { 317d4bfbc9aSGreg Clayton m_kext_summary_header_ptr_addr = symbol->GetValue(); 318d4bfbc9aSGreg Clayton // Update all image infos 319d4bfbc9aSGreg Clayton ReadAllKextSummaries (); 320d4bfbc9aSGreg Clayton } 321d4bfbc9aSGreg Clayton } 322d4bfbc9aSGreg Clayton else 323d4bfbc9aSGreg Clayton { 324d4bfbc9aSGreg Clayton m_kernel.Clear(false); 325d4bfbc9aSGreg Clayton } 326d4bfbc9aSGreg Clayton } 327d4bfbc9aSGreg Clayton } 328d4bfbc9aSGreg Clayton 329d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 330d4bfbc9aSGreg Clayton // Static callback function that gets called when our DYLD notification 331d4bfbc9aSGreg Clayton // breakpoint gets hit. We update all of our image infos and then 332d4bfbc9aSGreg Clayton // let our super class DynamicLoader class decide if we should stop 333d4bfbc9aSGreg Clayton // or not (based on global preference). 334d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 335d4bfbc9aSGreg Clayton bool 336944b828aSGreg Clayton DynamicLoaderDarwinKernel::BreakpointHitCallback (void *baton, 337d4bfbc9aSGreg Clayton StoppointCallbackContext *context, 338d4bfbc9aSGreg Clayton user_id_t break_id, 339d4bfbc9aSGreg Clayton user_id_t break_loc_id) 340d4bfbc9aSGreg Clayton { 341944b828aSGreg Clayton return static_cast<DynamicLoaderDarwinKernel*>(baton)->BreakpointHit (context, break_id, break_loc_id); 342d4bfbc9aSGreg Clayton } 343d4bfbc9aSGreg Clayton 344d4bfbc9aSGreg Clayton bool 345944b828aSGreg Clayton DynamicLoaderDarwinKernel::BreakpointHit (StoppointCallbackContext *context, 346d4bfbc9aSGreg Clayton user_id_t break_id, 347d4bfbc9aSGreg Clayton user_id_t break_loc_id) 348d4bfbc9aSGreg Clayton { 349d4bfbc9aSGreg Clayton LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 350d4bfbc9aSGreg Clayton if (log) 351944b828aSGreg Clayton log->Printf ("DynamicLoaderDarwinKernel::BreakpointHit (...)\n"); 352d4bfbc9aSGreg Clayton 353d4bfbc9aSGreg Clayton ReadAllKextSummaries (); 354d4bfbc9aSGreg Clayton 355d4bfbc9aSGreg Clayton if (log) 356d4bfbc9aSGreg Clayton PutToLog(log.get()); 357d4bfbc9aSGreg Clayton 358d4bfbc9aSGreg Clayton return GetStopWhenImagesChange(); 359d4bfbc9aSGreg Clayton } 360d4bfbc9aSGreg Clayton 361d4bfbc9aSGreg Clayton 362d4bfbc9aSGreg Clayton bool 363944b828aSGreg Clayton DynamicLoaderDarwinKernel::ReadKextSummaryHeader () 364d4bfbc9aSGreg Clayton { 365d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 366d4bfbc9aSGreg Clayton 367d4bfbc9aSGreg Clayton // the all image infos is already valid for this process stop ID 368d4bfbc9aSGreg Clayton 369d4bfbc9aSGreg Clayton m_kext_summaries.clear(); 370d4bfbc9aSGreg Clayton if (m_kext_summary_header_ptr_addr.IsValid()) 371d4bfbc9aSGreg Clayton { 372d4bfbc9aSGreg Clayton const uint32_t addr_size = m_kernel.GetAddressByteSize (); 373d4bfbc9aSGreg Clayton const ByteOrder byte_order = m_kernel.GetByteOrder(); 374d4bfbc9aSGreg Clayton Error error; 375d4bfbc9aSGreg Clayton // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure 376d4bfbc9aSGreg Clayton // which is currenty 4 uint32_t and a pointer. 377d4bfbc9aSGreg Clayton uint8_t buf[24]; 378d4bfbc9aSGreg Clayton DataExtractor data (buf, sizeof(buf), byte_order, addr_size); 379d4bfbc9aSGreg Clayton const size_t count = 4 * sizeof(uint32_t) + addr_size; 380d4bfbc9aSGreg Clayton const bool prefer_file_cache = false; 381d4bfbc9aSGreg Clayton if (m_process->GetTarget().ReadPointerFromMemory (m_kext_summary_header_ptr_addr, 382d4bfbc9aSGreg Clayton prefer_file_cache, 383d4bfbc9aSGreg Clayton error, 384d4bfbc9aSGreg Clayton m_kext_summary_header_addr)) 385d4bfbc9aSGreg Clayton { 386d4bfbc9aSGreg Clayton // We got a valid address for our kext summary header and make sure it isn't NULL 387d4bfbc9aSGreg Clayton if (m_kext_summary_header_addr.IsValid() && 388d4bfbc9aSGreg Clayton m_kext_summary_header_addr.GetFileAddress() != 0) 389d4bfbc9aSGreg Clayton { 390d4bfbc9aSGreg Clayton const size_t bytes_read = m_process->GetTarget().ReadMemory (m_kext_summary_header_addr, prefer_file_cache, buf, count, error); 391d4bfbc9aSGreg Clayton if (bytes_read == count) 392d4bfbc9aSGreg Clayton { 393d4bfbc9aSGreg Clayton uint32_t offset = 0; 394d4bfbc9aSGreg Clayton m_kext_summary_header.version = data.GetU32(&offset); 395d4bfbc9aSGreg Clayton if (m_kext_summary_header.version >= 2) 396d4bfbc9aSGreg Clayton { 397d4bfbc9aSGreg Clayton m_kext_summary_header.entry_size = data.GetU32(&offset); 398d4bfbc9aSGreg Clayton } 399d4bfbc9aSGreg Clayton else 400d4bfbc9aSGreg Clayton { 401d4bfbc9aSGreg Clayton // Versions less than 2 didn't have an entry size, it was hard coded 402d4bfbc9aSGreg Clayton m_kext_summary_header.entry_size = KERNEL_MODULE_ENTRY_SIZE_VERSION_1; 403d4bfbc9aSGreg Clayton } 404d4bfbc9aSGreg Clayton m_kext_summary_header.entry_count = data.GetU32(&offset); 405d4bfbc9aSGreg Clayton return true; 406d4bfbc9aSGreg Clayton } 407d4bfbc9aSGreg Clayton } 408d4bfbc9aSGreg Clayton } 409d4bfbc9aSGreg Clayton } 410d4bfbc9aSGreg Clayton m_kext_summary_header_addr.Clear(); 411d4bfbc9aSGreg Clayton return false; 412d4bfbc9aSGreg Clayton } 413d4bfbc9aSGreg Clayton 414d4bfbc9aSGreg Clayton 415d4bfbc9aSGreg Clayton bool 416944b828aSGreg Clayton DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr, 417d4bfbc9aSGreg Clayton uint32_t count) 418d4bfbc9aSGreg Clayton { 419d4bfbc9aSGreg Clayton OSKextLoadedKextSummary::collection kext_summaries; 420d4bfbc9aSGreg Clayton LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 421d4bfbc9aSGreg Clayton if (log) 422fd54b368SJason Molenda log->Printf ("Adding %d modules.\n", count); 423d4bfbc9aSGreg Clayton 424d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 425d4bfbc9aSGreg Clayton 426d4bfbc9aSGreg Clayton if (!ReadKextSummaries (kext_summary_addr, count, kext_summaries)) 427d4bfbc9aSGreg Clayton return false; 428d4bfbc9aSGreg Clayton 429d4bfbc9aSGreg Clayton Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream(); 430d4bfbc9aSGreg Clayton for (uint32_t i = 0; i < count; i++) 431d4bfbc9aSGreg Clayton { 432d4bfbc9aSGreg Clayton if (s) 433d4bfbc9aSGreg Clayton { 434d4bfbc9aSGreg Clayton const uint8_t *u = (const uint8_t *)kext_summaries[i].uuid.GetBytes(); 435d4bfbc9aSGreg Clayton if (u) 436d4bfbc9aSGreg Clayton { 4370ca4f8bbSJason 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\"...", 438d4bfbc9aSGreg Clayton u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7], 439d4bfbc9aSGreg Clayton u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15], 440d4bfbc9aSGreg Clayton kext_summaries[i].address, kext_summaries[i].name); 441d4bfbc9aSGreg Clayton } 442d4bfbc9aSGreg Clayton else 443d4bfbc9aSGreg Clayton { 4440ca4f8bbSJason Molenda s->Printf("0x%16.16llx \"%s\"...", kext_summaries[i].address, kext_summaries[i].name); 445d4bfbc9aSGreg Clayton } 446d4bfbc9aSGreg Clayton } 447d4bfbc9aSGreg Clayton 448*c859e2d5SGreg Clayton kext_summaries[i].LoadImageUsingMemoryModule (m_process); 449d4bfbc9aSGreg Clayton 450d4bfbc9aSGreg Clayton if (s) 451d4bfbc9aSGreg Clayton { 452d4bfbc9aSGreg Clayton if (kext_summaries[i].module_sp) 453*c859e2d5SGreg Clayton { 454*c859e2d5SGreg Clayton if (kext_summaries[i].module_sp->GetFileSpec().GetDirectory()) 4550ca4f8bbSJason Molenda s->Printf("\n found kext: %s/%s\n", 456d4bfbc9aSGreg Clayton kext_summaries[i].module_sp->GetFileSpec().GetDirectory().AsCString(), 457d4bfbc9aSGreg Clayton kext_summaries[i].module_sp->GetFileSpec().GetFilename().AsCString()); 4580ca4f8bbSJason Molenda else 459*c859e2d5SGreg Clayton s->Printf("\n found kext: %s\n", 460*c859e2d5SGreg Clayton kext_summaries[i].module_sp->GetFileSpec().GetFilename().AsCString()); 461*c859e2d5SGreg Clayton } 462*c859e2d5SGreg Clayton else 4630ca4f8bbSJason Molenda s->Printf (" failed to locate/load.\n"); 464d4bfbc9aSGreg Clayton } 465d4bfbc9aSGreg Clayton 466d4bfbc9aSGreg Clayton if (log) 467d4bfbc9aSGreg Clayton kext_summaries[i].PutToLog (log.get()); 468d4bfbc9aSGreg Clayton } 469d4bfbc9aSGreg Clayton bool return_value = AddModulesUsingImageInfos (kext_summaries); 470d4bfbc9aSGreg Clayton return return_value; 471d4bfbc9aSGreg Clayton } 472d4bfbc9aSGreg Clayton 473d4bfbc9aSGreg Clayton // Adds the modules in image_infos to m_kext_summaries. 474d4bfbc9aSGreg Clayton // NB don't call this passing in m_kext_summaries. 475d4bfbc9aSGreg Clayton 476d4bfbc9aSGreg Clayton bool 477944b828aSGreg Clayton DynamicLoaderDarwinKernel::AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos) 478d4bfbc9aSGreg Clayton { 479d4bfbc9aSGreg Clayton // Now add these images to the main list. 480d4bfbc9aSGreg Clayton ModuleList loaded_module_list; 481d4bfbc9aSGreg Clayton 482d4bfbc9aSGreg Clayton for (uint32_t idx = 0; idx < image_infos.size(); ++idx) 483d4bfbc9aSGreg Clayton { 484*c859e2d5SGreg Clayton OSKextLoadedKextSummary &image_info = image_infos[idx]; 485*c859e2d5SGreg Clayton m_kext_summaries.push_back(image_info); 486d4bfbc9aSGreg Clayton 487*c859e2d5SGreg Clayton if (image_info.module_sp && m_process->GetStopID() == image_info.load_process_stop_id) 488d4bfbc9aSGreg Clayton loaded_module_list.AppendIfNeeded (image_infos[idx].module_sp); 489d4bfbc9aSGreg Clayton } 490d4bfbc9aSGreg Clayton 491d4bfbc9aSGreg Clayton if (loaded_module_list.GetSize() > 0) 492d4bfbc9aSGreg Clayton { 493d4bfbc9aSGreg Clayton // FIXME: This should really be in the Runtime handlers class, which should get 494d4bfbc9aSGreg Clayton // called by the target's ModulesDidLoad, but we're doing it all locally for now 495d4bfbc9aSGreg Clayton // to save time. 496d4bfbc9aSGreg Clayton // Also, I'm assuming there can be only one libobjc dylib loaded... 497d4bfbc9aSGreg Clayton 498d4bfbc9aSGreg Clayton ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime(); 499d4bfbc9aSGreg Clayton if (objc_runtime != NULL && !objc_runtime->HasReadObjCLibrary()) 500d4bfbc9aSGreg Clayton { 501d4bfbc9aSGreg Clayton size_t num_modules = loaded_module_list.GetSize(); 502d4bfbc9aSGreg Clayton for (int i = 0; i < num_modules; i++) 503d4bfbc9aSGreg Clayton { 504d4bfbc9aSGreg Clayton if (objc_runtime->IsModuleObjCLibrary (loaded_module_list.GetModuleAtIndex (i))) 505d4bfbc9aSGreg Clayton { 506d4bfbc9aSGreg Clayton objc_runtime->ReadObjCLibrary (loaded_module_list.GetModuleAtIndex (i)); 507d4bfbc9aSGreg Clayton break; 508d4bfbc9aSGreg Clayton } 509d4bfbc9aSGreg Clayton } 510d4bfbc9aSGreg Clayton } 511d4bfbc9aSGreg Clayton // if (log) 512944b828aSGreg Clayton // loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderDarwinKernel::ModulesDidLoad"); 513d4bfbc9aSGreg Clayton m_process->GetTarget().ModulesDidLoad (loaded_module_list); 514d4bfbc9aSGreg Clayton } 515d4bfbc9aSGreg Clayton return true; 516d4bfbc9aSGreg Clayton } 517d4bfbc9aSGreg Clayton 518d4bfbc9aSGreg Clayton 519d4bfbc9aSGreg Clayton uint32_t 520944b828aSGreg Clayton DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr, 521d4bfbc9aSGreg Clayton uint32_t image_infos_count, 522d4bfbc9aSGreg Clayton OSKextLoadedKextSummary::collection &image_infos) 523d4bfbc9aSGreg Clayton { 524d4bfbc9aSGreg Clayton const ByteOrder endian = m_kernel.GetByteOrder(); 525d4bfbc9aSGreg Clayton const uint32_t addr_size = m_kernel.GetAddressByteSize(); 526d4bfbc9aSGreg Clayton 527d4bfbc9aSGreg Clayton image_infos.resize(image_infos_count); 528d4bfbc9aSGreg Clayton const size_t count = image_infos.size() * m_kext_summary_header.entry_size; 529d4bfbc9aSGreg Clayton DataBufferHeap data(count, 0); 530d4bfbc9aSGreg Clayton Error error; 531d4bfbc9aSGreg Clayton 532d4bfbc9aSGreg Clayton Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream(); 533d4bfbc9aSGreg Clayton 534d4bfbc9aSGreg Clayton if (s) 535d4bfbc9aSGreg Clayton s->Printf ("Reading %u kext summaries...\n", image_infos_count); 536d4bfbc9aSGreg Clayton const bool prefer_file_cache = false; 537d4bfbc9aSGreg Clayton const size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary_addr, 538d4bfbc9aSGreg Clayton prefer_file_cache, 539d4bfbc9aSGreg Clayton data.GetBytes(), 540d4bfbc9aSGreg Clayton data.GetByteSize(), 541d4bfbc9aSGreg Clayton error); 542d4bfbc9aSGreg Clayton if (bytes_read == count) 543d4bfbc9aSGreg Clayton { 544d4bfbc9aSGreg Clayton 545d4bfbc9aSGreg Clayton DataExtractor extractor (data.GetBytes(), data.GetByteSize(), endian, addr_size); 546d4bfbc9aSGreg Clayton uint32_t i=0; 547d4bfbc9aSGreg Clayton for (uint32_t kext_summary_offset = 0; 548d4bfbc9aSGreg Clayton i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size); 549d4bfbc9aSGreg Clayton ++i, kext_summary_offset += m_kext_summary_header.entry_size) 550d4bfbc9aSGreg Clayton { 551d4bfbc9aSGreg Clayton uint32_t offset = kext_summary_offset; 552d4bfbc9aSGreg Clayton const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME); 553d4bfbc9aSGreg Clayton if (name_data == NULL) 554d4bfbc9aSGreg Clayton break; 555d4bfbc9aSGreg Clayton memcpy (image_infos[i].name, name_data, KERNEL_MODULE_MAX_NAME); 556d4bfbc9aSGreg Clayton image_infos[i].uuid.SetBytes(extractor.GetData (&offset, 16)); 557d4bfbc9aSGreg Clayton image_infos[i].address = extractor.GetU64(&offset); 558d4bfbc9aSGreg Clayton if (!image_infos[i].so_address.SetLoadAddress (image_infos[i].address, &m_process->GetTarget())) 559d4bfbc9aSGreg Clayton m_process->GetTarget().GetImages().ResolveFileAddress (image_infos[i].address, image_infos[i].so_address); 560d4bfbc9aSGreg Clayton image_infos[i].size = extractor.GetU64(&offset); 561d4bfbc9aSGreg Clayton image_infos[i].version = extractor.GetU64(&offset); 562d4bfbc9aSGreg Clayton image_infos[i].load_tag = extractor.GetU32(&offset); 563d4bfbc9aSGreg Clayton image_infos[i].flags = extractor.GetU32(&offset); 564d4bfbc9aSGreg Clayton if ((offset - kext_summary_offset) < m_kext_summary_header.entry_size) 565d4bfbc9aSGreg Clayton { 566d4bfbc9aSGreg Clayton image_infos[i].reference_list = extractor.GetU64(&offset); 567d4bfbc9aSGreg Clayton } 568d4bfbc9aSGreg Clayton else 569d4bfbc9aSGreg Clayton { 570d4bfbc9aSGreg Clayton image_infos[i].reference_list = 0; 571d4bfbc9aSGreg Clayton } 572*c859e2d5SGreg 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", 573*c859e2d5SGreg Clayton i, 574*c859e2d5SGreg Clayton KERNEL_MODULE_MAX_NAME, KERNEL_MODULE_MAX_NAME, (char *)name_data, 575*c859e2d5SGreg Clayton image_infos[i].address, 576*c859e2d5SGreg Clayton image_infos[i].size, 577*c859e2d5SGreg Clayton image_infos[i].version, 578*c859e2d5SGreg Clayton image_infos[i].load_tag, 579*c859e2d5SGreg Clayton image_infos[i].flags); 580d4bfbc9aSGreg Clayton } 581d4bfbc9aSGreg Clayton if (i < image_infos.size()) 582d4bfbc9aSGreg Clayton image_infos.resize(i); 583d4bfbc9aSGreg Clayton } 584d4bfbc9aSGreg Clayton else 585d4bfbc9aSGreg Clayton { 586d4bfbc9aSGreg Clayton image_infos.clear(); 587d4bfbc9aSGreg Clayton } 588d4bfbc9aSGreg Clayton return image_infos.size(); 589d4bfbc9aSGreg Clayton } 590d4bfbc9aSGreg Clayton 591d4bfbc9aSGreg Clayton bool 592944b828aSGreg Clayton DynamicLoaderDarwinKernel::ReadAllKextSummaries () 593d4bfbc9aSGreg Clayton { 594d4bfbc9aSGreg Clayton LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 595d4bfbc9aSGreg Clayton 596d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 597d4bfbc9aSGreg Clayton 598d4bfbc9aSGreg Clayton if (ReadKextSummaryHeader ()) 599d4bfbc9aSGreg Clayton { 600d4bfbc9aSGreg Clayton if (m_kext_summary_header.entry_count > 0 && m_kext_summary_header_addr.IsValid()) 601d4bfbc9aSGreg Clayton { 602d4bfbc9aSGreg Clayton Address summary_addr (m_kext_summary_header_addr); 603d4bfbc9aSGreg Clayton summary_addr.Slide(m_kext_summary_header.GetSize()); 604d4bfbc9aSGreg Clayton if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count)) 605d4bfbc9aSGreg Clayton { 606d4bfbc9aSGreg Clayton m_kext_summaries.clear(); 607d4bfbc9aSGreg Clayton } 608d4bfbc9aSGreg Clayton return true; 609d4bfbc9aSGreg Clayton } 610d4bfbc9aSGreg Clayton } 611d4bfbc9aSGreg Clayton return false; 612d4bfbc9aSGreg Clayton } 613d4bfbc9aSGreg Clayton 614d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 615d4bfbc9aSGreg Clayton // Dump an image info structure to the file handle provided. 616d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 617d4bfbc9aSGreg Clayton void 618944b828aSGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::PutToLog (Log *log) const 619d4bfbc9aSGreg Clayton { 620d4bfbc9aSGreg Clayton if (log == NULL) 621d4bfbc9aSGreg Clayton return; 622d4bfbc9aSGreg Clayton const uint8_t *u = (uint8_t *)uuid.GetBytes(); 623d4bfbc9aSGreg Clayton 624d4bfbc9aSGreg Clayton if (address == LLDB_INVALID_ADDRESS) 625d4bfbc9aSGreg Clayton { 626d4bfbc9aSGreg Clayton if (u) 627d4bfbc9aSGreg Clayton { 628d4bfbc9aSGreg 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)", 629d4bfbc9aSGreg Clayton u[ 0], u[ 1], u[ 2], u[ 3], 630d4bfbc9aSGreg Clayton u[ 4], u[ 5], u[ 6], u[ 7], 631d4bfbc9aSGreg Clayton u[ 8], u[ 9], u[10], u[11], 632d4bfbc9aSGreg Clayton u[12], u[13], u[14], u[15], 633d4bfbc9aSGreg Clayton name); 634d4bfbc9aSGreg Clayton } 635d4bfbc9aSGreg Clayton else 636d4bfbc9aSGreg Clayton log->Printf("\tname=\"%s\" (UNLOADED)", name); 637d4bfbc9aSGreg Clayton } 638d4bfbc9aSGreg Clayton else 639d4bfbc9aSGreg Clayton { 640d4bfbc9aSGreg Clayton if (u) 641d4bfbc9aSGreg Clayton { 642d4bfbc9aSGreg 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\"", 643d4bfbc9aSGreg Clayton address, size, version, load_tag, flags, reference_list, 644d4bfbc9aSGreg Clayton u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7], 645d4bfbc9aSGreg Clayton u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15], 646d4bfbc9aSGreg Clayton name); 647d4bfbc9aSGreg Clayton } 648d4bfbc9aSGreg Clayton else 649d4bfbc9aSGreg Clayton { 650d4bfbc9aSGreg 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\"", 651d4bfbc9aSGreg Clayton address, address+size, version, load_tag, flags, reference_list, 652d4bfbc9aSGreg Clayton name); 653d4bfbc9aSGreg Clayton } 654d4bfbc9aSGreg Clayton } 655d4bfbc9aSGreg Clayton } 656d4bfbc9aSGreg Clayton 657d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 658d4bfbc9aSGreg Clayton // Dump the _dyld_all_image_infos members and all current image infos 659d4bfbc9aSGreg Clayton // that we have parsed to the file handle provided. 660d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 661d4bfbc9aSGreg Clayton void 662944b828aSGreg Clayton DynamicLoaderDarwinKernel::PutToLog(Log *log) const 663d4bfbc9aSGreg Clayton { 664d4bfbc9aSGreg Clayton if (log == NULL) 665d4bfbc9aSGreg Clayton return; 666d4bfbc9aSGreg Clayton 667d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 668d4bfbc9aSGreg Clayton log->Printf("gLoadedKextSummaries = 0x%16.16llx { version=%u, entry_size=%u, entry_count=%u }", 669d4bfbc9aSGreg Clayton m_kext_summary_header_addr.GetFileAddress(), 670d4bfbc9aSGreg Clayton m_kext_summary_header.version, 671d4bfbc9aSGreg Clayton m_kext_summary_header.entry_size, 672d4bfbc9aSGreg Clayton m_kext_summary_header.entry_count); 673d4bfbc9aSGreg Clayton 674d4bfbc9aSGreg Clayton size_t i; 675d4bfbc9aSGreg Clayton const size_t count = m_kext_summaries.size(); 676d4bfbc9aSGreg Clayton if (count > 0) 677d4bfbc9aSGreg Clayton { 678d4bfbc9aSGreg Clayton log->PutCString("Loaded:"); 679d4bfbc9aSGreg Clayton for (i = 0; i<count; i++) 680d4bfbc9aSGreg Clayton m_kext_summaries[i].PutToLog(log); 681d4bfbc9aSGreg Clayton } 682d4bfbc9aSGreg Clayton } 683d4bfbc9aSGreg Clayton 684d4bfbc9aSGreg Clayton void 685944b828aSGreg Clayton DynamicLoaderDarwinKernel::PrivateInitialize(Process *process) 686d4bfbc9aSGreg Clayton { 687944b828aSGreg Clayton DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); 688d4bfbc9aSGreg Clayton Clear(true); 689d4bfbc9aSGreg Clayton m_process = process; 690d4bfbc9aSGreg Clayton m_process->GetTarget().GetSectionLoadList().Clear(); 691d4bfbc9aSGreg Clayton } 692d4bfbc9aSGreg Clayton 693d4bfbc9aSGreg Clayton void 694944b828aSGreg Clayton DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded () 695d4bfbc9aSGreg Clayton { 696*c859e2d5SGreg Clayton if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.module_sp) 697d4bfbc9aSGreg Clayton { 698944b828aSGreg Clayton DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); 699d4bfbc9aSGreg Clayton 700d4bfbc9aSGreg Clayton 701d4bfbc9aSGreg Clayton const bool internal_bp = false; 702d4bfbc9aSGreg Clayton const LazyBool skip_prologue = eLazyBoolNo; 703969795f1SJim Ingham FileSpecList module_spec_list; 704969795f1SJim Ingham module_spec_list.Append (m_kernel.module_sp->GetFileSpec()); 705969795f1SJim Ingham Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&module_spec_list, 70687df91b8SJim Ingham NULL, 707d4bfbc9aSGreg Clayton "OSKextLoadedKextSummariesUpdated", 708d4bfbc9aSGreg Clayton eFunctionNameTypeFull, 709d4bfbc9aSGreg Clayton internal_bp, 710d4bfbc9aSGreg Clayton skip_prologue).get(); 711d4bfbc9aSGreg Clayton 712944b828aSGreg Clayton bp->SetCallback (DynamicLoaderDarwinKernel::BreakpointHitCallback, this, true); 713d4bfbc9aSGreg Clayton m_break_id = bp->GetID(); 714d4bfbc9aSGreg Clayton } 715d4bfbc9aSGreg Clayton } 716d4bfbc9aSGreg Clayton 717d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 718d4bfbc9aSGreg Clayton // Member function that gets called when the process state changes. 719d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 720d4bfbc9aSGreg Clayton void 721944b828aSGreg Clayton DynamicLoaderDarwinKernel::PrivateProcessStateChanged (Process *process, StateType state) 722d4bfbc9aSGreg Clayton { 723944b828aSGreg Clayton DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__, StateAsCString(state)); 724d4bfbc9aSGreg Clayton switch (state) 725d4bfbc9aSGreg Clayton { 726d4bfbc9aSGreg Clayton case eStateConnected: 727d4bfbc9aSGreg Clayton case eStateAttaching: 728d4bfbc9aSGreg Clayton case eStateLaunching: 729d4bfbc9aSGreg Clayton case eStateInvalid: 730d4bfbc9aSGreg Clayton case eStateUnloaded: 731d4bfbc9aSGreg Clayton case eStateExited: 732d4bfbc9aSGreg Clayton case eStateDetached: 733d4bfbc9aSGreg Clayton Clear(false); 734d4bfbc9aSGreg Clayton break; 735d4bfbc9aSGreg Clayton 736d4bfbc9aSGreg Clayton case eStateStopped: 737d4bfbc9aSGreg Clayton UpdateIfNeeded(); 738d4bfbc9aSGreg Clayton break; 739d4bfbc9aSGreg Clayton 740d4bfbc9aSGreg Clayton case eStateRunning: 741d4bfbc9aSGreg Clayton case eStateStepping: 742d4bfbc9aSGreg Clayton case eStateCrashed: 743d4bfbc9aSGreg Clayton case eStateSuspended: 744d4bfbc9aSGreg Clayton break; 745d4bfbc9aSGreg Clayton 746d4bfbc9aSGreg Clayton default: 747d4bfbc9aSGreg Clayton break; 748d4bfbc9aSGreg Clayton } 749d4bfbc9aSGreg Clayton } 750d4bfbc9aSGreg Clayton 751d4bfbc9aSGreg Clayton ThreadPlanSP 752944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) 753d4bfbc9aSGreg Clayton { 754d4bfbc9aSGreg Clayton ThreadPlanSP thread_plan_sp; 755d4bfbc9aSGreg Clayton LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 756d4bfbc9aSGreg Clayton if (log) 757d4bfbc9aSGreg Clayton log->Printf ("Could not find symbol for step through."); 758d4bfbc9aSGreg Clayton return thread_plan_sp; 759d4bfbc9aSGreg Clayton } 760d4bfbc9aSGreg Clayton 761d4bfbc9aSGreg Clayton Error 762944b828aSGreg Clayton DynamicLoaderDarwinKernel::CanLoadImage () 763d4bfbc9aSGreg Clayton { 764d4bfbc9aSGreg Clayton Error error; 765d4bfbc9aSGreg Clayton error.SetErrorString("always unsafe to load or unload shared libraries in the darwin kernel"); 766d4bfbc9aSGreg Clayton return error; 767d4bfbc9aSGreg Clayton } 768d4bfbc9aSGreg Clayton 769d4bfbc9aSGreg Clayton void 770944b828aSGreg Clayton DynamicLoaderDarwinKernel::Initialize() 771d4bfbc9aSGreg Clayton { 772d4bfbc9aSGreg Clayton PluginManager::RegisterPlugin (GetPluginNameStatic(), 773d4bfbc9aSGreg Clayton GetPluginDescriptionStatic(), 774d4bfbc9aSGreg Clayton CreateInstance); 775d4bfbc9aSGreg Clayton } 776d4bfbc9aSGreg Clayton 777d4bfbc9aSGreg Clayton void 778944b828aSGreg Clayton DynamicLoaderDarwinKernel::Terminate() 779d4bfbc9aSGreg Clayton { 780d4bfbc9aSGreg Clayton PluginManager::UnregisterPlugin (CreateInstance); 781d4bfbc9aSGreg Clayton } 782d4bfbc9aSGreg Clayton 783d4bfbc9aSGreg Clayton 784d4bfbc9aSGreg Clayton const char * 785944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetPluginNameStatic() 786d4bfbc9aSGreg Clayton { 787d4bfbc9aSGreg Clayton return "dynamic-loader.macosx-kernel"; 788d4bfbc9aSGreg Clayton } 789d4bfbc9aSGreg Clayton 790d4bfbc9aSGreg Clayton const char * 791944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetPluginDescriptionStatic() 792d4bfbc9aSGreg Clayton { 793d4bfbc9aSGreg Clayton return "Dynamic loader plug-in that watches for shared library loads/unloads in the MacOSX kernel."; 794d4bfbc9aSGreg Clayton } 795d4bfbc9aSGreg Clayton 796d4bfbc9aSGreg Clayton 797d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 798d4bfbc9aSGreg Clayton // PluginInterface protocol 799d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 800d4bfbc9aSGreg Clayton const char * 801944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetPluginName() 802d4bfbc9aSGreg Clayton { 803944b828aSGreg Clayton return "DynamicLoaderDarwinKernel"; 804d4bfbc9aSGreg Clayton } 805d4bfbc9aSGreg Clayton 806d4bfbc9aSGreg Clayton const char * 807944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetShortPluginName() 808d4bfbc9aSGreg Clayton { 809d4bfbc9aSGreg Clayton return GetPluginNameStatic(); 810d4bfbc9aSGreg Clayton } 811d4bfbc9aSGreg Clayton 812d4bfbc9aSGreg Clayton uint32_t 813944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetPluginVersion() 814d4bfbc9aSGreg Clayton { 815d4bfbc9aSGreg Clayton return 1; 816d4bfbc9aSGreg Clayton } 817d4bfbc9aSGreg Clayton 818