diff --git a/lldb/source/Host/aix/Host.cpp b/lldb/source/Host/aix/Host.cpp index b5572b93d93a9..6069c47e3052b 100644 --- a/lldb/source/Host/aix/Host.cpp +++ b/lldb/source/Host/aix/Host.cpp @@ -7,12 +7,15 @@ //===----------------------------------------------------------------------===// #include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Host/posix/Support.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/ProcessInfo.h" #include "lldb/Utility/Status.h" #include "llvm/BinaryFormat/XCOFF.h" +#include "llvm/Object/XCOFFObjectFile.h" +#include "llvm/Support/MemoryBuffer.h" #include #include #include @@ -81,6 +84,37 @@ static bool GetStatusInfo(::pid_t pid, ProcessInstanceInfo &processInfo, return true; } +static ArchSpec GetXCOFFProcessCPUType(llvm::StringRef exe_path) { + Log *log = GetLog(LLDBLog::Host); + + auto file_buffer = llvm::MemoryBuffer::getFile(exe_path); + if (!file_buffer) + return ArchSpec(); + + llvm::Expected> obj_or_err = + llvm::object::ObjectFile::createObjectFile( + (*file_buffer)->getMemBufferRef()); + + if (!obj_or_err) { + LLDB_LOG(log, "failed to create ObjectFile from buffer"); + return ArchSpec(); + } + + llvm::object::ObjectFile *obj = obj_or_err->get(); + + const llvm::object::XCOFFObjectFile *xcoff_obj = + llvm::dyn_cast(obj); + if (!xcoff_obj) { + LLDB_LOG(log, "Not an valid XCOFF object file: {0}", exe_path); + return ArchSpec(); + } + + if (xcoff_obj->is64Bit()) + return HostInfo::GetArchitecture(HostInfo::eArchKind64); + + return HostInfo::GetArchitecture(HostInfo::eArchKind32); +} + static bool GetExePathAndIds(::pid_t pid, ProcessInstanceInfo &process_info) { struct psinfo psinfoData; auto BufferOrError = getProcFile(pid, "psinfo"); @@ -100,9 +134,9 @@ static bool GetExePathAndIds(::pid_t pid, ProcessInstanceInfo &process_info) { return false; process_info.GetExecutableFile().SetFile(PathRef, FileSpec::Style::native); - ArchSpec arch_spec = ArchSpec(); - arch_spec.SetArchitecture(eArchTypeXCOFF, llvm::XCOFF::TCPU_PPC64, - LLDB_INVALID_CPUTYPE, llvm::Triple::AIX); + ArchSpec arch_spec = GetXCOFFProcessCPUType(PathRef); + if (!arch_spec) + return false; process_info.SetArchitecture(arch_spec); process_info.SetParentProcessID(psinfoData.pr_ppid); process_info.SetGroupID(psinfoData.pr_gid); diff --git a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp index ee05f3a8613b9..158519b6a1bc8 100644 --- a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp +++ b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp @@ -66,7 +66,7 @@ ObjectFile *ObjectFileXCOFF::CreateInstance(const lldb::ModuleSP &module_sp, data_offset = 0; extractor_sp = std::make_shared(data_sp); } - if (!ObjectFileXCOFF::MagicBytesMatch(extractor_sp, data_offset, length)) + if (!ObjectFileXCOFF::GetMagicBytes(extractor_sp, data_offset, length)) return nullptr; // Update the data to contain the entire file if it doesn't already if (extractor_sp->GetByteSize() < length) { @@ -133,44 +133,35 @@ ModuleSpecList ObjectFileXCOFF::GetModuleSpecifications( return {}; ModuleSpecList specs; - if (ObjectFileXCOFF::MagicBytesMatch(extractor_sp, 0, - extractor_sp->GetByteSize())) { + if (auto magic = ObjectFileXCOFF::GetMagicBytes( + extractor_sp, 0, extractor_sp->GetByteSize())) { + const uint32_t cpu_type = + (*magic == XCOFF::XCOFF64) ? XCOFF::TCPU_PPC64 : XCOFF::TCPU_PPC; ArchSpec arch_spec = - ArchSpec(eArchTypeXCOFF, XCOFF::TCPU_PPC64, LLDB_INVALID_CPUTYPE); + ArchSpec(eArchTypeXCOFF, cpu_type, LLDB_INVALID_CPUTYPE); ModuleSpec spec(file, arch_spec); - spec.GetArchitecture().SetArchitecture(eArchTypeXCOFF, XCOFF::TCPU_PPC64, - LLDB_INVALID_CPUTYPE, - llvm::Triple::AIX); + spec.GetArchitecture().SetArchitecture( + eArchTypeXCOFF, cpu_type, LLDB_INVALID_CPUTYPE, llvm::Triple::AIX); specs.Append(spec); } return specs; } -static uint32_t XCOFFHeaderSizeFromMagic(uint32_t magic) { - switch (magic) { - case XCOFF::XCOFF32: - return sizeof(struct llvm::object::XCOFFFileHeader32); - break; - case XCOFF::XCOFF64: - return sizeof(struct llvm::object::XCOFFFileHeader64); - break; - - default: - break; - } - return 0; -} - -bool ObjectFileXCOFF::MagicBytesMatch(DataExtractorSP &extractor_sp, - lldb::addr_t data_offset, - lldb::addr_t data_length) { +std::optional +ObjectFileXCOFF::GetMagicBytes(DataExtractorSP &extractor_sp, + lldb::addr_t data_offset, + lldb::addr_t data_length) { DataExtractorSP magic_extractor_sp = extractor_sp->GetSubsetExtractorSP(data_offset); // Need to set this as XCOFF is only compatible with Big Endian magic_extractor_sp->SetByteOrder(eByteOrderBig); lldb::offset_t offset = 0; uint16_t magic = magic_extractor_sp->GetU16(&offset); - return XCOFFHeaderSizeFromMagic(magic) != 0; + // Validating magic + if (magic == XCOFF::XCOFF64 || magic == XCOFF::XCOFF32) + return static_cast(magic); + + return std::nullopt; } bool ObjectFileXCOFF::ParseHeader() { @@ -368,9 +359,9 @@ void ObjectFileXCOFF::CreateSectionsWithBitness( void ObjectFileXCOFF::Dump(Stream *s) {} ArchSpec ObjectFileXCOFF::GetArchitecture() { - ArchSpec arch_spec = - ArchSpec(eArchTypeXCOFF, XCOFF::TCPU_PPC64, LLDB_INVALID_CPUTYPE); - return arch_spec; + const uint32_t cpu_type = + m_binary->is64Bit() ? XCOFF::TCPU_PPC64 : XCOFF::TCPU_PPC; + return (ArchSpec(eArchTypeXCOFF, cpu_type, LLDB_INVALID_CPUTYPE)); } UUID ObjectFileXCOFF::GetUUID() { return UUID(); } diff --git a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h index 1915affbd1be5..749902eebf300 100644 --- a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h +++ b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h @@ -52,8 +52,9 @@ class ObjectFileXCOFF : public lldb_private::ObjectFile { lldb::DataExtractorSP &extractor_sp, lldb::offset_t file_offset, lldb::offset_t length); - static bool MagicBytesMatch(lldb::DataExtractorSP &extractor_sp, - lldb::addr_t offset, lldb::addr_t length); + static std::optional + GetMagicBytes(lldb::DataExtractorSP &extractor_sp, lldb::addr_t offset, + lldb::addr_t length); // PluginInterface protocol llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } diff --git a/lldb/source/Utility/ArchSpec.cpp b/lldb/source/Utility/ArchSpec.cpp index f998e355691e9..fa46a48b7faa9 100644 --- a/lldb/source/Utility/ArchSpec.cpp +++ b/lldb/source/Utility/ArchSpec.cpp @@ -443,7 +443,7 @@ static const ArchDefinition g_coff_arch_def = { // clang-format off static const ArchDefinitionEntry g_xcoff_arch_entries[] = { - {ArchSpec::eCore_ppc_generic, llvm::XCOFF::TCPU_COM}, + {ArchSpec::eCore_ppc_generic, llvm::XCOFF::TCPU_PPC}, {ArchSpec::eCore_ppc64_generic, llvm::XCOFF::TCPU_PPC64} }; // clang-format on diff --git a/lldb/test/Shell/ObjectFile/XCOFF/basic-info32.yaml b/lldb/test/Shell/ObjectFile/XCOFF/basic-info32.yaml index dd1569fe52994..e3a8c1d144af0 100644 --- a/lldb/test/Shell/ObjectFile/XCOFF/basic-info32.yaml +++ b/lldb/test/Shell/ObjectFile/XCOFF/basic-info32.yaml @@ -2,7 +2,7 @@ # RUN: lldb-test object-file %t | FileCheck %s # CHECK: Plugin name: xcoff -# CHECK: Architecture: powerpc64-ibm-aix +# CHECK: Architecture: powerpc-ibm-aix # CHECK: Executable: true # CHECK: Stripped: false # CHECK: Type: executable