jasonmolenda updated this revision to Diff 503497.
jasonmolenda added a comment.
Show an alternate approach, where we check the file types of everything in the
kernel+kext list, and if something is not a kernel/kext, don't try to load it
at all. v. the first change in
`DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule` where I
call `!IsKernel() && !obj_macho->IsKext()` to detect something in the list
which isn't processed the standard way that kexts & the kernel are. Either one
would work in this case.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D145547/new/
https://reviews.llvm.org/D145547
Files:
lldb/source/Plugins/DynamicLoader/Darwin-Kernel/CMakeLists.txt
lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
Index: lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
===================================================================
--- lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
+++ lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
@@ -90,6 +90,8 @@
bool IsSharedCacheBinary() const;
+ bool IsKext() const;
+
uint32_t GetAddressByteSize() const override;
lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override;
@@ -151,6 +153,8 @@
bool AllowAssemblyEmulationUnwindPlans() override;
+ lldb_private::Section *GetMachHeaderSection();
+
// PluginInterface protocol
llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
@@ -193,8 +197,6 @@
/// should not be used.
void GetLLDBSharedCacheUUID(lldb::addr_t &base_addir, lldb_private::UUID &uuid);
- lldb_private::Section *GetMachHeaderSection();
-
lldb::addr_t CalculateSectionLoadAddressForMemoryImage(
lldb::addr_t mach_header_load_address,
const lldb_private::Section *mach_header_section,
Index: lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
===================================================================
--- lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -1141,6 +1141,9 @@
return m_header.flags & MH_DYLIB_IN_CACHE;
}
+bool ObjectFileMachO::IsKext() const {
+ return m_header.filetype == MH_KEXT_BUNDLE;
+}
uint32_t ObjectFileMachO::GetAddressByteSize() const {
return m_data.GetAddressByteSize();
}
Index: lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
===================================================================
--- lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
#include "Plugins/Platform/MacOSX/PlatformDarwinKernel.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
@@ -713,6 +714,7 @@
bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
Process *process) {
+ Log *log = GetLog(LLDBLog::DynamicLoader);
if (IsLoaded())
return true;
@@ -810,6 +812,25 @@
}
}
+ ObjectFile *ondisk_object_file = m_module_sp->GetObjectFile();
+ ObjectFileMachO *ondisk_objfile_macho = nullptr;
+ if (ondisk_object_file)
+ ondisk_objfile_macho =
+ llvm::dyn_cast<ObjectFileMachO>(ondisk_object_file);
+
+ if (m_module_sp && m_uuid.IsValid() && m_module_sp->GetUUID() == m_uuid) {
+ if (ondisk_objfile_macho) {
+ // If we have something in the kext list which is not a kext
+ // and not the kernel, don't try to load it.
+ if (!IsKernel() && !obj_macho->IsKext()) {
+ LLDB_LOGF(log,
+ "'%s' with UUID %s is not a kext or kernel, not loading.",
+ m_name.c_str(), m_uuid.GetAsString().c_str());
+ m_module_sp.reset();
+ }
+ }
+ }
+
// If we managed to find a module, append it to the target's list of
// images. If we also have a memory module, require that they have matching
// UUIDs
@@ -837,6 +858,35 @@
// it.
const bool ignore_linkedit = !IsKernel();
+ // Normally a kext will have its segment load commands
+ // (LC_SEGMENT vmaddrs) corrected in memory to have their
+ // actual segment addresses.
+ // Userland proceses have their libraries updated the same way
+ // by dyld. The Mach-O load commands in memory are the canonical
+ // addresses.
+ //
+ // If the kernel gives us a binary where the in-memory segment
+ // vmaddr is incorrect, then this binary was put in memory without
+ // updating its Mach-O load commands. We should assume a static
+ // slide value will be applied to every segment; we don't have the
+ // correct addresses for each individual segment.
+ addr_t fixed_slide = LLDB_INVALID_ADDRESS;
+ ObjectFileMachO *memory_objfile_macho =
+ llvm::dyn_cast<ObjectFileMachO>(memory_object_file);
+ if (memory_objfile_macho) {
+ if (Section *header_sect =
+ memory_objfile_macho->GetMachHeaderSection()) {
+ if (header_sect->GetFileAddress() != m_load_address) {
+ fixed_slide = m_load_address - header_sect->GetFileAddress();
+ LLDB_LOGF(
+ log,
+ "kext %s in-memory LC_SEGMENT vmaddr is not correct, using a "
+ "fixed slide of 0x%" PRIx64,
+ m_name.c_str(), fixed_slide);
+ }
+ }
+ }
+
SectionList *ondisk_section_list = ondisk_object_file->GetSectionList();
SectionList *memory_section_list = memory_object_file->GetSectionList();
if (memory_section_list && ondisk_section_list) {
@@ -865,14 +915,20 @@
ondisk_section_sp->GetName() == g_section_name_LINKEDIT)
continue;
- const Section *memory_section =
- memory_section_list
- ->FindSectionByName(ondisk_section_sp->GetName())
- .get();
- if (memory_section) {
- target.SetSectionLoadAddress(ondisk_section_sp,
- memory_section->GetFileAddress());
- ++num_sections_loaded;
+ if (fixed_slide != LLDB_INVALID_ADDRESS) {
+ target.SetSectionLoadAddress(
+ ondisk_section_sp,
+ ondisk_section_sp->GetFileAddress() + fixed_slide);
+ } else {
+ const Section *memory_section =
+ memory_section_list
+ ->FindSectionByName(ondisk_section_sp->GetName())
+ .get();
+ if (memory_section) {
+ target.SetSectionLoadAddress(
+ ondisk_section_sp, memory_section->GetFileAddress());
+ ++num_sections_loaded;
+ }
}
}
}
Index: lldb/source/Plugins/DynamicLoader/Darwin-Kernel/CMakeLists.txt
===================================================================
--- lldb/source/Plugins/DynamicLoader/Darwin-Kernel/CMakeLists.txt
+++ lldb/source/Plugins/DynamicLoader/Darwin-Kernel/CMakeLists.txt
@@ -17,6 +17,7 @@
lldbSymbol
lldbTarget
lldbUtility
+ lldbPluginObjectFileMachO
)
add_dependencies(lldbPluginDynamicLoaderDarwinKernel
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits