diff options
author | Jason Molenda <jmolenda@apple.com> | 2018-06-18 23:30:03 +0000 |
---|---|---|
committer | Jason Molenda <jmolenda@apple.com> | 2018-06-18 23:30:03 +0000 |
commit | 87f0f95e4c5fd702d4c03a53de1d5d8d071b8946 (patch) | |
tree | 1f395293593329fd017f5175d131dfc201a4b9fd /lldb/source/Plugins | |
parent | a7b7f2f4d85b8111caa32bcd9dc8e95c5963abdd (diff) | |
download | bcm5719-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.cpp | 84 | ||||
-rw-r--r-- | lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h | 6 |
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); |