diff options
Diffstat (limited to 'lldb/source')
3 files changed, 42 insertions, 33 deletions
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index 2ef69469286..87020cedb21 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -1040,7 +1040,7 @@ ObjectFileMachO::CreateSections (SectionList &unified_section_list) // is null out the SectionList vector and if a process has been set up, dump a message // to stdout. The most common case here is core file debugging with a truncated file. const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT"; - module_sp->ReportError("is a corrupt mach-o file: load command %u %s has a fileoff (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 ")", + module_sp->ReportWarning("load command %u %s has a fileoff (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 "), ignoring this section", i, lc_segment_name, load_cmd.fileoff, @@ -1058,7 +1058,7 @@ ObjectFileMachO::CreateSections (SectionList &unified_section_list) // is null out the SectionList vector and if a process has been set up, dump a message // to stdout. The most common case here is core file debugging with a truncated file. const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT"; - GetModule()->ReportError("is a corrupt mach-o file: load command %u %s has a fileoff + filesize (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 "), the segment will be truncated", + GetModule()->ReportWarning("load command %u %s has a fileoff + filesize (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 "), the segment will be truncated to match", i, lc_segment_name, load_cmd.fileoff + load_cmd.filesize, diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp index ba8f74d8be9..faf6a856d92 100644 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp @@ -107,6 +107,7 @@ ProcessMachCore::ProcessMachCore(Target& target, Listener &listener, const FileS m_core_module_sp (), m_core_file (core_file), m_dyld_addr (LLDB_INVALID_ADDRESS), + m_mach_kernel_addr (LLDB_INVALID_ADDRESS), m_dyld_plugin_name () { } @@ -173,7 +174,10 @@ ProcessMachCore::GetDynamicLoaderAddress (lldb::addr_t addr) case llvm::MachO::MH_DYLINKER: //printf("0x%16.16" PRIx64 ": file_type = MH_DYLINKER\n", vaddr); // Address of dyld "struct mach_header" in the core file - m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic(); + if (m_dyld_addr != LLDB_INVALID_ADDRESS) + { + assert (!"already had user process dyld"); + } m_dyld_addr = addr; return true; @@ -183,9 +187,8 @@ ProcessMachCore::GetDynamicLoaderAddress (lldb::addr_t addr) // is NOT set. If it isn't, then we have a mach_kernel. if ((header.flags & llvm::MachO::MH_DYLDLINK) == 0) { - m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic(); // Address of the mach kernel "struct mach_header" in the core file. - m_dyld_addr = addr; + m_mach_kernel_addr = addr; return true; } break; @@ -278,13 +281,6 @@ ProcessMachCore::DoLoadCore () { m_core_aranges.Append(range_entry); } - - // After we have added this section to our m_core_aranges map, - // we can check the start of the section to see if it might - // contain dyld for user space apps, or the mach kernel file - // for kernel cores. - if (m_dyld_addr == LLDB_INVALID_ADDRESS) - GetDynamicLoaderAddress (section_vm_addr); } } if (!ranges_are_sorted) @@ -292,40 +288,50 @@ ProcessMachCore::DoLoadCore () m_core_aranges.Sort(); } - // Even if the architecture is set in the target, we need to override - // it to match the core file which is always single arch. - ArchSpec arch (m_core_module_sp->GetArchitecture()); - if (arch.GetCore() == ArchSpec::eCore_x86_32_i486) - { - arch.SetTriple ("i386", m_target.GetPlatform().get()); - } - if (arch.IsValid()) - m_target.SetArchitecture(arch); - - if (m_dyld_addr == LLDB_INVALID_ADDRESS) + if (m_dyld_addr == LLDB_INVALID_ADDRESS || m_mach_kernel_addr == LLDB_INVALID_ADDRESS) { // We need to locate the main executable in the memory ranges - // we have in the core file. We already checked the first address - // in each memory zone above, so we just need to check each page - // except the first page in each range and stop once we have found - // our main executable + // we have in the core file. We need to search for both a user-process dyld binary + // and a kernel binary in memory; we must look at all the pages in the binary so + // we don't miss one or the other. If we find a user-process dyld binary, stop + // searching -- that's the one we'll prefer over the mach kernel. const size_t num_core_aranges = m_core_aranges.GetSize(); for (size_t i=0; i<num_core_aranges && m_dyld_addr == LLDB_INVALID_ADDRESS; ++i) { const VMRangeToFileOffset::Entry *entry = m_core_aranges.GetEntryAtIndex(i); lldb::addr_t section_vm_addr_start = entry->GetRangeBase(); lldb::addr_t section_vm_addr_end = entry->GetRangeEnd(); - for (lldb::addr_t section_vm_addr = section_vm_addr_start + 0x1000; + for (lldb::addr_t section_vm_addr = section_vm_addr_start; section_vm_addr < section_vm_addr_end; section_vm_addr += 0x1000) { - if (GetDynamicLoaderAddress (section_vm_addr)) - { - break; - } + GetDynamicLoaderAddress (section_vm_addr); } } } + + // If we find both a user process dyld and a mach kernel, prefer the + // user process dyld. We may be looking at an lldb debug session were they were debugging + // a mach kernel when lldb coredumped. + if (m_dyld_addr != LLDB_INVALID_ADDRESS) + { + m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic(); + } + else if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) + { + m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic(); + } + + // Even if the architecture is set in the target, we need to override + // it to match the core file which is always single arch. + ArchSpec arch (m_core_module_sp->GetArchitecture()); + if (arch.GetCore() == ArchSpec::eCore_x86_32_i486) + { + arch.SetTriple ("i386", m_target.GetPlatform().get()); + } + if (arch.IsValid()) + m_target.SetArchitecture(arch); + return error; } @@ -455,7 +461,9 @@ ProcessMachCore::Initialize() addr_t ProcessMachCore::GetImageInfoAddress() { - return m_dyld_addr; + if (m_dyld_addr != LLDB_INVALID_ADDRESS) + return m_dyld_addr; + return m_mach_kernel_addr; } diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h index 2aa208185ef..1f4af97a75b 100644 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h @@ -137,6 +137,7 @@ private: lldb::ModuleSP m_core_module_sp; lldb_private::FileSpec m_core_file; lldb::addr_t m_dyld_addr; + lldb::addr_t m_mach_kernel_addr; lldb_private::ConstString m_dyld_plugin_name; DISALLOW_COPY_AND_ASSIGN (ProcessMachCore); |

