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" 161f746071SGreg Clayton #include "lldb/Core/ModuleSpec.h" 17d4bfbc9aSGreg Clayton #include "lldb/Core/PluginManager.h" 181f746071SGreg Clayton #include "lldb/Core/Section.h" 19d4bfbc9aSGreg Clayton #include "lldb/Core/State.h" 20d4bfbc9aSGreg Clayton #include "lldb/Symbol/ObjectFile.h" 21d4bfbc9aSGreg Clayton #include "lldb/Target/ObjCLanguageRuntime.h" 22d4bfbc9aSGreg Clayton #include "lldb/Target/RegisterContext.h" 23d4bfbc9aSGreg Clayton #include "lldb/Target/Target.h" 24d4bfbc9aSGreg Clayton #include "lldb/Target/Thread.h" 25d4bfbc9aSGreg Clayton #include "lldb/Target/ThreadPlanRunToAddress.h" 26d4bfbc9aSGreg Clayton #include "lldb/Target/StackFrame.h" 27d4bfbc9aSGreg Clayton 28944b828aSGreg Clayton #include "DynamicLoaderDarwinKernel.h" 29d4bfbc9aSGreg Clayton 30d4bfbc9aSGreg Clayton //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN 31d4bfbc9aSGreg Clayton #ifdef ENABLE_DEBUG_PRINTF 32d4bfbc9aSGreg Clayton #include <stdio.h> 33d4bfbc9aSGreg Clayton #define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__) 34d4bfbc9aSGreg Clayton #else 35d4bfbc9aSGreg Clayton #define DEBUG_PRINTF(fmt, ...) 36d4bfbc9aSGreg Clayton #endif 37d4bfbc9aSGreg Clayton 38d4bfbc9aSGreg Clayton using namespace lldb; 39d4bfbc9aSGreg Clayton using namespace lldb_private; 40d4bfbc9aSGreg Clayton 41d4bfbc9aSGreg Clayton /// FIXME - The ObjC Runtime trampoline handler doesn't really belong here. 42d4bfbc9aSGreg Clayton /// I am putting it here so I can invoke it in the Trampoline code here, but 43d4bfbc9aSGreg Clayton /// it should be moved to the ObjC Runtime support when it is set up. 44d4bfbc9aSGreg Clayton 45d4bfbc9aSGreg Clayton 46d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 47d4bfbc9aSGreg Clayton // Create an instance of this class. This function is filled into 48d4bfbc9aSGreg Clayton // the plugin info class that gets handed out by the plugin factory and 49d4bfbc9aSGreg Clayton // allows the lldb to instantiate an instance of this class. 50d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 51d4bfbc9aSGreg Clayton DynamicLoader * 52944b828aSGreg Clayton DynamicLoaderDarwinKernel::CreateInstance (Process* process, bool force) 53d4bfbc9aSGreg Clayton { 54d4bfbc9aSGreg Clayton bool create = force; 55d4bfbc9aSGreg Clayton if (!create) 56d4bfbc9aSGreg Clayton { 57d4bfbc9aSGreg Clayton Module* exe_module = process->GetTarget().GetExecutableModulePointer(); 58d4bfbc9aSGreg Clayton if (exe_module) 59d4bfbc9aSGreg Clayton { 60d4bfbc9aSGreg Clayton ObjectFile *object_file = exe_module->GetObjectFile(); 61d4bfbc9aSGreg Clayton if (object_file) 62d4bfbc9aSGreg Clayton { 6349bce8ecSSean Callanan create = (object_file->GetStrata() == ObjectFile::eStrataKernel); 64d4bfbc9aSGreg Clayton } 65d4bfbc9aSGreg Clayton } 66d4bfbc9aSGreg Clayton 67d4bfbc9aSGreg Clayton if (create) 68d4bfbc9aSGreg Clayton { 69d4bfbc9aSGreg Clayton const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple(); 7070512317SGreg Clayton switch (triple_ref.getOS()) 7170512317SGreg Clayton { 7270512317SGreg Clayton case llvm::Triple::Darwin: 7370512317SGreg Clayton case llvm::Triple::MacOSX: 7470512317SGreg Clayton case llvm::Triple::IOS: 7570512317SGreg Clayton create = triple_ref.getVendor() == llvm::Triple::Apple; 7670512317SGreg Clayton break; 7770512317SGreg Clayton default: 7870512317SGreg Clayton create = false; 7970512317SGreg Clayton break; 8070512317SGreg Clayton } 81d4bfbc9aSGreg Clayton } 82d4bfbc9aSGreg Clayton } 83d4bfbc9aSGreg Clayton 84d4bfbc9aSGreg Clayton if (create) 8590539456SSean Callanan { 8690539456SSean Callanan process->SetCanJIT(false); 87944b828aSGreg Clayton return new DynamicLoaderDarwinKernel (process); 8890539456SSean Callanan } 89d4bfbc9aSGreg Clayton return NULL; 90d4bfbc9aSGreg Clayton } 91d4bfbc9aSGreg Clayton 92d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 93d4bfbc9aSGreg Clayton // Constructor 94d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 95944b828aSGreg Clayton DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel (Process* process) : 96d4bfbc9aSGreg Clayton DynamicLoader(process), 97d4bfbc9aSGreg Clayton m_kernel(), 98d4bfbc9aSGreg Clayton m_kext_summary_header_ptr_addr (), 99d4bfbc9aSGreg Clayton m_kext_summary_header_addr (), 100d4bfbc9aSGreg Clayton m_kext_summary_header (), 101d4bfbc9aSGreg Clayton m_kext_summaries(), 102a08823fdSDaniel Dunbar m_mutex(Mutex::eMutexTypeRecursive), 103a08823fdSDaniel Dunbar m_break_id (LLDB_INVALID_BREAK_ID) 104d4bfbc9aSGreg Clayton { 105d4bfbc9aSGreg Clayton } 106d4bfbc9aSGreg Clayton 107d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 108d4bfbc9aSGreg Clayton // Destructor 109d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 110944b828aSGreg Clayton DynamicLoaderDarwinKernel::~DynamicLoaderDarwinKernel() 111d4bfbc9aSGreg Clayton { 112d4bfbc9aSGreg Clayton Clear(true); 113d4bfbc9aSGreg Clayton } 114d4bfbc9aSGreg Clayton 115d4bfbc9aSGreg Clayton void 116944b828aSGreg Clayton DynamicLoaderDarwinKernel::UpdateIfNeeded() 117d4bfbc9aSGreg Clayton { 118d4bfbc9aSGreg Clayton LoadKernelModuleIfNeeded(); 119d4bfbc9aSGreg Clayton SetNotificationBreakpointIfNeeded (); 120d4bfbc9aSGreg Clayton } 121d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 122d4bfbc9aSGreg Clayton /// Called after attaching a process. 123d4bfbc9aSGreg Clayton /// 124d4bfbc9aSGreg Clayton /// Allow DynamicLoader plug-ins to execute some code after 125d4bfbc9aSGreg Clayton /// attaching to a process. 126d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 127d4bfbc9aSGreg Clayton void 128944b828aSGreg Clayton DynamicLoaderDarwinKernel::DidAttach () 129d4bfbc9aSGreg Clayton { 130d4bfbc9aSGreg Clayton PrivateInitialize(m_process); 131d4bfbc9aSGreg Clayton UpdateIfNeeded(); 132d4bfbc9aSGreg Clayton } 133d4bfbc9aSGreg Clayton 134d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 135d4bfbc9aSGreg Clayton /// Called after attaching a process. 136d4bfbc9aSGreg Clayton /// 137d4bfbc9aSGreg Clayton /// Allow DynamicLoader plug-ins to execute some code after 138d4bfbc9aSGreg Clayton /// attaching to a process. 139d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 140d4bfbc9aSGreg Clayton void 141944b828aSGreg Clayton DynamicLoaderDarwinKernel::DidLaunch () 142d4bfbc9aSGreg Clayton { 143d4bfbc9aSGreg Clayton PrivateInitialize(m_process); 144d4bfbc9aSGreg Clayton UpdateIfNeeded(); 145d4bfbc9aSGreg Clayton } 146d4bfbc9aSGreg Clayton 147d4bfbc9aSGreg Clayton 148d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 149d4bfbc9aSGreg Clayton // Clear out the state of this class. 150d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 151d4bfbc9aSGreg Clayton void 152944b828aSGreg Clayton DynamicLoaderDarwinKernel::Clear (bool clear_process) 153d4bfbc9aSGreg Clayton { 154d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 155d4bfbc9aSGreg Clayton 156d4bfbc9aSGreg Clayton if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id)) 157d4bfbc9aSGreg Clayton m_process->ClearBreakpointSiteByID(m_break_id); 158d4bfbc9aSGreg Clayton 159d4bfbc9aSGreg Clayton if (clear_process) 160d4bfbc9aSGreg Clayton m_process = NULL; 161d4bfbc9aSGreg Clayton m_kernel.Clear(false); 162d4bfbc9aSGreg Clayton m_kext_summary_header_ptr_addr.Clear(); 163d4bfbc9aSGreg Clayton m_kext_summary_header_addr.Clear(); 164d4bfbc9aSGreg Clayton m_kext_summaries.clear(); 165d4bfbc9aSGreg Clayton m_break_id = LLDB_INVALID_BREAK_ID; 166d4bfbc9aSGreg Clayton } 167d4bfbc9aSGreg Clayton 168d4bfbc9aSGreg Clayton 169c859e2d5SGreg Clayton bool 1702af282a1SGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageAtFileAddress (Process *process) 1712af282a1SGreg Clayton { 1722af282a1SGreg Clayton if (IsLoaded()) 1732af282a1SGreg Clayton return true; 1742af282a1SGreg Clayton 1752af282a1SGreg Clayton if (module_sp) 1762af282a1SGreg Clayton { 1772af282a1SGreg Clayton bool changed = false; 1782af282a1SGreg Clayton if (module_sp->SetLoadAddress (process->GetTarget(), 0, changed)) 1792af282a1SGreg Clayton load_process_stop_id = process->GetStopID(); 1802af282a1SGreg Clayton } 1812af282a1SGreg Clayton return false; 1822af282a1SGreg Clayton } 1832af282a1SGreg Clayton 1842af282a1SGreg Clayton bool 185c859e2d5SGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageUsingMemoryModule (Process *process) 186c859e2d5SGreg Clayton { 187c859e2d5SGreg Clayton if (IsLoaded()) 188c859e2d5SGreg Clayton return true; 189c859e2d5SGreg Clayton 190c859e2d5SGreg Clayton bool uuid_is_valid = uuid.IsValid(); 191c859e2d5SGreg Clayton 192c859e2d5SGreg Clayton Target &target = process->GetTarget(); 193c859e2d5SGreg Clayton ModuleSP memory_module_sp; 194c859e2d5SGreg Clayton // Use the memory module as the module if we have one... 195c859e2d5SGreg Clayton if (address != LLDB_INVALID_ADDRESS) 196c859e2d5SGreg Clayton { 197c859e2d5SGreg Clayton FileSpec file_spec; 198c859e2d5SGreg Clayton if (module_sp) 199c859e2d5SGreg Clayton file_spec = module_sp->GetFileSpec(); 200c859e2d5SGreg Clayton else 201c859e2d5SGreg Clayton file_spec.SetFile (name, false); 202c859e2d5SGreg Clayton 203c859e2d5SGreg Clayton memory_module_sp = process->ReadModuleFromMemory (file_spec, address, false, false); 204c859e2d5SGreg Clayton if (memory_module_sp && !uuid_is_valid) 205c859e2d5SGreg Clayton { 206c859e2d5SGreg Clayton uuid = memory_module_sp->GetUUID(); 207c859e2d5SGreg Clayton uuid_is_valid = uuid.IsValid(); 208c859e2d5SGreg Clayton } 209c859e2d5SGreg Clayton } 210c859e2d5SGreg Clayton 211c859e2d5SGreg Clayton if (!module_sp) 212c859e2d5SGreg Clayton { 213c859e2d5SGreg Clayton if (uuid_is_valid) 214c859e2d5SGreg Clayton { 215c859e2d5SGreg Clayton ModuleList &target_images = target.GetImages(); 216c859e2d5SGreg Clayton module_sp = target_images.FindModule(uuid); 217c859e2d5SGreg Clayton 218c859e2d5SGreg Clayton if (!module_sp) 219b9a01b39SGreg Clayton { 2202af282a1SGreg Clayton ModuleSpec module_spec; 221b9a01b39SGreg Clayton module_spec.GetUUID() = uuid; 222b9a01b39SGreg Clayton module_sp = target.GetSharedModule (module_spec); 223b9a01b39SGreg Clayton } 224c859e2d5SGreg Clayton } 225c859e2d5SGreg Clayton } 226c859e2d5SGreg Clayton 227c859e2d5SGreg Clayton 228c859e2d5SGreg Clayton if (memory_module_sp) 229c859e2d5SGreg Clayton { 230c859e2d5SGreg Clayton // Someone already supplied a file, make sure it is the right one. 231c859e2d5SGreg Clayton if (module_sp) 232c859e2d5SGreg Clayton { 233c859e2d5SGreg Clayton if (module_sp->GetUUID() == memory_module_sp->GetUUID()) 234c859e2d5SGreg Clayton { 235c859e2d5SGreg Clayton ObjectFile *ondisk_object_file = module_sp->GetObjectFile(); 236c859e2d5SGreg Clayton ObjectFile *memory_object_file = memory_module_sp->GetObjectFile(); 237c859e2d5SGreg Clayton if (memory_object_file && ondisk_object_file) 238c859e2d5SGreg Clayton { 239c859e2d5SGreg Clayton SectionList *ondisk_section_list = ondisk_object_file->GetSectionList (); 240c859e2d5SGreg Clayton SectionList *memory_section_list = memory_object_file->GetSectionList (); 241c859e2d5SGreg Clayton if (memory_section_list && ondisk_section_list) 242c859e2d5SGreg Clayton { 243bae2f2f8SGreg Clayton const uint32_t num_ondisk_sections = ondisk_section_list->GetSize(); 244c859e2d5SGreg Clayton // There may be CTF sections in the memory image so we can't 245c859e2d5SGreg Clayton // always just compare the number of sections (which are actually 246c859e2d5SGreg Clayton // segments in mach-o parlance) 247c859e2d5SGreg Clayton uint32_t sect_idx = 0; 248bae2f2f8SGreg Clayton 249bae2f2f8SGreg Clayton 250bae2f2f8SGreg Clayton // We now iterate through all sections in the file module 251bae2f2f8SGreg Clayton // and look to see if the memory module has a load address 252bae2f2f8SGreg Clayton // for that section. 253bae2f2f8SGreg Clayton uint32_t num_sections_loaded = 0; 254bae2f2f8SGreg Clayton for (sect_idx=0; sect_idx<num_ondisk_sections; ++sect_idx) 255c859e2d5SGreg Clayton { 2567820bd1eSGreg Clayton SectionSP ondisk_section_sp(ondisk_section_list->GetSectionAtIndex(sect_idx)); 2577820bd1eSGreg Clayton if (ondisk_section_sp) 258c859e2d5SGreg Clayton { 2597820bd1eSGreg Clayton const Section *memory_section = memory_section_list->FindSectionByName(ondisk_section_sp->GetName()).get(); 260bae2f2f8SGreg Clayton if (memory_section) 261c859e2d5SGreg Clayton { 2627820bd1eSGreg Clayton target.GetSectionLoadList().SetSectionLoadAddress (ondisk_section_sp, memory_section->GetFileAddress()); 263bae2f2f8SGreg Clayton ++num_sections_loaded; 264c859e2d5SGreg Clayton } 265bae2f2f8SGreg Clayton } 266bae2f2f8SGreg Clayton } 267bae2f2f8SGreg Clayton if (num_sections_loaded > 0) 268c859e2d5SGreg Clayton load_process_stop_id = process->GetStopID(); 269bae2f2f8SGreg Clayton else 270bae2f2f8SGreg Clayton module_sp.reset(); // No sections were loaded 271c859e2d5SGreg Clayton } 272c859e2d5SGreg Clayton else 273c859e2d5SGreg Clayton module_sp.reset(); // One or both section lists 274c859e2d5SGreg Clayton } 275c859e2d5SGreg Clayton else 276c859e2d5SGreg Clayton module_sp.reset(); // One or both object files missing 277c859e2d5SGreg Clayton } 278c859e2d5SGreg Clayton else 279c859e2d5SGreg Clayton module_sp.reset(); // UUID mismatch 280c859e2d5SGreg Clayton } 281c859e2d5SGreg Clayton 282c859e2d5SGreg Clayton // Use the memory module as the module if we didn't like the file 283c859e2d5SGreg Clayton // module we either found or were supplied with 284c859e2d5SGreg Clayton if (!module_sp) 285c859e2d5SGreg Clayton { 286c859e2d5SGreg Clayton module_sp = memory_module_sp; 287c859e2d5SGreg Clayton // Load the memory image in the target as all adresses are already correct 288c859e2d5SGreg Clayton bool changed = false; 289c859e2d5SGreg Clayton target.GetImages().Append (memory_module_sp); 290c859e2d5SGreg Clayton if (module_sp->SetLoadAddress (target, 0, changed)) 291c859e2d5SGreg Clayton load_process_stop_id = process->GetStopID(); 292c859e2d5SGreg Clayton } 293c859e2d5SGreg Clayton } 294c859e2d5SGreg Clayton bool is_loaded = IsLoaded(); 295c859e2d5SGreg Clayton 296c859e2d5SGreg Clayton if (so_address.IsValid()) 297c859e2d5SGreg Clayton { 298c859e2d5SGreg Clayton if (is_loaded) 299c859e2d5SGreg Clayton so_address.SetLoadAddress (address, &target); 300c859e2d5SGreg Clayton else 301c859e2d5SGreg Clayton target.GetImages().ResolveFileAddress (address, so_address); 302c859e2d5SGreg Clayton 303c859e2d5SGreg Clayton } 304c859e2d5SGreg Clayton return is_loaded; 305c859e2d5SGreg Clayton } 306c859e2d5SGreg Clayton 3071f746071SGreg Clayton uint32_t 3081f746071SGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetAddressByteSize () 3091f746071SGreg Clayton { 3101f746071SGreg Clayton if (module_sp) 3111f746071SGreg Clayton return module_sp->GetArchitecture().GetAddressByteSize(); 3121f746071SGreg Clayton return 0; 3131f746071SGreg Clayton } 3141f746071SGreg Clayton 3151f746071SGreg Clayton lldb::ByteOrder 3161f746071SGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetByteOrder() 3171f746071SGreg Clayton { 3181f746071SGreg Clayton if (module_sp) 3191f746071SGreg Clayton return module_sp->GetArchitecture().GetByteOrder(); 3201f746071SGreg Clayton return lldb::endian::InlHostByteOrder(); 3211f746071SGreg Clayton } 3221f746071SGreg Clayton 3231f746071SGreg Clayton lldb_private::ArchSpec 3241f746071SGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetArchitecture () const 3251f746071SGreg Clayton { 3261f746071SGreg Clayton if (module_sp) 3271f746071SGreg Clayton return module_sp->GetArchitecture(); 3281f746071SGreg Clayton return lldb_private::ArchSpec (); 3291f746071SGreg Clayton } 3301f746071SGreg Clayton 3311f746071SGreg Clayton 332d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 333d4bfbc9aSGreg Clayton // Load the kernel module and initialize the "m_kernel" member. Return 334d4bfbc9aSGreg Clayton // true _only_ if the kernel is loaded the first time through (subsequent 335d4bfbc9aSGreg Clayton // calls to this function should return false after the kernel has been 336d4bfbc9aSGreg Clayton // already loaded). 337d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 338d4bfbc9aSGreg Clayton void 339944b828aSGreg Clayton DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() 340d4bfbc9aSGreg Clayton { 341d4bfbc9aSGreg Clayton if (!m_kext_summary_header_ptr_addr.IsValid()) 342d4bfbc9aSGreg Clayton { 343d4bfbc9aSGreg Clayton m_kernel.Clear(false); 344d4bfbc9aSGreg Clayton m_kernel.module_sp = m_process->GetTarget().GetExecutableModule(); 345*4bd4e7e3SJason Molenda 346*4bd4e7e3SJason Molenda ConstString kernel_name("mach_kernel"); 347*4bd4e7e3SJason Molenda if (m_kernel.module_sp.get() 348*4bd4e7e3SJason Molenda && m_kernel.module_sp->GetObjectFile() 349*4bd4e7e3SJason Molenda && !m_kernel.module_sp->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty()) 350*4bd4e7e3SJason Molenda { 351*4bd4e7e3SJason Molenda kernel_name = m_kernel.module_sp->GetObjectFile()->GetFileSpec().GetFilename(); 352*4bd4e7e3SJason Molenda } 353*4bd4e7e3SJason Molenda strlcpy (m_kernel.name, kernel_name.AsCString(), sizeof(m_kernel.name)); 354*4bd4e7e3SJason Molenda 355c859e2d5SGreg Clayton if (m_kernel.address == LLDB_INVALID_ADDRESS) 356d4bfbc9aSGreg Clayton { 357c859e2d5SGreg Clayton m_kernel.address = m_process->GetImageInfoAddress (); 358c859e2d5SGreg Clayton if (m_kernel.address == LLDB_INVALID_ADDRESS && m_kernel.module_sp) 359c859e2d5SGreg Clayton { 360c859e2d5SGreg Clayton // We didn't get a hint from the process, so we will 361c859e2d5SGreg Clayton // try the kernel at the address that it exists at in 362c859e2d5SGreg Clayton // the file if we have one 363c859e2d5SGreg Clayton ObjectFile *kernel_object_file = m_kernel.module_sp->GetObjectFile(); 364c859e2d5SGreg Clayton if (kernel_object_file) 365*4bd4e7e3SJason Molenda { 366*4bd4e7e3SJason Molenda addr_t load_address = kernel_object_file->GetHeaderAddress().GetLoadAddress(&m_process->GetTarget()); 367*4bd4e7e3SJason Molenda addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress(); 368*4bd4e7e3SJason Molenda if (load_address != LLDB_INVALID_ADDRESS && load_address != 0) 369*4bd4e7e3SJason Molenda { 370*4bd4e7e3SJason Molenda m_kernel.address = load_address; 371*4bd4e7e3SJason Molenda if (load_address != file_address) 372*4bd4e7e3SJason Molenda { 373*4bd4e7e3SJason Molenda // Don't accidentally relocate the kernel to the File address -- 374*4bd4e7e3SJason Molenda // the Load address has already been set to its actual in-memory address. 375*4bd4e7e3SJason Molenda // Mark it as IsLoaded. 376*4bd4e7e3SJason Molenda m_kernel.load_process_stop_id = m_process->GetStopID(); 377*4bd4e7e3SJason Molenda } 378*4bd4e7e3SJason Molenda } 379*4bd4e7e3SJason Molenda else 380*4bd4e7e3SJason Molenda { 381*4bd4e7e3SJason Molenda m_kernel.address = file_address; 382*4bd4e7e3SJason Molenda } 383*4bd4e7e3SJason Molenda } 384c859e2d5SGreg Clayton } 385c859e2d5SGreg Clayton } 386c859e2d5SGreg Clayton 387c859e2d5SGreg Clayton if (m_kernel.address != LLDB_INVALID_ADDRESS) 3882af282a1SGreg Clayton { 3892af282a1SGreg Clayton if (!m_kernel.LoadImageUsingMemoryModule (m_process)) 3902af282a1SGreg Clayton { 3912af282a1SGreg Clayton m_kernel.LoadImageAtFileAddress (m_process); 3922af282a1SGreg Clayton } 3932af282a1SGreg Clayton } 394c859e2d5SGreg Clayton 395c859e2d5SGreg Clayton if (m_kernel.IsLoaded()) 396c859e2d5SGreg Clayton { 397d4bfbc9aSGreg Clayton static ConstString kext_summary_symbol ("gLoadedKextSummaries"); 398c859e2d5SGreg Clayton const Symbol *symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData); 399d4bfbc9aSGreg Clayton if (symbol) 400c859e2d5SGreg Clayton { 401e7612134SGreg Clayton m_kext_summary_header_ptr_addr = symbol->GetAddress(); 402d4bfbc9aSGreg Clayton // Update all image infos 403d4bfbc9aSGreg Clayton ReadAllKextSummaries (); 404d4bfbc9aSGreg Clayton } 405d4bfbc9aSGreg Clayton } 406d4bfbc9aSGreg Clayton else 407d4bfbc9aSGreg Clayton { 408d4bfbc9aSGreg Clayton m_kernel.Clear(false); 409d4bfbc9aSGreg Clayton } 410d4bfbc9aSGreg Clayton } 411d4bfbc9aSGreg Clayton } 412d4bfbc9aSGreg Clayton 413d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 414d4bfbc9aSGreg Clayton // Static callback function that gets called when our DYLD notification 415d4bfbc9aSGreg Clayton // breakpoint gets hit. We update all of our image infos and then 416d4bfbc9aSGreg Clayton // let our super class DynamicLoader class decide if we should stop 417d4bfbc9aSGreg Clayton // or not (based on global preference). 418d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 419d4bfbc9aSGreg Clayton bool 420944b828aSGreg Clayton DynamicLoaderDarwinKernel::BreakpointHitCallback (void *baton, 421d4bfbc9aSGreg Clayton StoppointCallbackContext *context, 422d4bfbc9aSGreg Clayton user_id_t break_id, 423d4bfbc9aSGreg Clayton user_id_t break_loc_id) 424d4bfbc9aSGreg Clayton { 425944b828aSGreg Clayton return static_cast<DynamicLoaderDarwinKernel*>(baton)->BreakpointHit (context, break_id, break_loc_id); 426d4bfbc9aSGreg Clayton } 427d4bfbc9aSGreg Clayton 428d4bfbc9aSGreg Clayton bool 429944b828aSGreg Clayton DynamicLoaderDarwinKernel::BreakpointHit (StoppointCallbackContext *context, 430d4bfbc9aSGreg Clayton user_id_t break_id, 431d4bfbc9aSGreg Clayton user_id_t break_loc_id) 432d4bfbc9aSGreg Clayton { 433d4bfbc9aSGreg Clayton LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 434d4bfbc9aSGreg Clayton if (log) 435944b828aSGreg Clayton log->Printf ("DynamicLoaderDarwinKernel::BreakpointHit (...)\n"); 436d4bfbc9aSGreg Clayton 437d4bfbc9aSGreg Clayton ReadAllKextSummaries (); 438d4bfbc9aSGreg Clayton 439d4bfbc9aSGreg Clayton if (log) 440d4bfbc9aSGreg Clayton PutToLog(log.get()); 441d4bfbc9aSGreg Clayton 442d4bfbc9aSGreg Clayton return GetStopWhenImagesChange(); 443d4bfbc9aSGreg Clayton } 444d4bfbc9aSGreg Clayton 445d4bfbc9aSGreg Clayton 446d4bfbc9aSGreg Clayton bool 447944b828aSGreg Clayton DynamicLoaderDarwinKernel::ReadKextSummaryHeader () 448d4bfbc9aSGreg Clayton { 449d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 450d4bfbc9aSGreg Clayton 451d4bfbc9aSGreg Clayton // the all image infos is already valid for this process stop ID 452d4bfbc9aSGreg Clayton 453d4bfbc9aSGreg Clayton m_kext_summaries.clear(); 454d4bfbc9aSGreg Clayton if (m_kext_summary_header_ptr_addr.IsValid()) 455d4bfbc9aSGreg Clayton { 456d4bfbc9aSGreg Clayton const uint32_t addr_size = m_kernel.GetAddressByteSize (); 457d4bfbc9aSGreg Clayton const ByteOrder byte_order = m_kernel.GetByteOrder(); 458d4bfbc9aSGreg Clayton Error error; 459d4bfbc9aSGreg Clayton // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure 460d4bfbc9aSGreg Clayton // which is currenty 4 uint32_t and a pointer. 461d4bfbc9aSGreg Clayton uint8_t buf[24]; 462d4bfbc9aSGreg Clayton DataExtractor data (buf, sizeof(buf), byte_order, addr_size); 463d4bfbc9aSGreg Clayton const size_t count = 4 * sizeof(uint32_t) + addr_size; 464d4bfbc9aSGreg Clayton const bool prefer_file_cache = false; 465d4bfbc9aSGreg Clayton if (m_process->GetTarget().ReadPointerFromMemory (m_kext_summary_header_ptr_addr, 466d4bfbc9aSGreg Clayton prefer_file_cache, 467d4bfbc9aSGreg Clayton error, 468d4bfbc9aSGreg Clayton m_kext_summary_header_addr)) 469d4bfbc9aSGreg Clayton { 470d4bfbc9aSGreg Clayton // We got a valid address for our kext summary header and make sure it isn't NULL 471d4bfbc9aSGreg Clayton if (m_kext_summary_header_addr.IsValid() && 472d4bfbc9aSGreg Clayton m_kext_summary_header_addr.GetFileAddress() != 0) 473d4bfbc9aSGreg Clayton { 474d4bfbc9aSGreg Clayton const size_t bytes_read = m_process->GetTarget().ReadMemory (m_kext_summary_header_addr, prefer_file_cache, buf, count, error); 475d4bfbc9aSGreg Clayton if (bytes_read == count) 476d4bfbc9aSGreg Clayton { 477d4bfbc9aSGreg Clayton uint32_t offset = 0; 478d4bfbc9aSGreg Clayton m_kext_summary_header.version = data.GetU32(&offset); 479d4bfbc9aSGreg Clayton if (m_kext_summary_header.version >= 2) 480d4bfbc9aSGreg Clayton { 481d4bfbc9aSGreg Clayton m_kext_summary_header.entry_size = data.GetU32(&offset); 482d4bfbc9aSGreg Clayton } 483d4bfbc9aSGreg Clayton else 484d4bfbc9aSGreg Clayton { 485d4bfbc9aSGreg Clayton // Versions less than 2 didn't have an entry size, it was hard coded 486d4bfbc9aSGreg Clayton m_kext_summary_header.entry_size = KERNEL_MODULE_ENTRY_SIZE_VERSION_1; 487d4bfbc9aSGreg Clayton } 488d4bfbc9aSGreg Clayton m_kext_summary_header.entry_count = data.GetU32(&offset); 489d4bfbc9aSGreg Clayton return true; 490d4bfbc9aSGreg Clayton } 491d4bfbc9aSGreg Clayton } 492d4bfbc9aSGreg Clayton } 493d4bfbc9aSGreg Clayton } 494d4bfbc9aSGreg Clayton m_kext_summary_header_addr.Clear(); 495d4bfbc9aSGreg Clayton return false; 496d4bfbc9aSGreg Clayton } 497d4bfbc9aSGreg Clayton 498d4bfbc9aSGreg Clayton 499d4bfbc9aSGreg Clayton bool 500944b828aSGreg Clayton DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr, 501d4bfbc9aSGreg Clayton uint32_t count) 502d4bfbc9aSGreg Clayton { 503d4bfbc9aSGreg Clayton OSKextLoadedKextSummary::collection kext_summaries; 504d4bfbc9aSGreg Clayton LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 505d4bfbc9aSGreg Clayton if (log) 506fd54b368SJason Molenda log->Printf ("Adding %d modules.\n", count); 507d4bfbc9aSGreg Clayton 508d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 509d4bfbc9aSGreg Clayton 510d4bfbc9aSGreg Clayton if (!ReadKextSummaries (kext_summary_addr, count, kext_summaries)) 511d4bfbc9aSGreg Clayton return false; 512d4bfbc9aSGreg Clayton 513d4bfbc9aSGreg Clayton Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream(); 514d4bfbc9aSGreg Clayton for (uint32_t i = 0; i < count; i++) 515d4bfbc9aSGreg Clayton { 516d4bfbc9aSGreg Clayton if (s) 517d4bfbc9aSGreg Clayton { 518d4bfbc9aSGreg Clayton const uint8_t *u = (const uint8_t *)kext_summaries[i].uuid.GetBytes(); 519d4bfbc9aSGreg Clayton if (u) 520d4bfbc9aSGreg Clayton { 5210ca4f8bbSJason 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\"...", 522d4bfbc9aSGreg Clayton u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7], 523d4bfbc9aSGreg Clayton u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15], 524d4bfbc9aSGreg Clayton kext_summaries[i].address, kext_summaries[i].name); 525d4bfbc9aSGreg Clayton } 526d4bfbc9aSGreg Clayton else 527d4bfbc9aSGreg Clayton { 5280ca4f8bbSJason Molenda s->Printf("0x%16.16llx \"%s\"...", kext_summaries[i].address, kext_summaries[i].name); 529d4bfbc9aSGreg Clayton } 530d4bfbc9aSGreg Clayton } 531d4bfbc9aSGreg Clayton 5322af282a1SGreg Clayton if (!kext_summaries[i].LoadImageUsingMemoryModule (m_process)) 5332af282a1SGreg Clayton kext_summaries[i].LoadImageAtFileAddress (m_process); 534d4bfbc9aSGreg Clayton 535d4bfbc9aSGreg Clayton if (s) 536d4bfbc9aSGreg Clayton { 537d4bfbc9aSGreg Clayton if (kext_summaries[i].module_sp) 538c859e2d5SGreg Clayton { 539c859e2d5SGreg Clayton if (kext_summaries[i].module_sp->GetFileSpec().GetDirectory()) 5400ca4f8bbSJason Molenda s->Printf("\n found kext: %s/%s\n", 541d4bfbc9aSGreg Clayton kext_summaries[i].module_sp->GetFileSpec().GetDirectory().AsCString(), 542d4bfbc9aSGreg Clayton kext_summaries[i].module_sp->GetFileSpec().GetFilename().AsCString()); 5430ca4f8bbSJason Molenda else 544c859e2d5SGreg Clayton s->Printf("\n found kext: %s\n", 545c859e2d5SGreg Clayton kext_summaries[i].module_sp->GetFileSpec().GetFilename().AsCString()); 546c859e2d5SGreg Clayton } 547c859e2d5SGreg Clayton else 5480ca4f8bbSJason Molenda s->Printf (" failed to locate/load.\n"); 549d4bfbc9aSGreg Clayton } 550d4bfbc9aSGreg Clayton 551d4bfbc9aSGreg Clayton if (log) 552d4bfbc9aSGreg Clayton kext_summaries[i].PutToLog (log.get()); 553d4bfbc9aSGreg Clayton } 554d4bfbc9aSGreg Clayton bool return_value = AddModulesUsingImageInfos (kext_summaries); 555d4bfbc9aSGreg Clayton return return_value; 556d4bfbc9aSGreg Clayton } 557d4bfbc9aSGreg Clayton 558d4bfbc9aSGreg Clayton // Adds the modules in image_infos to m_kext_summaries. 559d4bfbc9aSGreg Clayton // NB don't call this passing in m_kext_summaries. 560d4bfbc9aSGreg Clayton 561d4bfbc9aSGreg Clayton bool 562944b828aSGreg Clayton DynamicLoaderDarwinKernel::AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos) 563d4bfbc9aSGreg Clayton { 564d4bfbc9aSGreg Clayton // Now add these images to the main list. 565d4bfbc9aSGreg Clayton ModuleList loaded_module_list; 566d4bfbc9aSGreg Clayton 567d4bfbc9aSGreg Clayton for (uint32_t idx = 0; idx < image_infos.size(); ++idx) 568d4bfbc9aSGreg Clayton { 569c859e2d5SGreg Clayton OSKextLoadedKextSummary &image_info = image_infos[idx]; 570c859e2d5SGreg Clayton m_kext_summaries.push_back(image_info); 571d4bfbc9aSGreg Clayton 572c859e2d5SGreg Clayton if (image_info.module_sp && m_process->GetStopID() == image_info.load_process_stop_id) 573d4bfbc9aSGreg Clayton loaded_module_list.AppendIfNeeded (image_infos[idx].module_sp); 574d4bfbc9aSGreg Clayton } 575d4bfbc9aSGreg Clayton 576d4bfbc9aSGreg Clayton if (loaded_module_list.GetSize() > 0) 577d4bfbc9aSGreg Clayton { 578d4bfbc9aSGreg Clayton m_process->GetTarget().ModulesDidLoad (loaded_module_list); 579d4bfbc9aSGreg Clayton } 580d4bfbc9aSGreg Clayton return true; 581d4bfbc9aSGreg Clayton } 582d4bfbc9aSGreg Clayton 583d4bfbc9aSGreg Clayton 584d4bfbc9aSGreg Clayton uint32_t 585944b828aSGreg Clayton DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr, 586d4bfbc9aSGreg Clayton uint32_t image_infos_count, 587d4bfbc9aSGreg Clayton OSKextLoadedKextSummary::collection &image_infos) 588d4bfbc9aSGreg Clayton { 589d4bfbc9aSGreg Clayton const ByteOrder endian = m_kernel.GetByteOrder(); 590d4bfbc9aSGreg Clayton const uint32_t addr_size = m_kernel.GetAddressByteSize(); 591d4bfbc9aSGreg Clayton 592d4bfbc9aSGreg Clayton image_infos.resize(image_infos_count); 593d4bfbc9aSGreg Clayton const size_t count = image_infos.size() * m_kext_summary_header.entry_size; 594d4bfbc9aSGreg Clayton DataBufferHeap data(count, 0); 595d4bfbc9aSGreg Clayton Error error; 596d4bfbc9aSGreg Clayton 597d4bfbc9aSGreg Clayton Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream(); 598d4bfbc9aSGreg Clayton 599d4bfbc9aSGreg Clayton if (s) 600d4bfbc9aSGreg Clayton s->Printf ("Reading %u kext summaries...\n", image_infos_count); 601d4bfbc9aSGreg Clayton const bool prefer_file_cache = false; 602d4bfbc9aSGreg Clayton const size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary_addr, 603d4bfbc9aSGreg Clayton prefer_file_cache, 604d4bfbc9aSGreg Clayton data.GetBytes(), 605d4bfbc9aSGreg Clayton data.GetByteSize(), 606d4bfbc9aSGreg Clayton error); 607d4bfbc9aSGreg Clayton if (bytes_read == count) 608d4bfbc9aSGreg Clayton { 609d4bfbc9aSGreg Clayton 610d4bfbc9aSGreg Clayton DataExtractor extractor (data.GetBytes(), data.GetByteSize(), endian, addr_size); 611d4bfbc9aSGreg Clayton uint32_t i=0; 612d4bfbc9aSGreg Clayton for (uint32_t kext_summary_offset = 0; 613d4bfbc9aSGreg Clayton i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size); 614d4bfbc9aSGreg Clayton ++i, kext_summary_offset += m_kext_summary_header.entry_size) 615d4bfbc9aSGreg Clayton { 616d4bfbc9aSGreg Clayton uint32_t offset = kext_summary_offset; 617d4bfbc9aSGreg Clayton const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME); 618d4bfbc9aSGreg Clayton if (name_data == NULL) 619d4bfbc9aSGreg Clayton break; 620d4bfbc9aSGreg Clayton memcpy (image_infos[i].name, name_data, KERNEL_MODULE_MAX_NAME); 621d4bfbc9aSGreg Clayton image_infos[i].uuid.SetBytes(extractor.GetData (&offset, 16)); 622d4bfbc9aSGreg Clayton image_infos[i].address = extractor.GetU64(&offset); 623d4bfbc9aSGreg Clayton if (!image_infos[i].so_address.SetLoadAddress (image_infos[i].address, &m_process->GetTarget())) 624d4bfbc9aSGreg Clayton m_process->GetTarget().GetImages().ResolveFileAddress (image_infos[i].address, image_infos[i].so_address); 625d4bfbc9aSGreg Clayton image_infos[i].size = extractor.GetU64(&offset); 626d4bfbc9aSGreg Clayton image_infos[i].version = extractor.GetU64(&offset); 627d4bfbc9aSGreg Clayton image_infos[i].load_tag = extractor.GetU32(&offset); 628d4bfbc9aSGreg Clayton image_infos[i].flags = extractor.GetU32(&offset); 629d4bfbc9aSGreg Clayton if ((offset - kext_summary_offset) < m_kext_summary_header.entry_size) 630d4bfbc9aSGreg Clayton { 631d4bfbc9aSGreg Clayton image_infos[i].reference_list = extractor.GetU64(&offset); 632d4bfbc9aSGreg Clayton } 633d4bfbc9aSGreg Clayton else 634d4bfbc9aSGreg Clayton { 635d4bfbc9aSGreg Clayton image_infos[i].reference_list = 0; 636d4bfbc9aSGreg Clayton } 637bae2f2f8SGreg 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", 638bae2f2f8SGreg Clayton // i, 639bae2f2f8SGreg Clayton // KERNEL_MODULE_MAX_NAME, KERNEL_MODULE_MAX_NAME, (char *)name_data, 640bae2f2f8SGreg Clayton // image_infos[i].address, 641bae2f2f8SGreg Clayton // image_infos[i].size, 642bae2f2f8SGreg Clayton // image_infos[i].version, 643bae2f2f8SGreg Clayton // image_infos[i].load_tag, 644bae2f2f8SGreg Clayton // image_infos[i].flags); 645d4bfbc9aSGreg Clayton } 646d4bfbc9aSGreg Clayton if (i < image_infos.size()) 647d4bfbc9aSGreg Clayton image_infos.resize(i); 648d4bfbc9aSGreg Clayton } 649d4bfbc9aSGreg Clayton else 650d4bfbc9aSGreg Clayton { 651d4bfbc9aSGreg Clayton image_infos.clear(); 652d4bfbc9aSGreg Clayton } 653d4bfbc9aSGreg Clayton return image_infos.size(); 654d4bfbc9aSGreg Clayton } 655d4bfbc9aSGreg Clayton 656d4bfbc9aSGreg Clayton bool 657944b828aSGreg Clayton DynamicLoaderDarwinKernel::ReadAllKextSummaries () 658d4bfbc9aSGreg Clayton { 659d4bfbc9aSGreg Clayton LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 660d4bfbc9aSGreg Clayton 661d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 662d4bfbc9aSGreg Clayton 663d4bfbc9aSGreg Clayton if (ReadKextSummaryHeader ()) 664d4bfbc9aSGreg Clayton { 665d4bfbc9aSGreg Clayton if (m_kext_summary_header.entry_count > 0 && m_kext_summary_header_addr.IsValid()) 666d4bfbc9aSGreg Clayton { 667d4bfbc9aSGreg Clayton Address summary_addr (m_kext_summary_header_addr); 668d4bfbc9aSGreg Clayton summary_addr.Slide(m_kext_summary_header.GetSize()); 669d4bfbc9aSGreg Clayton if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count)) 670d4bfbc9aSGreg Clayton { 671d4bfbc9aSGreg Clayton m_kext_summaries.clear(); 672d4bfbc9aSGreg Clayton } 673d4bfbc9aSGreg Clayton return true; 674d4bfbc9aSGreg Clayton } 675d4bfbc9aSGreg Clayton } 676d4bfbc9aSGreg Clayton return false; 677d4bfbc9aSGreg Clayton } 678d4bfbc9aSGreg Clayton 679d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 680d4bfbc9aSGreg Clayton // Dump an image info structure to the file handle provided. 681d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 682d4bfbc9aSGreg Clayton void 683944b828aSGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::PutToLog (Log *log) const 684d4bfbc9aSGreg Clayton { 685d4bfbc9aSGreg Clayton if (log == NULL) 686d4bfbc9aSGreg Clayton return; 687d4bfbc9aSGreg Clayton const uint8_t *u = (uint8_t *)uuid.GetBytes(); 688d4bfbc9aSGreg Clayton 689d4bfbc9aSGreg Clayton if (address == LLDB_INVALID_ADDRESS) 690d4bfbc9aSGreg Clayton { 691d4bfbc9aSGreg Clayton if (u) 692d4bfbc9aSGreg Clayton { 693d4bfbc9aSGreg 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)", 694d4bfbc9aSGreg Clayton u[ 0], u[ 1], u[ 2], u[ 3], 695d4bfbc9aSGreg Clayton u[ 4], u[ 5], u[ 6], u[ 7], 696d4bfbc9aSGreg Clayton u[ 8], u[ 9], u[10], u[11], 697d4bfbc9aSGreg Clayton u[12], u[13], u[14], u[15], 698d4bfbc9aSGreg Clayton name); 699d4bfbc9aSGreg Clayton } 700d4bfbc9aSGreg Clayton else 701d4bfbc9aSGreg Clayton log->Printf("\tname=\"%s\" (UNLOADED)", name); 702d4bfbc9aSGreg Clayton } 703d4bfbc9aSGreg Clayton else 704d4bfbc9aSGreg Clayton { 705d4bfbc9aSGreg Clayton if (u) 706d4bfbc9aSGreg Clayton { 707d4bfbc9aSGreg 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\"", 708d4bfbc9aSGreg Clayton address, size, version, load_tag, flags, reference_list, 709d4bfbc9aSGreg Clayton u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7], 710d4bfbc9aSGreg Clayton u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15], 711d4bfbc9aSGreg Clayton name); 712d4bfbc9aSGreg Clayton } 713d4bfbc9aSGreg Clayton else 714d4bfbc9aSGreg Clayton { 715d4bfbc9aSGreg 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\"", 716d4bfbc9aSGreg Clayton address, address+size, version, load_tag, flags, reference_list, 717d4bfbc9aSGreg Clayton name); 718d4bfbc9aSGreg Clayton } 719d4bfbc9aSGreg Clayton } 720d4bfbc9aSGreg Clayton } 721d4bfbc9aSGreg Clayton 722d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 723d4bfbc9aSGreg Clayton // Dump the _dyld_all_image_infos members and all current image infos 724d4bfbc9aSGreg Clayton // that we have parsed to the file handle provided. 725d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 726d4bfbc9aSGreg Clayton void 727944b828aSGreg Clayton DynamicLoaderDarwinKernel::PutToLog(Log *log) const 728d4bfbc9aSGreg Clayton { 729d4bfbc9aSGreg Clayton if (log == NULL) 730d4bfbc9aSGreg Clayton return; 731d4bfbc9aSGreg Clayton 732d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 733d4bfbc9aSGreg Clayton log->Printf("gLoadedKextSummaries = 0x%16.16llx { version=%u, entry_size=%u, entry_count=%u }", 734d4bfbc9aSGreg Clayton m_kext_summary_header_addr.GetFileAddress(), 735d4bfbc9aSGreg Clayton m_kext_summary_header.version, 736d4bfbc9aSGreg Clayton m_kext_summary_header.entry_size, 737d4bfbc9aSGreg Clayton m_kext_summary_header.entry_count); 738d4bfbc9aSGreg Clayton 739d4bfbc9aSGreg Clayton size_t i; 740d4bfbc9aSGreg Clayton const size_t count = m_kext_summaries.size(); 741d4bfbc9aSGreg Clayton if (count > 0) 742d4bfbc9aSGreg Clayton { 743d4bfbc9aSGreg Clayton log->PutCString("Loaded:"); 744d4bfbc9aSGreg Clayton for (i = 0; i<count; i++) 745d4bfbc9aSGreg Clayton m_kext_summaries[i].PutToLog(log); 746d4bfbc9aSGreg Clayton } 747d4bfbc9aSGreg Clayton } 748d4bfbc9aSGreg Clayton 749d4bfbc9aSGreg Clayton void 750944b828aSGreg Clayton DynamicLoaderDarwinKernel::PrivateInitialize(Process *process) 751d4bfbc9aSGreg Clayton { 752944b828aSGreg Clayton DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); 753d4bfbc9aSGreg Clayton Clear(true); 754d4bfbc9aSGreg Clayton m_process = process; 755d4bfbc9aSGreg Clayton } 756d4bfbc9aSGreg Clayton 757d4bfbc9aSGreg Clayton void 758944b828aSGreg Clayton DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded () 759d4bfbc9aSGreg Clayton { 760c859e2d5SGreg Clayton if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.module_sp) 761d4bfbc9aSGreg Clayton { 762944b828aSGreg Clayton DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); 763d4bfbc9aSGreg Clayton 764d4bfbc9aSGreg Clayton 765a8558b62SJim Ingham const bool internal_bp = true; 766d4bfbc9aSGreg Clayton const LazyBool skip_prologue = eLazyBoolNo; 767969795f1SJim Ingham FileSpecList module_spec_list; 768969795f1SJim Ingham module_spec_list.Append (m_kernel.module_sp->GetFileSpec()); 769969795f1SJim Ingham Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&module_spec_list, 77087df91b8SJim Ingham NULL, 771d4bfbc9aSGreg Clayton "OSKextLoadedKextSummariesUpdated", 772d4bfbc9aSGreg Clayton eFunctionNameTypeFull, 773a8558b62SJim Ingham skip_prologue, 774a8558b62SJim Ingham internal_bp).get(); 775d4bfbc9aSGreg Clayton 776944b828aSGreg Clayton bp->SetCallback (DynamicLoaderDarwinKernel::BreakpointHitCallback, this, true); 777d4bfbc9aSGreg Clayton m_break_id = bp->GetID(); 778d4bfbc9aSGreg Clayton } 779d4bfbc9aSGreg Clayton } 780d4bfbc9aSGreg Clayton 781d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 782d4bfbc9aSGreg Clayton // Member function that gets called when the process state changes. 783d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 784d4bfbc9aSGreg Clayton void 785944b828aSGreg Clayton DynamicLoaderDarwinKernel::PrivateProcessStateChanged (Process *process, StateType state) 786d4bfbc9aSGreg Clayton { 787944b828aSGreg Clayton DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__, StateAsCString(state)); 788d4bfbc9aSGreg Clayton switch (state) 789d4bfbc9aSGreg Clayton { 790d4bfbc9aSGreg Clayton case eStateConnected: 791d4bfbc9aSGreg Clayton case eStateAttaching: 792d4bfbc9aSGreg Clayton case eStateLaunching: 793d4bfbc9aSGreg Clayton case eStateInvalid: 794d4bfbc9aSGreg Clayton case eStateUnloaded: 795d4bfbc9aSGreg Clayton case eStateExited: 796d4bfbc9aSGreg Clayton case eStateDetached: 797d4bfbc9aSGreg Clayton Clear(false); 798d4bfbc9aSGreg Clayton break; 799d4bfbc9aSGreg Clayton 800d4bfbc9aSGreg Clayton case eStateStopped: 801d4bfbc9aSGreg Clayton UpdateIfNeeded(); 802d4bfbc9aSGreg Clayton break; 803d4bfbc9aSGreg Clayton 804d4bfbc9aSGreg Clayton case eStateRunning: 805d4bfbc9aSGreg Clayton case eStateStepping: 806d4bfbc9aSGreg Clayton case eStateCrashed: 807d4bfbc9aSGreg Clayton case eStateSuspended: 808d4bfbc9aSGreg Clayton break; 809d4bfbc9aSGreg Clayton 810d4bfbc9aSGreg Clayton default: 811d4bfbc9aSGreg Clayton break; 812d4bfbc9aSGreg Clayton } 813d4bfbc9aSGreg Clayton } 814d4bfbc9aSGreg Clayton 815d4bfbc9aSGreg Clayton ThreadPlanSP 816944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) 817d4bfbc9aSGreg Clayton { 818d4bfbc9aSGreg Clayton ThreadPlanSP thread_plan_sp; 819d4bfbc9aSGreg Clayton LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 820d4bfbc9aSGreg Clayton if (log) 821d4bfbc9aSGreg Clayton log->Printf ("Could not find symbol for step through."); 822d4bfbc9aSGreg Clayton return thread_plan_sp; 823d4bfbc9aSGreg Clayton } 824d4bfbc9aSGreg Clayton 825d4bfbc9aSGreg Clayton Error 826944b828aSGreg Clayton DynamicLoaderDarwinKernel::CanLoadImage () 827d4bfbc9aSGreg Clayton { 828d4bfbc9aSGreg Clayton Error error; 829d4bfbc9aSGreg Clayton error.SetErrorString("always unsafe to load or unload shared libraries in the darwin kernel"); 830d4bfbc9aSGreg Clayton return error; 831d4bfbc9aSGreg Clayton } 832d4bfbc9aSGreg Clayton 833d4bfbc9aSGreg Clayton void 834944b828aSGreg Clayton DynamicLoaderDarwinKernel::Initialize() 835d4bfbc9aSGreg Clayton { 836d4bfbc9aSGreg Clayton PluginManager::RegisterPlugin (GetPluginNameStatic(), 837d4bfbc9aSGreg Clayton GetPluginDescriptionStatic(), 838d4bfbc9aSGreg Clayton CreateInstance); 839d4bfbc9aSGreg Clayton } 840d4bfbc9aSGreg Clayton 841d4bfbc9aSGreg Clayton void 842944b828aSGreg Clayton DynamicLoaderDarwinKernel::Terminate() 843d4bfbc9aSGreg Clayton { 844d4bfbc9aSGreg Clayton PluginManager::UnregisterPlugin (CreateInstance); 845d4bfbc9aSGreg Clayton } 846d4bfbc9aSGreg Clayton 847d4bfbc9aSGreg Clayton 848d4bfbc9aSGreg Clayton const char * 849944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetPluginNameStatic() 850d4bfbc9aSGreg Clayton { 851d4bfbc9aSGreg Clayton return "dynamic-loader.macosx-kernel"; 852d4bfbc9aSGreg Clayton } 853d4bfbc9aSGreg Clayton 854d4bfbc9aSGreg Clayton const char * 855944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetPluginDescriptionStatic() 856d4bfbc9aSGreg Clayton { 857d4bfbc9aSGreg Clayton return "Dynamic loader plug-in that watches for shared library loads/unloads in the MacOSX kernel."; 858d4bfbc9aSGreg Clayton } 859d4bfbc9aSGreg Clayton 860d4bfbc9aSGreg Clayton 861d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 862d4bfbc9aSGreg Clayton // PluginInterface protocol 863d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 864d4bfbc9aSGreg Clayton const char * 865944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetPluginName() 866d4bfbc9aSGreg Clayton { 867944b828aSGreg Clayton return "DynamicLoaderDarwinKernel"; 868d4bfbc9aSGreg Clayton } 869d4bfbc9aSGreg Clayton 870d4bfbc9aSGreg Clayton const char * 871944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetShortPluginName() 872d4bfbc9aSGreg Clayton { 873d4bfbc9aSGreg Clayton return GetPluginNameStatic(); 874d4bfbc9aSGreg Clayton } 875d4bfbc9aSGreg Clayton 876d4bfbc9aSGreg Clayton uint32_t 877944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetPluginVersion() 878d4bfbc9aSGreg Clayton { 879d4bfbc9aSGreg Clayton return 1; 880d4bfbc9aSGreg Clayton } 881d4bfbc9aSGreg Clayton 8821f746071SGreg Clayton lldb::ByteOrder 8831f746071SGreg Clayton DynamicLoaderDarwinKernel::GetByteOrderFromMagic (uint32_t magic) 8841f746071SGreg Clayton { 8851f746071SGreg Clayton switch (magic) 8861f746071SGreg Clayton { 8871f746071SGreg Clayton case llvm::MachO::HeaderMagic32: 8881f746071SGreg Clayton case llvm::MachO::HeaderMagic64: 8891f746071SGreg Clayton return lldb::endian::InlHostByteOrder(); 8901f746071SGreg Clayton 8911f746071SGreg Clayton case llvm::MachO::HeaderMagic32Swapped: 8921f746071SGreg Clayton case llvm::MachO::HeaderMagic64Swapped: 8931f746071SGreg Clayton if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig) 8941f746071SGreg Clayton return lldb::eByteOrderLittle; 8951f746071SGreg Clayton else 8961f746071SGreg Clayton return lldb::eByteOrderBig; 8971f746071SGreg Clayton 8981f746071SGreg Clayton default: 8991f746071SGreg Clayton break; 9001f746071SGreg Clayton } 9011f746071SGreg Clayton return lldb::eByteOrderInvalid; 9021f746071SGreg Clayton } 9031f746071SGreg Clayton 904