2011-08-22 22:30:57 +00:00
//===-- DynamicLoaderDarwinKernel.cpp -----------------------------*- C++ -*-===//
2011-07-08 00:48:09 +00:00
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
# include "lldb/Breakpoint/StoppointCallbackContext.h"
# include "lldb/Core/DataBuffer.h"
# include "lldb/Core/DataBufferHeap.h"
2011-07-20 03:41:06 +00:00
# include "lldb/Core/Debugger.h"
2011-07-08 00:48:09 +00:00
# include "lldb/Core/Log.h"
# include "lldb/Core/Module.h"
# include "lldb/Core/PluginManager.h"
# include "lldb/Core/State.h"
# include "lldb/Symbol/ObjectFile.h"
# include "lldb/Target/ObjCLanguageRuntime.h"
# include "lldb/Target/RegisterContext.h"
# include "lldb/Target/Target.h"
# include "lldb/Target/Thread.h"
# include "lldb/Target/ThreadPlanRunToAddress.h"
# include "lldb/Target/StackFrame.h"
2011-08-22 22:30:57 +00:00
# include "DynamicLoaderDarwinKernel.h"
2011-07-08 00:48:09 +00:00
//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
# ifdef ENABLE_DEBUG_PRINTF
# include <stdio.h>
# define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
# else
# define DEBUG_PRINTF(fmt, ...)
# endif
using namespace lldb ;
using namespace lldb_private ;
/// FIXME - The ObjC Runtime trampoline handler doesn't really belong here.
/// I am putting it here so I can invoke it in the Trampoline code here, but
/// it should be moved to the ObjC Runtime support when it is set up.
//----------------------------------------------------------------------
// Create an instance of this class. This function is filled into
// the plugin info class that gets handed out by the plugin factory and
// allows the lldb to instantiate an instance of this class.
//----------------------------------------------------------------------
DynamicLoader *
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : CreateInstance ( Process * process , bool force )
2011-07-08 00:48:09 +00:00
{
bool create = force ;
if ( ! create )
{
2011-08-11 02:48:45 +00:00
Module * exe_module = process - > GetTarget ( ) . GetExecutableModulePointer ( ) ;
2011-07-08 04:11:42 +00:00
if ( exe_module )
{
ObjectFile * object_file = exe_module - > GetObjectFile ( ) ;
if ( object_file )
{
SectionList * section_list = object_file - > GetSectionList ( ) ;
if ( section_list )
{
static ConstString g_kld_section_name ( " __KLD " ) ;
if ( section_list - > FindSectionByName ( g_kld_section_name ) )
{
create = true ;
}
}
}
}
if ( create )
{
const llvm : : Triple & triple_ref = process - > GetTarget ( ) . GetArchitecture ( ) . GetTriple ( ) ;
create = triple_ref . getOS ( ) = = llvm : : Triple : : Darwin & & triple_ref . getVendor ( ) = = llvm : : Triple : : Apple ;
}
2011-07-08 00:48:09 +00:00
}
if ( create )
2011-09-20 23:01:51 +00:00
{
process - > SetCanJIT ( false ) ;
2011-08-22 22:30:57 +00:00
return new DynamicLoaderDarwinKernel ( process ) ;
2011-09-20 23:01:51 +00:00
}
2011-07-08 00:48:09 +00:00
return NULL ;
}
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : DynamicLoaderDarwinKernel ( Process * process ) :
2011-07-08 00:48:09 +00:00
DynamicLoader ( process ) ,
m_kernel ( ) ,
2011-07-12 17:06:17 +00:00
m_kext_summary_header_ptr_addr ( ) ,
2011-07-08 03:21:57 +00:00
m_kext_summary_header_addr ( ) ,
2011-07-08 00:48:09 +00:00
m_kext_summary_header ( ) ,
m_kext_summaries ( ) ,
2011-10-31 22:50:49 +00:00
m_mutex ( Mutex : : eMutexTypeRecursive ) ,
m_break_id ( LLDB_INVALID_BREAK_ID )
2011-07-08 00:48:09 +00:00
{
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : ~ DynamicLoaderDarwinKernel ( )
2011-07-08 00:48:09 +00:00
{
Clear ( true ) ;
}
2011-07-09 17:15:55 +00:00
void
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : UpdateIfNeeded ( )
2011-07-09 17:15:55 +00:00
{
LoadKernelModuleIfNeeded ( ) ;
SetNotificationBreakpointIfNeeded ( ) ;
}
2011-07-08 00:48:09 +00:00
//------------------------------------------------------------------
/// Called after attaching a process.
///
/// Allow DynamicLoader plug-ins to execute some code after
/// attaching to a process.
//------------------------------------------------------------------
void
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : DidAttach ( )
2011-07-08 00:48:09 +00:00
{
PrivateInitialize ( m_process ) ;
2011-07-09 17:15:55 +00:00
UpdateIfNeeded ( ) ;
2011-07-08 00:48:09 +00:00
}
//------------------------------------------------------------------
/// Called after attaching a process.
///
/// Allow DynamicLoader plug-ins to execute some code after
/// attaching to a process.
//------------------------------------------------------------------
void
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : DidLaunch ( )
2011-07-08 00:48:09 +00:00
{
PrivateInitialize ( m_process ) ;
2011-07-09 17:15:55 +00:00
UpdateIfNeeded ( ) ;
2011-07-08 00:48:09 +00:00
}
//----------------------------------------------------------------------
// Clear out the state of this class.
//----------------------------------------------------------------------
void
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : Clear ( bool clear_process )
2011-07-08 00:48:09 +00:00
{
Mutex : : Locker locker ( m_mutex ) ;
if ( m_process - > IsAlive ( ) & & LLDB_BREAK_ID_IS_VALID ( m_break_id ) )
m_process - > ClearBreakpointSiteByID ( m_break_id ) ;
if ( clear_process )
m_process = NULL ;
m_kernel . Clear ( false ) ;
2011-07-12 17:06:17 +00:00
m_kext_summary_header_ptr_addr . Clear ( ) ;
2011-07-08 03:21:57 +00:00
m_kext_summary_header_addr . Clear ( ) ;
2011-07-08 00:48:09 +00:00
m_kext_summaries . clear ( ) ;
m_break_id = LLDB_INVALID_BREAK_ID ;
}
//----------------------------------------------------------------------
// Load the kernel module and initialize the "m_kernel" member. Return
// true _only_ if the kernel is loaded the first time through (subsequent
// calls to this function should return false after the kernel has been
// already loaded).
//----------------------------------------------------------------------
2011-07-09 17:15:55 +00:00
void
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : LoadKernelModuleIfNeeded ( )
2011-07-08 00:48:09 +00:00
{
2011-07-12 17:06:17 +00:00
if ( ! m_kext_summary_header_ptr_addr . IsValid ( ) )
2011-07-08 00:48:09 +00:00
{
m_kernel . Clear ( false ) ;
m_kernel . module_sp = m_process - > GetTarget ( ) . GetExecutableModule ( ) ;
if ( m_kernel . module_sp )
{
static ConstString mach_header_name ( " _mh_execute_header " ) ;
2011-07-08 04:11:42 +00:00
static ConstString kext_summary_symbol ( " gLoadedKextSummaries " ) ;
const Symbol * symbol = NULL ;
symbol = m_kernel . module_sp - > FindFirstSymbolWithNameAndType ( kext_summary_symbol , eSymbolTypeData ) ;
if ( symbol )
2011-07-12 17:06:17 +00:00
m_kext_summary_header_ptr_addr = symbol - > GetValue ( ) ;
2011-07-08 04:11:42 +00:00
symbol = m_kernel . module_sp - > FindFirstSymbolWithNameAndType ( mach_header_name , eSymbolTypeAbsolute ) ;
2011-07-08 00:48:09 +00:00
if ( symbol )
{
2011-07-08 04:11:42 +00:00
// The "_mh_execute_header" symbol is absolute and not a section based
// symbol that will have a valid address, so we need to resolve it...
m_process - > GetTarget ( ) . GetImages ( ) . ResolveFileAddress ( symbol - > GetValue ( ) . GetFileAddress ( ) , m_kernel . so_address ) ;
2011-07-08 00:48:09 +00:00
DataExtractor data ; // Load command data
2011-07-08 03:21:57 +00:00
if ( ReadMachHeader ( m_kernel , & data ) )
2011-07-08 00:48:09 +00:00
{
2011-07-08 04:11:42 +00:00
if ( m_kernel . header . filetype = = llvm : : MachO : : HeaderFileTypeExecutable )
2011-07-08 00:48:09 +00:00
{
if ( ParseLoadCommands ( data , m_kernel ) )
UpdateImageLoadAddress ( m_kernel ) ;
// Update all image infos
2011-07-09 17:15:55 +00:00
ReadAllKextSummaries ( ) ;
2011-07-08 00:48:09 +00:00
}
}
else
{
m_kernel . Clear ( false ) ;
}
}
}
}
}
bool
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : FindTargetModule ( OSKextLoadedKextSummary & image_info , bool can_create , bool * did_create_ptr )
2011-07-08 00:48:09 +00:00
{
if ( did_create_ptr )
* did_create_ptr = false ;
const bool image_info_uuid_is_valid = image_info . uuid . IsValid ( ) ;
if ( image_info . module_sp )
{
if ( image_info_uuid_is_valid )
{
if ( image_info . module_sp - > GetUUID ( ) = = image_info . uuid )
return true ;
else
image_info . module_sp . reset ( ) ;
}
else
return true ;
}
ModuleList & target_images = m_process - > GetTarget ( ) . GetImages ( ) ;
if ( image_info_uuid_is_valid )
image_info . module_sp = target_images . FindModule ( image_info . uuid ) ;
if ( image_info . module_sp )
return true ;
ArchSpec arch ( image_info . GetArchitecture ( ) ) ;
if ( can_create )
{
if ( image_info_uuid_is_valid )
{
image_info . module_sp = m_process - > GetTarget ( ) . GetSharedModule ( FileSpec ( ) ,
2011-07-19 03:57:15 +00:00
arch ,
& image_info . uuid ) ;
2011-07-08 00:48:09 +00:00
if ( did_create_ptr )
* did_create_ptr = image_info . module_sp ;
}
}
return image_info . module_sp ;
}
bool
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : UpdateCommPageLoadAddress ( Module * module )
2011-07-08 00:48:09 +00:00
{
bool changed = false ;
if ( module )
{
ObjectFile * image_object_file = module - > GetObjectFile ( ) ;
if ( image_object_file )
{
SectionList * section_list = image_object_file - > GetSectionList ( ) ;
if ( section_list )
{
uint32_t num_sections = section_list - > GetSize ( ) ;
for ( uint32_t i = 0 ; i < num_sections ; + + i )
{
Section * section = section_list - > GetSectionAtIndex ( i ) . get ( ) ;
if ( section )
{
const addr_t new_section_load_addr = section - > GetFileAddress ( ) ;
const addr_t old_section_load_addr = m_process - > GetTarget ( ) . GetSectionLoadList ( ) . GetSectionLoadAddress ( section ) ;
if ( old_section_load_addr = = LLDB_INVALID_ADDRESS | |
old_section_load_addr ! = new_section_load_addr )
{
if ( m_process - > GetTarget ( ) . GetSectionLoadList ( ) . SetSectionLoadAddress ( section , section - > GetFileAddress ( ) ) )
changed = true ;
}
}
}
}
}
}
return changed ;
}
//----------------------------------------------------------------------
// Update the load addresses for all segments in MODULE using the
// updated INFO that is passed in.
//----------------------------------------------------------------------
bool
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : UpdateImageLoadAddress ( OSKextLoadedKextSummary & info )
2011-07-08 00:48:09 +00:00
{
Module * module = info . module_sp . get ( ) ;
bool changed = false ;
if ( module )
{
ObjectFile * image_object_file = module - > GetObjectFile ( ) ;
if ( image_object_file )
{
SectionList * section_list = image_object_file - > GetSectionList ( ) ;
if ( section_list )
{
// We now know the slide amount, so go through all sections
// and update the load addresses with the correct values.
uint32_t num_segments = info . segments . size ( ) ;
for ( uint32_t i = 0 ; i < num_segments ; + + i )
{
const addr_t new_section_load_addr = info . segments [ i ] . vmaddr ;
2011-07-19 03:57:15 +00:00
if ( section_list - > FindSectionByName ( info . segments [ i ] . name ) )
2011-07-08 00:48:09 +00:00
{
2011-07-19 03:57:15 +00:00
SectionSP section_sp ( section_list - > FindSectionByName ( info . segments [ i ] . name ) ) ;
if ( section_sp )
2011-07-08 00:48:09 +00:00
{
2011-07-19 03:57:15 +00:00
const addr_t old_section_load_addr = m_process - > GetTarget ( ) . GetSectionLoadList ( ) . GetSectionLoadAddress ( section_sp . get ( ) ) ;
if ( old_section_load_addr = = LLDB_INVALID_ADDRESS | |
old_section_load_addr ! = new_section_load_addr )
{
if ( m_process - > GetTarget ( ) . GetSectionLoadList ( ) . SetSectionLoadAddress ( section_sp . get ( ) , new_section_load_addr ) )
changed = true ;
}
}
else
{
2012-01-05 03:57:59 +00:00
Host : : SystemLog ( Host : : eSystemLogWarning , " warning: unable to find and load segment named '%s' at 0x%llx in '%s/%s' in macosx dynamic loader plug-in. \n " ,
info . segments [ i ] . name . AsCString ( " <invalid> " ) ,
( uint64_t ) new_section_load_addr ,
image_object_file - > GetFileSpec ( ) . GetDirectory ( ) . AsCString ( ) ,
image_object_file - > GetFileSpec ( ) . GetFilename ( ) . AsCString ( ) ) ;
2011-07-08 00:48:09 +00:00
}
}
else
{
2011-07-19 03:57:15 +00:00
// The segment name is empty which means this is a .o file.
// Object files in LLDB end up getting reorganized so that
// the segment name that is in the section is promoted into
// an actual segment, so we just need to go through all sections
// and slide them by a single amount.
uint32_t num_sections = section_list - > GetSize ( ) ;
for ( uint32_t i = 0 ; i < num_sections ; + + i )
{
Section * section = section_list - > GetSectionAtIndex ( i ) . get ( ) ;
if ( section )
{
if ( m_process - > GetTarget ( ) . GetSectionLoadList ( ) . SetSectionLoadAddress ( section , section - > GetFileAddress ( ) + new_section_load_addr ) )
changed = true ;
}
}
2011-07-08 00:48:09 +00:00
}
}
}
}
}
return changed ;
}
//----------------------------------------------------------------------
// Update the load addresses for all segments in MODULE using the
// updated INFO that is passed in.
//----------------------------------------------------------------------
bool
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : UnloadImageLoadAddress ( OSKextLoadedKextSummary & info )
2011-07-08 00:48:09 +00:00
{
Module * module = info . module_sp . get ( ) ;
bool changed = false ;
if ( module )
{
ObjectFile * image_object_file = module - > GetObjectFile ( ) ;
if ( image_object_file )
{
SectionList * section_list = image_object_file - > GetSectionList ( ) ;
if ( section_list )
{
uint32_t num_segments = info . segments . size ( ) ;
for ( uint32_t i = 0 ; i < num_segments ; + + i )
{
SectionSP section_sp ( section_list - > FindSectionByName ( info . segments [ i ] . name ) ) ;
if ( section_sp )
{
const addr_t old_section_load_addr = info . segments [ i ] . vmaddr ;
if ( m_process - > GetTarget ( ) . GetSectionLoadList ( ) . SetSectionUnloaded ( section_sp . get ( ) , old_section_load_addr ) )
changed = true ;
}
else
{
2012-01-05 03:57:59 +00:00
Host : : SystemLog ( Host : : eSystemLogWarning ,
" warning: unable to find and unload segment named '%s' in '%s/%s' in macosx dynamic loader plug-in. \n " ,
info . segments [ i ] . name . AsCString ( " <invalid> " ) ,
image_object_file - > GetFileSpec ( ) . GetDirectory ( ) . AsCString ( ) ,
image_object_file - > GetFileSpec ( ) . GetFilename ( ) . AsCString ( ) ) ;
2011-07-08 00:48:09 +00:00
}
}
}
}
}
return changed ;
}
//----------------------------------------------------------------------
// Static callback function that gets called when our DYLD notification
// breakpoint gets hit. We update all of our image infos and then
// let our super class DynamicLoader class decide if we should stop
// or not (based on global preference).
//----------------------------------------------------------------------
bool
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : BreakpointHitCallback ( void * baton ,
2011-07-09 17:15:55 +00:00
StoppointCallbackContext * context ,
user_id_t break_id ,
user_id_t break_loc_id )
2011-07-08 03:21:57 +00:00
{
2011-08-22 22:30:57 +00:00
return static_cast < DynamicLoaderDarwinKernel * > ( baton ) - > BreakpointHit ( context , break_id , break_loc_id ) ;
2011-07-08 00:48:09 +00:00
}
2011-07-09 17:15:55 +00:00
bool
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : BreakpointHit ( StoppointCallbackContext * context ,
2011-07-09 17:15:55 +00:00
user_id_t break_id ,
user_id_t break_loc_id )
{
2011-07-12 17:06:17 +00:00
LogSP log ( GetLogIfAnyCategoriesSet ( LIBLLDB_LOG_DYNAMIC_LOADER ) ) ;
if ( log )
2011-08-22 22:30:57 +00:00
log - > Printf ( " DynamicLoaderDarwinKernel::BreakpointHit (...) \n " ) ;
2011-07-12 17:06:17 +00:00
2011-07-09 17:15:55 +00:00
ReadAllKextSummaries ( ) ;
2011-07-12 17:06:17 +00:00
if ( log )
PutToLog ( log . get ( ) ) ;
2011-07-09 17:15:55 +00:00
return GetStopWhenImagesChange ( ) ;
}
2011-07-08 00:48:09 +00:00
bool
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : ReadKextSummaryHeader ( )
2011-07-08 00:48:09 +00:00
{
Mutex : : Locker locker ( m_mutex ) ;
// the all image infos is already valid for this process stop ID
m_kext_summaries . clear ( ) ;
2011-07-12 17:06:17 +00:00
if ( m_kext_summary_header_ptr_addr . IsValid ( ) )
2011-07-08 00:48:09 +00:00
{
const uint32_t addr_size = m_kernel . GetAddressByteSize ( ) ;
const ByteOrder byte_order = m_kernel . GetByteOrder ( ) ;
Error error ;
// Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure
// which is currenty 4 uint32_t and a pointer.
uint8_t buf [ 24 ] ;
DataExtractor data ( buf , sizeof ( buf ) , byte_order , addr_size ) ;
const size_t count = 4 * sizeof ( uint32_t ) + addr_size ;
2011-07-08 03:21:57 +00:00
const bool prefer_file_cache = false ;
2011-07-12 17:06:17 +00:00
if ( m_process - > GetTarget ( ) . ReadPointerFromMemory ( m_kext_summary_header_ptr_addr ,
prefer_file_cache ,
error ,
m_kext_summary_header_addr ) )
2011-07-08 00:48:09 +00:00
{
2011-07-12 17:06:17 +00:00
// We got a valid address for our kext summary header and make sure it isn't NULL
if ( m_kext_summary_header_addr . IsValid ( ) & &
m_kext_summary_header_addr . GetFileAddress ( ) ! = 0 )
{
const size_t bytes_read = m_process - > GetTarget ( ) . ReadMemory ( m_kext_summary_header_addr , prefer_file_cache , buf , count , error ) ;
if ( bytes_read = = count )
{
uint32_t offset = 0 ;
2011-07-19 03:57:15 +00:00
m_kext_summary_header . version = data . GetU32 ( & offset ) ;
if ( m_kext_summary_header . version > = 2 )
{
m_kext_summary_header . entry_size = data . GetU32 ( & offset ) ;
}
else
{
// Versions less than 2 didn't have an entry size, it was hard coded
m_kext_summary_header . entry_size = KERNEL_MODULE_ENTRY_SIZE_VERSION_1 ;
}
m_kext_summary_header . entry_count = data . GetU32 ( & offset ) ;
2011-07-12 17:06:17 +00:00
return true ;
}
}
2011-07-08 00:48:09 +00:00
}
}
2011-07-12 17:06:17 +00:00
m_kext_summary_header_addr . Clear ( ) ;
2011-07-08 00:48:09 +00:00
return false ;
}
bool
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : ParseKextSummaries ( const Address & kext_summary_addr ,
2011-07-08 03:21:57 +00:00
uint32_t count )
2011-07-08 00:48:09 +00:00
{
OSKextLoadedKextSummary : : collection kext_summaries ;
2011-07-09 17:15:55 +00:00
LogSP log ( GetLogIfAnyCategoriesSet ( LIBLLDB_LOG_DYNAMIC_LOADER ) ) ;
2011-07-08 00:48:09 +00:00
if ( log )
2011-09-20 21:44:10 +00:00
log - > Printf ( " Adding %d modules. \n " , count ) ;
2011-07-08 00:48:09 +00:00
Mutex : : Locker locker ( m_mutex ) ;
if ( ! ReadKextSummaries ( kext_summary_addr , count , kext_summaries ) )
return false ;
2011-07-20 03:41:06 +00:00
Stream * s = & m_process - > GetTarget ( ) . GetDebugger ( ) . GetOutputStream ( ) ;
2011-07-08 00:48:09 +00:00
for ( uint32_t i = 0 ; i < count ; i + + )
{
2011-07-20 03:41:06 +00:00
if ( s )
{
const uint8_t * u = ( const uint8_t * ) kext_summaries [ i ] . uuid . GetBytes ( ) ;
if ( u )
{
2011-09-24 02:47:39 +00:00
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 \" ... " ,
2011-07-20 03:41:06 +00:00
u [ 0 ] , u [ 1 ] , u [ 2 ] , u [ 3 ] , u [ 4 ] , u [ 5 ] , u [ 6 ] , u [ 7 ] ,
u [ 8 ] , u [ 9 ] , u [ 10 ] , u [ 11 ] , u [ 12 ] , u [ 13 ] , u [ 14 ] , u [ 15 ] ,
kext_summaries [ i ] . address , kext_summaries [ i ] . name ) ;
}
else
{
2011-09-24 02:47:39 +00:00
s - > Printf ( " 0x%16.16llx \" %s \" ... " , kext_summaries [ i ] . address , kext_summaries [ i ] . name ) ;
2011-07-20 03:41:06 +00:00
}
}
2011-07-19 03:57:15 +00:00
DataExtractor data ; // Load command data
if ( ReadMachHeader ( kext_summaries [ i ] , & data ) )
2011-07-08 00:48:09 +00:00
{
ParseLoadCommands ( data , kext_summaries [ i ] ) ;
}
2011-07-19 03:57:15 +00:00
2011-07-21 01:12:01 +00:00
if ( s )
{
if ( kext_summaries [ i ] . module_sp )
2011-09-24 02:47:39 +00:00
s - > Printf ( " \n found kext: %s/%s \n " ,
2011-07-21 01:12:01 +00:00
kext_summaries [ i ] . module_sp - > GetFileSpec ( ) . GetDirectory ( ) . AsCString ( ) ,
kext_summaries [ i ] . module_sp - > GetFileSpec ( ) . GetFilename ( ) . AsCString ( ) ) ;
2011-09-24 02:47:39 +00:00
else
s - > Printf ( " failed to locate/load. \n " ) ;
2011-07-21 01:12:01 +00:00
}
2011-07-19 03:57:15 +00:00
if ( log )
kext_summaries [ i ] . PutToLog ( log . get ( ) ) ;
2011-07-08 00:48:09 +00:00
}
bool return_value = AddModulesUsingImageInfos ( kext_summaries ) ;
return return_value ;
}
// Adds the modules in image_infos to m_kext_summaries.
// NB don't call this passing in m_kext_summaries.
bool
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : AddModulesUsingImageInfos ( OSKextLoadedKextSummary : : collection & image_infos )
2011-07-08 00:48:09 +00:00
{
// Now add these images to the main list.
ModuleList loaded_module_list ;
for ( uint32_t idx = 0 ; idx < image_infos . size ( ) ; + + idx )
{
m_kext_summaries . push_back ( image_infos [ idx ] ) ;
if ( FindTargetModule ( image_infos [ idx ] , true , NULL ) )
{
// UpdateImageLoadAddress will return true if any segments
// change load address. We need to check this so we don't
// mention that all loaded shared libraries are newly loaded
// each time we hit out dyld breakpoint since dyld will list all
// shared libraries each time.
if ( UpdateImageLoadAddress ( image_infos [ idx ] ) )
{
loaded_module_list . AppendIfNeeded ( image_infos [ idx ] . module_sp ) ;
}
}
}
if ( loaded_module_list . GetSize ( ) > 0 )
{
// FIXME: This should really be in the Runtime handlers class, which should get
// called by the target's ModulesDidLoad, but we're doing it all locally for now
// to save time.
// Also, I'm assuming there can be only one libobjc dylib loaded...
ObjCLanguageRuntime * objc_runtime = m_process - > GetObjCLanguageRuntime ( ) ;
if ( objc_runtime ! = NULL & & ! objc_runtime - > HasReadObjCLibrary ( ) )
{
size_t num_modules = loaded_module_list . GetSize ( ) ;
for ( int i = 0 ; i < num_modules ; i + + )
{
if ( objc_runtime - > IsModuleObjCLibrary ( loaded_module_list . GetModuleAtIndex ( i ) ) )
{
objc_runtime - > ReadObjCLibrary ( loaded_module_list . GetModuleAtIndex ( i ) ) ;
break ;
}
}
}
2011-07-12 17:06:17 +00:00
// if (log)
2011-08-22 22:30:57 +00:00
// loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderDarwinKernel::ModulesDidLoad");
2011-07-08 00:48:09 +00:00
m_process - > GetTarget ( ) . ModulesDidLoad ( loaded_module_list ) ;
}
return true ;
}
uint32_t
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : ReadKextSummaries ( const Address & kext_summary_addr ,
2011-07-08 00:48:09 +00:00
uint32_t image_infos_count ,
OSKextLoadedKextSummary : : collection & image_infos )
{
const ByteOrder endian = m_kernel . GetByteOrder ( ) ;
const uint32_t addr_size = m_kernel . GetAddressByteSize ( ) ;
image_infos . resize ( image_infos_count ) ;
const size_t count = image_infos . size ( ) * m_kext_summary_header . entry_size ;
DataBufferHeap data ( count , 0 ) ;
Error error ;
2011-07-21 01:12:01 +00:00
Stream * s = & m_process - > GetTarget ( ) . GetDebugger ( ) . GetOutputStream ( ) ;
if ( s )
s - > Printf ( " Reading %u kext summaries... \n " , image_infos_count ) ;
2011-07-08 03:21:57 +00:00
const bool prefer_file_cache = false ;
const size_t bytes_read = m_process - > GetTarget ( ) . ReadMemory ( kext_summary_addr ,
prefer_file_cache ,
data . GetBytes ( ) ,
data . GetByteSize ( ) ,
error ) ;
2011-07-08 00:48:09 +00:00
if ( bytes_read = = count )
{
2011-07-19 03:57:15 +00:00
2011-07-08 00:48:09 +00:00
DataExtractor extractor ( data . GetBytes ( ) , data . GetByteSize ( ) , endian , addr_size ) ;
uint32_t i = 0 ;
2011-07-19 03:57:15 +00:00
for ( uint32_t kext_summary_offset = 0 ;
i < image_infos . size ( ) & & extractor . ValidOffsetForDataOfSize ( kext_summary_offset , m_kext_summary_header . entry_size ) ;
+ + i , kext_summary_offset + = m_kext_summary_header . entry_size )
2011-07-08 00:48:09 +00:00
{
2011-07-19 03:57:15 +00:00
uint32_t offset = kext_summary_offset ;
2011-07-08 00:48:09 +00:00
const void * name_data = extractor . GetData ( & offset , KERNEL_MODULE_MAX_NAME ) ;
if ( name_data = = NULL )
break ;
memcpy ( image_infos [ i ] . name , name_data , KERNEL_MODULE_MAX_NAME ) ;
image_infos [ i ] . uuid . SetBytes ( extractor . GetData ( & offset , 16 ) ) ;
image_infos [ i ] . address = extractor . GetU64 ( & offset ) ;
2011-07-08 03:21:57 +00:00
if ( ! image_infos [ i ] . so_address . SetLoadAddress ( image_infos [ i ] . address , & m_process - > GetTarget ( ) ) )
m_process - > GetTarget ( ) . GetImages ( ) . ResolveFileAddress ( image_infos [ i ] . address , image_infos [ i ] . so_address ) ;
2011-07-08 00:48:09 +00:00
image_infos [ i ] . size = extractor . GetU64 ( & offset ) ;
image_infos [ i ] . version = extractor . GetU64 ( & offset ) ;
image_infos [ i ] . load_tag = extractor . GetU32 ( & offset ) ;
image_infos [ i ] . flags = extractor . GetU32 ( & offset ) ;
2011-07-19 03:57:15 +00:00
if ( ( offset - kext_summary_offset ) < m_kext_summary_header . entry_size )
{
image_infos [ i ] . reference_list = extractor . GetU64 ( & offset ) ;
}
else
{
image_infos [ i ] . reference_list = 0 ;
}
2011-07-08 00:48:09 +00:00
}
if ( i < image_infos . size ( ) )
image_infos . resize ( i ) ;
}
else
{
image_infos . clear ( ) ;
}
return image_infos . size ( ) ;
}
bool
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : ReadAllKextSummaries ( )
2011-07-08 00:48:09 +00:00
{
2011-07-09 17:15:55 +00:00
LogSP log ( GetLogIfAnyCategoriesSet ( LIBLLDB_LOG_DYNAMIC_LOADER ) ) ;
2011-07-08 00:48:09 +00:00
Mutex : : Locker locker ( m_mutex ) ;
2011-07-09 17:15:55 +00:00
2011-07-08 00:48:09 +00:00
if ( ReadKextSummaryHeader ( ) )
{
2011-07-09 17:15:55 +00:00
if ( m_kext_summary_header . entry_count > 0 & & m_kext_summary_header_addr . IsValid ( ) )
2011-07-08 00:48:09 +00:00
{
2011-07-08 03:21:57 +00:00
Address summary_addr ( m_kext_summary_header_addr ) ;
2011-07-19 03:57:15 +00:00
summary_addr . Slide ( m_kext_summary_header . GetSize ( ) ) ;
2011-07-08 03:21:57 +00:00
if ( ! ParseKextSummaries ( summary_addr , m_kext_summary_header . entry_count ) )
2011-07-08 00:48:09 +00:00
{
m_kext_summaries . clear ( ) ;
}
return true ;
}
}
return false ;
}
//----------------------------------------------------------------------
// Read a mach_header at ADDR into HEADER, and also fill in the load
// command data into LOAD_COMMAND_DATA if it is non-NULL.
//
// Returns true if we succeed, false if we fail for any reason.
//----------------------------------------------------------------------
bool
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : ReadMachHeader ( OSKextLoadedKextSummary & kext_summary , DataExtractor * load_command_data )
2011-07-08 00:48:09 +00:00
{
DataBufferHeap header_bytes ( sizeof ( llvm : : MachO : : mach_header ) , 0 ) ;
Error error ;
2011-07-08 03:21:57 +00:00
const bool prefer_file_cache = false ;
size_t bytes_read = m_process - > GetTarget ( ) . ReadMemory ( kext_summary . so_address ,
prefer_file_cache ,
header_bytes . GetBytes ( ) ,
header_bytes . GetByteSize ( ) ,
error ) ;
2011-07-08 00:48:09 +00:00
if ( bytes_read = = sizeof ( llvm : : MachO : : mach_header ) )
{
uint32_t offset = 0 ;
2011-07-08 03:21:57 +00:00
: : memset ( & kext_summary . header , 0 , sizeof ( kext_summary . header ) ) ;
2011-07-08 00:48:09 +00:00
// Get the magic byte unswapped so we can figure out what we are dealing with
2011-07-09 17:15:55 +00:00
DataExtractor data ( header_bytes . GetBytes ( ) , header_bytes . GetByteSize ( ) , endian : : InlHostByteOrder ( ) , 4 ) ;
2011-07-08 03:21:57 +00:00
kext_summary . header . magic = data . GetU32 ( & offset ) ;
Address load_cmd_addr = kext_summary . so_address ;
2011-08-22 22:30:57 +00:00
data . SetByteOrder ( DynamicLoaderDarwinKernel : : GetByteOrderFromMagic ( kext_summary . header . magic ) ) ;
2011-07-08 03:21:57 +00:00
switch ( kext_summary . header . magic )
2011-07-08 00:48:09 +00:00
{
case llvm : : MachO : : HeaderMagic32 :
case llvm : : MachO : : HeaderMagic32Swapped :
data . SetAddressByteSize ( 4 ) ;
2011-07-08 03:21:57 +00:00
load_cmd_addr . Slide ( sizeof ( llvm : : MachO : : mach_header ) ) ;
2011-07-08 00:48:09 +00:00
break ;
case llvm : : MachO : : HeaderMagic64 :
case llvm : : MachO : : HeaderMagic64Swapped :
data . SetAddressByteSize ( 8 ) ;
2011-07-08 03:21:57 +00:00
load_cmd_addr . Slide ( sizeof ( llvm : : MachO : : mach_header_64 ) ) ;
2011-07-08 00:48:09 +00:00
break ;
default :
return false ;
}
// Read the rest of dyld's mach header
2011-07-08 03:21:57 +00:00
if ( data . GetU32 ( & offset , & kext_summary . header . cputype , ( sizeof ( llvm : : MachO : : mach_header ) / sizeof ( uint32_t ) ) - 1 ) )
2011-07-08 00:48:09 +00:00
{
if ( load_command_data = = NULL )
return true ; // We were able to read the mach_header and weren't asked to read the load command bytes
2011-07-08 03:21:57 +00:00
DataBufferSP load_cmd_data_sp ( new DataBufferHeap ( kext_summary . header . sizeofcmds , 0 ) ) ;
2011-07-08 00:48:09 +00:00
2011-07-08 03:21:57 +00:00
size_t load_cmd_bytes_read = m_process - > GetTarget ( ) . ReadMemory ( load_cmd_addr ,
prefer_file_cache ,
load_cmd_data_sp - > GetBytes ( ) ,
load_cmd_data_sp - > GetByteSize ( ) ,
error ) ;
2011-07-08 00:48:09 +00:00
2011-07-08 03:21:57 +00:00
if ( load_cmd_bytes_read = = kext_summary . header . sizeofcmds )
2011-07-08 00:48:09 +00:00
{
// Set the load command data and also set the correct endian
// swap settings and the correct address size
2011-07-08 03:21:57 +00:00
load_command_data - > SetData ( load_cmd_data_sp , 0 , kext_summary . header . sizeofcmds ) ;
2011-07-08 00:48:09 +00:00
load_command_data - > SetByteOrder ( data . GetByteOrder ( ) ) ;
load_command_data - > SetAddressByteSize ( data . GetAddressByteSize ( ) ) ;
return true ; // We successfully read the mach_header and the load command data
}
return false ; // We weren't able to read the load command data
}
}
return false ; // We failed the read the mach_header
}
//----------------------------------------------------------------------
// Parse the load commands for an image
//----------------------------------------------------------------------
uint32_t
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : ParseLoadCommands ( const DataExtractor & data , OSKextLoadedKextSummary & image_info )
2011-07-08 00:48:09 +00:00
{
uint32_t offset = 0 ;
uint32_t cmd_idx ;
Segment segment ;
2011-07-08 04:11:42 +00:00
image_info . Clear ( true ) ;
2011-07-08 00:48:09 +00:00
2011-07-08 04:11:42 +00:00
for ( cmd_idx = 0 ; cmd_idx < image_info . header . ncmds ; cmd_idx + + )
2011-07-08 00:48:09 +00:00
{
2011-07-08 04:11:42 +00:00
// Clear out any load command specific data from image_info since
2011-07-08 00:48:09 +00:00
// we are about to read it.
if ( data . ValidOffsetForDataOfSize ( offset , sizeof ( llvm : : MachO : : load_command ) ) )
{
llvm : : MachO : : load_command load_cmd ;
uint32_t load_cmd_offset = offset ;
load_cmd . cmd = data . GetU32 ( & offset ) ;
load_cmd . cmdsize = data . GetU32 ( & offset ) ;
switch ( load_cmd . cmd )
{
case llvm : : MachO : : LoadCommandSegment32 :
{
segment . name . SetTrimmedCStringWithLength ( ( const char * ) data . GetData ( & offset , 16 ) , 16 ) ;
// We are putting 4 uint32_t values 4 uint64_t values so
// we have to use multiple 32 bit gets below.
segment . vmaddr = data . GetU32 ( & offset ) ;
segment . vmsize = data . GetU32 ( & offset ) ;
segment . fileoff = data . GetU32 ( & offset ) ;
segment . filesize = data . GetU32 ( & offset ) ;
// Extract maxprot, initprot, nsects and flags all at once
data . GetU32 ( & offset , & segment . maxprot , 4 ) ;
2011-07-08 04:11:42 +00:00
image_info . segments . push_back ( segment ) ;
2011-07-08 00:48:09 +00:00
}
break ;
case llvm : : MachO : : LoadCommandSegment64 :
{
segment . name . SetTrimmedCStringWithLength ( ( const char * ) data . GetData ( & offset , 16 ) , 16 ) ;
// Extract vmaddr, vmsize, fileoff, and filesize all at once
data . GetU64 ( & offset , & segment . vmaddr , 4 ) ;
// Extract maxprot, initprot, nsects and flags all at once
data . GetU32 ( & offset , & segment . maxprot , 4 ) ;
2011-07-08 04:11:42 +00:00
image_info . segments . push_back ( segment ) ;
2011-07-08 00:48:09 +00:00
}
break ;
case llvm : : MachO : : LoadCommandUUID :
2011-07-08 04:11:42 +00:00
image_info . uuid . SetBytes ( data . GetData ( & offset , 16 ) ) ;
2011-07-08 00:48:09 +00:00
break ;
default :
break ;
}
// Set offset to be the beginning of the next load command.
offset = load_cmd_offset + load_cmd . cmdsize ;
}
}
#if 0
// No slide in the kernel...
// All sections listed in the dyld image info structure will all
// either be fixed up already, or they will all be off by a single
// slide amount that is determined by finding the first segment
// that is at file offset zero which also has bytes (a file size
// that is greater than zero) in the object file.
// Determine the slide amount (if any)
2011-07-08 04:11:42 +00:00
const size_t num_sections = image_info . segments . size ( ) ;
2011-07-08 00:48:09 +00:00
for ( size_t i = 0 ; i < num_sections ; + + i )
{
// Iterate through the object file sections to find the
// first section that starts of file offset zero and that
// has bytes in the file...
2011-07-08 04:11:42 +00:00
if ( image_info . segments [ i ] . fileoff = = 0 & & image_info . segments [ i ] . filesize > 0 )
2011-07-08 00:48:09 +00:00
{
2011-07-08 04:11:42 +00:00
image_info . slide = image_info . address - image_info . segments [ i ] . vmaddr ;
2011-07-08 00:48:09 +00:00
// We have found the slide amount, so we can exit
// this for loop.
break ;
}
}
# endif
2011-07-08 04:11:42 +00:00
if ( image_info . uuid . IsValid ( ) )
{
bool did_create = false ;
if ( FindTargetModule ( image_info , true , & did_create ) )
{
if ( did_create )
image_info . module_create_stop_id = m_process - > GetStopID ( ) ;
}
}
2011-07-08 00:48:09 +00:00
return cmd_idx ;
}
//----------------------------------------------------------------------
// Dump a Segment to the file handle provided.
//----------------------------------------------------------------------
void
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : Segment : : PutToLog ( Log * log , addr_t slide ) const
2011-07-08 00:48:09 +00:00
{
if ( log )
{
if ( slide = = 0 )
log - > Printf ( " \t \t %16s [0x%16.16llx - 0x%16.16llx) " ,
name . AsCString ( " " ) ,
vmaddr + slide ,
vmaddr + slide + vmsize ) ;
else
log - > Printf ( " \t \t %16s [0x%16.16llx - 0x%16.16llx) slide = 0x%llx " ,
name . AsCString ( " " ) ,
vmaddr + slide ,
vmaddr + slide + vmsize ,
slide ) ;
}
}
2011-08-22 22:30:57 +00:00
const DynamicLoaderDarwinKernel : : Segment *
DynamicLoaderDarwinKernel : : OSKextLoadedKextSummary : : FindSegment ( const ConstString & name ) const
2011-07-08 00:48:09 +00:00
{
const size_t num_segments = segments . size ( ) ;
for ( size_t i = 0 ; i < num_segments ; + + i )
{
if ( segments [ i ] . name = = name )
return & segments [ i ] ;
}
return NULL ;
}
//----------------------------------------------------------------------
// Dump an image info structure to the file handle provided.
//----------------------------------------------------------------------
void
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : OSKextLoadedKextSummary : : PutToLog ( Log * log ) const
2011-07-08 00:48:09 +00:00
{
if ( log = = NULL )
return ;
2011-07-20 03:41:06 +00:00
const uint8_t * u = ( uint8_t * ) uuid . GetBytes ( ) ;
2011-07-08 00:48:09 +00:00
if ( address = = LLDB_INVALID_ADDRESS )
{
if ( u )
{
2011-07-19 03:57:15 +00:00
log - > Printf ( " \t 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 \" (UNLOADED) " ,
2011-07-08 00:48:09 +00:00
u [ 0 ] , u [ 1 ] , u [ 2 ] , u [ 3 ] ,
u [ 4 ] , u [ 5 ] , u [ 6 ] , u [ 7 ] ,
u [ 8 ] , u [ 9 ] , u [ 10 ] , u [ 11 ] ,
u [ 12 ] , u [ 13 ] , u [ 14 ] , u [ 15 ] ,
name ) ;
}
else
2011-07-19 03:57:15 +00:00
log - > Printf ( " \t name= \" %s \" (UNLOADED) " , name ) ;
2011-07-08 00:48:09 +00:00
}
else
{
if ( u )
{
2011-07-19 03:57:15 +00:00
log - > Printf ( " \t addr=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 \" " ,
address , size , version , load_tag , flags , reference_list ,
u [ 0 ] , u [ 1 ] , u [ 2 ] , u [ 3 ] , u [ 4 ] , u [ 5 ] , u [ 6 ] , u [ 7 ] ,
u [ 8 ] , u [ 9 ] , u [ 10 ] , u [ 11 ] , u [ 12 ] , u [ 13 ] , u [ 14 ] , u [ 15 ] ,
2011-07-08 00:48:09 +00:00
name ) ;
}
else
{
2011-07-19 03:57:15 +00:00
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 \" " ,
address , address + size , version , load_tag , flags , reference_list ,
name ) ;
2011-07-08 00:48:09 +00:00
}
for ( uint32_t i = 0 ; i < segments . size ( ) ; + + i )
segments [ i ] . PutToLog ( log , 0 ) ;
}
}
//----------------------------------------------------------------------
// Dump the _dyld_all_image_infos members and all current image infos
// that we have parsed to the file handle provided.
//----------------------------------------------------------------------
void
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : PutToLog ( Log * log ) const
2011-07-08 00:48:09 +00:00
{
if ( log = = NULL )
return ;
Mutex : : Locker locker ( m_mutex ) ;
2011-07-19 03:57:15 +00:00
log - > Printf ( " gLoadedKextSummaries = 0x%16.16llx { version=%u, entry_size=%u, entry_count=%u } " ,
2011-07-08 03:21:57 +00:00
m_kext_summary_header_addr . GetFileAddress ( ) ,
2011-07-08 00:48:09 +00:00
m_kext_summary_header . version ,
m_kext_summary_header . entry_size ,
2011-07-19 03:57:15 +00:00
m_kext_summary_header . entry_count ) ;
2011-07-08 00:48:09 +00:00
size_t i ;
const size_t count = m_kext_summaries . size ( ) ;
if ( count > 0 )
{
log - > PutCString ( " Loaded: " ) ;
for ( i = 0 ; i < count ; i + + )
m_kext_summaries [ i ] . PutToLog ( log ) ;
}
}
void
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : PrivateInitialize ( Process * process )
2011-07-08 00:48:09 +00:00
{
2011-08-22 22:30:57 +00:00
DEBUG_PRINTF ( " DynamicLoaderDarwinKernel::%s() process state = %s \n " , __FUNCTION__ , StateAsCString ( m_process - > GetState ( ) ) ) ;
2011-07-08 00:48:09 +00:00
Clear ( true ) ;
m_process = process ;
m_process - > GetTarget ( ) . GetSectionLoadList ( ) . Clear ( ) ;
}
2011-07-09 17:15:55 +00:00
void
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : SetNotificationBreakpointIfNeeded ( )
2011-07-08 00:48:09 +00:00
{
2011-07-09 17:15:55 +00:00
if ( m_break_id = = LLDB_INVALID_BREAK_ID )
{
2011-08-22 22:30:57 +00:00
DEBUG_PRINTF ( " DynamicLoaderDarwinKernel::%s() process state = %s \n " , __FUNCTION__ , StateAsCString ( m_process - > GetState ( ) ) ) ;
2011-07-09 17:15:55 +00:00
2011-07-12 17:06:17 +00:00
2011-07-09 17:15:55 +00:00
const bool internal_bp = false ;
2011-07-12 17:06:17 +00:00
const LazyBool skip_prologue = eLazyBoolNo ;
2011-09-21 01:17:13 +00:00
FileSpecList module_spec_list ;
module_spec_list . Append ( m_kernel . module_sp - > GetFileSpec ( ) ) ;
Breakpoint * bp = m_process - > GetTarget ( ) . CreateBreakpoint ( & module_spec_list ,
2011-09-23 00:54:11 +00:00
NULL ,
2011-07-09 17:15:55 +00:00
" OSKextLoadedKextSummariesUpdated " ,
eFunctionNameTypeFull ,
2011-07-12 17:06:17 +00:00
internal_bp ,
skip_prologue ) . get ( ) ;
2011-07-09 17:15:55 +00:00
2011-08-22 22:30:57 +00:00
bp - > SetCallback ( DynamicLoaderDarwinKernel : : BreakpointHitCallback , this , true ) ;
2011-07-09 17:15:55 +00:00
m_break_id = bp - > GetID ( ) ;
}
2011-07-08 00:48:09 +00:00
}
//----------------------------------------------------------------------
// Member function that gets called when the process state changes.
//----------------------------------------------------------------------
void
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : PrivateProcessStateChanged ( Process * process , StateType state )
2011-07-08 00:48:09 +00:00
{
2011-08-22 22:30:57 +00:00
DEBUG_PRINTF ( " DynamicLoaderDarwinKernel::%s(%s) \n " , __FUNCTION__ , StateAsCString ( state ) ) ;
2011-07-08 00:48:09 +00:00
switch ( state )
{
case eStateConnected :
case eStateAttaching :
case eStateLaunching :
case eStateInvalid :
case eStateUnloaded :
case eStateExited :
case eStateDetached :
Clear ( false ) ;
break ;
case eStateStopped :
2011-07-09 17:15:55 +00:00
UpdateIfNeeded ( ) ;
2011-07-08 00:48:09 +00:00
break ;
case eStateRunning :
case eStateStepping :
case eStateCrashed :
case eStateSuspended :
break ;
default :
break ;
}
}
ThreadPlanSP
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : GetStepThroughTrampolinePlan ( Thread & thread , bool stop_others )
2011-07-08 00:48:09 +00:00
{
ThreadPlanSP thread_plan_sp ;
2011-07-09 17:15:55 +00:00
LogSP log ( GetLogIfAllCategoriesSet ( LIBLLDB_LOG_STEP ) ) ;
if ( log )
log - > Printf ( " Could not find symbol for step through. " ) ;
2011-07-08 00:48:09 +00:00
return thread_plan_sp ;
}
Error
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : CanLoadImage ( )
2011-07-08 00:48:09 +00:00
{
Error error ;
error . SetErrorString ( " always unsafe to load or unload shared libraries in the darwin kernel " ) ;
return error ;
}
void
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : Initialize ( )
2011-07-08 00:48:09 +00:00
{
PluginManager : : RegisterPlugin ( GetPluginNameStatic ( ) ,
GetPluginDescriptionStatic ( ) ,
CreateInstance ) ;
}
void
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : Terminate ( )
2011-07-08 00:48:09 +00:00
{
PluginManager : : UnregisterPlugin ( CreateInstance ) ;
}
const char *
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : GetPluginNameStatic ( )
2011-07-08 00:48:09 +00:00
{
return " dynamic-loader.macosx-kernel " ;
}
const char *
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : GetPluginDescriptionStatic ( )
2011-07-08 00:48:09 +00:00
{
return " Dynamic loader plug-in that watches for shared library loads/unloads in the MacOSX kernel. " ;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
const char *
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : GetPluginName ( )
2011-07-08 00:48:09 +00:00
{
2011-08-22 22:30:57 +00:00
return " DynamicLoaderDarwinKernel " ;
2011-07-08 00:48:09 +00:00
}
const char *
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : GetShortPluginName ( )
2011-07-08 00:48:09 +00:00
{
return GetPluginNameStatic ( ) ;
}
uint32_t
2011-08-22 22:30:57 +00:00
DynamicLoaderDarwinKernel : : GetPluginVersion ( )
2011-07-08 00:48:09 +00:00
{
return 1 ;
}