[Lldb-commits] [lldb] r134681 - in /lldb/trunk/source/Plugins/DynamicLoader/MacOSX-Kernel: DynamicLoaderMacOSXKernel.cpp DynamicLoaderMacOSXKernel.h

Greg Clayton gclayton at apple.com
Thu Jul 7 20:21:57 PDT 2011


Author: gclayton
Date: Thu Jul  7 22:21:57 2011
New Revision: 134681

URL: http://llvm.org/viewvc/llvm-project?rev=134681&view=rev
Log:
Make the kernel able to do its initial load from target memory with the
process being preferred for all memory reads.


Modified:
    lldb/trunk/source/Plugins/DynamicLoader/MacOSX-Kernel/DynamicLoaderMacOSXKernel.cpp
    lldb/trunk/source/Plugins/DynamicLoader/MacOSX-Kernel/DynamicLoaderMacOSXKernel.h

Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-Kernel/DynamicLoaderMacOSXKernel.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-Kernel/DynamicLoaderMacOSXKernel.cpp?rev=134681&r1=134680&r2=134681&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-Kernel/DynamicLoaderMacOSXKernel.cpp (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-Kernel/DynamicLoaderMacOSXKernel.cpp Thu Jul  7 22:21:57 2011
@@ -67,7 +67,7 @@
 DynamicLoaderMacOSXKernel::DynamicLoaderMacOSXKernel (Process* process) :
     DynamicLoader(process),
     m_kernel(),
-    m_kext_summary_header_addr (LLDB_INVALID_ADDRESS),
+    m_kext_summary_header_addr (),
     m_kext_summary_header (),
     m_kext_summary_header_stop_id (0),
     m_break_id (LLDB_INVALID_BREAK_ID),
@@ -129,7 +129,7 @@
     if (clear_process)
         m_process = NULL;
     m_kernel.Clear(false);
-    m_kext_summary_header_addr = LLDB_INVALID_ADDRESS;
+    m_kext_summary_header_addr.Clear();
     m_kext_summaries.clear();
     m_kext_summaries_stop_id = 0;
     m_break_id = LLDB_INVALID_BREAK_ID;
@@ -153,7 +153,7 @@
 bool
 DynamicLoaderMacOSXKernel::LoadKernelModule()
 {
-    if (m_kext_summary_header_addr == LLDB_INVALID_ADDRESS)
+    if (!m_kext_summary_header_addr.IsValid())
     {
         m_kernel.Clear(false);
         m_kernel.module_sp = m_process->GetTarget().GetExecutableModule();
@@ -163,9 +163,9 @@
             const Symbol *symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (mach_header_name, eSymbolTypeAbsolute);
             if (symbol)
             {
-                m_kernel.address = symbol->GetValue().GetFileAddress();
+                m_kernel.so_address = symbol->GetValue();
                 DataExtractor data; // Load command data
-                if (ReadMachHeader (m_kernel.address, &m_kernel.header, &data))
+                if (ReadMachHeader (m_kernel, &data))
                 {
                     if (m_kernel.header.filetype == llvm::MachO::HeaderFileTypeDynamicLinkEditor)
                     {
@@ -366,77 +366,12 @@
 //----------------------------------------------------------------------
 bool
 DynamicLoaderMacOSXKernel::NotifyBreakpointHit (void *baton, 
-                                              StoppointCallbackContext *context, 
-                                              lldb::user_id_t break_id, 
-                                              lldb::user_id_t break_loc_id)
-{
-    // Let the event know that the images have changed
-    // DYLD passes three arguments to the notification breakpoint.
-    // Arg1: enum dyld_image_mode mode - 0 = adding, 1 = removing 
-    // Arg2: uint32_t infoCount        - Number of shared libraries added  
-    // Arg3: dyld_image_info info[]    - Array of structs of the form:
-    //                                     const struct mach_header *imageLoadAddress
-    //                                     const char               *imageFilePath
-    //                                     uintptr_t                 imageFileModDate (a time_t)
-    
+                                                StoppointCallbackContext *context, 
+                                                lldb::user_id_t break_id, 
+                                                lldb::user_id_t break_loc_id)
+{    
     DynamicLoaderMacOSXKernel* dyld_instance = (DynamicLoaderMacOSXKernel*) baton;
     
-    // First step is to see if we've already initialized the all image infos.  If we haven't then this function
-    // will do so and return true.  In the course of initializing the all_image_infos it will read the complete
-    // current state, so we don't need to figure out what has changed from the data passed in to us.
-    
-    if (!dyld_instance->ReadAllKextSummaries(false))
-    {
-        Process *process = context->exe_ctx.process;
-        const lldb::ABISP &abi = process->GetABI();
-        if (abi != NULL)
-        {
-            // Build up the value array to store the three arguments given above, then get the values from the ABI:
-            
-            ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
-            ValueList argument_values;
-            Value input_value;
-            
-            void *clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
-            void *clang_uint32_type   = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint, 32);
-            input_value.SetValueType (Value::eValueTypeScalar);
-            input_value.SetContext (Value::eContextTypeClangType, clang_uint32_type);
-            argument_values.PushValue(input_value);
-            argument_values.PushValue(input_value);
-            input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
-            argument_values.PushValue (input_value);
-            
-            if (abi->GetArgumentValues (*context->exe_ctx.thread, argument_values))
-            {
-                uint32_t dyld_mode = argument_values.GetValueAtIndex(0)->GetScalar().UInt (-1);
-                if (dyld_mode != -1)
-                {
-                    // Okay the mode was right, now get the number of elements, and the array of new elements...
-                    uint32_t image_infos_count = argument_values.GetValueAtIndex(1)->GetScalar().UInt (-1);
-                    if (image_infos_count != -1)
-                    {
-                        // Got the number added, now go through the array of added elements, putting out the mach header 
-                        // address, and adding the image.
-                        // Note, I'm not putting in logging here, since the AddModules & RemoveModules functions do
-                        // all the logging internally.
-                        
-                        lldb::addr_t kext_summary_addr = argument_values.GetValueAtIndex(2)->GetScalar().ULongLong();
-                        if (dyld_mode == 0)
-                        {
-                            // This is add:
-                            dyld_instance->ParseKextSummaries (kext_summary_addr, image_infos_count);
-                        }
-                        else
-                        {
-                            // This is remove:
-                            dyld_instance->RemoveModulesUsingImageInfosAddress (kext_summary_addr, image_infos_count);
-                        }
-                        
-                    }
-                }
-            }
-        }
-    }
     // Return true to stop the target, false to just let the target run
     return dyld_instance->GetStopWhenImagesChange();
 }
@@ -451,7 +386,7 @@
         return true;
 
     m_kext_summaries.clear();
-    if (m_kext_summary_header_addr != LLDB_INVALID_ADDRESS)
+    if (m_kext_summary_header_addr.IsValid())
     {
         const uint32_t addr_size = m_kernel.GetAddressByteSize ();
         const ByteOrder byte_order = m_kernel.GetByteOrder();
@@ -461,7 +396,8 @@
         uint8_t buf[24];
         DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
         const size_t count = 4 * sizeof(uint32_t) + addr_size;
-        const size_t bytes_read = m_process->ReadMemory (m_kext_summary_header_addr, buf, count, error);
+        const bool prefer_file_cache = false;
+        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;
@@ -478,7 +414,8 @@
 
 
 bool
-DynamicLoaderMacOSXKernel::ParseKextSummaries (lldb::addr_t kext_summary_addr, uint32_t count)
+DynamicLoaderMacOSXKernel::ParseKextSummaries (const lldb_private::Address &kext_summary_addr, 
+                                               uint32_t count)
 {
     OSKextLoadedKextSummary::collection kext_summaries;
     LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
@@ -497,7 +434,7 @@
         if (!kext_summaries[i].UUIDValid())
         {
             DataExtractor data; // Load command data
-            if (!ReadMachHeader (kext_summaries[i].address, &kext_summaries[i].header, &data))
+            if (!ReadMachHeader (kext_summaries[i], &data))
                 continue;
             
             ParseLoadCommands (data, kext_summaries[i]);
@@ -569,98 +506,9 @@
     return true;
 }
 
-bool
-DynamicLoaderMacOSXKernel::RemoveModulesUsingImageInfosAddress (lldb::addr_t kext_summary_addr, uint32_t image_infos_count)
-{
-    OSKextLoadedKextSummary::collection image_infos;
-    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
-    
-    Mutex::Locker locker(m_mutex);
-    if (m_process->GetStopID() == m_kext_summaries_stop_id)
-        return true;
-
-    // First read in the image_infos for the removed modules, and their headers & load commands.
-    if (!ReadKextSummaries (kext_summary_addr, image_infos_count, image_infos))
-    {
-        if (log)
-            log->PutCString ("Failed reading image infos array.");
-        return false;
-    }
-    
-    if (log)
-        log->Printf ("Removing %d modules.", image_infos_count);
-    
-    ModuleList unloaded_module_list;
-    for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
-    {        
-        if (log)
-        {
-            log->Printf ("Removing module at address=0x%16.16llx.", image_infos[idx].address);
-            image_infos[idx].PutToLog (log.get());
-        }
-            
-        // Remove this image_infos from the m_all_image_infos.  We do the comparision by address
-        // rather than by file spec because we can have many modules with the same "file spec" in the
-        // case that they are modules loaded from memory.
-        //
-        // Also copy over the uuid from the old entry to the removed entry so we can 
-        // use it to lookup the module in the module list.
-        
-        OSKextLoadedKextSummary::collection::iterator pos, end = m_kext_summaries.end();
-        for (pos = m_kext_summaries.begin(); pos != end; pos++)
-        {
-            if (image_infos[idx].address == (*pos).address)
-            {
-                image_infos[idx].uuid = (*pos).uuid;
-
-                // Add the module from this image_info to the "unloaded_module_list".  We'll remove them all at
-                // one go later on.
-                
-                if (FindTargetModule (image_infos[idx], false, NULL))
-                {
-                    UnloadImageLoadAddress (image_infos[idx]);
-                    unloaded_module_list.AppendIfNeeded (image_infos[idx].module_sp);
-                }
-                else
-                {
-                    if (log)
-                    {
-                        log->Printf ("Could not find module for unloading info entry:");
-                        image_infos[idx].PutToLog(log.get());
-                    }
-                }
-                
-                // Then remove it from the m_kext_summaries:
-                
-                m_kext_summaries.erase(pos);
-                break;
-            }
-        }
-        
-        if (pos == end)
-        {
-            if (log)
-            {
-                log->Printf ("Could not find image_info entry for unloading image:");
-                image_infos[idx].PutToLog(log.get());            
-            }
-        }
-    }
-    if (unloaded_module_list.GetSize() > 0)
-    {
-        if (log)
-        {
-            log->PutCString("Unloaded:");
-            unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXKernel::ModulesDidUnload");
-        }
-        m_process->GetTarget().ModulesDidUnload (unloaded_module_list);
-    }
-    m_kext_summaries_stop_id = m_process->GetStopID();
-    return true;
-}
 
 uint32_t
-DynamicLoaderMacOSXKernel::ReadKextSummaries (lldb::addr_t kext_summary_addr, 
+DynamicLoaderMacOSXKernel::ReadKextSummaries (const lldb_private::Address &kext_summary_addr,
                                               uint32_t image_infos_count, 
                                               OSKextLoadedKextSummary::collection &image_infos)
 {
@@ -671,10 +519,12 @@
     const size_t count = image_infos.size() * m_kext_summary_header.entry_size;
     DataBufferHeap data(count, 0);
     Error error;
-    const size_t bytes_read = m_process->ReadMemory (kext_summary_addr, 
-                                                     data.GetBytes(), 
-                                                     data.GetByteSize(),
-                                                     error);
+    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);
     if (bytes_read == count)
     {
         uint32_t offset = 0;
@@ -688,6 +538,8 @@
             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);
+            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);
             image_infos[i].size             = extractor.GetU64(&offset);
             image_infos[i].version          = extractor.GetU64(&offset);
             image_infos[i].load_tag         = extractor.GetU32(&offset);
@@ -720,7 +572,9 @@
     {
         if (m_kext_summary_header.entry_count > 0)
         {
-            if (!ParseKextSummaries (m_kext_summary_header_addr + 16, m_kext_summary_header.entry_count))
+            Address summary_addr (m_kext_summary_header_addr);
+            summary_addr.Slide(16);
+            if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count))
             {
                 DEBUG_PRINTF( "unable to read all data for all_dylib_infos.");
                 m_kext_summaries.clear();
@@ -738,36 +592,38 @@
 // Returns true if we succeed, false if we fail for any reason.
 //----------------------------------------------------------------------
 bool
-DynamicLoaderMacOSXKernel::ReadMachHeader (lldb::addr_t addr, llvm::MachO::mach_header *header, DataExtractor *load_command_data)
+DynamicLoaderMacOSXKernel::ReadMachHeader (OSKextLoadedKextSummary& kext_summary, DataExtractor *load_command_data)
 {
     DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0);
     Error error;
-    size_t bytes_read = m_process->ReadMemory (addr, 
-                                               header_bytes.GetBytes(), 
-                                               header_bytes.GetByteSize(), 
-                                               error);
+    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);
     if (bytes_read == sizeof(llvm::MachO::mach_header))
     {
         uint32_t offset = 0;
-        ::memset (header, 0, sizeof(header));
+        ::memset (&kext_summary.header, 0, sizeof(kext_summary.header));
 
         // Get the magic byte unswapped so we can figure out what we are dealing with
         DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(), lldb::endian::InlHostByteOrder(), 4);
-        header->magic = data.GetU32(&offset);
-        lldb::addr_t load_cmd_addr = addr;
-        data.SetByteOrder(DynamicLoaderMacOSXKernel::GetByteOrderFromMagic(header->magic));
-        switch (header->magic)
+        kext_summary.header.magic = data.GetU32(&offset);
+        Address load_cmd_addr = kext_summary.so_address;
+        data.SetByteOrder(DynamicLoaderMacOSXKernel::GetByteOrderFromMagic(kext_summary.header.magic));
+        switch (kext_summary.header.magic)
         {
         case llvm::MachO::HeaderMagic32:
         case llvm::MachO::HeaderMagic32Swapped:
             data.SetAddressByteSize(4);
-            load_cmd_addr += sizeof(llvm::MachO::mach_header);
+            load_cmd_addr.Slide (sizeof(llvm::MachO::mach_header));
             break;
 
         case llvm::MachO::HeaderMagic64:
         case llvm::MachO::HeaderMagic64Swapped:
             data.SetAddressByteSize(8);
-            load_cmd_addr += sizeof(llvm::MachO::mach_header_64);
+            load_cmd_addr.Slide (sizeof(llvm::MachO::mach_header_64));
             break;
 
         default:
@@ -775,23 +631,24 @@
         }
 
         // Read the rest of dyld's mach header
-        if (data.GetU32(&offset, &header->cputype, (sizeof(llvm::MachO::mach_header)/sizeof(uint32_t)) - 1))
+        if (data.GetU32(&offset, &kext_summary.header.cputype, (sizeof(llvm::MachO::mach_header)/sizeof(uint32_t)) - 1))
         {
             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
 
-            DataBufferSP load_cmd_data_sp(new DataBufferHeap(header->sizeofcmds, 0));
+            DataBufferSP load_cmd_data_sp(new DataBufferHeap(kext_summary.header.sizeofcmds, 0));
 
-            size_t load_cmd_bytes_read = m_process->ReadMemory (load_cmd_addr, 
-                                                                load_cmd_data_sp->GetBytes(), 
-                                                                load_cmd_data_sp->GetByteSize(),
-                                                                error);
+            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);
             
-            if (load_cmd_bytes_read == header->sizeofcmds)
+            if (load_cmd_bytes_read == kext_summary.header.sizeofcmds)
             {
                 // Set the load command data and also set the correct endian
                 // swap settings and the correct address size
-                load_command_data->SetData(load_cmd_data_sp, 0, header->sizeofcmds);
+                load_command_data->SetData(load_cmd_data_sp, 0, kext_summary.header.sizeofcmds);
                 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
@@ -997,7 +854,7 @@
 
     Mutex::Locker locker(m_mutex);
     log->Printf("gLoadedKextSummaries = 0x%16.16llx { version=%u, entry_size=%u, entry_count=%u, reserved=%u }",
-                m_kext_summary_header_addr,
+                m_kext_summary_header_addr.GetFileAddress(),
                 m_kext_summary_header.version,
                 m_kext_summary_header.entry_size,
                 m_kext_summary_header.entry_count,

Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-Kernel/DynamicLoaderMacOSXKernel.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-Kernel/DynamicLoaderMacOSXKernel.h?rev=134681&r1=134680&r2=134681&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-Kernel/DynamicLoaderMacOSXKernel.h (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-Kernel/DynamicLoaderMacOSXKernel.h Thu Jul  7 22:21:57 2011
@@ -148,10 +148,6 @@
         return lldb::eByteOrderInvalid;
     }
 
-    bool
-    ReadMachHeader (lldb::addr_t addr,
-                    llvm::MachO::mach_header *header,
-                    lldb_private::DataExtractor *load_command_data);
     class Segment
     {
     public:
@@ -198,6 +194,7 @@
         char                     name[KERNEL_MODULE_MAX_NAME];
         lldb::ModuleSP           module_sp;
         lldb_private::UUID       uuid;            // UUID for this dylib if it has one, else all zeros
+        lldb_private::Address    so_address;        // The section offset address for this kext in case it can be read from object files
         uint64_t                 address;
         uint64_t                 size;
         uint64_t                 version;
@@ -210,6 +207,7 @@
         OSKextLoadedKextSummary() :
             module_sp (),
             uuid (),
+            so_address (),
             address (LLDB_INVALID_ADDRESS),
             size (0),
             version (0),
@@ -227,6 +225,7 @@
         {
             if (!load_cmd_data_only)
             {
+                so_address.Clear();
                 address = LLDB_INVALID_ADDRESS;
                 size = 0;
                 version = 0;
@@ -349,6 +348,10 @@
         }
     };
 
+    bool
+    ReadMachHeader (OSKextLoadedKextSummary& kext_summary,
+                    lldb_private::DataExtractor *load_command_data);
+
     void
     RegisterNotificationCallbacks();
 
@@ -377,14 +380,12 @@
     ReadKextSummaryHeader ();
     
     bool
-    ParseKextSummaries (lldb::addr_t kext_summary_addr, uint32_t count);
+    ParseKextSummaries (const lldb_private::Address &kext_summary_addr, 
+                        uint32_t count);
     
     bool
     AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos);
     
-    bool
-    RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count);
-
     void
     UpdateImageInfosHeaderAndLoadCommands(OSKextLoadedKextSummary::collection &image_infos, 
                                           uint32_t infos_count, 
@@ -394,7 +395,7 @@
     UpdateCommPageLoadAddress (lldb_private::Module *module);
 
     uint32_t
-    ReadKextSummaries (lldb::addr_t image_infos_addr, 
+    ReadKextSummaries (const lldb_private::Address &kext_summary_addr,
                        uint32_t image_infos_count, 
                        OSKextLoadedKextSummary::collection &image_infos);
     
@@ -402,7 +403,7 @@
     UnloadImageLoadAddress (OSKextLoadedKextSummary& info);
 
     OSKextLoadedKextSummary m_kernel; // Info about the current kernel image being used
-    lldb::addr_t m_kext_summary_header_addr;
+    lldb_private::Address m_kext_summary_header_addr;
     OSKextLoadedKextSummaryHeader m_kext_summary_header;
     uint32_t m_kext_summary_header_stop_id;             // The process stop ID that "m_kext_summary_header" is valid for
     lldb::user_id_t m_break_id;





More information about the lldb-commits mailing list