1*d4bfbc9aSGreg Clayton //===-- DynamicLoaderMacOSXKernel.cpp -----------------------------*- C++ -*-===// 2*d4bfbc9aSGreg Clayton // 3*d4bfbc9aSGreg Clayton // The LLVM Compiler Infrastructure 4*d4bfbc9aSGreg Clayton // 5*d4bfbc9aSGreg Clayton // This file is distributed under the University of Illinois Open Source 6*d4bfbc9aSGreg Clayton // License. See LICENSE.TXT for details. 7*d4bfbc9aSGreg Clayton // 8*d4bfbc9aSGreg Clayton //===----------------------------------------------------------------------===// 9*d4bfbc9aSGreg Clayton 10*d4bfbc9aSGreg Clayton #include "lldb/Breakpoint/StoppointCallbackContext.h" 11*d4bfbc9aSGreg Clayton #include "lldb/Core/DataBuffer.h" 12*d4bfbc9aSGreg Clayton #include "lldb/Core/DataBufferHeap.h" 13*d4bfbc9aSGreg Clayton #include "lldb/Core/Debugger.h" 14*d4bfbc9aSGreg Clayton #include "lldb/Core/Log.h" 15*d4bfbc9aSGreg Clayton #include "lldb/Core/Module.h" 16*d4bfbc9aSGreg Clayton #include "lldb/Core/PluginManager.h" 17*d4bfbc9aSGreg Clayton #include "lldb/Core/State.h" 18*d4bfbc9aSGreg Clayton #include "lldb/Symbol/ObjectFile.h" 19*d4bfbc9aSGreg Clayton #include "lldb/Target/ObjCLanguageRuntime.h" 20*d4bfbc9aSGreg Clayton #include "lldb/Target/RegisterContext.h" 21*d4bfbc9aSGreg Clayton #include "lldb/Target/Target.h" 22*d4bfbc9aSGreg Clayton #include "lldb/Target/Thread.h" 23*d4bfbc9aSGreg Clayton #include "lldb/Target/ThreadPlanRunToAddress.h" 24*d4bfbc9aSGreg Clayton #include "lldb/Target/StackFrame.h" 25*d4bfbc9aSGreg Clayton 26*d4bfbc9aSGreg Clayton #include "DynamicLoaderMacOSXKernel.h" 27*d4bfbc9aSGreg Clayton 28*d4bfbc9aSGreg Clayton //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN 29*d4bfbc9aSGreg Clayton #ifdef ENABLE_DEBUG_PRINTF 30*d4bfbc9aSGreg Clayton #include <stdio.h> 31*d4bfbc9aSGreg Clayton #define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__) 32*d4bfbc9aSGreg Clayton #else 33*d4bfbc9aSGreg Clayton #define DEBUG_PRINTF(fmt, ...) 34*d4bfbc9aSGreg Clayton #endif 35*d4bfbc9aSGreg Clayton 36*d4bfbc9aSGreg Clayton using namespace lldb; 37*d4bfbc9aSGreg Clayton using namespace lldb_private; 38*d4bfbc9aSGreg Clayton 39*d4bfbc9aSGreg Clayton /// FIXME - The ObjC Runtime trampoline handler doesn't really belong here. 40*d4bfbc9aSGreg Clayton /// I am putting it here so I can invoke it in the Trampoline code here, but 41*d4bfbc9aSGreg Clayton /// it should be moved to the ObjC Runtime support when it is set up. 42*d4bfbc9aSGreg Clayton 43*d4bfbc9aSGreg Clayton 44*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 45*d4bfbc9aSGreg Clayton // Create an instance of this class. This function is filled into 46*d4bfbc9aSGreg Clayton // the plugin info class that gets handed out by the plugin factory and 47*d4bfbc9aSGreg Clayton // allows the lldb to instantiate an instance of this class. 48*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 49*d4bfbc9aSGreg Clayton DynamicLoader * 50*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::CreateInstance (Process* process, bool force) 51*d4bfbc9aSGreg Clayton { 52*d4bfbc9aSGreg Clayton bool create = force; 53*d4bfbc9aSGreg Clayton if (!create) 54*d4bfbc9aSGreg Clayton { 55*d4bfbc9aSGreg Clayton Module* exe_module = process->GetTarget().GetExecutableModulePointer(); 56*d4bfbc9aSGreg Clayton if (exe_module) 57*d4bfbc9aSGreg Clayton { 58*d4bfbc9aSGreg Clayton ObjectFile *object_file = exe_module->GetObjectFile(); 59*d4bfbc9aSGreg Clayton if (object_file) 60*d4bfbc9aSGreg Clayton { 61*d4bfbc9aSGreg Clayton SectionList *section_list = object_file->GetSectionList(); 62*d4bfbc9aSGreg Clayton if (section_list) 63*d4bfbc9aSGreg Clayton { 64*d4bfbc9aSGreg Clayton static ConstString g_kld_section_name ("__KLD"); 65*d4bfbc9aSGreg Clayton if (section_list->FindSectionByName (g_kld_section_name)) 66*d4bfbc9aSGreg Clayton { 67*d4bfbc9aSGreg Clayton create = true; 68*d4bfbc9aSGreg Clayton } 69*d4bfbc9aSGreg Clayton } 70*d4bfbc9aSGreg Clayton } 71*d4bfbc9aSGreg Clayton } 72*d4bfbc9aSGreg Clayton 73*d4bfbc9aSGreg Clayton if (create) 74*d4bfbc9aSGreg Clayton { 75*d4bfbc9aSGreg Clayton const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple(); 76*d4bfbc9aSGreg Clayton create = triple_ref.getOS() == llvm::Triple::Darwin && triple_ref.getVendor() == llvm::Triple::Apple; 77*d4bfbc9aSGreg Clayton } 78*d4bfbc9aSGreg Clayton } 79*d4bfbc9aSGreg Clayton 80*d4bfbc9aSGreg Clayton if (create) 81*d4bfbc9aSGreg Clayton return new DynamicLoaderMacOSXKernel (process); 82*d4bfbc9aSGreg Clayton return NULL; 83*d4bfbc9aSGreg Clayton } 84*d4bfbc9aSGreg Clayton 85*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 86*d4bfbc9aSGreg Clayton // Constructor 87*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 88*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::DynamicLoaderMacOSXKernel (Process* process) : 89*d4bfbc9aSGreg Clayton DynamicLoader(process), 90*d4bfbc9aSGreg Clayton m_kernel(), 91*d4bfbc9aSGreg Clayton m_kext_summary_header_ptr_addr (), 92*d4bfbc9aSGreg Clayton m_kext_summary_header_addr (), 93*d4bfbc9aSGreg Clayton m_kext_summary_header (), 94*d4bfbc9aSGreg Clayton m_break_id (LLDB_INVALID_BREAK_ID), 95*d4bfbc9aSGreg Clayton m_kext_summaries(), 96*d4bfbc9aSGreg Clayton m_mutex(Mutex::eMutexTypeRecursive) 97*d4bfbc9aSGreg Clayton { 98*d4bfbc9aSGreg Clayton } 99*d4bfbc9aSGreg Clayton 100*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 101*d4bfbc9aSGreg Clayton // Destructor 102*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 103*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::~DynamicLoaderMacOSXKernel() 104*d4bfbc9aSGreg Clayton { 105*d4bfbc9aSGreg Clayton Clear(true); 106*d4bfbc9aSGreg Clayton } 107*d4bfbc9aSGreg Clayton 108*d4bfbc9aSGreg Clayton void 109*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::UpdateIfNeeded() 110*d4bfbc9aSGreg Clayton { 111*d4bfbc9aSGreg Clayton LoadKernelModuleIfNeeded(); 112*d4bfbc9aSGreg Clayton SetNotificationBreakpointIfNeeded (); 113*d4bfbc9aSGreg Clayton } 114*d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 115*d4bfbc9aSGreg Clayton /// Called after attaching a process. 116*d4bfbc9aSGreg Clayton /// 117*d4bfbc9aSGreg Clayton /// Allow DynamicLoader plug-ins to execute some code after 118*d4bfbc9aSGreg Clayton /// attaching to a process. 119*d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 120*d4bfbc9aSGreg Clayton void 121*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::DidAttach () 122*d4bfbc9aSGreg Clayton { 123*d4bfbc9aSGreg Clayton PrivateInitialize(m_process); 124*d4bfbc9aSGreg Clayton UpdateIfNeeded(); 125*d4bfbc9aSGreg Clayton } 126*d4bfbc9aSGreg Clayton 127*d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 128*d4bfbc9aSGreg Clayton /// Called after attaching a process. 129*d4bfbc9aSGreg Clayton /// 130*d4bfbc9aSGreg Clayton /// Allow DynamicLoader plug-ins to execute some code after 131*d4bfbc9aSGreg Clayton /// attaching to a process. 132*d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 133*d4bfbc9aSGreg Clayton void 134*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::DidLaunch () 135*d4bfbc9aSGreg Clayton { 136*d4bfbc9aSGreg Clayton PrivateInitialize(m_process); 137*d4bfbc9aSGreg Clayton UpdateIfNeeded(); 138*d4bfbc9aSGreg Clayton } 139*d4bfbc9aSGreg Clayton 140*d4bfbc9aSGreg Clayton 141*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 142*d4bfbc9aSGreg Clayton // Clear out the state of this class. 143*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 144*d4bfbc9aSGreg Clayton void 145*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::Clear (bool clear_process) 146*d4bfbc9aSGreg Clayton { 147*d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 148*d4bfbc9aSGreg Clayton 149*d4bfbc9aSGreg Clayton if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id)) 150*d4bfbc9aSGreg Clayton m_process->ClearBreakpointSiteByID(m_break_id); 151*d4bfbc9aSGreg Clayton 152*d4bfbc9aSGreg Clayton if (clear_process) 153*d4bfbc9aSGreg Clayton m_process = NULL; 154*d4bfbc9aSGreg Clayton m_kernel.Clear(false); 155*d4bfbc9aSGreg Clayton m_kext_summary_header_ptr_addr.Clear(); 156*d4bfbc9aSGreg Clayton m_kext_summary_header_addr.Clear(); 157*d4bfbc9aSGreg Clayton m_kext_summaries.clear(); 158*d4bfbc9aSGreg Clayton m_break_id = LLDB_INVALID_BREAK_ID; 159*d4bfbc9aSGreg Clayton } 160*d4bfbc9aSGreg Clayton 161*d4bfbc9aSGreg Clayton 162*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 163*d4bfbc9aSGreg Clayton // Load the kernel module and initialize the "m_kernel" member. Return 164*d4bfbc9aSGreg Clayton // true _only_ if the kernel is loaded the first time through (subsequent 165*d4bfbc9aSGreg Clayton // calls to this function should return false after the kernel has been 166*d4bfbc9aSGreg Clayton // already loaded). 167*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 168*d4bfbc9aSGreg Clayton void 169*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::LoadKernelModuleIfNeeded() 170*d4bfbc9aSGreg Clayton { 171*d4bfbc9aSGreg Clayton if (!m_kext_summary_header_ptr_addr.IsValid()) 172*d4bfbc9aSGreg Clayton { 173*d4bfbc9aSGreg Clayton m_kernel.Clear(false); 174*d4bfbc9aSGreg Clayton m_kernel.module_sp = m_process->GetTarget().GetExecutableModule(); 175*d4bfbc9aSGreg Clayton if (m_kernel.module_sp) 176*d4bfbc9aSGreg Clayton { 177*d4bfbc9aSGreg Clayton static ConstString mach_header_name ("_mh_execute_header"); 178*d4bfbc9aSGreg Clayton static ConstString kext_summary_symbol ("gLoadedKextSummaries"); 179*d4bfbc9aSGreg Clayton const Symbol *symbol = NULL; 180*d4bfbc9aSGreg Clayton symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData); 181*d4bfbc9aSGreg Clayton if (symbol) 182*d4bfbc9aSGreg Clayton m_kext_summary_header_ptr_addr = symbol->GetValue(); 183*d4bfbc9aSGreg Clayton 184*d4bfbc9aSGreg Clayton symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (mach_header_name, eSymbolTypeAbsolute); 185*d4bfbc9aSGreg Clayton if (symbol) 186*d4bfbc9aSGreg Clayton { 187*d4bfbc9aSGreg Clayton // The "_mh_execute_header" symbol is absolute and not a section based 188*d4bfbc9aSGreg Clayton // symbol that will have a valid address, so we need to resolve it... 189*d4bfbc9aSGreg Clayton m_process->GetTarget().GetImages().ResolveFileAddress (symbol->GetValue().GetFileAddress(), m_kernel.so_address); 190*d4bfbc9aSGreg Clayton DataExtractor data; // Load command data 191*d4bfbc9aSGreg Clayton if (ReadMachHeader (m_kernel, &data)) 192*d4bfbc9aSGreg Clayton { 193*d4bfbc9aSGreg Clayton if (m_kernel.header.filetype == llvm::MachO::HeaderFileTypeExecutable) 194*d4bfbc9aSGreg Clayton { 195*d4bfbc9aSGreg Clayton if (ParseLoadCommands (data, m_kernel)) 196*d4bfbc9aSGreg Clayton UpdateImageLoadAddress (m_kernel); 197*d4bfbc9aSGreg Clayton 198*d4bfbc9aSGreg Clayton // Update all image infos 199*d4bfbc9aSGreg Clayton ReadAllKextSummaries (); 200*d4bfbc9aSGreg Clayton } 201*d4bfbc9aSGreg Clayton } 202*d4bfbc9aSGreg Clayton else 203*d4bfbc9aSGreg Clayton { 204*d4bfbc9aSGreg Clayton m_kernel.Clear(false); 205*d4bfbc9aSGreg Clayton } 206*d4bfbc9aSGreg Clayton } 207*d4bfbc9aSGreg Clayton } 208*d4bfbc9aSGreg Clayton } 209*d4bfbc9aSGreg Clayton } 210*d4bfbc9aSGreg Clayton 211*d4bfbc9aSGreg Clayton bool 212*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::FindTargetModule (OSKextLoadedKextSummary &image_info, bool can_create, bool *did_create_ptr) 213*d4bfbc9aSGreg Clayton { 214*d4bfbc9aSGreg Clayton if (did_create_ptr) 215*d4bfbc9aSGreg Clayton *did_create_ptr = false; 216*d4bfbc9aSGreg Clayton 217*d4bfbc9aSGreg Clayton const bool image_info_uuid_is_valid = image_info.uuid.IsValid(); 218*d4bfbc9aSGreg Clayton 219*d4bfbc9aSGreg Clayton if (image_info.module_sp) 220*d4bfbc9aSGreg Clayton { 221*d4bfbc9aSGreg Clayton if (image_info_uuid_is_valid) 222*d4bfbc9aSGreg Clayton { 223*d4bfbc9aSGreg Clayton if (image_info.module_sp->GetUUID() == image_info.uuid) 224*d4bfbc9aSGreg Clayton return true; 225*d4bfbc9aSGreg Clayton else 226*d4bfbc9aSGreg Clayton image_info.module_sp.reset(); 227*d4bfbc9aSGreg Clayton } 228*d4bfbc9aSGreg Clayton else 229*d4bfbc9aSGreg Clayton return true; 230*d4bfbc9aSGreg Clayton } 231*d4bfbc9aSGreg Clayton 232*d4bfbc9aSGreg Clayton ModuleList &target_images = m_process->GetTarget().GetImages(); 233*d4bfbc9aSGreg Clayton if (image_info_uuid_is_valid) 234*d4bfbc9aSGreg Clayton image_info.module_sp = target_images.FindModule(image_info.uuid); 235*d4bfbc9aSGreg Clayton 236*d4bfbc9aSGreg Clayton if (image_info.module_sp) 237*d4bfbc9aSGreg Clayton return true; 238*d4bfbc9aSGreg Clayton 239*d4bfbc9aSGreg Clayton ArchSpec arch (image_info.GetArchitecture ()); 240*d4bfbc9aSGreg Clayton if (can_create) 241*d4bfbc9aSGreg Clayton { 242*d4bfbc9aSGreg Clayton if (image_info_uuid_is_valid) 243*d4bfbc9aSGreg Clayton { 244*d4bfbc9aSGreg Clayton image_info.module_sp = m_process->GetTarget().GetSharedModule (FileSpec(), 245*d4bfbc9aSGreg Clayton arch, 246*d4bfbc9aSGreg Clayton &image_info.uuid); 247*d4bfbc9aSGreg Clayton if (did_create_ptr) 248*d4bfbc9aSGreg Clayton *did_create_ptr = image_info.module_sp; 249*d4bfbc9aSGreg Clayton } 250*d4bfbc9aSGreg Clayton } 251*d4bfbc9aSGreg Clayton return image_info.module_sp; 252*d4bfbc9aSGreg Clayton } 253*d4bfbc9aSGreg Clayton 254*d4bfbc9aSGreg Clayton bool 255*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::UpdateCommPageLoadAddress(Module *module) 256*d4bfbc9aSGreg Clayton { 257*d4bfbc9aSGreg Clayton bool changed = false; 258*d4bfbc9aSGreg Clayton if (module) 259*d4bfbc9aSGreg Clayton { 260*d4bfbc9aSGreg Clayton ObjectFile *image_object_file = module->GetObjectFile(); 261*d4bfbc9aSGreg Clayton if (image_object_file) 262*d4bfbc9aSGreg Clayton { 263*d4bfbc9aSGreg Clayton SectionList *section_list = image_object_file->GetSectionList (); 264*d4bfbc9aSGreg Clayton if (section_list) 265*d4bfbc9aSGreg Clayton { 266*d4bfbc9aSGreg Clayton uint32_t num_sections = section_list->GetSize(); 267*d4bfbc9aSGreg Clayton for (uint32_t i=0; i<num_sections; ++i) 268*d4bfbc9aSGreg Clayton { 269*d4bfbc9aSGreg Clayton Section* section = section_list->GetSectionAtIndex (i).get(); 270*d4bfbc9aSGreg Clayton if (section) 271*d4bfbc9aSGreg Clayton { 272*d4bfbc9aSGreg Clayton const addr_t new_section_load_addr = section->GetFileAddress (); 273*d4bfbc9aSGreg Clayton const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section); 274*d4bfbc9aSGreg Clayton if (old_section_load_addr == LLDB_INVALID_ADDRESS || 275*d4bfbc9aSGreg Clayton old_section_load_addr != new_section_load_addr) 276*d4bfbc9aSGreg Clayton { 277*d4bfbc9aSGreg Clayton if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress ())) 278*d4bfbc9aSGreg Clayton changed = true; 279*d4bfbc9aSGreg Clayton } 280*d4bfbc9aSGreg Clayton } 281*d4bfbc9aSGreg Clayton } 282*d4bfbc9aSGreg Clayton } 283*d4bfbc9aSGreg Clayton } 284*d4bfbc9aSGreg Clayton } 285*d4bfbc9aSGreg Clayton return changed; 286*d4bfbc9aSGreg Clayton } 287*d4bfbc9aSGreg Clayton 288*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 289*d4bfbc9aSGreg Clayton // Update the load addresses for all segments in MODULE using the 290*d4bfbc9aSGreg Clayton // updated INFO that is passed in. 291*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 292*d4bfbc9aSGreg Clayton bool 293*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::UpdateImageLoadAddress (OSKextLoadedKextSummary& info) 294*d4bfbc9aSGreg Clayton { 295*d4bfbc9aSGreg Clayton Module *module = info.module_sp.get(); 296*d4bfbc9aSGreg Clayton bool changed = false; 297*d4bfbc9aSGreg Clayton if (module) 298*d4bfbc9aSGreg Clayton { 299*d4bfbc9aSGreg Clayton ObjectFile *image_object_file = module->GetObjectFile(); 300*d4bfbc9aSGreg Clayton if (image_object_file) 301*d4bfbc9aSGreg Clayton { 302*d4bfbc9aSGreg Clayton SectionList *section_list = image_object_file->GetSectionList (); 303*d4bfbc9aSGreg Clayton if (section_list) 304*d4bfbc9aSGreg Clayton { 305*d4bfbc9aSGreg Clayton // We now know the slide amount, so go through all sections 306*d4bfbc9aSGreg Clayton // and update the load addresses with the correct values. 307*d4bfbc9aSGreg Clayton uint32_t num_segments = info.segments.size(); 308*d4bfbc9aSGreg Clayton for (uint32_t i=0; i<num_segments; ++i) 309*d4bfbc9aSGreg Clayton { 310*d4bfbc9aSGreg Clayton const addr_t new_section_load_addr = info.segments[i].vmaddr; 311*d4bfbc9aSGreg Clayton if (section_list->FindSectionByName(info.segments[i].name)) 312*d4bfbc9aSGreg Clayton { 313*d4bfbc9aSGreg Clayton SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name)); 314*d4bfbc9aSGreg Clayton if (section_sp) 315*d4bfbc9aSGreg Clayton { 316*d4bfbc9aSGreg Clayton const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp.get()); 317*d4bfbc9aSGreg Clayton if (old_section_load_addr == LLDB_INVALID_ADDRESS || 318*d4bfbc9aSGreg Clayton old_section_load_addr != new_section_load_addr) 319*d4bfbc9aSGreg Clayton { 320*d4bfbc9aSGreg Clayton if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), new_section_load_addr)) 321*d4bfbc9aSGreg Clayton changed = true; 322*d4bfbc9aSGreg Clayton } 323*d4bfbc9aSGreg Clayton } 324*d4bfbc9aSGreg Clayton else 325*d4bfbc9aSGreg Clayton { 326*d4bfbc9aSGreg Clayton fprintf (stderr, 327*d4bfbc9aSGreg Clayton "warning: unable to find and load segment named '%s' at 0x%llx in '%s/%s' in macosx dynamic loader plug-in.\n", 328*d4bfbc9aSGreg Clayton info.segments[i].name.AsCString("<invalid>"), 329*d4bfbc9aSGreg Clayton (uint64_t)new_section_load_addr, 330*d4bfbc9aSGreg Clayton image_object_file->GetFileSpec().GetDirectory().AsCString(), 331*d4bfbc9aSGreg Clayton image_object_file->GetFileSpec().GetFilename().AsCString()); 332*d4bfbc9aSGreg Clayton } 333*d4bfbc9aSGreg Clayton } 334*d4bfbc9aSGreg Clayton else 335*d4bfbc9aSGreg Clayton { 336*d4bfbc9aSGreg Clayton // The segment name is empty which means this is a .o file. 337*d4bfbc9aSGreg Clayton // Object files in LLDB end up getting reorganized so that 338*d4bfbc9aSGreg Clayton // the segment name that is in the section is promoted into 339*d4bfbc9aSGreg Clayton // an actual segment, so we just need to go through all sections 340*d4bfbc9aSGreg Clayton // and slide them by a single amount. 341*d4bfbc9aSGreg Clayton 342*d4bfbc9aSGreg Clayton uint32_t num_sections = section_list->GetSize(); 343*d4bfbc9aSGreg Clayton for (uint32_t i=0; i<num_sections; ++i) 344*d4bfbc9aSGreg Clayton { 345*d4bfbc9aSGreg Clayton Section* section = section_list->GetSectionAtIndex (i).get(); 346*d4bfbc9aSGreg Clayton if (section) 347*d4bfbc9aSGreg Clayton { 348*d4bfbc9aSGreg Clayton if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress() + new_section_load_addr)) 349*d4bfbc9aSGreg Clayton changed = true; 350*d4bfbc9aSGreg Clayton } 351*d4bfbc9aSGreg Clayton } 352*d4bfbc9aSGreg Clayton } 353*d4bfbc9aSGreg Clayton } 354*d4bfbc9aSGreg Clayton } 355*d4bfbc9aSGreg Clayton } 356*d4bfbc9aSGreg Clayton } 357*d4bfbc9aSGreg Clayton return changed; 358*d4bfbc9aSGreg Clayton } 359*d4bfbc9aSGreg Clayton 360*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 361*d4bfbc9aSGreg Clayton // Update the load addresses for all segments in MODULE using the 362*d4bfbc9aSGreg Clayton // updated INFO that is passed in. 363*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 364*d4bfbc9aSGreg Clayton bool 365*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::UnloadImageLoadAddress (OSKextLoadedKextSummary& info) 366*d4bfbc9aSGreg Clayton { 367*d4bfbc9aSGreg Clayton Module *module = info.module_sp.get(); 368*d4bfbc9aSGreg Clayton bool changed = false; 369*d4bfbc9aSGreg Clayton if (module) 370*d4bfbc9aSGreg Clayton { 371*d4bfbc9aSGreg Clayton ObjectFile *image_object_file = module->GetObjectFile(); 372*d4bfbc9aSGreg Clayton if (image_object_file) 373*d4bfbc9aSGreg Clayton { 374*d4bfbc9aSGreg Clayton SectionList *section_list = image_object_file->GetSectionList (); 375*d4bfbc9aSGreg Clayton if (section_list) 376*d4bfbc9aSGreg Clayton { 377*d4bfbc9aSGreg Clayton uint32_t num_segments = info.segments.size(); 378*d4bfbc9aSGreg Clayton for (uint32_t i=0; i<num_segments; ++i) 379*d4bfbc9aSGreg Clayton { 380*d4bfbc9aSGreg Clayton SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name)); 381*d4bfbc9aSGreg Clayton if (section_sp) 382*d4bfbc9aSGreg Clayton { 383*d4bfbc9aSGreg Clayton const addr_t old_section_load_addr = info.segments[i].vmaddr; 384*d4bfbc9aSGreg Clayton if (m_process->GetTarget().GetSectionLoadList().SetSectionUnloaded (section_sp.get(), old_section_load_addr)) 385*d4bfbc9aSGreg Clayton changed = true; 386*d4bfbc9aSGreg Clayton } 387*d4bfbc9aSGreg Clayton else 388*d4bfbc9aSGreg Clayton { 389*d4bfbc9aSGreg Clayton fprintf (stderr, 390*d4bfbc9aSGreg Clayton "warning: unable to find and unload segment named '%s' in '%s/%s' in macosx dynamic loader plug-in.\n", 391*d4bfbc9aSGreg Clayton info.segments[i].name.AsCString("<invalid>"), 392*d4bfbc9aSGreg Clayton image_object_file->GetFileSpec().GetDirectory().AsCString(), 393*d4bfbc9aSGreg Clayton image_object_file->GetFileSpec().GetFilename().AsCString()); 394*d4bfbc9aSGreg Clayton } 395*d4bfbc9aSGreg Clayton } 396*d4bfbc9aSGreg Clayton } 397*d4bfbc9aSGreg Clayton } 398*d4bfbc9aSGreg Clayton } 399*d4bfbc9aSGreg Clayton return changed; 400*d4bfbc9aSGreg Clayton } 401*d4bfbc9aSGreg Clayton 402*d4bfbc9aSGreg Clayton 403*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 404*d4bfbc9aSGreg Clayton // Static callback function that gets called when our DYLD notification 405*d4bfbc9aSGreg Clayton // breakpoint gets hit. We update all of our image infos and then 406*d4bfbc9aSGreg Clayton // let our super class DynamicLoader class decide if we should stop 407*d4bfbc9aSGreg Clayton // or not (based on global preference). 408*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 409*d4bfbc9aSGreg Clayton bool 410*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::BreakpointHitCallback (void *baton, 411*d4bfbc9aSGreg Clayton StoppointCallbackContext *context, 412*d4bfbc9aSGreg Clayton user_id_t break_id, 413*d4bfbc9aSGreg Clayton user_id_t break_loc_id) 414*d4bfbc9aSGreg Clayton { 415*d4bfbc9aSGreg Clayton return static_cast<DynamicLoaderMacOSXKernel*>(baton)->BreakpointHit (context, break_id, break_loc_id); 416*d4bfbc9aSGreg Clayton } 417*d4bfbc9aSGreg Clayton 418*d4bfbc9aSGreg Clayton bool 419*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::BreakpointHit (StoppointCallbackContext *context, 420*d4bfbc9aSGreg Clayton user_id_t break_id, 421*d4bfbc9aSGreg Clayton user_id_t break_loc_id) 422*d4bfbc9aSGreg Clayton { 423*d4bfbc9aSGreg Clayton LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 424*d4bfbc9aSGreg Clayton if (log) 425*d4bfbc9aSGreg Clayton log->Printf ("DynamicLoaderMacOSXKernel::BreakpointHit (...)\n"); 426*d4bfbc9aSGreg Clayton 427*d4bfbc9aSGreg Clayton ReadAllKextSummaries (); 428*d4bfbc9aSGreg Clayton 429*d4bfbc9aSGreg Clayton if (log) 430*d4bfbc9aSGreg Clayton PutToLog(log.get()); 431*d4bfbc9aSGreg Clayton 432*d4bfbc9aSGreg Clayton return GetStopWhenImagesChange(); 433*d4bfbc9aSGreg Clayton } 434*d4bfbc9aSGreg Clayton 435*d4bfbc9aSGreg Clayton 436*d4bfbc9aSGreg Clayton bool 437*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::ReadKextSummaryHeader () 438*d4bfbc9aSGreg Clayton { 439*d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 440*d4bfbc9aSGreg Clayton 441*d4bfbc9aSGreg Clayton // the all image infos is already valid for this process stop ID 442*d4bfbc9aSGreg Clayton 443*d4bfbc9aSGreg Clayton m_kext_summaries.clear(); 444*d4bfbc9aSGreg Clayton if (m_kext_summary_header_ptr_addr.IsValid()) 445*d4bfbc9aSGreg Clayton { 446*d4bfbc9aSGreg Clayton const uint32_t addr_size = m_kernel.GetAddressByteSize (); 447*d4bfbc9aSGreg Clayton const ByteOrder byte_order = m_kernel.GetByteOrder(); 448*d4bfbc9aSGreg Clayton Error error; 449*d4bfbc9aSGreg Clayton // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure 450*d4bfbc9aSGreg Clayton // which is currenty 4 uint32_t and a pointer. 451*d4bfbc9aSGreg Clayton uint8_t buf[24]; 452*d4bfbc9aSGreg Clayton DataExtractor data (buf, sizeof(buf), byte_order, addr_size); 453*d4bfbc9aSGreg Clayton const size_t count = 4 * sizeof(uint32_t) + addr_size; 454*d4bfbc9aSGreg Clayton const bool prefer_file_cache = false; 455*d4bfbc9aSGreg Clayton if (m_process->GetTarget().ReadPointerFromMemory (m_kext_summary_header_ptr_addr, 456*d4bfbc9aSGreg Clayton prefer_file_cache, 457*d4bfbc9aSGreg Clayton error, 458*d4bfbc9aSGreg Clayton m_kext_summary_header_addr)) 459*d4bfbc9aSGreg Clayton { 460*d4bfbc9aSGreg Clayton // We got a valid address for our kext summary header and make sure it isn't NULL 461*d4bfbc9aSGreg Clayton if (m_kext_summary_header_addr.IsValid() && 462*d4bfbc9aSGreg Clayton m_kext_summary_header_addr.GetFileAddress() != 0) 463*d4bfbc9aSGreg Clayton { 464*d4bfbc9aSGreg Clayton const size_t bytes_read = m_process->GetTarget().ReadMemory (m_kext_summary_header_addr, prefer_file_cache, buf, count, error); 465*d4bfbc9aSGreg Clayton if (bytes_read == count) 466*d4bfbc9aSGreg Clayton { 467*d4bfbc9aSGreg Clayton uint32_t offset = 0; 468*d4bfbc9aSGreg Clayton m_kext_summary_header.version = data.GetU32(&offset); 469*d4bfbc9aSGreg Clayton if (m_kext_summary_header.version >= 2) 470*d4bfbc9aSGreg Clayton { 471*d4bfbc9aSGreg Clayton m_kext_summary_header.entry_size = data.GetU32(&offset); 472*d4bfbc9aSGreg Clayton } 473*d4bfbc9aSGreg Clayton else 474*d4bfbc9aSGreg Clayton { 475*d4bfbc9aSGreg Clayton // Versions less than 2 didn't have an entry size, it was hard coded 476*d4bfbc9aSGreg Clayton m_kext_summary_header.entry_size = KERNEL_MODULE_ENTRY_SIZE_VERSION_1; 477*d4bfbc9aSGreg Clayton } 478*d4bfbc9aSGreg Clayton m_kext_summary_header.entry_count = data.GetU32(&offset); 479*d4bfbc9aSGreg Clayton return true; 480*d4bfbc9aSGreg Clayton } 481*d4bfbc9aSGreg Clayton } 482*d4bfbc9aSGreg Clayton } 483*d4bfbc9aSGreg Clayton } 484*d4bfbc9aSGreg Clayton m_kext_summary_header_addr.Clear(); 485*d4bfbc9aSGreg Clayton return false; 486*d4bfbc9aSGreg Clayton } 487*d4bfbc9aSGreg Clayton 488*d4bfbc9aSGreg Clayton 489*d4bfbc9aSGreg Clayton bool 490*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::ParseKextSummaries (const Address &kext_summary_addr, 491*d4bfbc9aSGreg Clayton uint32_t count) 492*d4bfbc9aSGreg Clayton { 493*d4bfbc9aSGreg Clayton OSKextLoadedKextSummary::collection kext_summaries; 494*d4bfbc9aSGreg Clayton LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 495*d4bfbc9aSGreg Clayton if (log) 496*d4bfbc9aSGreg Clayton log->Printf ("Adding %d modules.\n"); 497*d4bfbc9aSGreg Clayton 498*d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 499*d4bfbc9aSGreg Clayton 500*d4bfbc9aSGreg Clayton if (!ReadKextSummaries (kext_summary_addr, count, kext_summaries)) 501*d4bfbc9aSGreg Clayton return false; 502*d4bfbc9aSGreg Clayton 503*d4bfbc9aSGreg Clayton Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream(); 504*d4bfbc9aSGreg Clayton for (uint32_t i = 0; i < count; i++) 505*d4bfbc9aSGreg Clayton { 506*d4bfbc9aSGreg Clayton if (s) 507*d4bfbc9aSGreg Clayton { 508*d4bfbc9aSGreg Clayton const uint8_t *u = (const uint8_t *)kext_summaries[i].uuid.GetBytes(); 509*d4bfbc9aSGreg Clayton if (u) 510*d4bfbc9aSGreg Clayton { 511*d4bfbc9aSGreg Clayton s->Printf("Loading kext: %2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X 0x%16.16llx \"%s\"...\n", 512*d4bfbc9aSGreg Clayton u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7], 513*d4bfbc9aSGreg Clayton u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15], 514*d4bfbc9aSGreg Clayton kext_summaries[i].address, kext_summaries[i].name); 515*d4bfbc9aSGreg Clayton } 516*d4bfbc9aSGreg Clayton else 517*d4bfbc9aSGreg Clayton { 518*d4bfbc9aSGreg Clayton s->Printf("0x%16.16llx \"%s\"...\n", kext_summaries[i].address, kext_summaries[i].name); 519*d4bfbc9aSGreg Clayton } 520*d4bfbc9aSGreg Clayton } 521*d4bfbc9aSGreg Clayton 522*d4bfbc9aSGreg Clayton DataExtractor data; // Load command data 523*d4bfbc9aSGreg Clayton if (ReadMachHeader (kext_summaries[i], &data)) 524*d4bfbc9aSGreg Clayton { 525*d4bfbc9aSGreg Clayton ParseLoadCommands (data, kext_summaries[i]); 526*d4bfbc9aSGreg Clayton } 527*d4bfbc9aSGreg Clayton 528*d4bfbc9aSGreg Clayton if (s) 529*d4bfbc9aSGreg Clayton { 530*d4bfbc9aSGreg Clayton if (kext_summaries[i].module_sp) 531*d4bfbc9aSGreg Clayton s->Printf(" found kext: %s/%s\n", 532*d4bfbc9aSGreg Clayton kext_summaries[i].module_sp->GetFileSpec().GetDirectory().AsCString(), 533*d4bfbc9aSGreg Clayton kext_summaries[i].module_sp->GetFileSpec().GetFilename().AsCString()); 534*d4bfbc9aSGreg Clayton } 535*d4bfbc9aSGreg Clayton 536*d4bfbc9aSGreg Clayton if (log) 537*d4bfbc9aSGreg Clayton kext_summaries[i].PutToLog (log.get()); 538*d4bfbc9aSGreg Clayton } 539*d4bfbc9aSGreg Clayton bool return_value = AddModulesUsingImageInfos (kext_summaries); 540*d4bfbc9aSGreg Clayton return return_value; 541*d4bfbc9aSGreg Clayton } 542*d4bfbc9aSGreg Clayton 543*d4bfbc9aSGreg Clayton // Adds the modules in image_infos to m_kext_summaries. 544*d4bfbc9aSGreg Clayton // NB don't call this passing in m_kext_summaries. 545*d4bfbc9aSGreg Clayton 546*d4bfbc9aSGreg Clayton bool 547*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos) 548*d4bfbc9aSGreg Clayton { 549*d4bfbc9aSGreg Clayton // Now add these images to the main list. 550*d4bfbc9aSGreg Clayton ModuleList loaded_module_list; 551*d4bfbc9aSGreg Clayton 552*d4bfbc9aSGreg Clayton for (uint32_t idx = 0; idx < image_infos.size(); ++idx) 553*d4bfbc9aSGreg Clayton { 554*d4bfbc9aSGreg Clayton m_kext_summaries.push_back(image_infos[idx]); 555*d4bfbc9aSGreg Clayton 556*d4bfbc9aSGreg Clayton if (FindTargetModule (image_infos[idx], true, NULL)) 557*d4bfbc9aSGreg Clayton { 558*d4bfbc9aSGreg Clayton // UpdateImageLoadAddress will return true if any segments 559*d4bfbc9aSGreg Clayton // change load address. We need to check this so we don't 560*d4bfbc9aSGreg Clayton // mention that all loaded shared libraries are newly loaded 561*d4bfbc9aSGreg Clayton // each time we hit out dyld breakpoint since dyld will list all 562*d4bfbc9aSGreg Clayton // shared libraries each time. 563*d4bfbc9aSGreg Clayton if (UpdateImageLoadAddress (image_infos[idx])) 564*d4bfbc9aSGreg Clayton { 565*d4bfbc9aSGreg Clayton loaded_module_list.AppendIfNeeded (image_infos[idx].module_sp); 566*d4bfbc9aSGreg Clayton } 567*d4bfbc9aSGreg Clayton } 568*d4bfbc9aSGreg Clayton } 569*d4bfbc9aSGreg Clayton 570*d4bfbc9aSGreg Clayton if (loaded_module_list.GetSize() > 0) 571*d4bfbc9aSGreg Clayton { 572*d4bfbc9aSGreg Clayton // FIXME: This should really be in the Runtime handlers class, which should get 573*d4bfbc9aSGreg Clayton // called by the target's ModulesDidLoad, but we're doing it all locally for now 574*d4bfbc9aSGreg Clayton // to save time. 575*d4bfbc9aSGreg Clayton // Also, I'm assuming there can be only one libobjc dylib loaded... 576*d4bfbc9aSGreg Clayton 577*d4bfbc9aSGreg Clayton ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime(); 578*d4bfbc9aSGreg Clayton if (objc_runtime != NULL && !objc_runtime->HasReadObjCLibrary()) 579*d4bfbc9aSGreg Clayton { 580*d4bfbc9aSGreg Clayton size_t num_modules = loaded_module_list.GetSize(); 581*d4bfbc9aSGreg Clayton for (int i = 0; i < num_modules; i++) 582*d4bfbc9aSGreg Clayton { 583*d4bfbc9aSGreg Clayton if (objc_runtime->IsModuleObjCLibrary (loaded_module_list.GetModuleAtIndex (i))) 584*d4bfbc9aSGreg Clayton { 585*d4bfbc9aSGreg Clayton objc_runtime->ReadObjCLibrary (loaded_module_list.GetModuleAtIndex (i)); 586*d4bfbc9aSGreg Clayton break; 587*d4bfbc9aSGreg Clayton } 588*d4bfbc9aSGreg Clayton } 589*d4bfbc9aSGreg Clayton } 590*d4bfbc9aSGreg Clayton // if (log) 591*d4bfbc9aSGreg Clayton // loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXKernel::ModulesDidLoad"); 592*d4bfbc9aSGreg Clayton m_process->GetTarget().ModulesDidLoad (loaded_module_list); 593*d4bfbc9aSGreg Clayton } 594*d4bfbc9aSGreg Clayton return true; 595*d4bfbc9aSGreg Clayton } 596*d4bfbc9aSGreg Clayton 597*d4bfbc9aSGreg Clayton 598*d4bfbc9aSGreg Clayton uint32_t 599*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::ReadKextSummaries (const Address &kext_summary_addr, 600*d4bfbc9aSGreg Clayton uint32_t image_infos_count, 601*d4bfbc9aSGreg Clayton OSKextLoadedKextSummary::collection &image_infos) 602*d4bfbc9aSGreg Clayton { 603*d4bfbc9aSGreg Clayton const ByteOrder endian = m_kernel.GetByteOrder(); 604*d4bfbc9aSGreg Clayton const uint32_t addr_size = m_kernel.GetAddressByteSize(); 605*d4bfbc9aSGreg Clayton 606*d4bfbc9aSGreg Clayton image_infos.resize(image_infos_count); 607*d4bfbc9aSGreg Clayton const size_t count = image_infos.size() * m_kext_summary_header.entry_size; 608*d4bfbc9aSGreg Clayton DataBufferHeap data(count, 0); 609*d4bfbc9aSGreg Clayton Error error; 610*d4bfbc9aSGreg Clayton 611*d4bfbc9aSGreg Clayton Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream(); 612*d4bfbc9aSGreg Clayton 613*d4bfbc9aSGreg Clayton if (s) 614*d4bfbc9aSGreg Clayton s->Printf ("Reading %u kext summaries...\n", image_infos_count); 615*d4bfbc9aSGreg Clayton const bool prefer_file_cache = false; 616*d4bfbc9aSGreg Clayton const size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary_addr, 617*d4bfbc9aSGreg Clayton prefer_file_cache, 618*d4bfbc9aSGreg Clayton data.GetBytes(), 619*d4bfbc9aSGreg Clayton data.GetByteSize(), 620*d4bfbc9aSGreg Clayton error); 621*d4bfbc9aSGreg Clayton if (bytes_read == count) 622*d4bfbc9aSGreg Clayton { 623*d4bfbc9aSGreg Clayton 624*d4bfbc9aSGreg Clayton DataExtractor extractor (data.GetBytes(), data.GetByteSize(), endian, addr_size); 625*d4bfbc9aSGreg Clayton uint32_t i=0; 626*d4bfbc9aSGreg Clayton for (uint32_t kext_summary_offset = 0; 627*d4bfbc9aSGreg Clayton i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size); 628*d4bfbc9aSGreg Clayton ++i, kext_summary_offset += m_kext_summary_header.entry_size) 629*d4bfbc9aSGreg Clayton { 630*d4bfbc9aSGreg Clayton uint32_t offset = kext_summary_offset; 631*d4bfbc9aSGreg Clayton const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME); 632*d4bfbc9aSGreg Clayton if (name_data == NULL) 633*d4bfbc9aSGreg Clayton break; 634*d4bfbc9aSGreg Clayton memcpy (image_infos[i].name, name_data, KERNEL_MODULE_MAX_NAME); 635*d4bfbc9aSGreg Clayton image_infos[i].uuid.SetBytes(extractor.GetData (&offset, 16)); 636*d4bfbc9aSGreg Clayton image_infos[i].address = extractor.GetU64(&offset); 637*d4bfbc9aSGreg Clayton if (!image_infos[i].so_address.SetLoadAddress (image_infos[i].address, &m_process->GetTarget())) 638*d4bfbc9aSGreg Clayton m_process->GetTarget().GetImages().ResolveFileAddress (image_infos[i].address, image_infos[i].so_address); 639*d4bfbc9aSGreg Clayton image_infos[i].size = extractor.GetU64(&offset); 640*d4bfbc9aSGreg Clayton image_infos[i].version = extractor.GetU64(&offset); 641*d4bfbc9aSGreg Clayton image_infos[i].load_tag = extractor.GetU32(&offset); 642*d4bfbc9aSGreg Clayton image_infos[i].flags = extractor.GetU32(&offset); 643*d4bfbc9aSGreg Clayton if ((offset - kext_summary_offset) < m_kext_summary_header.entry_size) 644*d4bfbc9aSGreg Clayton { 645*d4bfbc9aSGreg Clayton image_infos[i].reference_list = extractor.GetU64(&offset); 646*d4bfbc9aSGreg Clayton } 647*d4bfbc9aSGreg Clayton else 648*d4bfbc9aSGreg Clayton { 649*d4bfbc9aSGreg Clayton image_infos[i].reference_list = 0; 650*d4bfbc9aSGreg Clayton } 651*d4bfbc9aSGreg Clayton } 652*d4bfbc9aSGreg Clayton if (i < image_infos.size()) 653*d4bfbc9aSGreg Clayton image_infos.resize(i); 654*d4bfbc9aSGreg Clayton } 655*d4bfbc9aSGreg Clayton else 656*d4bfbc9aSGreg Clayton { 657*d4bfbc9aSGreg Clayton image_infos.clear(); 658*d4bfbc9aSGreg Clayton } 659*d4bfbc9aSGreg Clayton return image_infos.size(); 660*d4bfbc9aSGreg Clayton } 661*d4bfbc9aSGreg Clayton 662*d4bfbc9aSGreg Clayton bool 663*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::ReadAllKextSummaries () 664*d4bfbc9aSGreg Clayton { 665*d4bfbc9aSGreg Clayton LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 666*d4bfbc9aSGreg Clayton 667*d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 668*d4bfbc9aSGreg Clayton 669*d4bfbc9aSGreg Clayton if (ReadKextSummaryHeader ()) 670*d4bfbc9aSGreg Clayton { 671*d4bfbc9aSGreg Clayton if (m_kext_summary_header.entry_count > 0 && m_kext_summary_header_addr.IsValid()) 672*d4bfbc9aSGreg Clayton { 673*d4bfbc9aSGreg Clayton Address summary_addr (m_kext_summary_header_addr); 674*d4bfbc9aSGreg Clayton summary_addr.Slide(m_kext_summary_header.GetSize()); 675*d4bfbc9aSGreg Clayton if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count)) 676*d4bfbc9aSGreg Clayton { 677*d4bfbc9aSGreg Clayton m_kext_summaries.clear(); 678*d4bfbc9aSGreg Clayton } 679*d4bfbc9aSGreg Clayton return true; 680*d4bfbc9aSGreg Clayton } 681*d4bfbc9aSGreg Clayton } 682*d4bfbc9aSGreg Clayton return false; 683*d4bfbc9aSGreg Clayton } 684*d4bfbc9aSGreg Clayton 685*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 686*d4bfbc9aSGreg Clayton // Read a mach_header at ADDR into HEADER, and also fill in the load 687*d4bfbc9aSGreg Clayton // command data into LOAD_COMMAND_DATA if it is non-NULL. 688*d4bfbc9aSGreg Clayton // 689*d4bfbc9aSGreg Clayton // Returns true if we succeed, false if we fail for any reason. 690*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 691*d4bfbc9aSGreg Clayton bool 692*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::ReadMachHeader (OSKextLoadedKextSummary& kext_summary, DataExtractor *load_command_data) 693*d4bfbc9aSGreg Clayton { 694*d4bfbc9aSGreg Clayton DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0); 695*d4bfbc9aSGreg Clayton Error error; 696*d4bfbc9aSGreg Clayton const bool prefer_file_cache = false; 697*d4bfbc9aSGreg Clayton size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary.so_address, 698*d4bfbc9aSGreg Clayton prefer_file_cache, 699*d4bfbc9aSGreg Clayton header_bytes.GetBytes(), 700*d4bfbc9aSGreg Clayton header_bytes.GetByteSize(), 701*d4bfbc9aSGreg Clayton error); 702*d4bfbc9aSGreg Clayton if (bytes_read == sizeof(llvm::MachO::mach_header)) 703*d4bfbc9aSGreg Clayton { 704*d4bfbc9aSGreg Clayton uint32_t offset = 0; 705*d4bfbc9aSGreg Clayton ::memset (&kext_summary.header, 0, sizeof(kext_summary.header)); 706*d4bfbc9aSGreg Clayton 707*d4bfbc9aSGreg Clayton // Get the magic byte unswapped so we can figure out what we are dealing with 708*d4bfbc9aSGreg Clayton DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(), endian::InlHostByteOrder(), 4); 709*d4bfbc9aSGreg Clayton kext_summary.header.magic = data.GetU32(&offset); 710*d4bfbc9aSGreg Clayton Address load_cmd_addr = kext_summary.so_address; 711*d4bfbc9aSGreg Clayton data.SetByteOrder(DynamicLoaderMacOSXKernel::GetByteOrderFromMagic(kext_summary.header.magic)); 712*d4bfbc9aSGreg Clayton switch (kext_summary.header.magic) 713*d4bfbc9aSGreg Clayton { 714*d4bfbc9aSGreg Clayton case llvm::MachO::HeaderMagic32: 715*d4bfbc9aSGreg Clayton case llvm::MachO::HeaderMagic32Swapped: 716*d4bfbc9aSGreg Clayton data.SetAddressByteSize(4); 717*d4bfbc9aSGreg Clayton load_cmd_addr.Slide (sizeof(llvm::MachO::mach_header)); 718*d4bfbc9aSGreg Clayton break; 719*d4bfbc9aSGreg Clayton 720*d4bfbc9aSGreg Clayton case llvm::MachO::HeaderMagic64: 721*d4bfbc9aSGreg Clayton case llvm::MachO::HeaderMagic64Swapped: 722*d4bfbc9aSGreg Clayton data.SetAddressByteSize(8); 723*d4bfbc9aSGreg Clayton load_cmd_addr.Slide (sizeof(llvm::MachO::mach_header_64)); 724*d4bfbc9aSGreg Clayton break; 725*d4bfbc9aSGreg Clayton 726*d4bfbc9aSGreg Clayton default: 727*d4bfbc9aSGreg Clayton return false; 728*d4bfbc9aSGreg Clayton } 729*d4bfbc9aSGreg Clayton 730*d4bfbc9aSGreg Clayton // Read the rest of dyld's mach header 731*d4bfbc9aSGreg Clayton if (data.GetU32(&offset, &kext_summary.header.cputype, (sizeof(llvm::MachO::mach_header)/sizeof(uint32_t)) - 1)) 732*d4bfbc9aSGreg Clayton { 733*d4bfbc9aSGreg Clayton if (load_command_data == NULL) 734*d4bfbc9aSGreg Clayton return true; // We were able to read the mach_header and weren't asked to read the load command bytes 735*d4bfbc9aSGreg Clayton 736*d4bfbc9aSGreg Clayton DataBufferSP load_cmd_data_sp(new DataBufferHeap(kext_summary.header.sizeofcmds, 0)); 737*d4bfbc9aSGreg Clayton 738*d4bfbc9aSGreg Clayton size_t load_cmd_bytes_read = m_process->GetTarget().ReadMemory (load_cmd_addr, 739*d4bfbc9aSGreg Clayton prefer_file_cache, 740*d4bfbc9aSGreg Clayton load_cmd_data_sp->GetBytes(), 741*d4bfbc9aSGreg Clayton load_cmd_data_sp->GetByteSize(), 742*d4bfbc9aSGreg Clayton error); 743*d4bfbc9aSGreg Clayton 744*d4bfbc9aSGreg Clayton if (load_cmd_bytes_read == kext_summary.header.sizeofcmds) 745*d4bfbc9aSGreg Clayton { 746*d4bfbc9aSGreg Clayton // Set the load command data and also set the correct endian 747*d4bfbc9aSGreg Clayton // swap settings and the correct address size 748*d4bfbc9aSGreg Clayton load_command_data->SetData(load_cmd_data_sp, 0, kext_summary.header.sizeofcmds); 749*d4bfbc9aSGreg Clayton load_command_data->SetByteOrder(data.GetByteOrder()); 750*d4bfbc9aSGreg Clayton load_command_data->SetAddressByteSize(data.GetAddressByteSize()); 751*d4bfbc9aSGreg Clayton return true; // We successfully read the mach_header and the load command data 752*d4bfbc9aSGreg Clayton } 753*d4bfbc9aSGreg Clayton 754*d4bfbc9aSGreg Clayton return false; // We weren't able to read the load command data 755*d4bfbc9aSGreg Clayton } 756*d4bfbc9aSGreg Clayton } 757*d4bfbc9aSGreg Clayton return false; // We failed the read the mach_header 758*d4bfbc9aSGreg Clayton } 759*d4bfbc9aSGreg Clayton 760*d4bfbc9aSGreg Clayton 761*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 762*d4bfbc9aSGreg Clayton // Parse the load commands for an image 763*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 764*d4bfbc9aSGreg Clayton uint32_t 765*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::ParseLoadCommands (const DataExtractor& data, OSKextLoadedKextSummary& image_info) 766*d4bfbc9aSGreg Clayton { 767*d4bfbc9aSGreg Clayton uint32_t offset = 0; 768*d4bfbc9aSGreg Clayton uint32_t cmd_idx; 769*d4bfbc9aSGreg Clayton Segment segment; 770*d4bfbc9aSGreg Clayton image_info.Clear (true); 771*d4bfbc9aSGreg Clayton 772*d4bfbc9aSGreg Clayton for (cmd_idx = 0; cmd_idx < image_info.header.ncmds; cmd_idx++) 773*d4bfbc9aSGreg Clayton { 774*d4bfbc9aSGreg Clayton // Clear out any load command specific data from image_info since 775*d4bfbc9aSGreg Clayton // we are about to read it. 776*d4bfbc9aSGreg Clayton 777*d4bfbc9aSGreg Clayton if (data.ValidOffsetForDataOfSize (offset, sizeof(llvm::MachO::load_command))) 778*d4bfbc9aSGreg Clayton { 779*d4bfbc9aSGreg Clayton llvm::MachO::load_command load_cmd; 780*d4bfbc9aSGreg Clayton uint32_t load_cmd_offset = offset; 781*d4bfbc9aSGreg Clayton load_cmd.cmd = data.GetU32 (&offset); 782*d4bfbc9aSGreg Clayton load_cmd.cmdsize = data.GetU32 (&offset); 783*d4bfbc9aSGreg Clayton switch (load_cmd.cmd) 784*d4bfbc9aSGreg Clayton { 785*d4bfbc9aSGreg Clayton case llvm::MachO::LoadCommandSegment32: 786*d4bfbc9aSGreg Clayton { 787*d4bfbc9aSGreg Clayton segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16); 788*d4bfbc9aSGreg Clayton // We are putting 4 uint32_t values 4 uint64_t values so 789*d4bfbc9aSGreg Clayton // we have to use multiple 32 bit gets below. 790*d4bfbc9aSGreg Clayton segment.vmaddr = data.GetU32 (&offset); 791*d4bfbc9aSGreg Clayton segment.vmsize = data.GetU32 (&offset); 792*d4bfbc9aSGreg Clayton segment.fileoff = data.GetU32 (&offset); 793*d4bfbc9aSGreg Clayton segment.filesize = data.GetU32 (&offset); 794*d4bfbc9aSGreg Clayton // Extract maxprot, initprot, nsects and flags all at once 795*d4bfbc9aSGreg Clayton data.GetU32(&offset, &segment.maxprot, 4); 796*d4bfbc9aSGreg Clayton image_info.segments.push_back (segment); 797*d4bfbc9aSGreg Clayton } 798*d4bfbc9aSGreg Clayton break; 799*d4bfbc9aSGreg Clayton 800*d4bfbc9aSGreg Clayton case llvm::MachO::LoadCommandSegment64: 801*d4bfbc9aSGreg Clayton { 802*d4bfbc9aSGreg Clayton segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16); 803*d4bfbc9aSGreg Clayton // Extract vmaddr, vmsize, fileoff, and filesize all at once 804*d4bfbc9aSGreg Clayton data.GetU64(&offset, &segment.vmaddr, 4); 805*d4bfbc9aSGreg Clayton // Extract maxprot, initprot, nsects and flags all at once 806*d4bfbc9aSGreg Clayton data.GetU32(&offset, &segment.maxprot, 4); 807*d4bfbc9aSGreg Clayton image_info.segments.push_back (segment); 808*d4bfbc9aSGreg Clayton } 809*d4bfbc9aSGreg Clayton break; 810*d4bfbc9aSGreg Clayton 811*d4bfbc9aSGreg Clayton case llvm::MachO::LoadCommandUUID: 812*d4bfbc9aSGreg Clayton image_info.uuid.SetBytes(data.GetData (&offset, 16)); 813*d4bfbc9aSGreg Clayton break; 814*d4bfbc9aSGreg Clayton 815*d4bfbc9aSGreg Clayton default: 816*d4bfbc9aSGreg Clayton break; 817*d4bfbc9aSGreg Clayton } 818*d4bfbc9aSGreg Clayton // Set offset to be the beginning of the next load command. 819*d4bfbc9aSGreg Clayton offset = load_cmd_offset + load_cmd.cmdsize; 820*d4bfbc9aSGreg Clayton } 821*d4bfbc9aSGreg Clayton } 822*d4bfbc9aSGreg Clayton #if 0 823*d4bfbc9aSGreg Clayton // No slide in the kernel... 824*d4bfbc9aSGreg Clayton 825*d4bfbc9aSGreg Clayton // All sections listed in the dyld image info structure will all 826*d4bfbc9aSGreg Clayton // either be fixed up already, or they will all be off by a single 827*d4bfbc9aSGreg Clayton // slide amount that is determined by finding the first segment 828*d4bfbc9aSGreg Clayton // that is at file offset zero which also has bytes (a file size 829*d4bfbc9aSGreg Clayton // that is greater than zero) in the object file. 830*d4bfbc9aSGreg Clayton 831*d4bfbc9aSGreg Clayton // Determine the slide amount (if any) 832*d4bfbc9aSGreg Clayton const size_t num_sections = image_info.segments.size(); 833*d4bfbc9aSGreg Clayton for (size_t i = 0; i < num_sections; ++i) 834*d4bfbc9aSGreg Clayton { 835*d4bfbc9aSGreg Clayton // Iterate through the object file sections to find the 836*d4bfbc9aSGreg Clayton // first section that starts of file offset zero and that 837*d4bfbc9aSGreg Clayton // has bytes in the file... 838*d4bfbc9aSGreg Clayton if (image_info.segments[i].fileoff == 0 && image_info.segments[i].filesize > 0) 839*d4bfbc9aSGreg Clayton { 840*d4bfbc9aSGreg Clayton image_info.slide = image_info.address - image_info.segments[i].vmaddr; 841*d4bfbc9aSGreg Clayton // We have found the slide amount, so we can exit 842*d4bfbc9aSGreg Clayton // this for loop. 843*d4bfbc9aSGreg Clayton break; 844*d4bfbc9aSGreg Clayton } 845*d4bfbc9aSGreg Clayton } 846*d4bfbc9aSGreg Clayton #endif 847*d4bfbc9aSGreg Clayton if (image_info.uuid.IsValid()) 848*d4bfbc9aSGreg Clayton { 849*d4bfbc9aSGreg Clayton bool did_create = false; 850*d4bfbc9aSGreg Clayton if (FindTargetModule(image_info, true, &did_create)) 851*d4bfbc9aSGreg Clayton { 852*d4bfbc9aSGreg Clayton if (did_create) 853*d4bfbc9aSGreg Clayton image_info.module_create_stop_id = m_process->GetStopID(); 854*d4bfbc9aSGreg Clayton } 855*d4bfbc9aSGreg Clayton } 856*d4bfbc9aSGreg Clayton return cmd_idx; 857*d4bfbc9aSGreg Clayton } 858*d4bfbc9aSGreg Clayton 859*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 860*d4bfbc9aSGreg Clayton // Dump a Segment to the file handle provided. 861*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 862*d4bfbc9aSGreg Clayton void 863*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::Segment::PutToLog (Log *log, addr_t slide) const 864*d4bfbc9aSGreg Clayton { 865*d4bfbc9aSGreg Clayton if (log) 866*d4bfbc9aSGreg Clayton { 867*d4bfbc9aSGreg Clayton if (slide == 0) 868*d4bfbc9aSGreg Clayton log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx)", 869*d4bfbc9aSGreg Clayton name.AsCString(""), 870*d4bfbc9aSGreg Clayton vmaddr + slide, 871*d4bfbc9aSGreg Clayton vmaddr + slide + vmsize); 872*d4bfbc9aSGreg Clayton else 873*d4bfbc9aSGreg Clayton log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx) slide = 0x%llx", 874*d4bfbc9aSGreg Clayton name.AsCString(""), 875*d4bfbc9aSGreg Clayton vmaddr + slide, 876*d4bfbc9aSGreg Clayton vmaddr + slide + vmsize, 877*d4bfbc9aSGreg Clayton slide); 878*d4bfbc9aSGreg Clayton } 879*d4bfbc9aSGreg Clayton } 880*d4bfbc9aSGreg Clayton 881*d4bfbc9aSGreg Clayton const DynamicLoaderMacOSXKernel::Segment * 882*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::OSKextLoadedKextSummary::FindSegment (const ConstString &name) const 883*d4bfbc9aSGreg Clayton { 884*d4bfbc9aSGreg Clayton const size_t num_segments = segments.size(); 885*d4bfbc9aSGreg Clayton for (size_t i=0; i<num_segments; ++i) 886*d4bfbc9aSGreg Clayton { 887*d4bfbc9aSGreg Clayton if (segments[i].name == name) 888*d4bfbc9aSGreg Clayton return &segments[i]; 889*d4bfbc9aSGreg Clayton } 890*d4bfbc9aSGreg Clayton return NULL; 891*d4bfbc9aSGreg Clayton } 892*d4bfbc9aSGreg Clayton 893*d4bfbc9aSGreg Clayton 894*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 895*d4bfbc9aSGreg Clayton // Dump an image info structure to the file handle provided. 896*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 897*d4bfbc9aSGreg Clayton void 898*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::OSKextLoadedKextSummary::PutToLog (Log *log) const 899*d4bfbc9aSGreg Clayton { 900*d4bfbc9aSGreg Clayton if (log == NULL) 901*d4bfbc9aSGreg Clayton return; 902*d4bfbc9aSGreg Clayton const uint8_t *u = (uint8_t *)uuid.GetBytes(); 903*d4bfbc9aSGreg Clayton 904*d4bfbc9aSGreg Clayton if (address == LLDB_INVALID_ADDRESS) 905*d4bfbc9aSGreg Clayton { 906*d4bfbc9aSGreg Clayton if (u) 907*d4bfbc9aSGreg Clayton { 908*d4bfbc9aSGreg 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)", 909*d4bfbc9aSGreg Clayton u[ 0], u[ 1], u[ 2], u[ 3], 910*d4bfbc9aSGreg Clayton u[ 4], u[ 5], u[ 6], u[ 7], 911*d4bfbc9aSGreg Clayton u[ 8], u[ 9], u[10], u[11], 912*d4bfbc9aSGreg Clayton u[12], u[13], u[14], u[15], 913*d4bfbc9aSGreg Clayton name); 914*d4bfbc9aSGreg Clayton } 915*d4bfbc9aSGreg Clayton else 916*d4bfbc9aSGreg Clayton log->Printf("\tname=\"%s\" (UNLOADED)", name); 917*d4bfbc9aSGreg Clayton } 918*d4bfbc9aSGreg Clayton else 919*d4bfbc9aSGreg Clayton { 920*d4bfbc9aSGreg Clayton if (u) 921*d4bfbc9aSGreg Clayton { 922*d4bfbc9aSGreg 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\"", 923*d4bfbc9aSGreg Clayton address, size, version, load_tag, flags, reference_list, 924*d4bfbc9aSGreg Clayton u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7], 925*d4bfbc9aSGreg Clayton u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15], 926*d4bfbc9aSGreg Clayton name); 927*d4bfbc9aSGreg Clayton } 928*d4bfbc9aSGreg Clayton else 929*d4bfbc9aSGreg Clayton { 930*d4bfbc9aSGreg 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\"", 931*d4bfbc9aSGreg Clayton address, address+size, version, load_tag, flags, reference_list, 932*d4bfbc9aSGreg Clayton name); 933*d4bfbc9aSGreg Clayton } 934*d4bfbc9aSGreg Clayton for (uint32_t i=0; i<segments.size(); ++i) 935*d4bfbc9aSGreg Clayton segments[i].PutToLog(log, 0); 936*d4bfbc9aSGreg Clayton } 937*d4bfbc9aSGreg Clayton } 938*d4bfbc9aSGreg Clayton 939*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 940*d4bfbc9aSGreg Clayton // Dump the _dyld_all_image_infos members and all current image infos 941*d4bfbc9aSGreg Clayton // that we have parsed to the file handle provided. 942*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 943*d4bfbc9aSGreg Clayton void 944*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::PutToLog(Log *log) const 945*d4bfbc9aSGreg Clayton { 946*d4bfbc9aSGreg Clayton if (log == NULL) 947*d4bfbc9aSGreg Clayton return; 948*d4bfbc9aSGreg Clayton 949*d4bfbc9aSGreg Clayton Mutex::Locker locker(m_mutex); 950*d4bfbc9aSGreg Clayton log->Printf("gLoadedKextSummaries = 0x%16.16llx { version=%u, entry_size=%u, entry_count=%u }", 951*d4bfbc9aSGreg Clayton m_kext_summary_header_addr.GetFileAddress(), 952*d4bfbc9aSGreg Clayton m_kext_summary_header.version, 953*d4bfbc9aSGreg Clayton m_kext_summary_header.entry_size, 954*d4bfbc9aSGreg Clayton m_kext_summary_header.entry_count); 955*d4bfbc9aSGreg Clayton 956*d4bfbc9aSGreg Clayton size_t i; 957*d4bfbc9aSGreg Clayton const size_t count = m_kext_summaries.size(); 958*d4bfbc9aSGreg Clayton if (count > 0) 959*d4bfbc9aSGreg Clayton { 960*d4bfbc9aSGreg Clayton log->PutCString("Loaded:"); 961*d4bfbc9aSGreg Clayton for (i = 0; i<count; i++) 962*d4bfbc9aSGreg Clayton m_kext_summaries[i].PutToLog(log); 963*d4bfbc9aSGreg Clayton } 964*d4bfbc9aSGreg Clayton } 965*d4bfbc9aSGreg Clayton 966*d4bfbc9aSGreg Clayton void 967*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::PrivateInitialize(Process *process) 968*d4bfbc9aSGreg Clayton { 969*d4bfbc9aSGreg Clayton DEBUG_PRINTF("DynamicLoaderMacOSXKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); 970*d4bfbc9aSGreg Clayton Clear(true); 971*d4bfbc9aSGreg Clayton m_process = process; 972*d4bfbc9aSGreg Clayton m_process->GetTarget().GetSectionLoadList().Clear(); 973*d4bfbc9aSGreg Clayton } 974*d4bfbc9aSGreg Clayton 975*d4bfbc9aSGreg Clayton void 976*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::SetNotificationBreakpointIfNeeded () 977*d4bfbc9aSGreg Clayton { 978*d4bfbc9aSGreg Clayton if (m_break_id == LLDB_INVALID_BREAK_ID) 979*d4bfbc9aSGreg Clayton { 980*d4bfbc9aSGreg Clayton DEBUG_PRINTF("DynamicLoaderMacOSXKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); 981*d4bfbc9aSGreg Clayton 982*d4bfbc9aSGreg Clayton 983*d4bfbc9aSGreg Clayton const bool internal_bp = false; 984*d4bfbc9aSGreg Clayton const LazyBool skip_prologue = eLazyBoolNo; 985*d4bfbc9aSGreg Clayton Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&m_kernel.module_sp->GetFileSpec(), 986*d4bfbc9aSGreg Clayton "OSKextLoadedKextSummariesUpdated", 987*d4bfbc9aSGreg Clayton eFunctionNameTypeFull, 988*d4bfbc9aSGreg Clayton internal_bp, 989*d4bfbc9aSGreg Clayton skip_prologue).get(); 990*d4bfbc9aSGreg Clayton 991*d4bfbc9aSGreg Clayton bp->SetCallback (DynamicLoaderMacOSXKernel::BreakpointHitCallback, this, true); 992*d4bfbc9aSGreg Clayton m_break_id = bp->GetID(); 993*d4bfbc9aSGreg Clayton } 994*d4bfbc9aSGreg Clayton } 995*d4bfbc9aSGreg Clayton 996*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 997*d4bfbc9aSGreg Clayton // Member function that gets called when the process state changes. 998*d4bfbc9aSGreg Clayton //---------------------------------------------------------------------- 999*d4bfbc9aSGreg Clayton void 1000*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::PrivateProcessStateChanged (Process *process, StateType state) 1001*d4bfbc9aSGreg Clayton { 1002*d4bfbc9aSGreg Clayton DEBUG_PRINTF("DynamicLoaderMacOSXKernel::%s(%s)\n", __FUNCTION__, StateAsCString(state)); 1003*d4bfbc9aSGreg Clayton switch (state) 1004*d4bfbc9aSGreg Clayton { 1005*d4bfbc9aSGreg Clayton case eStateConnected: 1006*d4bfbc9aSGreg Clayton case eStateAttaching: 1007*d4bfbc9aSGreg Clayton case eStateLaunching: 1008*d4bfbc9aSGreg Clayton case eStateInvalid: 1009*d4bfbc9aSGreg Clayton case eStateUnloaded: 1010*d4bfbc9aSGreg Clayton case eStateExited: 1011*d4bfbc9aSGreg Clayton case eStateDetached: 1012*d4bfbc9aSGreg Clayton Clear(false); 1013*d4bfbc9aSGreg Clayton break; 1014*d4bfbc9aSGreg Clayton 1015*d4bfbc9aSGreg Clayton case eStateStopped: 1016*d4bfbc9aSGreg Clayton UpdateIfNeeded(); 1017*d4bfbc9aSGreg Clayton break; 1018*d4bfbc9aSGreg Clayton 1019*d4bfbc9aSGreg Clayton case eStateRunning: 1020*d4bfbc9aSGreg Clayton case eStateStepping: 1021*d4bfbc9aSGreg Clayton case eStateCrashed: 1022*d4bfbc9aSGreg Clayton case eStateSuspended: 1023*d4bfbc9aSGreg Clayton break; 1024*d4bfbc9aSGreg Clayton 1025*d4bfbc9aSGreg Clayton default: 1026*d4bfbc9aSGreg Clayton break; 1027*d4bfbc9aSGreg Clayton } 1028*d4bfbc9aSGreg Clayton } 1029*d4bfbc9aSGreg Clayton 1030*d4bfbc9aSGreg Clayton ThreadPlanSP 1031*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) 1032*d4bfbc9aSGreg Clayton { 1033*d4bfbc9aSGreg Clayton ThreadPlanSP thread_plan_sp; 1034*d4bfbc9aSGreg Clayton LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 1035*d4bfbc9aSGreg Clayton if (log) 1036*d4bfbc9aSGreg Clayton log->Printf ("Could not find symbol for step through."); 1037*d4bfbc9aSGreg Clayton return thread_plan_sp; 1038*d4bfbc9aSGreg Clayton } 1039*d4bfbc9aSGreg Clayton 1040*d4bfbc9aSGreg Clayton Error 1041*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::CanLoadImage () 1042*d4bfbc9aSGreg Clayton { 1043*d4bfbc9aSGreg Clayton Error error; 1044*d4bfbc9aSGreg Clayton error.SetErrorString("always unsafe to load or unload shared libraries in the darwin kernel"); 1045*d4bfbc9aSGreg Clayton return error; 1046*d4bfbc9aSGreg Clayton } 1047*d4bfbc9aSGreg Clayton 1048*d4bfbc9aSGreg Clayton void 1049*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::Initialize() 1050*d4bfbc9aSGreg Clayton { 1051*d4bfbc9aSGreg Clayton PluginManager::RegisterPlugin (GetPluginNameStatic(), 1052*d4bfbc9aSGreg Clayton GetPluginDescriptionStatic(), 1053*d4bfbc9aSGreg Clayton CreateInstance); 1054*d4bfbc9aSGreg Clayton } 1055*d4bfbc9aSGreg Clayton 1056*d4bfbc9aSGreg Clayton void 1057*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::Terminate() 1058*d4bfbc9aSGreg Clayton { 1059*d4bfbc9aSGreg Clayton PluginManager::UnregisterPlugin (CreateInstance); 1060*d4bfbc9aSGreg Clayton } 1061*d4bfbc9aSGreg Clayton 1062*d4bfbc9aSGreg Clayton 1063*d4bfbc9aSGreg Clayton const char * 1064*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::GetPluginNameStatic() 1065*d4bfbc9aSGreg Clayton { 1066*d4bfbc9aSGreg Clayton return "dynamic-loader.macosx-kernel"; 1067*d4bfbc9aSGreg Clayton } 1068*d4bfbc9aSGreg Clayton 1069*d4bfbc9aSGreg Clayton const char * 1070*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::GetPluginDescriptionStatic() 1071*d4bfbc9aSGreg Clayton { 1072*d4bfbc9aSGreg Clayton return "Dynamic loader plug-in that watches for shared library loads/unloads in the MacOSX kernel."; 1073*d4bfbc9aSGreg Clayton } 1074*d4bfbc9aSGreg Clayton 1075*d4bfbc9aSGreg Clayton 1076*d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 1077*d4bfbc9aSGreg Clayton // PluginInterface protocol 1078*d4bfbc9aSGreg Clayton //------------------------------------------------------------------ 1079*d4bfbc9aSGreg Clayton const char * 1080*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::GetPluginName() 1081*d4bfbc9aSGreg Clayton { 1082*d4bfbc9aSGreg Clayton return "DynamicLoaderMacOSXKernel"; 1083*d4bfbc9aSGreg Clayton } 1084*d4bfbc9aSGreg Clayton 1085*d4bfbc9aSGreg Clayton const char * 1086*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::GetShortPluginName() 1087*d4bfbc9aSGreg Clayton { 1088*d4bfbc9aSGreg Clayton return GetPluginNameStatic(); 1089*d4bfbc9aSGreg Clayton } 1090*d4bfbc9aSGreg Clayton 1091*d4bfbc9aSGreg Clayton uint32_t 1092*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::GetPluginVersion() 1093*d4bfbc9aSGreg Clayton { 1094*d4bfbc9aSGreg Clayton return 1; 1095*d4bfbc9aSGreg Clayton } 1096*d4bfbc9aSGreg Clayton 1097