[Lldb-commits] [lldb] r286926 - Change the kernel searching code to not go through the

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Mon Nov 14 17:41:27 PST 2016


Author: jmolenda
Date: Mon Nov 14 19:41:27 2016
New Revision: 286926

URL: http://llvm.org/viewvc/llvm-project?rev=286926&view=rev
Log:
Change the kernel searching code to not go through the
memory cache subsystem so we're reading only the 4 bytes
needed to check for the magic word at the start of a mach-o
binary instead of the default 512 block.  It can be a small
performance help to reduce the size of memory reads from 
possibly unmapped memory.

<rdar://problem/29256385> 

Modified:
    lldb/trunk/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.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=286926&r1=286925&r2=286926&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp Mon Nov 14 19:41:27 2016
@@ -239,27 +239,40 @@ DynamicLoaderDarwinKernel::SearchForKern
     return LLDB_INVALID_ADDRESS;
 
   Error read_err;
-  addr_t addr = LLDB_INVALID_ADDRESS;
   addr_t kernel_addresses_64[] = {
       0xfffffff000004010ULL, // newest arm64 devices
       0xffffff8000004010ULL, // 2014-2015-ish arm64 devices
       0xffffff8000002010ULL, // oldest arm64 devices
       LLDB_INVALID_ADDRESS};
   addr_t kernel_addresses_32[] = {0xffff0110, LLDB_INVALID_ADDRESS};
+
+  uint8_t uval[8];
+  if (process->GetAddressByteSize() == 8) {
   for (size_t i = 0; kernel_addresses_64[i] != LLDB_INVALID_ADDRESS; i++) {
-    addr = process->ReadUnsignedIntegerFromMemory(
-        kernel_addresses_64[i], 8, LLDB_INVALID_ADDRESS, read_err);
-    if (CheckForKernelImageAtAddress(addr, process).IsValid()) {
-      return addr;
-    }
+      if (process->ReadMemoryFromInferior (kernel_addresses_64[i], uval, 8, read_err) == 8)
+      {
+          DataExtractor data (&uval, 8, process->GetByteOrder(), process->GetAddressByteSize());
+          offset_t offset = 0;
+          uint64_t addr = data.GetU64 (&offset);
+          if (CheckForKernelImageAtAddress(addr, process).IsValid()) {
+              return addr;
+          }
+      }
+  }
   }
 
+  if (process->GetAddressByteSize() == 4) {
   for (size_t i = 0; kernel_addresses_32[i] != LLDB_INVALID_ADDRESS; i++) {
-    addr = process->ReadUnsignedIntegerFromMemory(
-        kernel_addresses_32[i], 4, LLDB_INVALID_ADDRESS, read_err);
-    if (CheckForKernelImageAtAddress(addr, process).IsValid()) {
-      return addr;
-    }
+      if (process->ReadMemoryFromInferior (kernel_addresses_32[i], uval, 4, read_err) == 4)
+      {
+          DataExtractor data (&uval, 4, process->GetByteOrder(), process->GetAddressByteSize());
+          offset_t offset = 0;
+          uint32_t addr = data.GetU32 (&offset);
+          if (CheckForKernelImageAtAddress(addr, process).IsValid()) {
+              return addr;
+          }
+      }
+  }
   }
 
   return LLDB_INVALID_ADDRESS;
@@ -380,12 +393,19 @@ DynamicLoaderDarwinKernel::CheckForKerne
   // (the first field of the mach_header/mach_header_64 struct).
 
   Error read_error;
-  uint64_t result = process->ReadUnsignedIntegerFromMemory(
-      addr, 4, LLDB_INVALID_ADDRESS, read_error);
-  if (result != llvm::MachO::MH_MAGIC_64 && result != llvm::MachO::MH_MAGIC &&
-      result != llvm::MachO::MH_CIGAM && result != llvm::MachO::MH_CIGAM_64) {
-    return UUID();
-  }
+  uint8_t magicbuf[4];
+  if (process->ReadMemoryFromInferior (addr, magicbuf, sizeof (magicbuf), read_error) != sizeof (magicbuf))
+      return UUID();
+
+  const uint32_t magicks[] = { llvm::MachO::MH_MAGIC_64, llvm::MachO::MH_MAGIC, llvm::MachO::MH_CIGAM, llvm::MachO::MH_CIGAM_64};
+
+  bool found_matching_pattern = false;
+  for (int i = 0; i < llvm::array_lengthof (magicks); i++)
+    if (::memcmp (magicbuf, &magicks[i], sizeof (magicbuf)) == 0)
+        found_matching_pattern = true;
+
+  if (found_matching_pattern == false)
+      return UUID();
 
   // Read the mach header and see whether it looks like a kernel
   llvm::MachO::mach_header header;




More information about the lldb-commits mailing list