Author: jmolenda Date: Wed Apr 5 20:50:11 2017 New Revision: 299612 URL: http://llvm.org/viewvc/llvm-project?rev=299612&view=rev Log: Some old mach-o core files have an LC_IDENT load command and there's a string in there that can be helpful in locating the kernel binary. Use it. <rdar://problem/31444711>
Modified: lldb/trunk/include/lldb/Symbol/ObjectFile.h lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp Modified: lldb/trunk/include/lldb/Symbol/ObjectFile.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ObjectFile.h?rev=299612&r1=299611&r2=299612&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/ObjectFile.h (original) +++ lldb/trunk/include/lldb/Symbol/ObjectFile.h Wed Apr 5 20:50:11 2017 @@ -563,6 +563,19 @@ public: virtual uint32_t GetNumThreadContexts() { return 0; } + //------------------------------------------------------------------ + /// Some object files may have an identifier string embedded in them, + /// e.g. in a Mach-O core file using the LC_IDENT load command (which + /// is obsolete, but can still be found in some old files) + /// + /// @return + /// Returns the identifier string if one exists, else an empty + /// string. + //------------------------------------------------------------------ + virtual std::string GetIdentifierString () { + return std::string(); + } + virtual lldb::RegisterContextSP GetThreadContextAtIndex(uint32_t idx, lldb_private::Thread &thread) { return lldb::RegisterContextSP(); Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=299612&r1=299611&r2=299612&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original) +++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Wed Apr 5 20:50:11 2017 @@ -5353,6 +5353,37 @@ uint32_t ObjectFileMachO::GetNumThreadCo return m_thread_context_offsets.GetSize(); } +// The LC_IDENT load command has been obsoleted for a very +// long time and it should not occur in Mach-O files. But +// if it is there, it may contain a hint about where to find +// the main binary in a core file, so we'll use it. +std::string ObjectFileMachO::GetIdentifierString() { + std::string result; + ModuleSP module_sp(GetModule()); + if (module_sp) { + std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); + lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); + for (uint32_t i = 0; i < m_header.ncmds; ++i) { + const uint32_t cmd_offset = offset; + struct ident_command ident_command; + if (m_data.GetU32(&offset, &ident_command, 2) == NULL) + break; + if (ident_command.cmd == LC_IDENT && ident_command.cmdsize != 0) { + char *buf = (char *)malloc (ident_command.cmdsize); + if (buf != nullptr + && m_data.CopyData (offset, ident_command.cmdsize, buf) == ident_command.cmdsize) { + buf[ident_command.cmdsize - 1] = '\0'; + result = buf; + } + if (buf) + free (buf); + } + offset = cmd_offset + ident_command.cmdsize; + } + } + return result; +} + lldb::RegisterContextSP ObjectFileMachO::GetThreadContextAtIndex(uint32_t idx, lldb_private::Thread &thread) { Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h?rev=299612&r1=299611&r2=299612&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h (original) +++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h Wed Apr 5 20:50:11 2017 @@ -111,6 +111,8 @@ public: uint32_t GetNumThreadContexts() override; + std::string GetIdentifierString() override; + lldb::RegisterContextSP GetThreadContextAtIndex(uint32_t idx, lldb_private::Thread &thread) override; Modified: lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp?rev=299612&r1=299611&r2=299612&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp (original) +++ lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp Wed Apr 5 20:50:11 2017 @@ -291,8 +291,42 @@ Error ProcessMachCore::DoLoadCore() { m_core_range_infos.Sort(); } - if (m_dyld_addr == LLDB_INVALID_ADDRESS || - m_mach_kernel_addr == LLDB_INVALID_ADDRESS) { + + bool found_main_binary_definitively = false; + + // This checks for the presence of an LC_IDENT string in a core file; + // LC_IDENT is very obsolete and should not be used in new code, but + // if the load command is present, let's use the contents. + std::string corefile_identifier = core_objfile->GetIdentifierString(); + if (corefile_identifier.find("Darwin Kernel") != std::string::npos) { + UUID uuid; + addr_t addr = LLDB_INVALID_ADDRESS; + if (corefile_identifier.find("UUID=") != std::string::npos) { + size_t p = corefile_identifier.find("UUID=") + strlen("UUID="); + std::string uuid_str = corefile_identifier.substr(p, 36); + uuid.SetFromCString(uuid_str.c_str()); + } + if (corefile_identifier.find("stext=") != std::string::npos) { + size_t p = corefile_identifier.find("stext=") + strlen("stext="); + if (corefile_identifier[p] == '0' && corefile_identifier[p + 1] == 'x') { + errno = 0; + addr = ::strtoul(corefile_identifier.c_str() + p, NULL, 16); + if (errno != 0 || addr == 0) + addr = LLDB_INVALID_ADDRESS; + } + } + if (uuid.IsValid() && addr != LLDB_INVALID_ADDRESS) { + m_mach_kernel_addr = addr; + found_main_binary_definitively = true; + if (log) + log->Printf("ProcessMachCore::DoLoadCore: Using the kernel address 0x%" PRIx64 + "from LC_IDENT string '%s'", addr, corefile_identifier.c_str()); + } + } + + if (found_main_binary_definitively == false && + (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 need to search for both a user-process dyld // binary @@ -317,7 +351,8 @@ Error ProcessMachCore::DoLoadCore() { } } - if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) { + if (found_main_binary_definitively == false + && m_mach_kernel_addr != LLDB_INVALID_ADDRESS) { // In the case of multiple kernel images found in the core file via // exhaustive // search, we may not pick the correct one. See if the _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits