[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 01:15:16 PDT 2026


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

This PR is in reference to porting LLDB on AIX. Ref discusssions: [llvm discourse](https://discourse.llvm.org/t/port-lldb-to-ibm-aix/80640) and [#101657](https://github.com/llvm/llvm-project/issues/101657).
Complete changes together in this draft:
- [Extending LLDB to work on AIX #102601](https://github.com/llvm/llvm-project/pull/102601)

Description:
The process architecture was previously initialized using a hardcoded TCPU_PPC64 CPU type.

The logic has been updated to determine the CPU type dynamically by inspecting the magic bytes and the XCOFF header. Based on this information, the appropriate CPU type (TCPU_PPC or TCPU_PPC64) is selected and used when constructing and setting the ArchSpec.

This change ensures that the process architecture correctly reflects the underlying binary format.

>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] 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(); }



More information about the lldb-commits mailing list