Author: jmolenda
Date: Fri Feb  5 22:55:26 2016
New Revision: 259983

URL: http://llvm.org/viewvc/llvm-project?rev=259983&view=rev
Log:
ProcessMachCore scans through the core file pages looking for a
user process dyld binary and/or a mach kernel binary image.  By
default, it prefers the kernel if it finds both.

But if it finds two kernel binary images (which can happen when
random things are mapped into memory), it may pick the wrong
kernel image.  

DynamicLoaderDarwinKernel has heuristics to find a kernel in memory;
once we've established that there is a kernel binary in memory,
call over to that class to see if it can find a kernel address via
its search methods.  If it does, use that.

Some minor cleanups to DynamicLoaderDarwinKernel while I was at it.

<rdar://problem/24446112> 

Modified:
    
lldb/trunk/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
    
lldb/trunk/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
    lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp

Modified: 
lldb/trunk/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp?rev=259983&r1=259982&r2=259983&view=diff
==============================================================================
--- 
lldb/trunk/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
 (original)
+++ 
lldb/trunk/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
 Fri Feb  5 22:55:26 2016
@@ -254,37 +254,29 @@ DynamicLoaderDarwinKernel::SearchForKern
 
     Error read_err;
     addr_t addr = LLDB_INVALID_ADDRESS;
-    if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
+    addr_t kernel_addresses_64[] = { 0xffffff8000002010ULL, 
0xffffff8000004010ULL, 
+                                     0xfffffff000002010ULL, 
0xfffffff000004010ULL, 
+                                     LLDB_INVALID_ADDRESS };
+    addr_t kernel_addresses_32[] = { 0xffff0110,
+                                     LLDB_INVALID_ADDRESS };
+    for (size_t i = 0; kernel_addresses_64[i] != LLDB_INVALID_ADDRESS; i++)
     {
-        addr = process->ReadUnsignedIntegerFromMemory (0xffffff8000002010ULL, 
8, LLDB_INVALID_ADDRESS, read_err);
-        if (CheckForKernelImageAtAddress (addr, process).IsValid())
-        {
-            return addr;
-        }
-        addr = process->ReadUnsignedIntegerFromMemory (0xffffff8000004010ULL, 
8, LLDB_INVALID_ADDRESS, read_err);
-        if (CheckForKernelImageAtAddress (addr, process).IsValid())
-        {
-            return addr;
-        }
-        addr = process->ReadUnsignedIntegerFromMemory (0xfffffff000002010ULL, 
8, LLDB_INVALID_ADDRESS, read_err);
-        if (CheckForKernelImageAtAddress (addr, process).IsValid())
-        {
-            return addr;
-        }
-        addr = process->ReadUnsignedIntegerFromMemory (0xfffffff000004010ULL, 
8, LLDB_INVALID_ADDRESS, read_err);
+        addr = process->ReadUnsignedIntegerFromMemory (kernel_addresses_64[i], 
8, LLDB_INVALID_ADDRESS, read_err);
         if (CheckForKernelImageAtAddress (addr, process).IsValid())
         {
             return addr;
         }
     }
-    else
+
+    for (size_t i = 0; kernel_addresses_32[i] != LLDB_INVALID_ADDRESS; i++)
     {
-        addr = process->ReadUnsignedIntegerFromMemory (0xffff0110, 4, 
LLDB_INVALID_ADDRESS, read_err);
+        addr = process->ReadUnsignedIntegerFromMemory (kernel_addresses_32[i], 
4, LLDB_INVALID_ADDRESS, read_err);
         if (CheckForKernelImageAtAddress (addr, process).IsValid())
         {
             return addr;
         }
     }
+
     return LLDB_INVALID_ADDRESS;
 }
 
@@ -311,28 +303,14 @@ DynamicLoaderDarwinKernel::SearchForKern
     if (pc == LLDB_INVALID_ADDRESS)
         return LLDB_INVALID_ADDRESS;
 
-    addr_t kernel_range_low;
-    if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
-    {
-        kernel_range_low = 1ULL << 63;
-    }
-    else
-    {
-        kernel_range_low = 1ULL << 31;
-    }
-
-    // Outside the normal kernel address range, this is probably userland code 
running right now
-    if (pc < kernel_range_low)
-        return LLDB_INVALID_ADDRESS;
-
     // The kernel will load at at one megabyte boundary (0x100000), or at that 
boundary plus 
-    // an offset of one page (0x1000) or two, depending on the device.
+    // an offset of one page (0x1000) or two, or four (0x4000), depending on 
the device.
 
     // Round the current pc down to the nearest one megabyte boundary - the 
place where we will start searching.
     addr_t addr = pc & ~0xfffff;
 
-    int i = 0;
-    while (i < 32 && pc >= kernel_range_low)
+    // Search backwards 32 megabytes, looking for the start of the kernel at 
each one-megabyte boundary.
+    for (int i = 0; i < 32; i++, addr -= 0x100000)
     {
         if (CheckForKernelImageAtAddress (addr, process).IsValid())
             return addr;
@@ -342,8 +320,6 @@ DynamicLoaderDarwinKernel::SearchForKern
             return addr + 0x2000;
         if (CheckForKernelImageAtAddress (addr + 0x4000, process).IsValid())
             return addr + 0x4000;
-        i++;
-        addr -= 0x100000;
     }
 
     return LLDB_INVALID_ADDRESS;
@@ -429,19 +405,19 @@ DynamicLoaderDarwinKernel::CheckForKerne
 
     // Read the mach header and see whether it looks like a kernel
     llvm::MachO::mach_header header;
-    if (process->DoReadMemory (addr, &header, sizeof(header), read_error) != 
sizeof(header))
+    if (process->DoReadMemory (addr, &header, sizeof (header), read_error) != 
sizeof (header))
         return UUID();
 
     if (header.magic == llvm::MachO::MH_CIGAM ||
         header.magic == llvm::MachO::MH_CIGAM_64)
     {
-        header.magic        = llvm::ByteSwap_32(header.magic);
-        header.cputype      = llvm::ByteSwap_32(header.cputype);
-        header.cpusubtype   = llvm::ByteSwap_32(header.cpusubtype);
-        header.filetype     = llvm::ByteSwap_32(header.filetype);
-        header.ncmds        = llvm::ByteSwap_32(header.ncmds);
-        header.sizeofcmds   = llvm::ByteSwap_32(header.sizeofcmds);
-        header.flags        = llvm::ByteSwap_32(header.flags);
+        header.magic        = llvm::ByteSwap_32 (header.magic);
+        header.cputype      = llvm::ByteSwap_32 (header.cputype);
+        header.cpusubtype   = llvm::ByteSwap_32 (header.cpusubtype);
+        header.filetype     = llvm::ByteSwap_32 (header.filetype);
+        header.ncmds        = llvm::ByteSwap_32 (header.ncmds);
+        header.sizeofcmds   = llvm::ByteSwap_32 (header.sizeofcmds);
+        header.flags        = llvm::ByteSwap_32 (header.flags);
     }
 
     // A kernel is an executable which does not have the dynamic link object 
flag set.

Modified: 
lldb/trunk/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h?rev=259983&r1=259982&r2=259983&view=diff
==============================================================================
--- 
lldb/trunk/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
 (original)
+++ 
lldb/trunk/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
 Fri Feb  5 22:55:26 2016
@@ -52,6 +52,9 @@ public:
     static void
     DebuggerInitialize (lldb_private::Debugger &debugger);
 
+    static lldb::addr_t
+    SearchForDarwinKernel (lldb_private::Process *process);
+
     //------------------------------------------------------------------
     /// Called after attaching a process.
     ///
@@ -337,9 +340,6 @@ protected:
                        KextImageInfo::collection &image_infos);
 
     static lldb::addr_t
-    SearchForDarwinKernel (lldb_private::Process *process);
-    
-    static lldb::addr_t
     SearchForKernelAtSameLoadAddr (lldb_private::Process *process);
 
     static lldb::addr_t

Modified: lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp?rev=259983&r1=259982&r2=259983&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp (original)
+++ lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp Fri Feb  5 
22:55:26 2016
@@ -335,6 +335,38 @@ ProcessMachCore::DoLoadCore ()
         }
     }
 
+
+    if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
+    {
+        // In the case of multiple kernel images found in the core file via 
exhaustive
+        // search, we may not pick the correct one.  See if the 
DynamicLoaderDarwinKernel's
+        // search heuristics might identify the correct one.
+        // Most of the time, I expect the address from SearchForDarwinKernel() 
will be the
+        // same as the address we found via exhaustive search.
+        // 
+        // NB SearchForDarwinKernel will end up calling back into this this 
class in the GetImageInfoAddress
+        // method which will give it the m_mach_kernel_addr address it already 
has.  Save that aside
+        // and set m_mach_kernel_addr to an invalid address temporarily so 
DynamicLoaderDarwinKernel does
+        // a real search for the kernel using its own heuristics.
+
+        if (GetTarget().GetArchitecture().IsValid() == false && 
m_core_module_sp.get())
+        {
+            GetTarget().SetArchitecture (m_core_module_sp->GetArchitecture());
+        }
+
+        addr_t saved_mach_kernel_addr = m_mach_kernel_addr;
+        m_mach_kernel_addr = LLDB_INVALID_ADDRESS;
+        addr_t better_kernel_address = 
DynamicLoaderDarwinKernel::SearchForDarwinKernel (this);
+        m_mach_kernel_addr = saved_mach_kernel_addr;
+        if (better_kernel_address != LLDB_INVALID_ADDRESS)
+        {
+            if (log)
+                log->Printf ("ProcessMachCore::DoLoadCore: Using the kernel 
address from DynamicLoaderDarwinKernel");
+            m_mach_kernel_addr = better_kernel_address;
+        }
+    }
+
+
     // If we found both a user-process dyld and a kernel binary, we need to 
decide
     // which to prefer.
     if (GetCorefilePreference() == eKernelCorefile)


_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to