[Lldb-commits] [lldb] [lldb][AIX] Extract CPU type and set up process architecture accordingly (PR #189910)

Hemang Gadhavi via lldb-commits lldb-commits at lists.llvm.org
Wed Apr 1 22:33:22 PDT 2026


https://github.com/HemangGadhavi updated https://github.com/llvm/llvm-project/pull/189910

>From 2f4f37f4f1c45165593e9d04a2d8887feb9b2377 Mon Sep 17 00:00:00 2001
From: HemangGadhavi <hemang.gadhavi at ibm.com>
Date: Wed, 1 Apr 2026 02:37:34 -0500
Subject: [PATCH 1/2] Extract CPU type and set up process architecture
 accordingly

---
 lldb/source/Host/aix/Host.cpp                 | 37 ++++++++++++--
 .../ObjectFile/XCOFF/ObjectFileXCOFF.cpp      | 48 ++++++++-----------
 .../ObjectFile/XCOFF/ObjectFileXCOFF.h        |  4 +-
 3 files changed, 55 insertions(+), 34 deletions(-)

diff --git a/lldb/source/Host/aix/Host.cpp b/lldb/source/Host/aix/Host.cpp
index b5572b93d93a9..5d4c7d0eb0d99 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 <dirent.h>
 #include <sys/proc.h>
 #include <sys/procfs.h>
@@ -81,6 +84,35 @@ 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<std::unique_ptr<llvm::object::ObjectFile>> obj_or_err =
+      llvm::object::ObjectFile::createObjectFile(
+          (*file_buffer)->getMemBufferRef());
+
+  if (!obj_or_err)
+    return ArchSpec();
+
+  llvm::object::ObjectFile *obj = obj_or_err->get();
+
+  const llvm::object::XCOFFObjectFile *xcoff_obj =
+      llvm::dyn_cast<llvm::object::XCOFFObjectFile>(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);
+  else
+    return HostInfo::GetArchitecture(HostInfo::eArchKind32);
+}
+
 static bool GetExePathAndIds(::pid_t pid, ProcessInstanceInfo &process_info) {
   struct psinfo psinfoData;
   auto BufferOrError = getProcFile(pid, "psinfo");
@@ -100,10 +132,7 @@ 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);
-  process_info.SetArchitecture(arch_spec);
+  process_info.SetArchitecture(GetXCOFFProcessCPUType(PathRef));
   process_info.SetParentProcessID(psinfoData.pr_ppid);
   process_info.SetGroupID(psinfoData.pr_gid);
   process_info.SetEffectiveGroupID(psinfoData.pr_egid);
diff --git a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
index ee05f3a8613b9..8bc886f80a1b0 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<lldb_private::DataExtractor>(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())) {
+  uint16_t magic = 0;
+  if ((magic = ObjectFileXCOFF::GetMagicBytes(
+           extractor_sp, 0, extractor_sp->GetByteSize())) != 0) {
+    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) {
+uint16_t 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 magic;
+  else
+    return 0;
 }
 
 bool ObjectFileXCOFF::ParseHeader() {
@@ -368,8 +359,9 @@ void ObjectFileXCOFF::CreateSectionsWithBitness(
 void ObjectFileXCOFF::Dump(Stream *s) {}
 
 ArchSpec ObjectFileXCOFF::GetArchitecture() {
-  ArchSpec arch_spec =
-      ArchSpec(eArchTypeXCOFF, XCOFF::TCPU_PPC64, LLDB_INVALID_CPUTYPE);
+  const uint32_t cpu_type =
+      m_binary->is64Bit() ? XCOFF::TCPU_PPC64 : XCOFF::TCPU_PPC;
+  ArchSpec arch_spec = ArchSpec(eArchTypeXCOFF, cpu_type, LLDB_INVALID_CPUTYPE);
   return arch_spec;
 }
 
diff --git a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h
index 1915affbd1be5..de1120f951bf3 100644
--- a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h
+++ b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h
@@ -52,8 +52,8 @@ 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 uint16_t GetMagicBytes(lldb::DataExtractorSP &extractor_sp,
+                                lldb::addr_t offset, lldb::addr_t length);
 
   // PluginInterface protocol
   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }

>From 5e13dffb53d01cbe250c2f84e30f2ec0a6aa074b Mon Sep 17 00:00:00 2001
From: HemangGadhavi <hemang.gadhavi at ibm.com>
Date: Wed, 1 Apr 2026 07:06:06 -0500
Subject: [PATCH 2/2] Modified testcase for 32bit and addressed review comments

---
 lldb/source/Host/aix/Host.cpp                 | 13 +++++++----
 .../ObjectFile/XCOFF/ObjectFileXCOFF.cpp      | 23 +++++++++----------
 .../ObjectFile/XCOFF/ObjectFileXCOFF.h        |  5 ++--
 lldb/source/Utility/ArchSpec.cpp              |  2 +-
 .../Shell/ObjectFile/XCOFF/basic-info32.yaml  |  2 +-
 5 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/lldb/source/Host/aix/Host.cpp b/lldb/source/Host/aix/Host.cpp
index 5d4c7d0eb0d99..6069c47e3052b 100644
--- a/lldb/source/Host/aix/Host.cpp
+++ b/lldb/source/Host/aix/Host.cpp
@@ -95,8 +95,10 @@ static ArchSpec GetXCOFFProcessCPUType(llvm::StringRef exe_path) {
       llvm::object::ObjectFile::createObjectFile(
           (*file_buffer)->getMemBufferRef());
 
-  if (!obj_or_err)
+  if (!obj_or_err) {
+    LLDB_LOG(log, "failed to create ObjectFile from buffer");
     return ArchSpec();
+  }
 
   llvm::object::ObjectFile *obj = obj_or_err->get();
 
@@ -109,8 +111,8 @@ static ArchSpec GetXCOFFProcessCPUType(llvm::StringRef exe_path) {
 
   if (xcoff_obj->is64Bit())
     return HostInfo::GetArchitecture(HostInfo::eArchKind64);
-  else
-    return HostInfo::GetArchitecture(HostInfo::eArchKind32);
+
+  return HostInfo::GetArchitecture(HostInfo::eArchKind32);
 }
 
 static bool GetExePathAndIds(::pid_t pid, ProcessInstanceInfo &process_info) {
@@ -132,7 +134,10 @@ static bool GetExePathAndIds(::pid_t pid, ProcessInstanceInfo &process_info) {
     return false;
 
   process_info.GetExecutableFile().SetFile(PathRef, FileSpec::Style::native);
-  process_info.SetArchitecture(GetXCOFFProcessCPUType(PathRef));
+  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);
   process_info.SetEffectiveGroupID(psinfoData.pr_egid);
diff --git a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
index 8bc886f80a1b0..158519b6a1bc8 100644
--- a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
+++ b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
@@ -133,11 +133,10 @@ ModuleSpecList ObjectFileXCOFF::GetModuleSpecifications(
     return {};
 
   ModuleSpecList specs;
-  uint16_t magic = 0;
-  if ((magic = ObjectFileXCOFF::GetMagicBytes(
-           extractor_sp, 0, extractor_sp->GetByteSize())) != 0) {
+  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;
+        (*magic == XCOFF::XCOFF64) ? XCOFF::TCPU_PPC64 : XCOFF::TCPU_PPC;
     ArchSpec arch_spec =
         ArchSpec(eArchTypeXCOFF, cpu_type, LLDB_INVALID_CPUTYPE);
     ModuleSpec spec(file, arch_spec);
@@ -148,9 +147,10 @@ ModuleSpecList ObjectFileXCOFF::GetModuleSpecifications(
   return specs;
 }
 
-uint16_t ObjectFileXCOFF::GetMagicBytes(DataExtractorSP &extractor_sp,
-                                        lldb::addr_t data_offset,
-                                        lldb::addr_t data_length) {
+std::optional<XCOFF::MagicNumber>
+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
@@ -159,9 +159,9 @@ uint16_t ObjectFileXCOFF::GetMagicBytes(DataExtractorSP &extractor_sp,
   uint16_t magic = magic_extractor_sp->GetU16(&offset);
   // Validating magic
   if (magic == XCOFF::XCOFF64 || magic == XCOFF::XCOFF32)
-    return magic;
-  else
-    return 0;
+    return static_cast<llvm::XCOFF::MagicNumber>(magic);
+
+  return std::nullopt;
 }
 
 bool ObjectFileXCOFF::ParseHeader() {
@@ -361,8 +361,7 @@ void ObjectFileXCOFF::Dump(Stream *s) {}
 ArchSpec ObjectFileXCOFF::GetArchitecture() {
   const uint32_t cpu_type =
       m_binary->is64Bit() ? XCOFF::TCPU_PPC64 : XCOFF::TCPU_PPC;
-  ArchSpec arch_spec = ArchSpec(eArchTypeXCOFF, cpu_type, LLDB_INVALID_CPUTYPE);
-  return arch_spec;
+  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 de1120f951bf3..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 uint16_t GetMagicBytes(lldb::DataExtractorSP &extractor_sp,
-                                lldb::addr_t offset, lldb::addr_t length);
+  static std::optional<llvm::XCOFF::MagicNumber>
+  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



More information about the lldb-commits mailing list