summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins
diff options
context:
space:
mode:
authorJason Molenda <jmolenda@apple.com>2018-06-18 23:30:03 +0000
committerJason Molenda <jmolenda@apple.com>2018-06-18 23:30:03 +0000
commit87f0f95e4c5fd702d4c03a53de1d5d8d071b8946 (patch)
tree1f395293593329fd017f5175d131dfc201a4b9fd /lldb/source/Plugins
parenta7b7f2f4d85b8111caa32bcd9dc8e95c5963abdd (diff)
downloadbcm5719-llvm-87f0f95e4c5fd702d4c03a53de1d5d8d071b8946.tar.gz
bcm5719-llvm-87f0f95e4c5fd702d4c03a53de1d5d8d071b8946.zip
Some NFC changes to how we scan of kexts & kernels in memory in the
DynamicLoaderDarwinKernel plugin. Created a new function ReadMachHeader and instead of reading through the target cached memory reader, start by reading only a mach header sized chunk of memory, then check it for a valid mach-o magic # and use the size of the load commands to pre-fetch the entire load commands of the kext which is the only thing we're going to read, instead of letting the generic mach-o parser read it in 512 byte chunks. Functionally this is doing exactly the same thing as before, but by cutting down on the # of packets going back and forth, even on a local connection it's close to a quarter faster than it was before. <rdar://problem/38570146> llvm-svn: 334995
Diffstat (limited to 'lldb/source/Plugins')
-rw-r--r--lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp84
-rw-r--r--lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h6
2 files changed, 58 insertions, 32 deletions
diff --git a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index fbf255a3c0d..6d114d9a892 100644
--- a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -8,8 +8,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Utility/SafeMachO.h"
-
#include "Plugins/Platform/MacOSX/PlatformDarwinKernel.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
@@ -368,46 +366,30 @@ lldb::addr_t DynamicLoaderDarwinKernel::SearchForKernelViaExhaustiveSearch(
}
//----------------------------------------------------------------------
-// Given an address in memory, look to see if there is a kernel image at that
-// address. Returns a UUID; if a kernel was not found at that address,
-// UUID.IsValid() will be false.
+// Read the mach_header struct out of memory and return it.
+// Returns true if the mach_header was successfully read,
+// Returns false if there was a problem reading the header, or it was not
+// a Mach-O header.
//----------------------------------------------------------------------
-lldb_private::UUID
-DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress(lldb::addr_t addr,
- Process *process) {
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (addr == LLDB_INVALID_ADDRESS)
- return UUID();
-
- if (log)
- log->Printf("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: "
- "looking for kernel binary at 0x%" PRIx64,
- addr);
-
- // First try a quick test -- read the first 4 bytes and see if there is a
- // valid Mach-O magic field there (the first field of the
- // mach_header/mach_header_64 struct).
+bool
+DynamicLoaderDarwinKernel::ReadMachHeader(addr_t addr, Process *process, llvm::MachO::mach_header &header) {
Status read_error;
- uint8_t magicbuf[4];
- if (process->ReadMemoryFromInferior (addr, magicbuf, sizeof (magicbuf), read_error) != sizeof (magicbuf))
- return UUID();
+
+ // Read the mach header and see whether it looks like a kernel
+ if (process->DoReadMemory (addr, &header, sizeof(header), read_error) !=
+ sizeof(header))
+ return false;
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 (size_t i = 0; i < llvm::array_lengthof (magicks); i++)
- if (::memcmp (magicbuf, &magicks[i], sizeof (magicbuf)) == 0)
+ if (::memcmp (&header.magic, &magicks[i], sizeof (uint32_t)) == 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;
- if (process->DoReadMemory(addr, &header, sizeof(header), read_error) !=
- sizeof(header))
- return UUID();
+ return false;
if (header.magic == llvm::MachO::MH_CIGAM ||
header.magic == llvm::MachO::MH_CIGAM_64) {
@@ -420,6 +402,35 @@ DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress(lldb::addr_t addr,
header.flags = llvm::ByteSwap_32(header.flags);
}
+ return true;
+}
+
+//----------------------------------------------------------------------
+// Given an address in memory, look to see if there is a kernel image at that
+// address.
+// Returns a UUID; if a kernel was not found at that address, UUID.IsValid()
+// will be false.
+//----------------------------------------------------------------------
+lldb_private::UUID
+DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress(lldb::addr_t addr,
+ Process *process) {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (addr == LLDB_INVALID_ADDRESS)
+ return UUID();
+
+ if (log)
+ log->Printf("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: "
+ "looking for kernel binary at 0x%" PRIx64,
+ addr);
+
+ llvm::MachO::mach_header header;
+
+ if (ReadMachHeader (addr, process, header) == false)
+ return UUID();
+
+ // First try a quick test -- read the first 4 bytes and see if there is a
+ // valid Mach-O magic field there
+ // (the first field of the mach_header/mach_header_64 struct).
// A kernel is an executable which does not have the dynamic link object flag
// set.
if (header.filetype == llvm::MachO::MH_EXECUTE &&
@@ -639,8 +650,17 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule(
FileSpec file_spec;
file_spec.SetFile(m_name.c_str(), false, FileSpec::Style::native);
+ llvm::MachO::mach_header mh;
+ size_t size_to_read = 512;
+ if (ReadMachHeader (m_load_address, process, mh)) {
+ if (mh.magic == llvm::MachO::MH_CIGAM || llvm::MachO::MH_MAGIC)
+ size_to_read = sizeof (llvm::MachO::mach_header) + mh.sizeofcmds;
+ if (mh.magic == llvm::MachO::MH_CIGAM_64 || llvm::MachO::MH_MAGIC_64)
+ size_to_read = sizeof (llvm::MachO::mach_header_64) + mh.sizeofcmds;
+ }
+
ModuleSP memory_module_sp =
- process->ReadModuleFromMemory(file_spec, m_load_address);
+ process->ReadModuleFromMemory(file_spec, m_load_address, size_to_read);
if (memory_module_sp.get() == NULL)
return false;
diff --git a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
index ad4f7c631d8..75998f1cc3b 100644
--- a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
+++ b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
@@ -17,6 +17,9 @@
#include <vector>
// Other libraries and framework includes
+
+#include "lldb/Utility/SafeMachO.h"
+
// Project includes
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Process.h"
@@ -284,6 +287,9 @@ protected:
static lldb::addr_t
SearchForKernelViaExhaustiveSearch(lldb_private::Process *process);
+ static bool
+ ReadMachHeader(lldb::addr_t addr, lldb_private::Process *process, llvm::MachO::mach_header &mh);
+
static lldb_private::UUID
CheckForKernelImageAtAddress(lldb::addr_t addr,
lldb_private::Process *process);
OpenPOWER on IntegriCloud