|
6 | 6 | //
|
7 | 7 | //===----------------------------------------------------------------------===//
|
8 | 8 |
|
| 9 | +#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h" |
9 | 10 | #include "Plugins/Platform/MacOSX/PlatformDarwinKernel.h"
|
10 | 11 | #include "lldb/Breakpoint/StoppointCallbackContext.h"
|
11 | 12 | #include "lldb/Core/Debugger.h"
|
@@ -713,6 +714,7 @@ void DynamicLoaderDarwinKernel::KextImageInfo::SetIsKernel(bool is_kernel) {
|
713 | 714 |
|
714 | 715 | bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
|
715 | 716 | Process *process) {
|
| 717 | + Log *log = GetLog(LLDBLog::DynamicLoader); |
716 | 718 | if (IsLoaded())
|
717 | 719 | return true;
|
718 | 720 |
|
@@ -810,6 +812,28 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
|
810 | 812 | }
|
811 | 813 | }
|
812 | 814 |
|
| 815 | + if (m_module_sp && m_uuid.IsValid() && m_module_sp->GetUUID() == m_uuid) { |
| 816 | + ObjectFileMachO *ondisk_objfile_macho = |
| 817 | + llvm::dyn_cast_or_null<ObjectFileMachO>( |
| 818 | + m_module_sp ? m_module_sp->GetObjectFile() : nullptr); |
| 819 | + if (ondisk_objfile_macho) { |
| 820 | + if (!IsKernel() && !ondisk_objfile_macho->IsKext()) { |
| 821 | + // We have a non-kext, non-kernel binary. If we already have this |
| 822 | + // loaded in the Target with load addresses, don't re-load it again. |
| 823 | + ModuleSP existing_module_sp = target.GetImages().FindModule(m_uuid); |
| 824 | + if (existing_module_sp && |
| 825 | + existing_module_sp->IsLoadedInTarget(&target)) { |
| 826 | + LLDB_LOGF(log, |
| 827 | + "'%s' with UUID %s is not a kext or kernel, and is " |
| 828 | + "already registered in target, not loading.", |
| 829 | + m_name.c_str(), m_uuid.GetAsString().c_str()); |
| 830 | + // It's already loaded, return true. |
| 831 | + return true; |
| 832 | + } |
| 833 | + } |
| 834 | + } |
| 835 | + } |
| 836 | + |
813 | 837 | // If we managed to find a module, append it to the target's list of
|
814 | 838 | // images. If we also have a memory module, require that they have matching
|
815 | 839 | // UUIDs
|
@@ -837,6 +861,34 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
|
837 | 861 | // it.
|
838 | 862 | const bool ignore_linkedit = !IsKernel();
|
839 | 863 |
|
| 864 | + // Normally a kext will have its segment load commands |
| 865 | + // (LC_SEGMENT vmaddrs) corrected in memory to have their |
| 866 | + // actual segment addresses. |
| 867 | + // Userland proceses have their libraries updated the same way |
| 868 | + // by dyld. The Mach-O load commands in memory are the canonical |
| 869 | + // addresses. |
| 870 | + // |
| 871 | + // If the kernel gives us a binary where the in-memory segment |
| 872 | + // vmaddr is incorrect, then this binary was put in memory without |
| 873 | + // updating its Mach-O load commands. We should assume a static |
| 874 | + // slide value will be applied to every segment; we don't have the |
| 875 | + // correct addresses for each individual segment. |
| 876 | + addr_t fixed_slide = LLDB_INVALID_ADDRESS; |
| 877 | + if (ObjectFileMachO *memory_objfile_macho = |
| 878 | + llvm::dyn_cast<ObjectFileMachO>(memory_object_file)) { |
| 879 | + if (Section *header_sect = |
| 880 | + memory_objfile_macho->GetMachHeaderSection()) { |
| 881 | + if (header_sect->GetFileAddress() != m_load_address) { |
| 882 | + fixed_slide = m_load_address - header_sect->GetFileAddress(); |
| 883 | + LLDB_LOGF( |
| 884 | + log, |
| 885 | + "kext %s in-memory LC_SEGMENT vmaddr is not correct, using a " |
| 886 | + "fixed slide of 0x%" PRIx64, |
| 887 | + m_name.c_str(), fixed_slide); |
| 888 | + } |
| 889 | + } |
| 890 | + } |
| 891 | + |
840 | 892 | SectionList *ondisk_section_list = ondisk_object_file->GetSectionList();
|
841 | 893 | SectionList *memory_section_list = memory_object_file->GetSectionList();
|
842 | 894 | if (memory_section_list && ondisk_section_list) {
|
@@ -865,14 +917,20 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
|
865 | 917 | ondisk_section_sp->GetName() == g_section_name_LINKEDIT)
|
866 | 918 | continue;
|
867 | 919 |
|
868 |
| - const Section *memory_section = |
869 |
| - memory_section_list |
870 |
| - ->FindSectionByName(ondisk_section_sp->GetName()) |
871 |
| - .get(); |
872 |
| - if (memory_section) { |
873 |
| - target.SetSectionLoadAddress(ondisk_section_sp, |
874 |
| - memory_section->GetFileAddress()); |
875 |
| - ++num_sections_loaded; |
| 920 | + if (fixed_slide != LLDB_INVALID_ADDRESS) { |
| 921 | + target.SetSectionLoadAddress( |
| 922 | + ondisk_section_sp, |
| 923 | + ondisk_section_sp->GetFileAddress() + fixed_slide); |
| 924 | + } else { |
| 925 | + const Section *memory_section = |
| 926 | + memory_section_list |
| 927 | + ->FindSectionByName(ondisk_section_sp->GetName()) |
| 928 | + .get(); |
| 929 | + if (memory_section) { |
| 930 | + target.SetSectionLoadAddress( |
| 931 | + ondisk_section_sp, memory_section->GetFileAddress()); |
| 932 | + ++num_sections_loaded; |
| 933 | + } |
876 | 934 | }
|
877 | 935 | }
|
878 | 936 | }
|
|
0 commit comments