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 42e8cd0c98SGreg Clayton static PropertyDefinition 43e8cd0c98SGreg Clayton g_properties[] = 44e8cd0c98SGreg Clayton { 45e8cd0c98SGreg Clayton { "disable-kext-loading" , OptionValue::eTypeBoolean, false, false, NULL, NULL, "Disable kext image loading in a Darwin kernel debug session." }, 46e8cd0c98SGreg Clayton { NULL , OptionValue::eTypeInvalid, false, 0 , NULL, NULL, NULL } 47e8cd0c98SGreg Clayton }; 48e8cd0c98SGreg Clayton 49e8cd0c98SGreg Clayton enum { 50e8cd0c98SGreg Clayton ePropertyDisableKextLoading 51e8cd0c98SGreg Clayton }; 52e8cd0c98SGreg Clayton 53e8cd0c98SGreg Clayton class DynamicLoaderDarwinKernelProperties : public Properties 54e8cd0c98SGreg Clayton { 55e8cd0c98SGreg Clayton public: 56e8cd0c98SGreg Clayton 57e8cd0c98SGreg Clayton static ConstString & 58e8cd0c98SGreg Clayton GetSettingName () 59e8cd0c98SGreg Clayton { 60*468ea4ebSGreg Clayton static ConstString g_setting_name("darwin-kernel"); 61e8cd0c98SGreg Clayton return g_setting_name; 62e8cd0c98SGreg Clayton } 63e8cd0c98SGreg Clayton 64e8cd0c98SGreg Clayton DynamicLoaderDarwinKernelProperties() : 65e8cd0c98SGreg Clayton Properties () 66e8cd0c98SGreg Clayton { 67e8cd0c98SGreg Clayton m_collection_sp.reset (new OptionValueProperties(GetSettingName())); 68e8cd0c98SGreg Clayton m_collection_sp->Initialize(g_properties); 69e8cd0c98SGreg Clayton } 70e8cd0c98SGreg Clayton 71e8cd0c98SGreg Clayton virtual 72e8cd0c98SGreg Clayton ~DynamicLoaderDarwinKernelProperties() 73e8cd0c98SGreg Clayton { 74e8cd0c98SGreg Clayton } 75e8cd0c98SGreg Clayton 76e8cd0c98SGreg Clayton bool 77e8cd0c98SGreg Clayton GetDisableKextLoading() const 78e8cd0c98SGreg Clayton { 79e8cd0c98SGreg Clayton const uint32_t idx = ePropertyDisableKextLoading; 80e8cd0c98SGreg Clayton return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 81e8cd0c98SGreg Clayton } 82e8cd0c98SGreg Clayton 83e8cd0c98SGreg Clayton }; 84e8cd0c98SGreg Clayton 85e8cd0c98SGreg Clayton typedef STD_SHARED_PTR(DynamicLoaderDarwinKernelProperties) DynamicLoaderDarwinKernelPropertiesSP; 86e8cd0c98SGreg Clayton 87e8cd0c98SGreg Clayton static const DynamicLoaderDarwinKernelPropertiesSP & 88e8cd0c98SGreg Clayton GetGlobalProperties() 89e8cd0c98SGreg Clayton { 90e8cd0c98SGreg Clayton static DynamicLoaderDarwinKernelPropertiesSP g_settings_sp; 91e8cd0c98SGreg Clayton if (!g_settings_sp) 92e8cd0c98SGreg Clayton g_settings_sp.reset (new DynamicLoaderDarwinKernelProperties ()); 93e8cd0c98SGreg Clayton return g_settings_sp; 94e8cd0c98SGreg Clayton } 95e8cd0c98SGreg Clayton 96d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 97d4bfbc9aSGreg Clayton // Create an instance of this class. This function is filled into 98d4bfbc9aSGreg Clayton // the plugin info class that gets handed out by the plugin factory and 99d4bfbc9aSGreg Clayton // allows the lldb to instantiate an instance of this class. 100d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 101d4bfbc9aSGreg Clayton DynamicLoader * 102944b828aSGreg Clayton DynamicLoaderDarwinKernel::CreateInstance (Process* process, bool force) 103d4bfbc9aSGreg Clayton { 104d4bfbc9aSGreg Clayton bool create = force; 105d4bfbc9aSGreg Clayton if (!create) 106d4bfbc9aSGreg Clayton { 107d4bfbc9aSGreg Clayton Module* exe_module = process->GetTarget().GetExecutableModulePointer(); 108d4bfbc9aSGreg Clayton if (exe_module) 109d4bfbc9aSGreg Clayton { 110d4bfbc9aSGreg Clayton ObjectFile *object_file = exe_module->GetObjectFile(); 111d4bfbc9aSGreg Clayton if (object_file) 112d4bfbc9aSGreg Clayton { 11349bce8ecSSean Callanan create = (object_file->GetStrata() == ObjectFile::eStrataKernel); 114d4bfbc9aSGreg Clayton } 115d4bfbc9aSGreg Clayton } 116d4bfbc9aSGreg Clayton 117d4bfbc9aSGreg Clayton if (create) 118d4bfbc9aSGreg Clayton { 119d4bfbc9aSGreg Clayton const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple(); 12070512317SGreg Clayton switch (triple_ref.getOS()) 12170512317SGreg Clayton { 12270512317SGreg Clayton case llvm::Triple::Darwin: 12370512317SGreg Clayton case llvm::Triple::MacOSX: 12470512317SGreg Clayton case llvm::Triple::IOS: 12570512317SGreg Clayton create = triple_ref.getVendor() == llvm::Triple::Apple; 12670512317SGreg Clayton break; 12770512317SGreg Clayton default: 12870512317SGreg Clayton create = false; 12970512317SGreg Clayton break; 13070512317SGreg Clayton } 131d4bfbc9aSGreg Clayton } 132d4bfbc9aSGreg Clayton } 133d4bfbc9aSGreg Clayton 134d4bfbc9aSGreg Clayton if (create) 13590539456SSean Callanan { 13690539456SSean Callanan process->SetCanJIT(false); 137944b828aSGreg Clayton return new DynamicLoaderDarwinKernel (process); 13890539456SSean Callanan } 139d4bfbc9aSGreg Clayton return NULL; 140d4bfbc9aSGreg Clayton } 141d4bfbc9aSGreg Clayton 142d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 143d4bfbc9aSGreg Clayton // Constructor 144d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 145944b828aSGreg Clayton DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel (Process* process) : 146d4bfbc9aSGreg Clayton DynamicLoader(process), 147d4bfbc9aSGreg Clayton m_kernel(), 148d4bfbc9aSGreg Clayton m_kext_summary_header_ptr_addr (), 149d4bfbc9aSGreg Clayton m_kext_summary_header_addr (), 150d4bfbc9aSGreg Clayton m_kext_summary_header (), 151d4bfbc9aSGreg Clayton m_kext_summaries(), 152a08823fdSDaniel Dunbar m_mutex(Mutex::eMutexTypeRecursive), 153a08823fdSDaniel Dunbar m_break_id (LLDB_INVALID_BREAK_ID) 154d4bfbc9aSGreg Clayton { 155d4bfbc9aSGreg Clayton } 156d4bfbc9aSGreg Clayton 157d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 158d4bfbc9aSGreg Clayton // Destructor 159d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 160944b828aSGreg Clayton DynamicLoaderDarwinKernel::~DynamicLoaderDarwinKernel() 161d4bfbc9aSGreg Clayton { 162d4bfbc9aSGreg Clayton Clear(true); 163d4bfbc9aSGreg Clayton } 164d4bfbc9aSGreg Clayton 165d4bfbc9aSGreg Clayton void 166944b828aSGreg Clayton DynamicLoaderDarwinKernel::UpdateIfNeeded() 167d4bfbc9aSGreg Clayton { 168d4bfbc9aSGreg Clayton LoadKernelModuleIfNeeded(); 169d4bfbc9aSGreg Clayton SetNotificationBreakpointIfNeeded (); 170d4bfbc9aSGreg Clayton } 171d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 172d4bfbc9aSGreg Clayton /// Called after attaching a process. 173d4bfbc9aSGreg Clayton /// 174d4bfbc9aSGreg Clayton /// Allow DynamicLoader plug-ins to execute some code after 175d4bfbc9aSGreg Clayton /// attaching to a process. 176d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 177d4bfbc9aSGreg Clayton void 178944b828aSGreg Clayton DynamicLoaderDarwinKernel::DidAttach () 179d4bfbc9aSGreg Clayton { 180d4bfbc9aSGreg Clayton PrivateInitialize(m_process); 181d4bfbc9aSGreg Clayton UpdateIfNeeded(); 182d4bfbc9aSGreg Clayton } 183d4bfbc9aSGreg Clayton 184d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 185d4bfbc9aSGreg Clayton /// Called after attaching a process. 186d4bfbc9aSGreg Clayton /// 187d4bfbc9aSGreg Clayton /// Allow DynamicLoader plug-ins to execute some code after 188d4bfbc9aSGreg Clayton /// attaching to a process. 189d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 190d4bfbc9aSGreg Clayton void 191944b828aSGreg Clayton DynamicLoaderDarwinKernel::DidLaunch () 192d4bfbc9aSGreg Clayton { 193d4bfbc9aSGreg Clayton PrivateInitialize(m_process); 194d4bfbc9aSGreg Clayton UpdateIfNeeded(); 195d4bfbc9aSGreg Clayton } 196d4bfbc9aSGreg Clayton 197d4bfbc9aSGreg Clayton 198d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 199d4bfbc9aSGreg Clayton // Clear out the state of this class. 200d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 201d4bfbc9aSGreg Clayton void 202944b828aSGreg Clayton DynamicLoaderDarwinKernel::Clear (bool clear_process) 203d4bfbc9aSGreg Clayton { 204d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 205d4bfbc9aSGreg Clayton 206d4bfbc9aSGreg Clayton if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id)) 207d4bfbc9aSGreg Clayton m_process->ClearBreakpointSiteByID(m_break_id); 208d4bfbc9aSGreg Clayton 209d4bfbc9aSGreg Clayton if (clear_process) 210d4bfbc9aSGreg Clayton m_process = NULL; 211d4bfbc9aSGreg Clayton m_kernel.Clear(false); 212d4bfbc9aSGreg Clayton m_kext_summary_header_ptr_addr.Clear(); 213d4bfbc9aSGreg Clayton m_kext_summary_header_addr.Clear(); 214d4bfbc9aSGreg Clayton m_kext_summaries.clear(); 215d4bfbc9aSGreg Clayton m_break_id = LLDB_INVALID_BREAK_ID; 216d4bfbc9aSGreg Clayton } 217d4bfbc9aSGreg Clayton 218d4bfbc9aSGreg Clayton 219c859e2d5SGreg Clayton bool 2202af282a1SGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageAtFileAddress (Process *process) 2212af282a1SGreg Clayton { 2222af282a1SGreg Clayton if (IsLoaded()) 2232af282a1SGreg Clayton return true; 2242af282a1SGreg Clayton 2252af282a1SGreg Clayton if (module_sp) 2262af282a1SGreg Clayton { 2272af282a1SGreg Clayton bool changed = false; 2282af282a1SGreg Clayton if (module_sp->SetLoadAddress (process->GetTarget(), 0, changed)) 2292af282a1SGreg Clayton load_process_stop_id = process->GetStopID(); 2302af282a1SGreg Clayton } 2312af282a1SGreg Clayton return false; 2322af282a1SGreg Clayton } 2332af282a1SGreg Clayton 2342af282a1SGreg Clayton bool 235c859e2d5SGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageUsingMemoryModule (Process *process) 236c859e2d5SGreg Clayton { 237c859e2d5SGreg Clayton if (IsLoaded()) 238c859e2d5SGreg Clayton return true; 239c859e2d5SGreg Clayton 240c859e2d5SGreg Clayton bool uuid_is_valid = uuid.IsValid(); 24168b3607fSJason Molenda bool memory_module_is_kernel = false; 242c859e2d5SGreg Clayton 243c859e2d5SGreg Clayton Target &target = process->GetTarget(); 244c859e2d5SGreg Clayton ModuleSP memory_module_sp; 24587a04b24SJason Molenda 24687a04b24SJason Molenda // If this is a kext and the user asked us to ignore kexts, don't try to load it. 247e8cd0c98SGreg Clayton if (kernel_image == false && GetGlobalProperties()->GetDisableKextLoading() == true) 24887a04b24SJason Molenda { 24987a04b24SJason Molenda return false; 25087a04b24SJason Molenda } 25187a04b24SJason Molenda 25287a04b24SJason Molenda // Use the memory module as the module if we have one 253c859e2d5SGreg Clayton if (address != LLDB_INVALID_ADDRESS) 254c859e2d5SGreg Clayton { 255c859e2d5SGreg Clayton FileSpec file_spec; 256c859e2d5SGreg Clayton if (module_sp) 257c859e2d5SGreg Clayton file_spec = module_sp->GetFileSpec(); 258c859e2d5SGreg Clayton else 259c859e2d5SGreg Clayton file_spec.SetFile (name, false); 260c859e2d5SGreg Clayton 261c859e2d5SGreg Clayton memory_module_sp = process->ReadModuleFromMemory (file_spec, address, false, false); 262c859e2d5SGreg Clayton if (memory_module_sp && !uuid_is_valid) 263c859e2d5SGreg Clayton { 264c859e2d5SGreg Clayton uuid = memory_module_sp->GetUUID(); 265c859e2d5SGreg Clayton uuid_is_valid = uuid.IsValid(); 266c859e2d5SGreg Clayton } 26768b3607fSJason Molenda if (memory_module_sp->GetObjectFile() 26868b3607fSJason Molenda && memory_module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable 26968b3607fSJason Molenda && memory_module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel) 27068b3607fSJason Molenda { 27168b3607fSJason Molenda memory_module_is_kernel = true; 27253667f5dSJason Molenda if (memory_module_sp->GetArchitecture().IsValid()) 27353667f5dSJason Molenda { 27453667f5dSJason Molenda target.SetArchitecture(memory_module_sp->GetArchitecture()); 27553667f5dSJason Molenda } 27668b3607fSJason Molenda } 277c859e2d5SGreg Clayton } 278c859e2d5SGreg Clayton 279c859e2d5SGreg Clayton if (!module_sp) 280c859e2d5SGreg Clayton { 281c859e2d5SGreg Clayton if (uuid_is_valid) 282c859e2d5SGreg Clayton { 283c859e2d5SGreg Clayton ModuleList &target_images = target.GetImages(); 284c859e2d5SGreg Clayton module_sp = target_images.FindModule(uuid); 285c859e2d5SGreg Clayton 286c859e2d5SGreg Clayton if (!module_sp) 287b9a01b39SGreg Clayton { 2882af282a1SGreg Clayton ModuleSpec module_spec; 289b9a01b39SGreg Clayton module_spec.GetUUID() = uuid; 29053667f5dSJason Molenda module_spec.GetArchitecture() = target.GetArchitecture(); 291bb860bd2SJason Molenda 292bb860bd2SJason Molenda // For the kernel, we really do need an on-disk file copy of the 293bb860bd2SJason Molenda // binary. 294bb860bd2SJason Molenda bool force_symbols_search = false; 295bb860bd2SJason Molenda if (memory_module_is_kernel) 296bb860bd2SJason Molenda { 297bb860bd2SJason Molenda force_symbols_search = true; 298bb860bd2SJason Molenda } 299bb860bd2SJason Molenda 300bb860bd2SJason Molenda if (Symbols::DownloadObjectAndSymbolFile (module_spec, force_symbols_search)) 301bb860bd2SJason Molenda { 302bb860bd2SJason Molenda if (module_spec.GetFileSpec().Exists()) 303bb860bd2SJason Molenda { 304bb860bd2SJason Molenda module_sp.reset(new Module (module_spec.GetFileSpec(), target.GetArchitecture())); 305bb860bd2SJason Molenda if (module_sp.get() && module_sp->MatchesModuleSpec (module_spec)) 306bb860bd2SJason Molenda { 307bb860bd2SJason Molenda ModuleList loaded_module_list; 308bb860bd2SJason Molenda loaded_module_list.Append (module_sp); 309bb860bd2SJason Molenda target.ModulesDidLoad (loaded_module_list); 310bb860bd2SJason Molenda } 311bb860bd2SJason Molenda } 312bb860bd2SJason Molenda } 313bb860bd2SJason Molenda 314bb860bd2SJason Molenda // Ask the Target to find this file on the local system, if possible. 315bb860bd2SJason Molenda // This will search in the list of currently-loaded files, look in the 316bb860bd2SJason Molenda // standard search paths on the system, and on a Mac it will try calling 317bb860bd2SJason Molenda // the DebugSymbols framework with the UUID to find the binary via its 318bb860bd2SJason Molenda // search methods. 319bb860bd2SJason Molenda if (!module_sp) 320bb860bd2SJason Molenda { 321b9a01b39SGreg Clayton module_sp = target.GetSharedModule (module_spec); 322b9a01b39SGreg Clayton } 323c859e2d5SGreg Clayton } 324c859e2d5SGreg Clayton } 325bb860bd2SJason Molenda } 326c859e2d5SGreg Clayton 327c859e2d5SGreg Clayton 328bb860bd2SJason Molenda if (memory_module_sp && module_sp) 329c859e2d5SGreg Clayton { 330c859e2d5SGreg Clayton if (module_sp->GetUUID() == memory_module_sp->GetUUID()) 331c859e2d5SGreg Clayton { 332bb860bd2SJason Molenda target.GetImages().Append(module_sp); 333bb860bd2SJason Molenda if (memory_module_is_kernel && target.GetExecutableModulePointer() != module_sp.get()) 334bb860bd2SJason Molenda { 335bb860bd2SJason Molenda target.SetExecutableModule (module_sp, false); 336bb860bd2SJason Molenda } 337bb860bd2SJason Molenda 338c859e2d5SGreg Clayton ObjectFile *ondisk_object_file = module_sp->GetObjectFile(); 339c859e2d5SGreg Clayton ObjectFile *memory_object_file = memory_module_sp->GetObjectFile(); 340c859e2d5SGreg Clayton if (memory_object_file && ondisk_object_file) 341c859e2d5SGreg Clayton { 342c859e2d5SGreg Clayton SectionList *ondisk_section_list = ondisk_object_file->GetSectionList (); 343c859e2d5SGreg Clayton SectionList *memory_section_list = memory_object_file->GetSectionList (); 344c859e2d5SGreg Clayton if (memory_section_list && ondisk_section_list) 345c859e2d5SGreg Clayton { 346bae2f2f8SGreg Clayton const uint32_t num_ondisk_sections = ondisk_section_list->GetSize(); 347c859e2d5SGreg Clayton // There may be CTF sections in the memory image so we can't 348c859e2d5SGreg Clayton // always just compare the number of sections (which are actually 349c859e2d5SGreg Clayton // segments in mach-o parlance) 350c859e2d5SGreg Clayton uint32_t sect_idx = 0; 351bae2f2f8SGreg Clayton 35253667f5dSJason Molenda // Use the memory_module's addresses for each section to set the 35353667f5dSJason Molenda // file module's load address as appropriate. We don't want to use 35453667f5dSJason Molenda // a single slide value for the entire kext - different segments may 35553667f5dSJason Molenda // be slid different amounts by the kext loader. 356bae2f2f8SGreg Clayton 357bae2f2f8SGreg Clayton uint32_t num_sections_loaded = 0; 358bae2f2f8SGreg Clayton for (sect_idx=0; sect_idx<num_ondisk_sections; ++sect_idx) 359c859e2d5SGreg Clayton { 3607820bd1eSGreg Clayton SectionSP ondisk_section_sp(ondisk_section_list->GetSectionAtIndex(sect_idx)); 3617820bd1eSGreg Clayton if (ondisk_section_sp) 362c859e2d5SGreg Clayton { 3637820bd1eSGreg Clayton const Section *memory_section = memory_section_list->FindSectionByName(ondisk_section_sp->GetName()).get(); 364bae2f2f8SGreg Clayton if (memory_section) 365c859e2d5SGreg Clayton { 3667820bd1eSGreg Clayton target.GetSectionLoadList().SetSectionLoadAddress (ondisk_section_sp, memory_section->GetFileAddress()); 367bae2f2f8SGreg Clayton ++num_sections_loaded; 368c859e2d5SGreg Clayton } 369bae2f2f8SGreg Clayton } 370bae2f2f8SGreg Clayton } 371bae2f2f8SGreg Clayton if (num_sections_loaded > 0) 372c859e2d5SGreg Clayton load_process_stop_id = process->GetStopID(); 373bae2f2f8SGreg Clayton else 374bae2f2f8SGreg Clayton module_sp.reset(); // No sections were loaded 375c859e2d5SGreg Clayton } 376c859e2d5SGreg Clayton else 377c859e2d5SGreg Clayton module_sp.reset(); // One or both section lists 378c859e2d5SGreg Clayton } 379c859e2d5SGreg Clayton else 380c859e2d5SGreg Clayton module_sp.reset(); // One or both object files missing 381c859e2d5SGreg Clayton } 382c859e2d5SGreg Clayton else 383c859e2d5SGreg Clayton module_sp.reset(); // UUID mismatch 384c859e2d5SGreg Clayton } 385c859e2d5SGreg Clayton 386c859e2d5SGreg Clayton bool is_loaded = IsLoaded(); 387c859e2d5SGreg Clayton 388c859e2d5SGreg Clayton if (so_address.IsValid()) 389c859e2d5SGreg Clayton { 390c859e2d5SGreg Clayton if (is_loaded) 391c859e2d5SGreg Clayton so_address.SetLoadAddress (address, &target); 392c859e2d5SGreg Clayton else 393c859e2d5SGreg Clayton target.GetImages().ResolveFileAddress (address, so_address); 394c859e2d5SGreg Clayton 395c859e2d5SGreg Clayton } 39668b3607fSJason Molenda 39768b3607fSJason Molenda if (is_loaded && module_sp && memory_module_is_kernel) 39868b3607fSJason Molenda { 39968b3607fSJason Molenda Stream *s = &target.GetDebugger().GetOutputStream(); 40068b3607fSJason Molenda if (s) 40168b3607fSJason Molenda { 40268b3607fSJason Molenda char uuidbuf[64]; 40368b3607fSJason Molenda s->Printf ("Kernel UUID: %s\n", module_sp->GetUUID().GetAsCString(uuidbuf, sizeof (uuidbuf))); 40468b3607fSJason Molenda s->Printf ("Load Address: 0x%llx\n", address); 405743e4396SJason Molenda if (module_sp->GetFileSpec().GetDirectory().IsEmpty()) 406743e4396SJason Molenda { 407743e4396SJason Molenda s->Printf ("Loaded kernel file %s\n", module_sp->GetFileSpec().GetFilename().AsCString()); 408743e4396SJason Molenda } 409743e4396SJason Molenda else 410743e4396SJason Molenda { 41168b3607fSJason Molenda s->Printf ("Loaded kernel file %s/%s\n", 41268b3607fSJason Molenda module_sp->GetFileSpec().GetDirectory().AsCString(), 41368b3607fSJason Molenda module_sp->GetFileSpec().GetFilename().AsCString()); 414743e4396SJason Molenda } 41568b3607fSJason Molenda s->Flush (); 41668b3607fSJason Molenda } 41768b3607fSJason Molenda } 418c859e2d5SGreg Clayton return is_loaded; 419c859e2d5SGreg Clayton } 420c859e2d5SGreg Clayton 4211f746071SGreg Clayton uint32_t 4221f746071SGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetAddressByteSize () 4231f746071SGreg Clayton { 4241f746071SGreg Clayton if (module_sp) 4251f746071SGreg Clayton return module_sp->GetArchitecture().GetAddressByteSize(); 4261f746071SGreg Clayton return 0; 4271f746071SGreg Clayton } 4281f746071SGreg Clayton 4291f746071SGreg Clayton lldb::ByteOrder 4301f746071SGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetByteOrder() 4311f746071SGreg Clayton { 4321f746071SGreg Clayton if (module_sp) 4331f746071SGreg Clayton return module_sp->GetArchitecture().GetByteOrder(); 4341f746071SGreg Clayton return lldb::endian::InlHostByteOrder(); 4351f746071SGreg Clayton } 4361f746071SGreg Clayton 4371f746071SGreg Clayton lldb_private::ArchSpec 4381f746071SGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetArchitecture () const 4391f746071SGreg Clayton { 4401f746071SGreg Clayton if (module_sp) 4411f746071SGreg Clayton return module_sp->GetArchitecture(); 4421f746071SGreg Clayton return lldb_private::ArchSpec (); 4431f746071SGreg Clayton } 4441f746071SGreg Clayton 4451f746071SGreg Clayton 446d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 447d4bfbc9aSGreg Clayton // Load the kernel module and initialize the "m_kernel" member. Return 448d4bfbc9aSGreg Clayton // true _only_ if the kernel is loaded the first time through (subsequent 449d4bfbc9aSGreg Clayton // calls to this function should return false after the kernel has been 450d4bfbc9aSGreg Clayton // already loaded). 451d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 452d4bfbc9aSGreg Clayton void 453944b828aSGreg Clayton DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() 454d4bfbc9aSGreg Clayton { 455d4bfbc9aSGreg Clayton if (!m_kext_summary_header_ptr_addr.IsValid()) 456d4bfbc9aSGreg Clayton { 457d4bfbc9aSGreg Clayton m_kernel.Clear(false); 458d4bfbc9aSGreg Clayton m_kernel.module_sp = m_process->GetTarget().GetExecutableModule(); 45987a04b24SJason Molenda m_kernel.kernel_image = true; 4604bd4e7e3SJason Molenda 4614bd4e7e3SJason Molenda ConstString kernel_name("mach_kernel"); 4624bd4e7e3SJason Molenda if (m_kernel.module_sp.get() 4634bd4e7e3SJason Molenda && m_kernel.module_sp->GetObjectFile() 4644bd4e7e3SJason Molenda && !m_kernel.module_sp->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty()) 4654bd4e7e3SJason Molenda { 4664bd4e7e3SJason Molenda kernel_name = m_kernel.module_sp->GetObjectFile()->GetFileSpec().GetFilename(); 4674bd4e7e3SJason Molenda } 46831a6961cSJason Molenda strncpy (m_kernel.name, kernel_name.AsCString(), sizeof(m_kernel.name)); 46931a6961cSJason Molenda m_kernel.name[sizeof (m_kernel.name) - 1] = '\0'; 4704bd4e7e3SJason Molenda 471c859e2d5SGreg Clayton if (m_kernel.address == LLDB_INVALID_ADDRESS) 472d4bfbc9aSGreg Clayton { 473c859e2d5SGreg Clayton m_kernel.address = m_process->GetImageInfoAddress (); 474c859e2d5SGreg Clayton if (m_kernel.address == LLDB_INVALID_ADDRESS && m_kernel.module_sp) 475c859e2d5SGreg Clayton { 476c859e2d5SGreg Clayton // We didn't get a hint from the process, so we will 477c859e2d5SGreg Clayton // try the kernel at the address that it exists at in 478c859e2d5SGreg Clayton // the file if we have one 479c859e2d5SGreg Clayton ObjectFile *kernel_object_file = m_kernel.module_sp->GetObjectFile(); 480c859e2d5SGreg Clayton if (kernel_object_file) 4814bd4e7e3SJason Molenda { 4824bd4e7e3SJason Molenda addr_t load_address = kernel_object_file->GetHeaderAddress().GetLoadAddress(&m_process->GetTarget()); 4834bd4e7e3SJason Molenda addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress(); 4844bd4e7e3SJason Molenda if (load_address != LLDB_INVALID_ADDRESS && load_address != 0) 4854bd4e7e3SJason Molenda { 4864bd4e7e3SJason Molenda m_kernel.address = load_address; 4874bd4e7e3SJason Molenda if (load_address != file_address) 4884bd4e7e3SJason Molenda { 4894bd4e7e3SJason Molenda // Don't accidentally relocate the kernel to the File address -- 4904bd4e7e3SJason Molenda // the Load address has already been set to its actual in-memory address. 4914bd4e7e3SJason Molenda // Mark it as IsLoaded. 4924bd4e7e3SJason Molenda m_kernel.load_process_stop_id = m_process->GetStopID(); 4934bd4e7e3SJason Molenda } 4944bd4e7e3SJason Molenda } 4954bd4e7e3SJason Molenda else 4964bd4e7e3SJason Molenda { 4974bd4e7e3SJason Molenda m_kernel.address = file_address; 4984bd4e7e3SJason Molenda } 4994bd4e7e3SJason Molenda } 500c859e2d5SGreg Clayton } 501c859e2d5SGreg Clayton } 502c859e2d5SGreg Clayton 503c859e2d5SGreg Clayton if (m_kernel.address != LLDB_INVALID_ADDRESS) 5042af282a1SGreg Clayton { 5052af282a1SGreg Clayton if (!m_kernel.LoadImageUsingMemoryModule (m_process)) 5062af282a1SGreg Clayton { 5072af282a1SGreg Clayton m_kernel.LoadImageAtFileAddress (m_process); 5082af282a1SGreg Clayton } 5092af282a1SGreg Clayton } 510c859e2d5SGreg Clayton 51128eb5711SJim Ingham if (m_kernel.IsLoaded() && m_kernel.module_sp) 512c859e2d5SGreg Clayton { 513d4bfbc9aSGreg Clayton static ConstString kext_summary_symbol ("gLoadedKextSummaries"); 514c859e2d5SGreg Clayton const Symbol *symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData); 515d4bfbc9aSGreg Clayton if (symbol) 516c859e2d5SGreg Clayton { 517e7612134SGreg Clayton m_kext_summary_header_ptr_addr = symbol->GetAddress(); 518d4bfbc9aSGreg Clayton // Update all image infos 519d4bfbc9aSGreg Clayton ReadAllKextSummaries (); 520d4bfbc9aSGreg Clayton } 521d4bfbc9aSGreg Clayton } 522d4bfbc9aSGreg Clayton else 523d4bfbc9aSGreg Clayton { 524d4bfbc9aSGreg Clayton m_kernel.Clear(false); 525d4bfbc9aSGreg Clayton } 526d4bfbc9aSGreg Clayton } 527d4bfbc9aSGreg Clayton } 528d4bfbc9aSGreg Clayton 529d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 530d4bfbc9aSGreg Clayton // Static callback function that gets called when our DYLD notification 531d4bfbc9aSGreg Clayton // breakpoint gets hit. We update all of our image infos and then 532d4bfbc9aSGreg Clayton // let our super class DynamicLoader class decide if we should stop 533d4bfbc9aSGreg Clayton // or not (based on global preference). 534d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 535d4bfbc9aSGreg Clayton bool 536944b828aSGreg Clayton DynamicLoaderDarwinKernel::BreakpointHitCallback (void *baton, 537d4bfbc9aSGreg Clayton StoppointCallbackContext *context, 538d4bfbc9aSGreg Clayton user_id_t break_id, 539d4bfbc9aSGreg Clayton user_id_t break_loc_id) 540d4bfbc9aSGreg Clayton { 541944b828aSGreg Clayton return static_cast<DynamicLoaderDarwinKernel*>(baton)->BreakpointHit (context, break_id, break_loc_id); 542d4bfbc9aSGreg Clayton } 543d4bfbc9aSGreg Clayton 544d4bfbc9aSGreg Clayton bool 545944b828aSGreg Clayton DynamicLoaderDarwinKernel::BreakpointHit (StoppointCallbackContext *context, 546d4bfbc9aSGreg Clayton user_id_t break_id, 547d4bfbc9aSGreg Clayton user_id_t break_loc_id) 548d4bfbc9aSGreg Clayton { 549d4bfbc9aSGreg Clayton LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 550d4bfbc9aSGreg Clayton if (log) 551944b828aSGreg Clayton log->Printf ("DynamicLoaderDarwinKernel::BreakpointHit (...)\n"); 552d4bfbc9aSGreg Clayton 553d4bfbc9aSGreg Clayton ReadAllKextSummaries (); 554d4bfbc9aSGreg Clayton 555d4bfbc9aSGreg Clayton if (log) 556d4bfbc9aSGreg Clayton PutToLog(log.get()); 557d4bfbc9aSGreg Clayton 558d4bfbc9aSGreg Clayton return GetStopWhenImagesChange(); 559d4bfbc9aSGreg Clayton } 560d4bfbc9aSGreg Clayton 561d4bfbc9aSGreg Clayton 562d4bfbc9aSGreg Clayton bool 563944b828aSGreg Clayton DynamicLoaderDarwinKernel::ReadKextSummaryHeader () 564d4bfbc9aSGreg Clayton { 565d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 566d4bfbc9aSGreg Clayton 567d4bfbc9aSGreg Clayton // the all image infos is already valid for this process stop ID 568d4bfbc9aSGreg Clayton 569d4bfbc9aSGreg Clayton m_kext_summaries.clear(); 570d4bfbc9aSGreg Clayton if (m_kext_summary_header_ptr_addr.IsValid()) 571d4bfbc9aSGreg Clayton { 572d4bfbc9aSGreg Clayton const uint32_t addr_size = m_kernel.GetAddressByteSize (); 573d4bfbc9aSGreg Clayton const ByteOrder byte_order = m_kernel.GetByteOrder(); 574d4bfbc9aSGreg Clayton Error error; 575d4bfbc9aSGreg Clayton // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure 576d4bfbc9aSGreg Clayton // which is currenty 4 uint32_t and a pointer. 577d4bfbc9aSGreg Clayton uint8_t buf[24]; 578d4bfbc9aSGreg Clayton DataExtractor data (buf, sizeof(buf), byte_order, addr_size); 579d4bfbc9aSGreg Clayton const size_t count = 4 * sizeof(uint32_t) + addr_size; 580d4bfbc9aSGreg Clayton const bool prefer_file_cache = false; 581d4bfbc9aSGreg Clayton if (m_process->GetTarget().ReadPointerFromMemory (m_kext_summary_header_ptr_addr, 582d4bfbc9aSGreg Clayton prefer_file_cache, 583d4bfbc9aSGreg Clayton error, 584d4bfbc9aSGreg Clayton m_kext_summary_header_addr)) 585d4bfbc9aSGreg Clayton { 586d4bfbc9aSGreg Clayton // We got a valid address for our kext summary header and make sure it isn't NULL 587d4bfbc9aSGreg Clayton if (m_kext_summary_header_addr.IsValid() && 588d4bfbc9aSGreg Clayton m_kext_summary_header_addr.GetFileAddress() != 0) 589d4bfbc9aSGreg Clayton { 590d4bfbc9aSGreg Clayton const size_t bytes_read = m_process->GetTarget().ReadMemory (m_kext_summary_header_addr, prefer_file_cache, buf, count, error); 591d4bfbc9aSGreg Clayton if (bytes_read == count) 592d4bfbc9aSGreg Clayton { 593d4bfbc9aSGreg Clayton uint32_t offset = 0; 594d4bfbc9aSGreg Clayton m_kext_summary_header.version = data.GetU32(&offset); 595d4bfbc9aSGreg Clayton if (m_kext_summary_header.version >= 2) 596d4bfbc9aSGreg Clayton { 597d4bfbc9aSGreg Clayton m_kext_summary_header.entry_size = data.GetU32(&offset); 598d4bfbc9aSGreg Clayton } 599d4bfbc9aSGreg Clayton else 600d4bfbc9aSGreg Clayton { 601d4bfbc9aSGreg Clayton // Versions less than 2 didn't have an entry size, it was hard coded 602d4bfbc9aSGreg Clayton m_kext_summary_header.entry_size = KERNEL_MODULE_ENTRY_SIZE_VERSION_1; 603d4bfbc9aSGreg Clayton } 604d4bfbc9aSGreg Clayton m_kext_summary_header.entry_count = data.GetU32(&offset); 605d4bfbc9aSGreg Clayton return true; 606d4bfbc9aSGreg Clayton } 607d4bfbc9aSGreg Clayton } 608d4bfbc9aSGreg Clayton } 609d4bfbc9aSGreg Clayton } 610d4bfbc9aSGreg Clayton m_kext_summary_header_addr.Clear(); 611d4bfbc9aSGreg Clayton return false; 612d4bfbc9aSGreg Clayton } 613d4bfbc9aSGreg Clayton 614d4bfbc9aSGreg Clayton 615d4bfbc9aSGreg Clayton bool 616944b828aSGreg Clayton DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr, 617d4bfbc9aSGreg Clayton uint32_t count) 618d4bfbc9aSGreg Clayton { 619d4bfbc9aSGreg Clayton OSKextLoadedKextSummary::collection kext_summaries; 620d4bfbc9aSGreg Clayton LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 621d4bfbc9aSGreg Clayton if (log) 622fd54b368SJason Molenda log->Printf ("Adding %d modules.\n", count); 623d4bfbc9aSGreg Clayton 624d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 625d4bfbc9aSGreg Clayton 626d4bfbc9aSGreg Clayton if (!ReadKextSummaries (kext_summary_addr, count, kext_summaries)) 627d4bfbc9aSGreg Clayton return false; 628d4bfbc9aSGreg Clayton 629d4bfbc9aSGreg Clayton Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream(); 63068b3607fSJason Molenda if (s) 63168b3607fSJason Molenda s->Printf ("Loading %d kext modules ", count); 632d4bfbc9aSGreg Clayton for (uint32_t i = 0; i < count; i++) 633d4bfbc9aSGreg Clayton { 6342af282a1SGreg Clayton if (!kext_summaries[i].LoadImageUsingMemoryModule (m_process)) 6352af282a1SGreg Clayton kext_summaries[i].LoadImageAtFileAddress (m_process); 636d4bfbc9aSGreg Clayton 637d4bfbc9aSGreg Clayton if (s) 63868b3607fSJason Molenda s->Printf ("."); 639d4bfbc9aSGreg Clayton 640d4bfbc9aSGreg Clayton if (log) 641d4bfbc9aSGreg Clayton kext_summaries[i].PutToLog (log.get()); 642d4bfbc9aSGreg Clayton } 64368b3607fSJason Molenda if (s) 64468b3607fSJason Molenda { 64568b3607fSJason Molenda s->Printf (" done.\n"); 64668b3607fSJason Molenda s->Flush (); 64768b3607fSJason Molenda } 64868b3607fSJason Molenda 649d4bfbc9aSGreg Clayton bool return_value = AddModulesUsingImageInfos (kext_summaries); 650d4bfbc9aSGreg Clayton return return_value; 651d4bfbc9aSGreg Clayton } 652d4bfbc9aSGreg Clayton 653d4bfbc9aSGreg Clayton // Adds the modules in image_infos to m_kext_summaries. 654d4bfbc9aSGreg Clayton // NB don't call this passing in m_kext_summaries. 655d4bfbc9aSGreg Clayton 656d4bfbc9aSGreg Clayton bool 657944b828aSGreg Clayton DynamicLoaderDarwinKernel::AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos) 658d4bfbc9aSGreg Clayton { 659d4bfbc9aSGreg Clayton // Now add these images to the main list. 660d4bfbc9aSGreg Clayton ModuleList loaded_module_list; 661d4bfbc9aSGreg Clayton 662d4bfbc9aSGreg Clayton for (uint32_t idx = 0; idx < image_infos.size(); ++idx) 663d4bfbc9aSGreg Clayton { 664c859e2d5SGreg Clayton OSKextLoadedKextSummary &image_info = image_infos[idx]; 665c859e2d5SGreg Clayton m_kext_summaries.push_back(image_info); 666d4bfbc9aSGreg Clayton 667c859e2d5SGreg Clayton if (image_info.module_sp && m_process->GetStopID() == image_info.load_process_stop_id) 668d4bfbc9aSGreg Clayton loaded_module_list.AppendIfNeeded (image_infos[idx].module_sp); 669d4bfbc9aSGreg Clayton } 670d4bfbc9aSGreg Clayton 671d4bfbc9aSGreg Clayton if (loaded_module_list.GetSize() > 0) 672d4bfbc9aSGreg Clayton { 673d4bfbc9aSGreg Clayton m_process->GetTarget().ModulesDidLoad (loaded_module_list); 674d4bfbc9aSGreg Clayton } 675d4bfbc9aSGreg Clayton return true; 676d4bfbc9aSGreg Clayton } 677d4bfbc9aSGreg Clayton 678d4bfbc9aSGreg Clayton 679d4bfbc9aSGreg Clayton uint32_t 680944b828aSGreg Clayton DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr, 681d4bfbc9aSGreg Clayton uint32_t image_infos_count, 682d4bfbc9aSGreg Clayton OSKextLoadedKextSummary::collection &image_infos) 683d4bfbc9aSGreg Clayton { 684d4bfbc9aSGreg Clayton const ByteOrder endian = m_kernel.GetByteOrder(); 685d4bfbc9aSGreg Clayton const uint32_t addr_size = m_kernel.GetAddressByteSize(); 686d4bfbc9aSGreg Clayton 687d4bfbc9aSGreg Clayton image_infos.resize(image_infos_count); 688d4bfbc9aSGreg Clayton const size_t count = image_infos.size() * m_kext_summary_header.entry_size; 689d4bfbc9aSGreg Clayton DataBufferHeap data(count, 0); 690d4bfbc9aSGreg Clayton Error error; 691d4bfbc9aSGreg Clayton 692d4bfbc9aSGreg Clayton const bool prefer_file_cache = false; 693d4bfbc9aSGreg Clayton const size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary_addr, 694d4bfbc9aSGreg Clayton prefer_file_cache, 695d4bfbc9aSGreg Clayton data.GetBytes(), 696d4bfbc9aSGreg Clayton data.GetByteSize(), 697d4bfbc9aSGreg Clayton error); 698d4bfbc9aSGreg Clayton if (bytes_read == count) 699d4bfbc9aSGreg Clayton { 700d4bfbc9aSGreg Clayton 701d4bfbc9aSGreg Clayton DataExtractor extractor (data.GetBytes(), data.GetByteSize(), endian, addr_size); 702d4bfbc9aSGreg Clayton uint32_t i=0; 703d4bfbc9aSGreg Clayton for (uint32_t kext_summary_offset = 0; 704d4bfbc9aSGreg Clayton i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size); 705d4bfbc9aSGreg Clayton ++i, kext_summary_offset += m_kext_summary_header.entry_size) 706d4bfbc9aSGreg Clayton { 707d4bfbc9aSGreg Clayton uint32_t offset = kext_summary_offset; 708d4bfbc9aSGreg Clayton const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME); 709d4bfbc9aSGreg Clayton if (name_data == NULL) 710d4bfbc9aSGreg Clayton break; 711d4bfbc9aSGreg Clayton memcpy (image_infos[i].name, name_data, KERNEL_MODULE_MAX_NAME); 712d4bfbc9aSGreg Clayton image_infos[i].uuid.SetBytes(extractor.GetData (&offset, 16)); 713d4bfbc9aSGreg Clayton image_infos[i].address = extractor.GetU64(&offset); 714d4bfbc9aSGreg Clayton if (!image_infos[i].so_address.SetLoadAddress (image_infos[i].address, &m_process->GetTarget())) 715d4bfbc9aSGreg Clayton m_process->GetTarget().GetImages().ResolveFileAddress (image_infos[i].address, image_infos[i].so_address); 716d4bfbc9aSGreg Clayton image_infos[i].size = extractor.GetU64(&offset); 717d4bfbc9aSGreg Clayton image_infos[i].version = extractor.GetU64(&offset); 718d4bfbc9aSGreg Clayton image_infos[i].load_tag = extractor.GetU32(&offset); 719d4bfbc9aSGreg Clayton image_infos[i].flags = extractor.GetU32(&offset); 720d4bfbc9aSGreg Clayton if ((offset - kext_summary_offset) < m_kext_summary_header.entry_size) 721d4bfbc9aSGreg Clayton { 722d4bfbc9aSGreg Clayton image_infos[i].reference_list = extractor.GetU64(&offset); 723d4bfbc9aSGreg Clayton } 724d4bfbc9aSGreg Clayton else 725d4bfbc9aSGreg Clayton { 726d4bfbc9aSGreg Clayton image_infos[i].reference_list = 0; 727d4bfbc9aSGreg Clayton } 728bae2f2f8SGreg 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", 729bae2f2f8SGreg Clayton // i, 730bae2f2f8SGreg Clayton // KERNEL_MODULE_MAX_NAME, KERNEL_MODULE_MAX_NAME, (char *)name_data, 731bae2f2f8SGreg Clayton // image_infos[i].address, 732bae2f2f8SGreg Clayton // image_infos[i].size, 733bae2f2f8SGreg Clayton // image_infos[i].version, 734bae2f2f8SGreg Clayton // image_infos[i].load_tag, 735bae2f2f8SGreg Clayton // image_infos[i].flags); 736d4bfbc9aSGreg Clayton } 737d4bfbc9aSGreg Clayton if (i < image_infos.size()) 738d4bfbc9aSGreg Clayton image_infos.resize(i); 739d4bfbc9aSGreg Clayton } 740d4bfbc9aSGreg Clayton else 741d4bfbc9aSGreg Clayton { 742d4bfbc9aSGreg Clayton image_infos.clear(); 743d4bfbc9aSGreg Clayton } 744d4bfbc9aSGreg Clayton return image_infos.size(); 745d4bfbc9aSGreg Clayton } 746d4bfbc9aSGreg Clayton 747d4bfbc9aSGreg Clayton bool 748944b828aSGreg Clayton DynamicLoaderDarwinKernel::ReadAllKextSummaries () 749d4bfbc9aSGreg Clayton { 750d4bfbc9aSGreg Clayton LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 751d4bfbc9aSGreg Clayton 752d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 753d4bfbc9aSGreg Clayton 754d4bfbc9aSGreg Clayton if (ReadKextSummaryHeader ()) 755d4bfbc9aSGreg Clayton { 756d4bfbc9aSGreg Clayton if (m_kext_summary_header.entry_count > 0 && m_kext_summary_header_addr.IsValid()) 757d4bfbc9aSGreg Clayton { 758d4bfbc9aSGreg Clayton Address summary_addr (m_kext_summary_header_addr); 759d4bfbc9aSGreg Clayton summary_addr.Slide(m_kext_summary_header.GetSize()); 760d4bfbc9aSGreg Clayton if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count)) 761d4bfbc9aSGreg Clayton { 762d4bfbc9aSGreg Clayton m_kext_summaries.clear(); 763d4bfbc9aSGreg Clayton } 764d4bfbc9aSGreg Clayton return true; 765d4bfbc9aSGreg Clayton } 766d4bfbc9aSGreg Clayton } 767d4bfbc9aSGreg Clayton return false; 768d4bfbc9aSGreg Clayton } 769d4bfbc9aSGreg Clayton 770d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 771d4bfbc9aSGreg Clayton // Dump an image info structure to the file handle provided. 772d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 773d4bfbc9aSGreg Clayton void 774944b828aSGreg Clayton DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::PutToLog (Log *log) const 775d4bfbc9aSGreg Clayton { 776d4bfbc9aSGreg Clayton if (log == NULL) 777d4bfbc9aSGreg Clayton return; 778d4bfbc9aSGreg Clayton const uint8_t *u = (uint8_t *)uuid.GetBytes(); 779d4bfbc9aSGreg Clayton 780d4bfbc9aSGreg Clayton if (address == LLDB_INVALID_ADDRESS) 781d4bfbc9aSGreg Clayton { 782d4bfbc9aSGreg Clayton if (u) 783d4bfbc9aSGreg Clayton { 784d4bfbc9aSGreg 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)", 785d4bfbc9aSGreg Clayton u[ 0], u[ 1], u[ 2], u[ 3], 786d4bfbc9aSGreg Clayton u[ 4], u[ 5], u[ 6], u[ 7], 787d4bfbc9aSGreg Clayton u[ 8], u[ 9], u[10], u[11], 788d4bfbc9aSGreg Clayton u[12], u[13], u[14], u[15], 789d4bfbc9aSGreg Clayton name); 790d4bfbc9aSGreg Clayton } 791d4bfbc9aSGreg Clayton else 792d4bfbc9aSGreg Clayton log->Printf("\tname=\"%s\" (UNLOADED)", name); 793d4bfbc9aSGreg Clayton } 794d4bfbc9aSGreg Clayton else 795d4bfbc9aSGreg Clayton { 796d4bfbc9aSGreg Clayton if (u) 797d4bfbc9aSGreg Clayton { 798d4bfbc9aSGreg 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\"", 799d4bfbc9aSGreg Clayton address, size, version, load_tag, flags, reference_list, 800d4bfbc9aSGreg Clayton u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7], 801d4bfbc9aSGreg Clayton u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15], 802d4bfbc9aSGreg Clayton name); 803d4bfbc9aSGreg Clayton } 804d4bfbc9aSGreg Clayton else 805d4bfbc9aSGreg Clayton { 806d4bfbc9aSGreg 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\"", 807d4bfbc9aSGreg Clayton address, address+size, version, load_tag, flags, reference_list, 808d4bfbc9aSGreg Clayton name); 809d4bfbc9aSGreg Clayton } 810d4bfbc9aSGreg Clayton } 811d4bfbc9aSGreg Clayton } 812d4bfbc9aSGreg Clayton 813d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 814d4bfbc9aSGreg Clayton // Dump the _dyld_all_image_infos members and all current image infos 815d4bfbc9aSGreg Clayton // that we have parsed to the file handle provided. 816d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 817d4bfbc9aSGreg Clayton void 818944b828aSGreg Clayton DynamicLoaderDarwinKernel::PutToLog(Log *log) const 819d4bfbc9aSGreg Clayton { 820d4bfbc9aSGreg Clayton if (log == NULL) 821d4bfbc9aSGreg Clayton return; 822d4bfbc9aSGreg Clayton 823d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 824d4bfbc9aSGreg Clayton log->Printf("gLoadedKextSummaries = 0x%16.16llx { version=%u, entry_size=%u, entry_count=%u }", 825d4bfbc9aSGreg Clayton m_kext_summary_header_addr.GetFileAddress(), 826d4bfbc9aSGreg Clayton m_kext_summary_header.version, 827d4bfbc9aSGreg Clayton m_kext_summary_header.entry_size, 828d4bfbc9aSGreg Clayton m_kext_summary_header.entry_count); 829d4bfbc9aSGreg Clayton 830d4bfbc9aSGreg Clayton size_t i; 831d4bfbc9aSGreg Clayton const size_t count = m_kext_summaries.size(); 832d4bfbc9aSGreg Clayton if (count > 0) 833d4bfbc9aSGreg Clayton { 834d4bfbc9aSGreg Clayton log->PutCString("Loaded:"); 835d4bfbc9aSGreg Clayton for (i = 0; i<count; i++) 836d4bfbc9aSGreg Clayton m_kext_summaries[i].PutToLog(log); 837d4bfbc9aSGreg Clayton } 838d4bfbc9aSGreg Clayton } 839d4bfbc9aSGreg Clayton 840d4bfbc9aSGreg Clayton void 841944b828aSGreg Clayton DynamicLoaderDarwinKernel::PrivateInitialize(Process *process) 842d4bfbc9aSGreg Clayton { 843944b828aSGreg Clayton DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); 844d4bfbc9aSGreg Clayton Clear(true); 845d4bfbc9aSGreg Clayton m_process = process; 846d4bfbc9aSGreg Clayton } 847d4bfbc9aSGreg Clayton 848d4bfbc9aSGreg Clayton void 849944b828aSGreg Clayton DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded () 850d4bfbc9aSGreg Clayton { 851c859e2d5SGreg Clayton if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.module_sp) 852d4bfbc9aSGreg Clayton { 853944b828aSGreg Clayton DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); 854d4bfbc9aSGreg Clayton 855d4bfbc9aSGreg Clayton 856a8558b62SJim Ingham const bool internal_bp = true; 857d4bfbc9aSGreg Clayton const LazyBool skip_prologue = eLazyBoolNo; 858969795f1SJim Ingham FileSpecList module_spec_list; 859969795f1SJim Ingham module_spec_list.Append (m_kernel.module_sp->GetFileSpec()); 860969795f1SJim Ingham Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&module_spec_list, 86187df91b8SJim Ingham NULL, 862d4bfbc9aSGreg Clayton "OSKextLoadedKextSummariesUpdated", 863d4bfbc9aSGreg Clayton eFunctionNameTypeFull, 864a8558b62SJim Ingham skip_prologue, 865a8558b62SJim Ingham internal_bp).get(); 866d4bfbc9aSGreg Clayton 867944b828aSGreg Clayton bp->SetCallback (DynamicLoaderDarwinKernel::BreakpointHitCallback, this, true); 868d4bfbc9aSGreg Clayton m_break_id = bp->GetID(); 869d4bfbc9aSGreg Clayton } 870d4bfbc9aSGreg Clayton } 871d4bfbc9aSGreg Clayton 872d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 873d4bfbc9aSGreg Clayton // Member function that gets called when the process state changes. 874d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 875d4bfbc9aSGreg Clayton void 876944b828aSGreg Clayton DynamicLoaderDarwinKernel::PrivateProcessStateChanged (Process *process, StateType state) 877d4bfbc9aSGreg Clayton { 878944b828aSGreg Clayton DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__, StateAsCString(state)); 879d4bfbc9aSGreg Clayton switch (state) 880d4bfbc9aSGreg Clayton { 881d4bfbc9aSGreg Clayton case eStateConnected: 882d4bfbc9aSGreg Clayton case eStateAttaching: 883d4bfbc9aSGreg Clayton case eStateLaunching: 884d4bfbc9aSGreg Clayton case eStateInvalid: 885d4bfbc9aSGreg Clayton case eStateUnloaded: 886d4bfbc9aSGreg Clayton case eStateExited: 887d4bfbc9aSGreg Clayton case eStateDetached: 888d4bfbc9aSGreg Clayton Clear(false); 889d4bfbc9aSGreg Clayton break; 890d4bfbc9aSGreg Clayton 891d4bfbc9aSGreg Clayton case eStateStopped: 892d4bfbc9aSGreg Clayton UpdateIfNeeded(); 893d4bfbc9aSGreg Clayton break; 894d4bfbc9aSGreg Clayton 895d4bfbc9aSGreg Clayton case eStateRunning: 896d4bfbc9aSGreg Clayton case eStateStepping: 897d4bfbc9aSGreg Clayton case eStateCrashed: 898d4bfbc9aSGreg Clayton case eStateSuspended: 899d4bfbc9aSGreg Clayton break; 900d4bfbc9aSGreg Clayton 901d4bfbc9aSGreg Clayton default: 902d4bfbc9aSGreg Clayton break; 903d4bfbc9aSGreg Clayton } 904d4bfbc9aSGreg Clayton } 905d4bfbc9aSGreg Clayton 906d4bfbc9aSGreg Clayton ThreadPlanSP 907944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) 908d4bfbc9aSGreg Clayton { 909d4bfbc9aSGreg Clayton ThreadPlanSP thread_plan_sp; 910d4bfbc9aSGreg Clayton LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 911d4bfbc9aSGreg Clayton if (log) 912d4bfbc9aSGreg Clayton log->Printf ("Could not find symbol for step through."); 913d4bfbc9aSGreg Clayton return thread_plan_sp; 914d4bfbc9aSGreg Clayton } 915d4bfbc9aSGreg Clayton 916d4bfbc9aSGreg Clayton Error 917944b828aSGreg Clayton DynamicLoaderDarwinKernel::CanLoadImage () 918d4bfbc9aSGreg Clayton { 919d4bfbc9aSGreg Clayton Error error; 920d4bfbc9aSGreg Clayton error.SetErrorString("always unsafe to load or unload shared libraries in the darwin kernel"); 921d4bfbc9aSGreg Clayton return error; 922d4bfbc9aSGreg Clayton } 923d4bfbc9aSGreg Clayton 924d4bfbc9aSGreg Clayton void 925944b828aSGreg Clayton DynamicLoaderDarwinKernel::Initialize() 926d4bfbc9aSGreg Clayton { 927d4bfbc9aSGreg Clayton PluginManager::RegisterPlugin (GetPluginNameStatic(), 928d4bfbc9aSGreg Clayton GetPluginDescriptionStatic(), 929e8cd0c98SGreg Clayton CreateInstance, 930e8cd0c98SGreg Clayton DebuggerInitialize); 931d4bfbc9aSGreg Clayton } 932d4bfbc9aSGreg Clayton 933d4bfbc9aSGreg Clayton void 934944b828aSGreg Clayton DynamicLoaderDarwinKernel::Terminate() 935d4bfbc9aSGreg Clayton { 936d4bfbc9aSGreg Clayton PluginManager::UnregisterPlugin (CreateInstance); 937d4bfbc9aSGreg Clayton } 938d4bfbc9aSGreg Clayton 939e8cd0c98SGreg Clayton void 940e8cd0c98SGreg Clayton DynamicLoaderDarwinKernel::DebuggerInitialize (lldb_private::Debugger &debugger) 941e8cd0c98SGreg Clayton { 942e8cd0c98SGreg Clayton if (!PluginManager::GetSettingForDynamicLoaderPlugin (debugger, DynamicLoaderDarwinKernelProperties::GetSettingName())) 943e8cd0c98SGreg Clayton { 944e8cd0c98SGreg Clayton const bool is_global_setting = true; 945e8cd0c98SGreg Clayton PluginManager::CreateSettingForDynamicLoaderPlugin (debugger, 946e8cd0c98SGreg Clayton GetGlobalProperties()->GetValueProperties(), 947e8cd0c98SGreg Clayton ConstString ("Properties for the DynamicLoaderDarwinKernel plug-in."), 948e8cd0c98SGreg Clayton is_global_setting); 949e8cd0c98SGreg Clayton } 950e8cd0c98SGreg Clayton } 951d4bfbc9aSGreg Clayton 952d4bfbc9aSGreg Clayton const char * 953944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetPluginNameStatic() 954d4bfbc9aSGreg Clayton { 955*468ea4ebSGreg Clayton return "dynamic-loader.darwin-kernel"; 956d4bfbc9aSGreg Clayton } 957d4bfbc9aSGreg Clayton 958d4bfbc9aSGreg Clayton const char * 959944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetPluginDescriptionStatic() 960d4bfbc9aSGreg Clayton { 961d4bfbc9aSGreg Clayton return "Dynamic loader plug-in that watches for shared library loads/unloads in the MacOSX kernel."; 962d4bfbc9aSGreg Clayton } 963d4bfbc9aSGreg Clayton 964d4bfbc9aSGreg Clayton 965d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 966d4bfbc9aSGreg Clayton // PluginInterface protocol 967d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 968d4bfbc9aSGreg Clayton const char * 969944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetPluginName() 970d4bfbc9aSGreg Clayton { 971944b828aSGreg Clayton return "DynamicLoaderDarwinKernel"; 972d4bfbc9aSGreg Clayton } 973d4bfbc9aSGreg Clayton 974d4bfbc9aSGreg Clayton const char * 975944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetShortPluginName() 976d4bfbc9aSGreg Clayton { 977d4bfbc9aSGreg Clayton return GetPluginNameStatic(); 978d4bfbc9aSGreg Clayton } 979d4bfbc9aSGreg Clayton 980d4bfbc9aSGreg Clayton uint32_t 981944b828aSGreg Clayton DynamicLoaderDarwinKernel::GetPluginVersion() 982d4bfbc9aSGreg Clayton { 983d4bfbc9aSGreg Clayton return 1; 984d4bfbc9aSGreg Clayton } 985d4bfbc9aSGreg Clayton 9861f746071SGreg Clayton lldb::ByteOrder 9871f746071SGreg Clayton DynamicLoaderDarwinKernel::GetByteOrderFromMagic (uint32_t magic) 9881f746071SGreg Clayton { 9891f746071SGreg Clayton switch (magic) 9901f746071SGreg Clayton { 9911f746071SGreg Clayton case llvm::MachO::HeaderMagic32: 9921f746071SGreg Clayton case llvm::MachO::HeaderMagic64: 9931f746071SGreg Clayton return lldb::endian::InlHostByteOrder(); 9941f746071SGreg Clayton 9951f746071SGreg Clayton case llvm::MachO::HeaderMagic32Swapped: 9961f746071SGreg Clayton case llvm::MachO::HeaderMagic64Swapped: 9971f746071SGreg Clayton if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig) 9981f746071SGreg Clayton return lldb::eByteOrderLittle; 9991f746071SGreg Clayton else 10001f746071SGreg Clayton return lldb::eByteOrderBig; 10011f746071SGreg Clayton 10021f746071SGreg Clayton default: 10031f746071SGreg Clayton break; 10041f746071SGreg Clayton } 10051f746071SGreg Clayton return lldb::eByteOrderInvalid; 10061f746071SGreg Clayton } 10071f746071SGreg Clayton 1008