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" 2068b3607fSJason Molenda #include "lldb/Host/Symbols.h" 21d4bfbc9aSGreg Clayton #include "lldb/Symbol/ObjectFile.h" 22d4bfbc9aSGreg Clayton #include "lldb/Target/RegisterContext.h" 2368b3607fSJason Molenda #include "lldb/Target/StackFrame.h" 24d4bfbc9aSGreg Clayton #include "lldb/Target/Target.h" 25d4bfbc9aSGreg Clayton #include "lldb/Target/Thread.h" 26d4bfbc9aSGreg Clayton #include "lldb/Target/ThreadPlanRunToAddress.h" 2768b3607fSJason Molenda 28d4bfbc9aSGreg Clayton 29944b828aSGreg Clayton #include "DynamicLoaderDarwinKernel.h" 30d4bfbc9aSGreg Clayton 31d4bfbc9aSGreg Clayton //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN 32d4bfbc9aSGreg Clayton #ifdef ENABLE_DEBUG_PRINTF 33d4bfbc9aSGreg Clayton #include <stdio.h> 34d4bfbc9aSGreg Clayton #define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__) 35d4bfbc9aSGreg Clayton #else 36d4bfbc9aSGreg Clayton #define DEBUG_PRINTF(fmt, ...) 37d4bfbc9aSGreg Clayton #endif 38d4bfbc9aSGreg Clayton 39d4bfbc9aSGreg Clayton using namespace lldb; 40d4bfbc9aSGreg Clayton using namespace lldb_private; 41d4bfbc9aSGreg Clayton 42d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 43d4bfbc9aSGreg Clayton // Create an instance of this class. This function is filled into 44d4bfbc9aSGreg Clayton // the plugin info class that gets handed out by the plugin factory and 45d4bfbc9aSGreg Clayton // allows the lldb to instantiate an instance of this class. 46d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 47d4bfbc9aSGreg Clayton DynamicLoader * 48944b828aSGreg Clayton DynamicLoaderDarwinKernel::CreateInstance (Process* process, bool force) 49d4bfbc9aSGreg Clayton { 50d4bfbc9aSGreg Clayton bool create = force; 51d4bfbc9aSGreg Clayton if (!create) 52d4bfbc9aSGreg Clayton { 53d4bfbc9aSGreg Clayton Module* exe_module = process->GetTarget().GetExecutableModulePointer(); 54d4bfbc9aSGreg Clayton if (exe_module) 55d4bfbc9aSGreg Clayton { 56d4bfbc9aSGreg Clayton ObjectFile *object_file = exe_module->GetObjectFile(); 57d4bfbc9aSGreg Clayton if (object_file) 58d4bfbc9aSGreg Clayton { 5949bce8ecSSean Callanan create = (object_file->GetStrata() == ObjectFile::eStrataKernel); 60d4bfbc9aSGreg Clayton } 61d4bfbc9aSGreg Clayton } 62d4bfbc9aSGreg Clayton 63d4bfbc9aSGreg Clayton if (create) 64d4bfbc9aSGreg Clayton { 65d4bfbc9aSGreg Clayton const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple(); 6670512317SGreg Clayton switch (triple_ref.getOS()) 6770512317SGreg Clayton { 6870512317SGreg Clayton case llvm::Triple::Darwin: 6970512317SGreg Clayton case llvm::Triple::MacOSX: 7070512317SGreg Clayton case llvm::Triple::IOS: 7170512317SGreg Clayton create = triple_ref.getVendor() == llvm::Triple::Apple; 7270512317SGreg Clayton break; 7370512317SGreg Clayton default: 7470512317SGreg Clayton create = false; 7570512317SGreg Clayton break; 7670512317SGreg Clayton } 77d4bfbc9aSGreg Clayton } 78d4bfbc9aSGreg Clayton } 79d4bfbc9aSGreg Clayton 80d4bfbc9aSGreg Clayton if (create) 8190539456SSean Callanan { 8290539456SSean Callanan process->SetCanJIT(false); 83944b828aSGreg Clayton return new DynamicLoaderDarwinKernel (process); 8490539456SSean Callanan } 85d4bfbc9aSGreg Clayton return NULL; 86d4bfbc9aSGreg Clayton } 87d4bfbc9aSGreg Clayton 88d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 89d4bfbc9aSGreg Clayton // Constructor 90d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 91944b828aSGreg Clayton DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel (Process* process) : 92d4bfbc9aSGreg Clayton DynamicLoader(process), 93d4bfbc9aSGreg Clayton m_kernel(), 94d4bfbc9aSGreg Clayton m_kext_summary_header_ptr_addr (), 95d4bfbc9aSGreg Clayton m_kext_summary_header_addr (), 96d4bfbc9aSGreg Clayton m_kext_summary_header (), 97d4bfbc9aSGreg Clayton m_kext_summaries(), 98a08823fdSDaniel Dunbar m_mutex(Mutex::eMutexTypeRecursive), 99a08823fdSDaniel Dunbar m_break_id (LLDB_INVALID_BREAK_ID) 100d4bfbc9aSGreg Clayton { 101d4bfbc9aSGreg Clayton } 102d4bfbc9aSGreg Clayton 103d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 104d4bfbc9aSGreg Clayton // Destructor 105d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 106944b828aSGreg Clayton DynamicLoaderDarwinKernel::~DynamicLoaderDarwinKernel() 107d4bfbc9aSGreg Clayton { 108d4bfbc9aSGreg Clayton Clear(true); 109d4bfbc9aSGreg Clayton } 110d4bfbc9aSGreg Clayton 111d4bfbc9aSGreg Clayton void 112944b828aSGreg Clayton DynamicLoaderDarwinKernel::UpdateIfNeeded() 113d4bfbc9aSGreg Clayton { 114d4bfbc9aSGreg Clayton LoadKernelModuleIfNeeded(); 115d4bfbc9aSGreg Clayton SetNotificationBreakpointIfNeeded (); 116d4bfbc9aSGreg Clayton } 117d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 118d4bfbc9aSGreg Clayton /// Called after attaching a process. 119d4bfbc9aSGreg Clayton /// 120d4bfbc9aSGreg Clayton /// Allow DynamicLoader plug-ins to execute some code after 121d4bfbc9aSGreg Clayton /// attaching to a process. 122d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 123d4bfbc9aSGreg Clayton void 124944b828aSGreg Clayton DynamicLoaderDarwinKernel::DidAttach () 125d4bfbc9aSGreg Clayton { 126d4bfbc9aSGreg Clayton PrivateInitialize(m_process); 127d4bfbc9aSGreg Clayton UpdateIfNeeded(); 128d4bfbc9aSGreg Clayton } 129d4bfbc9aSGreg Clayton 130d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 131d4bfbc9aSGreg Clayton /// Called after attaching a process. 132d4bfbc9aSGreg Clayton /// 133d4bfbc9aSGreg Clayton /// Allow DynamicLoader plug-ins to execute some code after 134d4bfbc9aSGreg Clayton /// attaching to a process. 135d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 136d4bfbc9aSGreg Clayton void 137944b828aSGreg Clayton DynamicLoaderDarwinKernel::DidLaunch () 138d4bfbc9aSGreg Clayton { 139d4bfbc9aSGreg Clayton PrivateInitialize(m_process); 140d4bfbc9aSGreg Clayton UpdateIfNeeded(); 141d4bfbc9aSGreg Clayton } 142d4bfbc9aSGreg Clayton 143d4bfbc9aSGreg Clayton 144d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 145d4bfbc9aSGreg Clayton // Clear out the state of this class. 146d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 147d4bfbc9aSGreg Clayton void 148944b828aSGreg Clayton DynamicLoaderDarwinKernel::Clear (bool clear_process) 149d4bfbc9aSGreg Clayton { 150d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 151d4bfbc9aSGreg Clayton 152d4bfbc9aSGreg Clayton if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id)) 153d4bfbc9aSGreg Clayton m_process->ClearBreakpointSiteByID(m_break_id); 154d4bfbc9aSGreg Clayton 155d4bfbc9aSGreg Clayton if (clear_process) 156d4bfbc9aSGreg Clayton m_process = NULL; 157d4bfbc9aSGreg Clayton m_kernel.Clear(false); 158d4bfbc9aSGreg Clayton m_kext_summary_header_ptr_addr.Clear(); 159d4bfbc9aSGreg Clayton m_kext_summary_header_addr.Clear(); 160d4bfbc9aSGreg Clayton m_kext_summaries.clear(); 161d4bfbc9aSGreg Clayton m_break_id = LLDB_INVALID_BREAK_ID; 162d4bfbc9aSGreg Clayton } 163d4bfbc9aSGreg Clayton 164d4bfbc9aSGreg Clayton 165c859e2d5SGreg Clayton bool 1662af282a1SGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageAtFileAddress (Process *process) 1672af282a1SGreg Clayton { 1682af282a1SGreg Clayton if (IsLoaded()) 1692af282a1SGreg Clayton return true; 1702af282a1SGreg Clayton 1712af282a1SGreg Clayton if (module_sp) 1722af282a1SGreg Clayton { 1732af282a1SGreg Clayton bool changed = false; 1742af282a1SGreg Clayton if (module_sp->SetLoadAddress (process->GetTarget(), 0, changed)) 1752af282a1SGreg Clayton load_process_stop_id = process->GetStopID(); 1762af282a1SGreg Clayton } 1772af282a1SGreg Clayton return false; 1782af282a1SGreg Clayton } 1792af282a1SGreg Clayton 1802af282a1SGreg Clayton bool 181c859e2d5SGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageUsingMemoryModule (Process *process) 182c859e2d5SGreg Clayton { 183c859e2d5SGreg Clayton if (IsLoaded()) 184c859e2d5SGreg Clayton return true; 185c859e2d5SGreg Clayton 186c859e2d5SGreg Clayton bool uuid_is_valid = uuid.IsValid(); 18768b3607fSJason Molenda bool memory_module_is_kernel = false; 188c859e2d5SGreg Clayton 189c859e2d5SGreg Clayton Target &target = process->GetTarget(); 190c859e2d5SGreg Clayton ModuleSP memory_module_sp; 191c859e2d5SGreg Clayton // Use the memory module as the module if we have one... 192c859e2d5SGreg Clayton if (address != LLDB_INVALID_ADDRESS) 193c859e2d5SGreg Clayton { 194c859e2d5SGreg Clayton FileSpec file_spec; 195c859e2d5SGreg Clayton if (module_sp) 196c859e2d5SGreg Clayton file_spec = module_sp->GetFileSpec(); 197c859e2d5SGreg Clayton else 198c859e2d5SGreg Clayton file_spec.SetFile (name, false); 199c859e2d5SGreg Clayton 200c859e2d5SGreg Clayton memory_module_sp = process->ReadModuleFromMemory (file_spec, address, false, false); 201c859e2d5SGreg Clayton if (memory_module_sp && !uuid_is_valid) 202c859e2d5SGreg Clayton { 203c859e2d5SGreg Clayton uuid = memory_module_sp->GetUUID(); 204c859e2d5SGreg Clayton uuid_is_valid = uuid.IsValid(); 205c859e2d5SGreg Clayton } 20668b3607fSJason Molenda if (memory_module_sp->GetObjectFile() 20768b3607fSJason Molenda && memory_module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable 20868b3607fSJason Molenda && memory_module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel) 20968b3607fSJason Molenda { 21068b3607fSJason Molenda memory_module_is_kernel = true; 21153667f5dSJason Molenda if (memory_module_sp->GetArchitecture().IsValid()) 21253667f5dSJason Molenda { 21353667f5dSJason Molenda target.SetArchitecture(memory_module_sp->GetArchitecture()); 21453667f5dSJason Molenda } 21568b3607fSJason Molenda } 216c859e2d5SGreg Clayton } 217c859e2d5SGreg Clayton 218c859e2d5SGreg Clayton if (!module_sp) 219c859e2d5SGreg Clayton { 220c859e2d5SGreg Clayton if (uuid_is_valid) 221c859e2d5SGreg Clayton { 222c859e2d5SGreg Clayton ModuleList &target_images = target.GetImages(); 223c859e2d5SGreg Clayton module_sp = target_images.FindModule(uuid); 224c859e2d5SGreg Clayton 225c859e2d5SGreg Clayton if (!module_sp) 226b9a01b39SGreg Clayton { 2272af282a1SGreg Clayton ModuleSpec module_spec; 228b9a01b39SGreg Clayton module_spec.GetUUID() = uuid; 22953667f5dSJason Molenda module_spec.GetArchitecture() = target.GetArchitecture(); 230*bb860bd2SJason Molenda 231*bb860bd2SJason Molenda // For the kernel, we really do need an on-disk file copy of the 232*bb860bd2SJason Molenda // binary. 233*bb860bd2SJason Molenda bool force_symbols_search = false; 234*bb860bd2SJason Molenda if (memory_module_is_kernel) 235*bb860bd2SJason Molenda { 236*bb860bd2SJason Molenda force_symbols_search = true; 237*bb860bd2SJason Molenda } 238*bb860bd2SJason Molenda 239*bb860bd2SJason Molenda if (Symbols::DownloadObjectAndSymbolFile (module_spec, force_symbols_search)) 240*bb860bd2SJason Molenda { 241*bb860bd2SJason Molenda if (module_spec.GetFileSpec().Exists()) 242*bb860bd2SJason Molenda { 243*bb860bd2SJason Molenda module_sp.reset(new Module (module_spec.GetFileSpec(), target.GetArchitecture())); 244*bb860bd2SJason Molenda if (module_sp.get() && module_sp->MatchesModuleSpec (module_spec)) 245*bb860bd2SJason Molenda { 246*bb860bd2SJason Molenda ModuleList loaded_module_list; 247*bb860bd2SJason Molenda loaded_module_list.Append (module_sp); 248*bb860bd2SJason Molenda target.ModulesDidLoad (loaded_module_list); 249*bb860bd2SJason Molenda } 250*bb860bd2SJason Molenda } 251*bb860bd2SJason Molenda } 252*bb860bd2SJason Molenda 253*bb860bd2SJason Molenda // Ask the Target to find this file on the local system, if possible. 254*bb860bd2SJason Molenda // This will search in the list of currently-loaded files, look in the 255*bb860bd2SJason Molenda // standard search paths on the system, and on a Mac it will try calling 256*bb860bd2SJason Molenda // the DebugSymbols framework with the UUID to find the binary via its 257*bb860bd2SJason Molenda // search methods. 258*bb860bd2SJason Molenda if (!module_sp) 259*bb860bd2SJason Molenda { 260b9a01b39SGreg Clayton module_sp = target.GetSharedModule (module_spec); 261b9a01b39SGreg Clayton } 262c859e2d5SGreg Clayton } 263c859e2d5SGreg Clayton } 264*bb860bd2SJason Molenda } 265c859e2d5SGreg Clayton 266c859e2d5SGreg Clayton 267*bb860bd2SJason Molenda if (memory_module_sp && module_sp) 268c859e2d5SGreg Clayton { 269c859e2d5SGreg Clayton if (module_sp->GetUUID() == memory_module_sp->GetUUID()) 270c859e2d5SGreg Clayton { 271*bb860bd2SJason Molenda target.GetImages().Append(module_sp); 272*bb860bd2SJason Molenda if (memory_module_is_kernel && target.GetExecutableModulePointer() != module_sp.get()) 273*bb860bd2SJason Molenda { 274*bb860bd2SJason Molenda target.SetExecutableModule (module_sp, false); 275*bb860bd2SJason Molenda } 276*bb860bd2SJason Molenda 277c859e2d5SGreg Clayton ObjectFile *ondisk_object_file = module_sp->GetObjectFile(); 278c859e2d5SGreg Clayton ObjectFile *memory_object_file = memory_module_sp->GetObjectFile(); 279c859e2d5SGreg Clayton if (memory_object_file && ondisk_object_file) 280c859e2d5SGreg Clayton { 281c859e2d5SGreg Clayton SectionList *ondisk_section_list = ondisk_object_file->GetSectionList (); 282c859e2d5SGreg Clayton SectionList *memory_section_list = memory_object_file->GetSectionList (); 283c859e2d5SGreg Clayton if (memory_section_list && ondisk_section_list) 284c859e2d5SGreg Clayton { 285bae2f2f8SGreg Clayton const uint32_t num_ondisk_sections = ondisk_section_list->GetSize(); 286c859e2d5SGreg Clayton // There may be CTF sections in the memory image so we can't 287c859e2d5SGreg Clayton // always just compare the number of sections (which are actually 288c859e2d5SGreg Clayton // segments in mach-o parlance) 289c859e2d5SGreg Clayton uint32_t sect_idx = 0; 290bae2f2f8SGreg Clayton 29153667f5dSJason Molenda // Use the memory_module's addresses for each section to set the 29253667f5dSJason Molenda // file module's load address as appropriate. We don't want to use 29353667f5dSJason Molenda // a single slide value for the entire kext - different segments may 29453667f5dSJason Molenda // be slid different amounts by the kext loader. 295bae2f2f8SGreg Clayton 296bae2f2f8SGreg Clayton uint32_t num_sections_loaded = 0; 297bae2f2f8SGreg Clayton for (sect_idx=0; sect_idx<num_ondisk_sections; ++sect_idx) 298c859e2d5SGreg Clayton { 2997820bd1eSGreg Clayton SectionSP ondisk_section_sp(ondisk_section_list->GetSectionAtIndex(sect_idx)); 3007820bd1eSGreg Clayton if (ondisk_section_sp) 301c859e2d5SGreg Clayton { 3027820bd1eSGreg Clayton const Section *memory_section = memory_section_list->FindSectionByName(ondisk_section_sp->GetName()).get(); 303bae2f2f8SGreg Clayton if (memory_section) 304c859e2d5SGreg Clayton { 3057820bd1eSGreg Clayton target.GetSectionLoadList().SetSectionLoadAddress (ondisk_section_sp, memory_section->GetFileAddress()); 306bae2f2f8SGreg Clayton ++num_sections_loaded; 307c859e2d5SGreg Clayton } 308bae2f2f8SGreg Clayton } 309bae2f2f8SGreg Clayton } 310bae2f2f8SGreg Clayton if (num_sections_loaded > 0) 311c859e2d5SGreg Clayton load_process_stop_id = process->GetStopID(); 312bae2f2f8SGreg Clayton else 313bae2f2f8SGreg Clayton module_sp.reset(); // No sections were loaded 314c859e2d5SGreg Clayton } 315c859e2d5SGreg Clayton else 316c859e2d5SGreg Clayton module_sp.reset(); // One or both section lists 317c859e2d5SGreg Clayton } 318c859e2d5SGreg Clayton else 319c859e2d5SGreg Clayton module_sp.reset(); // One or both object files missing 320c859e2d5SGreg Clayton } 321c859e2d5SGreg Clayton else 322c859e2d5SGreg Clayton module_sp.reset(); // UUID mismatch 323c859e2d5SGreg Clayton } 324c859e2d5SGreg Clayton 325c859e2d5SGreg Clayton bool is_loaded = IsLoaded(); 326c859e2d5SGreg Clayton 327c859e2d5SGreg Clayton if (so_address.IsValid()) 328c859e2d5SGreg Clayton { 329c859e2d5SGreg Clayton if (is_loaded) 330c859e2d5SGreg Clayton so_address.SetLoadAddress (address, &target); 331c859e2d5SGreg Clayton else 332c859e2d5SGreg Clayton target.GetImages().ResolveFileAddress (address, so_address); 333c859e2d5SGreg Clayton 334c859e2d5SGreg Clayton } 33568b3607fSJason Molenda 33668b3607fSJason Molenda if (is_loaded && module_sp && memory_module_is_kernel) 33768b3607fSJason Molenda { 33868b3607fSJason Molenda Stream *s = &target.GetDebugger().GetOutputStream(); 33968b3607fSJason Molenda if (s) 34068b3607fSJason Molenda { 34168b3607fSJason Molenda char uuidbuf[64]; 34268b3607fSJason Molenda s->Printf ("Kernel UUID: %s\n", module_sp->GetUUID().GetAsCString(uuidbuf, sizeof (uuidbuf))); 34368b3607fSJason Molenda s->Printf ("Load Address: 0x%llx\n", address); 344743e4396SJason Molenda if (module_sp->GetFileSpec().GetDirectory().IsEmpty()) 345743e4396SJason Molenda { 346743e4396SJason Molenda s->Printf ("Loaded kernel file %s\n", module_sp->GetFileSpec().GetFilename().AsCString()); 347743e4396SJason Molenda } 348743e4396SJason Molenda else 349743e4396SJason Molenda { 35068b3607fSJason Molenda s->Printf ("Loaded kernel file %s/%s\n", 35168b3607fSJason Molenda module_sp->GetFileSpec().GetDirectory().AsCString(), 35268b3607fSJason Molenda module_sp->GetFileSpec().GetFilename().AsCString()); 353743e4396SJason Molenda } 35468b3607fSJason Molenda s->Flush (); 35568b3607fSJason Molenda } 35668b3607fSJason Molenda } 357c859e2d5SGreg Clayton return is_loaded; 358c859e2d5SGreg Clayton } 359c859e2d5SGreg Clayton 3601f746071SGreg Clayton uint32_t 3611f746071SGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetAddressByteSize () 3621f746071SGreg Clayton { 3631f746071SGreg Clayton if (module_sp) 3641f746071SGreg Clayton return module_sp->GetArchitecture().GetAddressByteSize(); 3651f746071SGreg Clayton return 0; 3661f746071SGreg Clayton } 3671f746071SGreg Clayton 3681f746071SGreg Clayton lldb::ByteOrder 3691f746071SGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetByteOrder() 3701f746071SGreg Clayton { 3711f746071SGreg Clayton if (module_sp) 3721f746071SGreg Clayton return module_sp->GetArchitecture().GetByteOrder(); 3731f746071SGreg Clayton return lldb::endian::InlHostByteOrder(); 3741f746071SGreg Clayton } 3751f746071SGreg Clayton 3761f746071SGreg Clayton lldb_private::ArchSpec 3771f746071SGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetArchitecture () const 3781f746071SGreg Clayton { 3791f746071SGreg Clayton if (module_sp) 3801f746071SGreg Clayton return module_sp->GetArchitecture(); 3811f746071SGreg Clayton return lldb_private::ArchSpec (); 3821f746071SGreg Clayton } 3831f746071SGreg Clayton 3841f746071SGreg Clayton 385d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 386d4bfbc9aSGreg Clayton // Load the kernel module and initialize the "m_kernel" member. Return 387d4bfbc9aSGreg Clayton // true _only_ if the kernel is loaded the first time through (subsequent 388d4bfbc9aSGreg Clayton // calls to this function should return false after the kernel has been 389d4bfbc9aSGreg Clayton // already loaded). 390d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 391d4bfbc9aSGreg Clayton void 392944b828aSGreg Clayton DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() 393d4bfbc9aSGreg Clayton { 394d4bfbc9aSGreg Clayton if (!m_kext_summary_header_ptr_addr.IsValid()) 395d4bfbc9aSGreg Clayton { 396d4bfbc9aSGreg Clayton m_kernel.Clear(false); 397d4bfbc9aSGreg Clayton m_kernel.module_sp = m_process->GetTarget().GetExecutableModule(); 3984bd4e7e3SJason Molenda 3994bd4e7e3SJason Molenda ConstString kernel_name("mach_kernel"); 4004bd4e7e3SJason Molenda if (m_kernel.module_sp.get() 4014bd4e7e3SJason Molenda && m_kernel.module_sp->GetObjectFile() 4024bd4e7e3SJason Molenda && !m_kernel.module_sp->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty()) 4034bd4e7e3SJason Molenda { 4044bd4e7e3SJason Molenda kernel_name = m_kernel.module_sp->GetObjectFile()->GetFileSpec().GetFilename(); 4054bd4e7e3SJason Molenda } 40631a6961cSJason Molenda strncpy (m_kernel.name, kernel_name.AsCString(), sizeof(m_kernel.name)); 40731a6961cSJason Molenda m_kernel.name[sizeof (m_kernel.name) - 1] = '\0'; 4084bd4e7e3SJason Molenda 409c859e2d5SGreg Clayton if (m_kernel.address == LLDB_INVALID_ADDRESS) 410d4bfbc9aSGreg Clayton { 411c859e2d5SGreg Clayton m_kernel.address = m_process->GetImageInfoAddress (); 412c859e2d5SGreg Clayton if (m_kernel.address == LLDB_INVALID_ADDRESS && m_kernel.module_sp) 413c859e2d5SGreg Clayton { 414c859e2d5SGreg Clayton // We didn't get a hint from the process, so we will 415c859e2d5SGreg Clayton // try the kernel at the address that it exists at in 416c859e2d5SGreg Clayton // the file if we have one 417c859e2d5SGreg Clayton ObjectFile *kernel_object_file = m_kernel.module_sp->GetObjectFile(); 418c859e2d5SGreg Clayton if (kernel_object_file) 4194bd4e7e3SJason Molenda { 4204bd4e7e3SJason Molenda addr_t load_address = kernel_object_file->GetHeaderAddress().GetLoadAddress(&m_process->GetTarget()); 4214bd4e7e3SJason Molenda addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress(); 4224bd4e7e3SJason Molenda if (load_address != LLDB_INVALID_ADDRESS && load_address != 0) 4234bd4e7e3SJason Molenda { 4244bd4e7e3SJason Molenda m_kernel.address = load_address; 4254bd4e7e3SJason Molenda if (load_address != file_address) 4264bd4e7e3SJason Molenda { 4274bd4e7e3SJason Molenda // Don't accidentally relocate the kernel to the File address -- 4284bd4e7e3SJason Molenda // the Load address has already been set to its actual in-memory address. 4294bd4e7e3SJason Molenda // Mark it as IsLoaded. 4304bd4e7e3SJason Molenda m_kernel.load_process_stop_id = m_process->GetStopID(); 4314bd4e7e3SJason Molenda } 4324bd4e7e3SJason Molenda } 4334bd4e7e3SJason Molenda else 4344bd4e7e3SJason Molenda { 4354bd4e7e3SJason Molenda m_kernel.address = file_address; 4364bd4e7e3SJason Molenda } 4374bd4e7e3SJason Molenda } 438c859e2d5SGreg Clayton } 439c859e2d5SGreg Clayton } 440c859e2d5SGreg Clayton 441c859e2d5SGreg Clayton if (m_kernel.address != LLDB_INVALID_ADDRESS) 4422af282a1SGreg Clayton { 4432af282a1SGreg Clayton if (!m_kernel.LoadImageUsingMemoryModule (m_process)) 4442af282a1SGreg Clayton { 4452af282a1SGreg Clayton m_kernel.LoadImageAtFileAddress (m_process); 4462af282a1SGreg Clayton } 4472af282a1SGreg Clayton } 448c859e2d5SGreg Clayton 449c859e2d5SGreg Clayton if (m_kernel.IsLoaded()) 450c859e2d5SGreg Clayton { 451d4bfbc9aSGreg Clayton static ConstString kext_summary_symbol ("gLoadedKextSummaries"); 452c859e2d5SGreg Clayton const Symbol *symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData); 453d4bfbc9aSGreg Clayton if (symbol) 454c859e2d5SGreg Clayton { 455e7612134SGreg Clayton m_kext_summary_header_ptr_addr = symbol->GetAddress(); 456d4bfbc9aSGreg Clayton // Update all image infos 457d4bfbc9aSGreg Clayton ReadAllKextSummaries (); 458d4bfbc9aSGreg Clayton } 459d4bfbc9aSGreg Clayton } 460d4bfbc9aSGreg Clayton else 461d4bfbc9aSGreg Clayton { 462d4bfbc9aSGreg Clayton m_kernel.Clear(false); 463d4bfbc9aSGreg Clayton } 464d4bfbc9aSGreg Clayton } 465d4bfbc9aSGreg Clayton } 466d4bfbc9aSGreg Clayton 467d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 468d4bfbc9aSGreg Clayton // Static callback function that gets called when our DYLD notification 469d4bfbc9aSGreg Clayton // breakpoint gets hit. We update all of our image infos and then 470d4bfbc9aSGreg Clayton // let our super class DynamicLoader class decide if we should stop 471d4bfbc9aSGreg Clayton // or not (based on global preference). 472d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 473d4bfbc9aSGreg Clayton bool 474944b828aSGreg Clayton DynamicLoaderDarwinKernel::BreakpointHitCallback (void *baton, 475d4bfbc9aSGreg Clayton StoppointCallbackContext *context, 476d4bfbc9aSGreg Clayton user_id_t break_id, 477d4bfbc9aSGreg Clayton user_id_t break_loc_id) 478d4bfbc9aSGreg Clayton { 479944b828aSGreg Clayton return static_cast<DynamicLoaderDarwinKernel*>(baton)->BreakpointHit (context, break_id, break_loc_id); 480d4bfbc9aSGreg Clayton } 481d4bfbc9aSGreg Clayton 482d4bfbc9aSGreg Clayton bool 483944b828aSGreg Clayton DynamicLoaderDarwinKernel::BreakpointHit (StoppointCallbackContext *context, 484d4bfbc9aSGreg Clayton user_id_t break_id, 485d4bfbc9aSGreg Clayton user_id_t break_loc_id) 486d4bfbc9aSGreg Clayton { 487d4bfbc9aSGreg Clayton LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 488d4bfbc9aSGreg Clayton if (log) 489944b828aSGreg Clayton log->Printf ("DynamicLoaderDarwinKernel::BreakpointHit (...)\n"); 490d4bfbc9aSGreg Clayton 491d4bfbc9aSGreg Clayton ReadAllKextSummaries (); 492d4bfbc9aSGreg Clayton 493d4bfbc9aSGreg Clayton if (log) 494d4bfbc9aSGreg Clayton PutToLog(log.get()); 495d4bfbc9aSGreg Clayton 496d4bfbc9aSGreg Clayton return GetStopWhenImagesChange(); 497d4bfbc9aSGreg Clayton } 498d4bfbc9aSGreg Clayton 499d4bfbc9aSGreg Clayton 500d4bfbc9aSGreg Clayton bool 501944b828aSGreg Clayton DynamicLoaderDarwinKernel::ReadKextSummaryHeader () 502d4bfbc9aSGreg Clayton { 503d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 504d4bfbc9aSGreg Clayton 505d4bfbc9aSGreg Clayton // the all image infos is already valid for this process stop ID 506d4bfbc9aSGreg Clayton 507d4bfbc9aSGreg Clayton m_kext_summaries.clear(); 508d4bfbc9aSGreg Clayton if (m_kext_summary_header_ptr_addr.IsValid()) 509d4bfbc9aSGreg Clayton { 510d4bfbc9aSGreg Clayton const uint32_t addr_size = m_kernel.GetAddressByteSize (); 511d4bfbc9aSGreg Clayton const ByteOrder byte_order = m_kernel.GetByteOrder(); 512d4bfbc9aSGreg Clayton Error error; 513d4bfbc9aSGreg Clayton // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure 514d4bfbc9aSGreg Clayton // which is currenty 4 uint32_t and a pointer. 515d4bfbc9aSGreg Clayton uint8_t buf[24]; 516d4bfbc9aSGreg Clayton DataExtractor data (buf, sizeof(buf), byte_order, addr_size); 517d4bfbc9aSGreg Clayton const size_t count = 4 * sizeof(uint32_t) + addr_size; 518d4bfbc9aSGreg Clayton const bool prefer_file_cache = false; 519d4bfbc9aSGreg Clayton if (m_process->GetTarget().ReadPointerFromMemory (m_kext_summary_header_ptr_addr, 520d4bfbc9aSGreg Clayton prefer_file_cache, 521d4bfbc9aSGreg Clayton error, 522d4bfbc9aSGreg Clayton m_kext_summary_header_addr)) 523d4bfbc9aSGreg Clayton { 524d4bfbc9aSGreg Clayton // We got a valid address for our kext summary header and make sure it isn't NULL 525d4bfbc9aSGreg Clayton if (m_kext_summary_header_addr.IsValid() && 526d4bfbc9aSGreg Clayton m_kext_summary_header_addr.GetFileAddress() != 0) 527d4bfbc9aSGreg Clayton { 528d4bfbc9aSGreg Clayton const size_t bytes_read = m_process->GetTarget().ReadMemory (m_kext_summary_header_addr, prefer_file_cache, buf, count, error); 529d4bfbc9aSGreg Clayton if (bytes_read == count) 530d4bfbc9aSGreg Clayton { 531d4bfbc9aSGreg Clayton uint32_t offset = 0; 532d4bfbc9aSGreg Clayton m_kext_summary_header.version = data.GetU32(&offset); 533d4bfbc9aSGreg Clayton if (m_kext_summary_header.version >= 2) 534d4bfbc9aSGreg Clayton { 535d4bfbc9aSGreg Clayton m_kext_summary_header.entry_size = data.GetU32(&offset); 536d4bfbc9aSGreg Clayton } 537d4bfbc9aSGreg Clayton else 538d4bfbc9aSGreg Clayton { 539d4bfbc9aSGreg Clayton // Versions less than 2 didn't have an entry size, it was hard coded 540d4bfbc9aSGreg Clayton m_kext_summary_header.entry_size = KERNEL_MODULE_ENTRY_SIZE_VERSION_1; 541d4bfbc9aSGreg Clayton } 542d4bfbc9aSGreg Clayton m_kext_summary_header.entry_count = data.GetU32(&offset); 543d4bfbc9aSGreg Clayton return true; 544d4bfbc9aSGreg Clayton } 545d4bfbc9aSGreg Clayton } 546d4bfbc9aSGreg Clayton } 547d4bfbc9aSGreg Clayton } 548d4bfbc9aSGreg Clayton m_kext_summary_header_addr.Clear(); 549d4bfbc9aSGreg Clayton return false; 550d4bfbc9aSGreg Clayton } 551d4bfbc9aSGreg Clayton 552d4bfbc9aSGreg Clayton 553d4bfbc9aSGreg Clayton bool 554944b828aSGreg Clayton DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr, 555d4bfbc9aSGreg Clayton uint32_t count) 556d4bfbc9aSGreg Clayton { 557d4bfbc9aSGreg Clayton OSKextLoadedKextSummary::collection kext_summaries; 558d4bfbc9aSGreg Clayton LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 559d4bfbc9aSGreg Clayton if (log) 560fd54b368SJason Molenda log->Printf ("Adding %d modules.\n", count); 561d4bfbc9aSGreg Clayton 562d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 563d4bfbc9aSGreg Clayton 564d4bfbc9aSGreg Clayton if (!ReadKextSummaries (kext_summary_addr, count, kext_summaries)) 565d4bfbc9aSGreg Clayton return false; 566d4bfbc9aSGreg Clayton 567d4bfbc9aSGreg Clayton Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream(); 56868b3607fSJason Molenda if (s) 56968b3607fSJason Molenda s->Printf ("Loading %d kext modules ", count); 570d4bfbc9aSGreg Clayton for (uint32_t i = 0; i < count; i++) 571d4bfbc9aSGreg Clayton { 5722af282a1SGreg Clayton if (!kext_summaries[i].LoadImageUsingMemoryModule (m_process)) 5732af282a1SGreg Clayton kext_summaries[i].LoadImageAtFileAddress (m_process); 574d4bfbc9aSGreg Clayton 575d4bfbc9aSGreg Clayton if (s) 57668b3607fSJason Molenda s->Printf ("."); 577d4bfbc9aSGreg Clayton 578d4bfbc9aSGreg Clayton if (log) 579d4bfbc9aSGreg Clayton kext_summaries[i].PutToLog (log.get()); 580d4bfbc9aSGreg Clayton } 58168b3607fSJason Molenda if (s) 58268b3607fSJason Molenda { 58368b3607fSJason Molenda s->Printf (" done.\n"); 58468b3607fSJason Molenda s->Flush (); 58568b3607fSJason Molenda } 58668b3607fSJason Molenda 587d4bfbc9aSGreg Clayton bool return_value = AddModulesUsingImageInfos (kext_summaries); 588d4bfbc9aSGreg Clayton return return_value; 589d4bfbc9aSGreg Clayton } 590d4bfbc9aSGreg Clayton 591d4bfbc9aSGreg Clayton // Adds the modules in image_infos to m_kext_summaries. 592d4bfbc9aSGreg Clayton // NB don't call this passing in m_kext_summaries. 593d4bfbc9aSGreg Clayton 594d4bfbc9aSGreg Clayton bool 595944b828aSGreg Clayton DynamicLoaderDarwinKernel::AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos) 596d4bfbc9aSGreg Clayton { 597d4bfbc9aSGreg Clayton // Now add these images to the main list. 598d4bfbc9aSGreg Clayton ModuleList loaded_module_list; 599d4bfbc9aSGreg Clayton 600d4bfbc9aSGreg Clayton for (uint32_t idx = 0; idx < image_infos.size(); ++idx) 601d4bfbc9aSGreg Clayton { 602c859e2d5SGreg Clayton OSKextLoadedKextSummary &image_info = image_infos[idx]; 603c859e2d5SGreg Clayton m_kext_summaries.push_back(image_info); 604d4bfbc9aSGreg Clayton 605c859e2d5SGreg Clayton if (image_info.module_sp && m_process->GetStopID() == image_info.load_process_stop_id) 606d4bfbc9aSGreg Clayton loaded_module_list.AppendIfNeeded (image_infos[idx].module_sp); 607d4bfbc9aSGreg Clayton } 608d4bfbc9aSGreg Clayton 609d4bfbc9aSGreg Clayton if (loaded_module_list.GetSize() > 0) 610d4bfbc9aSGreg Clayton { 611d4bfbc9aSGreg Clayton m_process->GetTarget().ModulesDidLoad (loaded_module_list); 612d4bfbc9aSGreg Clayton } 613d4bfbc9aSGreg Clayton return true; 614d4bfbc9aSGreg Clayton } 615d4bfbc9aSGreg Clayton 616d4bfbc9aSGreg Clayton 617d4bfbc9aSGreg Clayton uint32_t 618944b828aSGreg Clayton DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr, 619d4bfbc9aSGreg Clayton uint32_t image_infos_count, 620d4bfbc9aSGreg Clayton OSKextLoadedKextSummary::collection &image_infos) 621d4bfbc9aSGreg Clayton { 622d4bfbc9aSGreg Clayton const ByteOrder endian = m_kernel.GetByteOrder(); 623d4bfbc9aSGreg Clayton const uint32_t addr_size = m_kernel.GetAddressByteSize(); 624d4bfbc9aSGreg Clayton 625d4bfbc9aSGreg Clayton image_infos.resize(image_infos_count); 626d4bfbc9aSGreg Clayton const size_t count = image_infos.size() * m_kext_summary_header.entry_size; 627d4bfbc9aSGreg Clayton DataBufferHeap data(count, 0); 628d4bfbc9aSGreg Clayton Error error; 629d4bfbc9aSGreg Clayton 630d4bfbc9aSGreg Clayton const bool prefer_file_cache = false; 631d4bfbc9aSGreg Clayton const size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary_addr, 632d4bfbc9aSGreg Clayton prefer_file_cache, 633d4bfbc9aSGreg Clayton data.GetBytes(), 634d4bfbc9aSGreg Clayton data.GetByteSize(), 635d4bfbc9aSGreg Clayton error); 636d4bfbc9aSGreg Clayton if (bytes_read == count) 637d4bfbc9aSGreg Clayton { 638d4bfbc9aSGreg Clayton 639d4bfbc9aSGreg Clayton DataExtractor extractor (data.GetBytes(), data.GetByteSize(), endian, addr_size); 640d4bfbc9aSGreg Clayton uint32_t i=0; 641d4bfbc9aSGreg Clayton for (uint32_t kext_summary_offset = 0; 642d4bfbc9aSGreg Clayton i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size); 643d4bfbc9aSGreg Clayton ++i, kext_summary_offset += m_kext_summary_header.entry_size) 644d4bfbc9aSGreg Clayton { 645d4bfbc9aSGreg Clayton uint32_t offset = kext_summary_offset; 646d4bfbc9aSGreg Clayton const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME); 647d4bfbc9aSGreg Clayton if (name_data == NULL) 648d4bfbc9aSGreg Clayton break; 649d4bfbc9aSGreg Clayton memcpy (image_infos[i].name, name_data, KERNEL_MODULE_MAX_NAME); 650d4bfbc9aSGreg Clayton image_infos[i].uuid.SetBytes(extractor.GetData (&offset, 16)); 651d4bfbc9aSGreg Clayton image_infos[i].address = extractor.GetU64(&offset); 652d4bfbc9aSGreg Clayton if (!image_infos[i].so_address.SetLoadAddress (image_infos[i].address, &m_process->GetTarget())) 653d4bfbc9aSGreg Clayton m_process->GetTarget().GetImages().ResolveFileAddress (image_infos[i].address, image_infos[i].so_address); 654d4bfbc9aSGreg Clayton image_infos[i].size = extractor.GetU64(&offset); 655d4bfbc9aSGreg Clayton image_infos[i].version = extractor.GetU64(&offset); 656d4bfbc9aSGreg Clayton image_infos[i].load_tag = extractor.GetU32(&offset); 657d4bfbc9aSGreg Clayton image_infos[i].flags = extractor.GetU32(&offset); 658d4bfbc9aSGreg Clayton if ((offset - kext_summary_offset) < m_kext_summary_header.entry_size) 659d4bfbc9aSGreg Clayton { 660d4bfbc9aSGreg Clayton image_infos[i].reference_list = extractor.GetU64(&offset); 661d4bfbc9aSGreg Clayton } 662d4bfbc9aSGreg Clayton else 663d4bfbc9aSGreg Clayton { 664d4bfbc9aSGreg Clayton image_infos[i].reference_list = 0; 665d4bfbc9aSGreg Clayton } 666bae2f2f8SGreg 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", 667bae2f2f8SGreg Clayton // i, 668bae2f2f8SGreg Clayton // KERNEL_MODULE_MAX_NAME, KERNEL_MODULE_MAX_NAME, (char *)name_data, 669bae2f2f8SGreg Clayton // image_infos[i].address, 670bae2f2f8SGreg Clayton // image_infos[i].size, 671bae2f2f8SGreg Clayton // image_infos[i].version, 672bae2f2f8SGreg Clayton // image_infos[i].load_tag, 673bae2f2f8SGreg Clayton // image_infos[i].flags); 674d4bfbc9aSGreg Clayton } 675d4bfbc9aSGreg Clayton if (i < image_infos.size()) 676d4bfbc9aSGreg Clayton image_infos.resize(i); 677d4bfbc9aSGreg Clayton } 678d4bfbc9aSGreg Clayton else 679d4bfbc9aSGreg Clayton { 680d4bfbc9aSGreg Clayton image_infos.clear(); 681d4bfbc9aSGreg Clayton } 682d4bfbc9aSGreg Clayton return image_infos.size(); 683d4bfbc9aSGreg Clayton } 684d4bfbc9aSGreg Clayton 685d4bfbc9aSGreg Clayton bool 686944b828aSGreg Clayton DynamicLoaderDarwinKernel::ReadAllKextSummaries () 687d4bfbc9aSGreg Clayton { 688d4bfbc9aSGreg Clayton LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 689d4bfbc9aSGreg Clayton 690d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 691d4bfbc9aSGreg Clayton 692d4bfbc9aSGreg Clayton if (ReadKextSummaryHeader ()) 693d4bfbc9aSGreg Clayton { 694d4bfbc9aSGreg Clayton if (m_kext_summary_header.entry_count > 0 && m_kext_summary_header_addr.IsValid()) 695d4bfbc9aSGreg Clayton { 696d4bfbc9aSGreg Clayton Address summary_addr (m_kext_summary_header_addr); 697d4bfbc9aSGreg Clayton summary_addr.Slide(m_kext_summary_header.GetSize()); 698d4bfbc9aSGreg Clayton if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count)) 699d4bfbc9aSGreg Clayton { 700d4bfbc9aSGreg Clayton m_kext_summaries.clear(); 701d4bfbc9aSGreg Clayton } 702d4bfbc9aSGreg Clayton return true; 703d4bfbc9aSGreg Clayton } 704d4bfbc9aSGreg Clayton } 705d4bfbc9aSGreg Clayton return false; 706d4bfbc9aSGreg Clayton } 707d4bfbc9aSGreg Clayton 708d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 709d4bfbc9aSGreg Clayton // Dump an image info structure to the file handle provided. 710d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 711d4bfbc9aSGreg Clayton void 712944b828aSGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::PutToLog (Log *log) const 713d4bfbc9aSGreg Clayton { 714d4bfbc9aSGreg Clayton if (log == NULL) 715d4bfbc9aSGreg Clayton return; 716d4bfbc9aSGreg Clayton const uint8_t *u = (uint8_t *)uuid.GetBytes(); 717d4bfbc9aSGreg Clayton 718d4bfbc9aSGreg Clayton if (address == LLDB_INVALID_ADDRESS) 719d4bfbc9aSGreg Clayton { 720d4bfbc9aSGreg Clayton if (u) 721d4bfbc9aSGreg Clayton { 722d4bfbc9aSGreg 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)", 723d4bfbc9aSGreg Clayton u[ 0], u[ 1], u[ 2], u[ 3], 724d4bfbc9aSGreg Clayton u[ 4], u[ 5], u[ 6], u[ 7], 725d4bfbc9aSGreg Clayton u[ 8], u[ 9], u[10], u[11], 726d4bfbc9aSGreg Clayton u[12], u[13], u[14], u[15], 727d4bfbc9aSGreg Clayton name); 728d4bfbc9aSGreg Clayton } 729d4bfbc9aSGreg Clayton else 730d4bfbc9aSGreg Clayton log->Printf("\tname=\"%s\" (UNLOADED)", name); 731d4bfbc9aSGreg Clayton } 732d4bfbc9aSGreg Clayton else 733d4bfbc9aSGreg Clayton { 734d4bfbc9aSGreg Clayton if (u) 735d4bfbc9aSGreg Clayton { 736d4bfbc9aSGreg 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\"", 737d4bfbc9aSGreg Clayton address, size, version, load_tag, flags, reference_list, 738d4bfbc9aSGreg Clayton u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7], 739d4bfbc9aSGreg Clayton u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15], 740d4bfbc9aSGreg Clayton name); 741d4bfbc9aSGreg Clayton } 742d4bfbc9aSGreg Clayton else 743d4bfbc9aSGreg Clayton { 744d4bfbc9aSGreg 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\"", 745d4bfbc9aSGreg Clayton address, address+size, version, load_tag, flags, reference_list, 746d4bfbc9aSGreg Clayton name); 747d4bfbc9aSGreg Clayton } 748d4bfbc9aSGreg Clayton } 749d4bfbc9aSGreg Clayton } 750d4bfbc9aSGreg Clayton 751d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 752d4bfbc9aSGreg Clayton // Dump the _dyld_all_image_infos members and all current image infos 753d4bfbc9aSGreg Clayton // that we have parsed to the file handle provided. 754d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 755d4bfbc9aSGreg Clayton void 756944b828aSGreg Clayton DynamicLoaderDarwinKernel::PutToLog(Log *log) const 757d4bfbc9aSGreg Clayton { 758d4bfbc9aSGreg Clayton if (log == NULL) 759d4bfbc9aSGreg Clayton return; 760d4bfbc9aSGreg Clayton 761d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 762d4bfbc9aSGreg Clayton log->Printf("gLoadedKextSummaries = 0x%16.16llx { version=%u, entry_size=%u, entry_count=%u }", 763d4bfbc9aSGreg Clayton m_kext_summary_header_addr.GetFileAddress(), 764d4bfbc9aSGreg Clayton m_kext_summary_header.version, 765d4bfbc9aSGreg Clayton m_kext_summary_header.entry_size, 766d4bfbc9aSGreg Clayton m_kext_summary_header.entry_count); 767d4bfbc9aSGreg Clayton 768d4bfbc9aSGreg Clayton size_t i; 769d4bfbc9aSGreg Clayton const size_t count = m_kext_summaries.size(); 770d4bfbc9aSGreg Clayton if (count > 0) 771d4bfbc9aSGreg Clayton { 772d4bfbc9aSGreg Clayton log->PutCString("Loaded:"); 773d4bfbc9aSGreg Clayton for (i = 0; i<count; i++) 774d4bfbc9aSGreg Clayton m_kext_summaries[i].PutToLog(log); 775d4bfbc9aSGreg Clayton } 776d4bfbc9aSGreg Clayton } 777d4bfbc9aSGreg Clayton 778d4bfbc9aSGreg Clayton void 779944b828aSGreg Clayton DynamicLoaderDarwinKernel::PrivateInitialize(Process *process) 780d4bfbc9aSGreg Clayton { 781944b828aSGreg Clayton DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); 782d4bfbc9aSGreg Clayton Clear(true); 783d4bfbc9aSGreg Clayton m_process = process; 784d4bfbc9aSGreg Clayton } 785d4bfbc9aSGreg Clayton 786d4bfbc9aSGreg Clayton void 787944b828aSGreg Clayton DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded () 788d4bfbc9aSGreg Clayton { 789c859e2d5SGreg Clayton if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.module_sp) 790d4bfbc9aSGreg Clayton { 791944b828aSGreg Clayton DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); 792d4bfbc9aSGreg Clayton 793d4bfbc9aSGreg Clayton 794a8558b62SJim Ingham const bool internal_bp = true; 795d4bfbc9aSGreg Clayton const LazyBool skip_prologue = eLazyBoolNo; 796969795f1SJim Ingham FileSpecList module_spec_list; 797969795f1SJim Ingham module_spec_list.Append (m_kernel.module_sp->GetFileSpec()); 798969795f1SJim Ingham Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&module_spec_list, 79987df91b8SJim Ingham NULL, 800d4bfbc9aSGreg Clayton "OSKextLoadedKextSummariesUpdated", 801d4bfbc9aSGreg Clayton eFunctionNameTypeFull, 802a8558b62SJim Ingham skip_prologue, 803a8558b62SJim Ingham internal_bp).get(); 804d4bfbc9aSGreg Clayton 805944b828aSGreg Clayton bp->SetCallback (DynamicLoaderDarwinKernel::BreakpointHitCallback, this, true); 806d4bfbc9aSGreg Clayton m_break_id = bp->GetID(); 807d4bfbc9aSGreg Clayton } 808d4bfbc9aSGreg Clayton } 809d4bfbc9aSGreg Clayton 810d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 811d4bfbc9aSGreg Clayton // Member function that gets called when the process state changes. 812d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 813d4bfbc9aSGreg Clayton void 814944b828aSGreg Clayton DynamicLoaderDarwinKernel::PrivateProcessStateChanged (Process *process, StateType state) 815d4bfbc9aSGreg Clayton { 816944b828aSGreg Clayton DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__, StateAsCString(state)); 817d4bfbc9aSGreg Clayton switch (state) 818d4bfbc9aSGreg Clayton { 819d4bfbc9aSGreg Clayton case eStateConnected: 820d4bfbc9aSGreg Clayton case eStateAttaching: 821d4bfbc9aSGreg Clayton case eStateLaunching: 822d4bfbc9aSGreg Clayton case eStateInvalid: 823d4bfbc9aSGreg Clayton case eStateUnloaded: 824d4bfbc9aSGreg Clayton case eStateExited: 825d4bfbc9aSGreg Clayton case eStateDetached: 826d4bfbc9aSGreg Clayton Clear(false); 827d4bfbc9aSGreg Clayton break; 828d4bfbc9aSGreg Clayton 829d4bfbc9aSGreg Clayton case eStateStopped: 830d4bfbc9aSGreg Clayton UpdateIfNeeded(); 831d4bfbc9aSGreg Clayton break; 832d4bfbc9aSGreg Clayton 833d4bfbc9aSGreg Clayton case eStateRunning: 834d4bfbc9aSGreg Clayton case eStateStepping: 835d4bfbc9aSGreg Clayton case eStateCrashed: 836d4bfbc9aSGreg Clayton case eStateSuspended: 837d4bfbc9aSGreg Clayton break; 838d4bfbc9aSGreg Clayton 839d4bfbc9aSGreg Clayton default: 840d4bfbc9aSGreg Clayton break; 841d4bfbc9aSGreg Clayton } 842d4bfbc9aSGreg Clayton } 843d4bfbc9aSGreg Clayton 844d4bfbc9aSGreg Clayton ThreadPlanSP 845944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) 846d4bfbc9aSGreg Clayton { 847d4bfbc9aSGreg Clayton ThreadPlanSP thread_plan_sp; 848d4bfbc9aSGreg Clayton LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 849d4bfbc9aSGreg Clayton if (log) 850d4bfbc9aSGreg Clayton log->Printf ("Could not find symbol for step through."); 851d4bfbc9aSGreg Clayton return thread_plan_sp; 852d4bfbc9aSGreg Clayton } 853d4bfbc9aSGreg Clayton 854d4bfbc9aSGreg Clayton Error 855944b828aSGreg Clayton DynamicLoaderDarwinKernel::CanLoadImage () 856d4bfbc9aSGreg Clayton { 857d4bfbc9aSGreg Clayton Error error; 858d4bfbc9aSGreg Clayton error.SetErrorString("always unsafe to load or unload shared libraries in the darwin kernel"); 859d4bfbc9aSGreg Clayton return error; 860d4bfbc9aSGreg Clayton } 861d4bfbc9aSGreg Clayton 862d4bfbc9aSGreg Clayton void 863944b828aSGreg Clayton DynamicLoaderDarwinKernel::Initialize() 864d4bfbc9aSGreg Clayton { 865d4bfbc9aSGreg Clayton PluginManager::RegisterPlugin (GetPluginNameStatic(), 866d4bfbc9aSGreg Clayton GetPluginDescriptionStatic(), 867d4bfbc9aSGreg Clayton CreateInstance); 868d4bfbc9aSGreg Clayton } 869d4bfbc9aSGreg Clayton 870d4bfbc9aSGreg Clayton void 871944b828aSGreg Clayton DynamicLoaderDarwinKernel::Terminate() 872d4bfbc9aSGreg Clayton { 873d4bfbc9aSGreg Clayton PluginManager::UnregisterPlugin (CreateInstance); 874d4bfbc9aSGreg Clayton } 875d4bfbc9aSGreg Clayton 876d4bfbc9aSGreg Clayton 877d4bfbc9aSGreg Clayton const char * 878944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetPluginNameStatic() 879d4bfbc9aSGreg Clayton { 880d4bfbc9aSGreg Clayton return "dynamic-loader.macosx-kernel"; 881d4bfbc9aSGreg Clayton } 882d4bfbc9aSGreg Clayton 883d4bfbc9aSGreg Clayton const char * 884944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetPluginDescriptionStatic() 885d4bfbc9aSGreg Clayton { 886d4bfbc9aSGreg Clayton return "Dynamic loader plug-in that watches for shared library loads/unloads in the MacOSX kernel."; 887d4bfbc9aSGreg Clayton } 888d4bfbc9aSGreg Clayton 889d4bfbc9aSGreg Clayton 890d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 891d4bfbc9aSGreg Clayton // PluginInterface protocol 892d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 893d4bfbc9aSGreg Clayton const char * 894944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetPluginName() 895d4bfbc9aSGreg Clayton { 896944b828aSGreg Clayton return "DynamicLoaderDarwinKernel"; 897d4bfbc9aSGreg Clayton } 898d4bfbc9aSGreg Clayton 899d4bfbc9aSGreg Clayton const char * 900944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetShortPluginName() 901d4bfbc9aSGreg Clayton { 902d4bfbc9aSGreg Clayton return GetPluginNameStatic(); 903d4bfbc9aSGreg Clayton } 904d4bfbc9aSGreg Clayton 905d4bfbc9aSGreg Clayton uint32_t 906944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetPluginVersion() 907d4bfbc9aSGreg Clayton { 908d4bfbc9aSGreg Clayton return 1; 909d4bfbc9aSGreg Clayton } 910d4bfbc9aSGreg Clayton 9111f746071SGreg Clayton lldb::ByteOrder 9121f746071SGreg Clayton DynamicLoaderDarwinKernel::GetByteOrderFromMagic (uint32_t magic) 9131f746071SGreg Clayton { 9141f746071SGreg Clayton switch (magic) 9151f746071SGreg Clayton { 9161f746071SGreg Clayton case llvm::MachO::HeaderMagic32: 9171f746071SGreg Clayton case llvm::MachO::HeaderMagic64: 9181f746071SGreg Clayton return lldb::endian::InlHostByteOrder(); 9191f746071SGreg Clayton 9201f746071SGreg Clayton case llvm::MachO::HeaderMagic32Swapped: 9211f746071SGreg Clayton case llvm::MachO::HeaderMagic64Swapped: 9221f746071SGreg Clayton if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig) 9231f746071SGreg Clayton return lldb::eByteOrderLittle; 9241f746071SGreg Clayton else 9251f746071SGreg Clayton return lldb::eByteOrderBig; 9261f746071SGreg Clayton 9271f746071SGreg Clayton default: 9281f746071SGreg Clayton break; 9291f746071SGreg Clayton } 9301f746071SGreg Clayton return lldb::eByteOrderInvalid; 9311f746071SGreg Clayton } 9321f746071SGreg Clayton 933