Skip to content

[lldb][AIX] Added 32-bit XCOFF Executable support #139875

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 16, 2025

Conversation

DhruvSrivastavaX
Copy link
Contributor

This PR is in reference to porting LLDB on AIX.

Link to discussions on llvm discourse and github:

  1. https://discourse.llvm.org/t/port-lldb-to-ibm-aix/80640
  2. Extending LLDB to work on AIX #101657
    The complete changes for porting are present in this draft PR:
    Extending LLDB to work on AIX #102601

Description:
Adding support for XCOFF 32 bit file format as well in lldb, up to the point where 64-bit support is implemented.
Added a new test case for the same.
This is an incremental PR on top of the previous couple of XCOFF support commits.

@llvmbot
Copy link
Member

llvmbot commented May 14, 2025

@llvm/pr-subscribers-lldb

Author: Dhruv Srivastava (DhruvSrivastavaX)

Changes

This PR is in reference to porting LLDB on AIX.

Link to discussions on llvm discourse and github:

  1. https://discourse.llvm.org/t/port-lldb-to-ibm-aix/80640
  2. Extending LLDB to work on AIX #101657
    The complete changes for porting are present in this draft PR:
    Extending LLDB to work on AIX #102601

Description:
Adding support for XCOFF 32 bit file format as well in lldb, up to the point where 64-bit support is implemented.
Added a new test case for the same.
This is an incremental PR on top of the previous couple of XCOFF support commits.


Full diff: https://github.com/llvm/llvm-project/pull/139875.diff

3 Files Affected:

  • (modified) lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp (+37-17)
  • (modified) lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h (+13-1)
  • (added) lldb/test/Shell/ObjectFile/XCOFF/basic-info32.yaml (+110)
diff --git a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
index 1666677c360ba..1ad488ff20c24 100644
--- a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
+++ b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
@@ -39,7 +39,6 @@ using namespace lldb;
 using namespace lldb_private;
 
 LLDB_PLUGIN_DEFINE(ObjectFileXCOFF)
-
 // FIXME: target 64bit at this moment.
 
 // Static methods.
@@ -95,10 +94,11 @@ bool ObjectFileXCOFF::CreateBinary() {
 
   Log *log = GetLog(LLDBLog::Object);
 
-  auto binary = llvm::object::ObjectFile::createObjectFile(
-      llvm::MemoryBufferRef(toStringRef(m_data.GetData()),
-                            m_file.GetFilename().GetStringRef()),
-      file_magic::xcoff_object_64);
+  auto memory_ref = llvm::MemoryBufferRef(toStringRef(m_data.GetData()),
+                                          m_file.GetFilename().GetStringRef());
+  llvm::file_magic magic = llvm::identify_magic(memory_ref.getBuffer());
+
+  auto binary = llvm::object::ObjectFile::createObjectFile(memory_ref, magic);
   if (!binary) {
     LLDB_LOG_ERROR(log, binary.takeError(),
                    "Failed to create binary for file ({1}): {0}", m_file);
@@ -143,9 +143,9 @@ size_t ObjectFileXCOFF::GetModuleSpecifications(
 
 static uint32_t XCOFFHeaderSizeFromMagic(uint32_t magic) {
   switch (magic) {
-    // TODO: 32bit not supported.
-    // case XCOFF::XCOFF32:
-    //  return sizeof(struct llvm::object::XCOFFFileHeader32);
+  case XCOFF::XCOFF32:
+    return sizeof(struct llvm::object::XCOFFFileHeader32);
+    break;
   case XCOFF::XCOFF64:
     return sizeof(struct llvm::object::XCOFFFileHeader64);
     break;
@@ -169,8 +169,9 @@ bool ObjectFileXCOFF::MagicBytesMatch(DataBufferSP &data_sp,
 }
 
 bool ObjectFileXCOFF::ParseHeader() {
-  // Only 64-bit is supported for now
-  return m_binary->fileHeader64()->Magic == XCOFF::XCOFF64;
+  if (m_binary->is64Bit())
+    return m_binary->fileHeader64()->Magic == XCOFF::XCOFF64;
+  return m_binary->fileHeader64()->Magic == XCOFF::XCOFF32;
 }
 
 ByteOrder ObjectFileXCOFF::GetByteOrder() const { return eByteOrderBig; }
@@ -178,8 +179,9 @@ ByteOrder ObjectFileXCOFF::GetByteOrder() const { return eByteOrderBig; }
 bool ObjectFileXCOFF::IsExecutable() const { return true; }
 
 uint32_t ObjectFileXCOFF::GetAddressByteSize() const {
-  // 32-bit not supported. return 8 for 64-bit XCOFF::XCOFF64
-  return 8;
+  if (m_binary->is64Bit())
+    return 8;
+  return 4;
 }
 
 AddressClass ObjectFileXCOFF::GetAddressClass(addr_t file_addr) {
@@ -191,20 +193,36 @@ void ObjectFileXCOFF::ParseSymtab(Symtab &lldb_symtab) {}
 bool ObjectFileXCOFF::IsStripped() { return false; }
 
 void ObjectFileXCOFF::CreateSections(SectionList &unified_section_list) {
+
   if (m_sections_up)
     return;
 
   m_sections_up = std::make_unique<SectionList>();
-  ModuleSP module_sp(GetModule());
+  if (m_binary->is64Bit())
+    CreateSectionsWithBitness<XCOFF64>(unified_section_list);
+  else
+    CreateSectionsWithBitness<XCOFF32>(unified_section_list);
+}
+
+template <typename T> auto GetSections(llvm::object::XCOFFObjectFile *binary) {
+  if constexpr (T::Is64Bit)
+    return binary->sections64();
+  else
+    return binary->sections32();
+}
 
+template <typename T>
+void ObjectFileXCOFF::CreateSectionsWithBitness(
+    SectionList &unified_section_list) {
+  ModuleSP module_sp(GetModule());
   if (!module_sp)
     return;
 
   std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
 
   int idx = 0;
-  for (const llvm::object::XCOFFSectionHeader64 &section :
-       m_binary->sections64()) {
+  for (const typename T::SectionHeader &section :
+       GetSections<T>(m_binary.get())) {
 
     ConstString const_sect_name(section.Name);
 
@@ -253,9 +271,11 @@ UUID ObjectFileXCOFF::GetUUID() { return UUID(); }
 uint32_t ObjectFileXCOFF::GetDependentModules(FileSpecList &files) { return 0; }
 
 ObjectFile::Type ObjectFileXCOFF::CalculateType() {
-  if (m_binary->fileHeader64()->Flags & XCOFF::F_EXEC)
+  if (m_binary->fileHeader64()->Flags & XCOFF::F_EXEC ||
+      m_binary->fileHeader32()->Flags & XCOFF::F_EXEC)
     return eTypeExecutable;
-  else if (m_binary->fileHeader64()->Flags & XCOFF::F_SHROBJ)
+  else if (m_binary->fileHeader64()->Flags & XCOFF::F_SHROBJ ||
+           m_binary->fileHeader32()->Flags & XCOFF::F_SHROBJ)
     return eTypeSharedLibrary;
   return eTypeUnknown;
 }
diff --git a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h
index 2d4f9f3f2dab8..d359fe6927240 100644
--- a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h
+++ b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h
@@ -97,6 +97,19 @@ class ObjectFileXCOFF : public lldb_private::ObjectFile {
                   lldb::DataBufferSP header_data_sp,
                   const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
 
+  struct XCOFF32 {
+    using SectionHeader = llvm::object::XCOFFSectionHeader32;
+    static constexpr bool Is64Bit = false;
+  };
+  struct XCOFF64 {
+    using SectionHeader = llvm::object::XCOFFSectionHeader64;
+    static constexpr bool Is64Bit = true;
+  };
+
+  template <typename T>
+  void
+  CreateSectionsWithBitness(lldb_private::SectionList &unified_section_list);
+
 protected:
   static lldb::WritableDataBufferSP
   MapFileDataWritable(const lldb_private::FileSpec &file, uint64_t Size,
@@ -104,7 +117,6 @@ class ObjectFileXCOFF : public lldb_private::ObjectFile {
 
 private:
   bool CreateBinary();
-
   std::unique_ptr<llvm::object::XCOFFObjectFile> m_binary;
 };
 
diff --git a/lldb/test/Shell/ObjectFile/XCOFF/basic-info32.yaml b/lldb/test/Shell/ObjectFile/XCOFF/basic-info32.yaml
new file mode 100644
index 0000000000000..dd1569fe52994
--- /dev/null
+++ b/lldb/test/Shell/ObjectFile/XCOFF/basic-info32.yaml
@@ -0,0 +1,110 @@
+# RUN: yaml2obj %s -o %t
+# RUN: lldb-test object-file %t | FileCheck %s
+
+# CHECK: Plugin name: xcoff
+# CHECK: Architecture: powerpc64-ibm-aix
+# CHECK: Executable: true
+# CHECK: Stripped: false
+# CHECK: Type: executable
+# CHECK: Strata: unknown
+# CHECK: Name: .text
+# CHECK-NEXT: Type: code
+# CHECK-NEXT: Permissions: r-x
+# CHECK: Name: .data
+# CHECK-NEXT: Type: data
+# CHECK-NEXT: Permissions: rw-
+# CHECK: Name: .bss
+# CHECK-NEXT: Type: zero-fill
+# CHECK-NEXT: Permissions: rw-
+# CHECK: Name: .loader
+# CHECK-NEXT: Type: regular
+# CHECK-NEXT: Permissions: r--
+# CHECK: Name: .dwline
+# CHECK-NEXT: Type: dwarf-line
+# CHECK-NEXT: Permissions: r--
+# CHECK: Name: .dwinfo
+# CHECK-NEXT: Type: dwarf-info
+# CHECK-NEXT: Permissions: r--
+# CHECK: Name: .dwabrev
+# CHECK-NEXT: Type: dwarf-abbrev
+# CHECK-NEXT: Permissions: r--
+
+--- !XCOFF
+FileHeader:
+  MagicNumber:     0x1DF
+  NumberOfSections: 7 
+  CreationTime:    000000000
+  Flags:           0x1002
+Sections:
+  - Name:            .text
+    Address:         0x10000268
+    Size:            0x512
+    FileOffsetToData: 0x268
+    FileOffsetToRelocations: 0xECC
+    FileOffsetToLineNumbers: 0x0
+    NumberOfRelocations: 0x24
+    NumberOfLineNumbers: 0x0
+    Flags:           [ STYP_TEXT ]
+    SectionData:     80C20000
+  - Name:            .data
+    Address:         0x2000077A
+    Size:            0x242
+    FileOffsetToData: 0x77A
+    FileOffsetToRelocations: 0x1034
+    FileOffsetToLineNumbers: 0x0
+    NumberOfRelocations: 0x25
+    NumberOfLineNumbers: 0x0
+    Flags:           [ STYP_DATA ]
+    SectionData:     '' 
+  - Name:            .bss
+    Address:         0x200009BC
+    Size:            0x10
+    FileOffsetToData: 0x0
+    FileOffsetToRelocations: 0x0
+    FileOffsetToLineNumbers: 0x0
+    NumberOfRelocations: 0x0
+    NumberOfLineNumbers: 0x0
+    Flags:           [ STYP_BSS ]
+    SectionData:     ''
+  - Name:            .loader
+    Address:         0x0
+    Size:            0x3A4
+    FileOffsetToData: 0x9BC
+    FileOffsetToRelocations: 0x0
+    FileOffsetToLineNumbers: 0x0
+    NumberOfRelocations: 0x0
+    NumberOfLineNumbers: 0x0
+    Flags:           [ STYP_LOADER ]
+    SectionData:     00000001
+  - Name:            .dwline
+    Address:         0x0
+    Size:            0x73
+    FileOffsetToData: 0xD60
+    FileOffsetToRelocations: 0x11A6
+    FileOffsetToLineNumbers: 0x0
+    NumberOfRelocations: 0x5
+    NumberOfLineNumbers: 0x0
+    Flags:           [ STYP_DWARF ]
+    SectionData:     FFFFFFFF
+  - Name:            .dwinfo
+    Address:         0x0
+    Size:            0xB4
+    FileOffsetToData: 0xDD4
+    FileOffsetToRelocations: 0x11D8
+    FileOffsetToLineNumbers: 0x0
+    NumberOfRelocations: 0x6
+    NumberOfLineNumbers: 0x0
+    Flags:           [ STYP_DWARF ]
+    SectionData:     FFFFFFFF
+  - Name:            .dwabrev
+    Address:         0x0
+    Size:            0x43
+    FileOffsetToData: 0xE88
+    FileOffsetToRelocations: 0x0
+    FileOffsetToLineNumbers: 0x0
+    NumberOfRelocations: 0x0
+    NumberOfLineNumbers: 0x0
+    Flags:           [ STYP_DWARF ]
+    SectionData:     01110125
+StringTable:     {}
+...

@DhruvSrivastavaX
Copy link
Contributor Author

DhruvSrivastavaX commented May 16, 2025

Hi @labath , So I have created the template based access for the functions.
See if this looks okay?

Copy link
Collaborator

@labath labath left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine. Ship it.

@DhruvSrivastavaX DhruvSrivastavaX merged commit c02e6ca into llvm:main May 16, 2025
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants