Skip to content

[lldb][AIX] Support for XCOFF Sections #131304

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 7 commits into from
May 12, 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

Incremental PR on ObjectFileXCOFF.cpp
This PR is intended to handle XCOFF sections.

@llvmbot
Copy link
Member

llvmbot commented Mar 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

Incremental PR on ObjectFileXCOFF.cpp
This PR is intended to handle XCOFF sections.


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

1 Files Affected:

  • (modified) lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp (+114-39)
diff --git a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
index b54d43c5dd737..0dd9126468923 100644
--- a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
+++ b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
@@ -190,50 +190,125 @@ void ObjectFileXCOFF::ParseSymtab(Symtab &lldb_symtab) {}
 
 bool ObjectFileXCOFF::IsStripped() { return false; }
 
-void ObjectFileXCOFF::CreateSections(SectionList &unified_section_list) {}
-
-void ObjectFileXCOFF::Dump(Stream *s) {}
-
-ArchSpec ObjectFileXCOFF::GetArchitecture() {
-  ArchSpec arch_spec =
-      ArchSpec(eArchTypeXCOFF, XCOFF::TCPU_PPC64, LLDB_INVALID_CPUTYPE);
-  return arch_spec;
+void ObjectFileXCOFF::CreateSections(SectionList &unified_section_list) {
+
+  if (m_sections_up)
+    return;
+  m_sections_up = std::make_unique<SectionList>();
+  ModuleSP module_sp(GetModule());
+  if (module_sp) {
+    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+
+    ModuleSP module_sp(GetModule());
+    for (auto sIdx = m_binary->section_begin(); sIdx != m_binary->section_end();
+         ++sIdx) {
+      llvm::Expected<llvm::StringRef> name =
+          m_binary->getSectionName(sIdx->getRawDataRefImpl());
+      if (!name) {
+        llvm::Error err = name.takeError();
+      }
+      llvm::StringRef sect_name = *name;
+      ConstString const_sect_name(sect_name);
+      int sect_index = sIdx->getIndex(), idx = 1;
+      llvm::Expected<llvm::object::DataRefImpl> section =
+          m_binary->getSectionByNum(sect_index);
+      if (!section) {
+        llvm::Error err = section.takeError();
+      }
+      llvm::object::DataRefImpl dataref = section.get();
+      const llvm::object::XCOFFSectionHeader64 *sectionPtr =
+          reinterpret_cast<const llvm::object::XCOFFSectionHeader64 *>(
+              dataref.p);
+
+      SectionType section_type = lldb::eSectionTypeOther;
+      if (sectionPtr->Flags & XCOFF::STYP_TEXT)
+        section_type = eSectionTypeCode;
+      if (sectionPtr->Flags & XCOFF::STYP_DATA)
+        section_type = eSectionTypeData;
+      if (sectionPtr->Flags & XCOFF::STYP_BSS)
+        section_type = eSectionTypeZeroFill;
+      if (sectionPtr->Flags & XCOFF::STYP_DWARF) {
+        SectionType section_type =
+            llvm::StringSwitch<SectionType>(sect_name)
+                .Case(".dwinfo", eSectionTypeDWARFDebugInfo)
+                .Case(".dwline", eSectionTypeDWARFDebugLine)
+                .Case(".dwabrev", eSectionTypeDWARFDebugAbbrev)
+                .Default(eSectionTypeInvalid);
+
+        if (section_type == eSectionTypeInvalid)
+          section_type = lldb::eSectionTypeOther;
+      }
+      SectionSP section_sp(new Section(
+          module_sp,       // Module to which this section belongs
+          this,            // Object file to which this section belongs
+          idx++,           // Section ID is the 1 based section index.
+          const_sect_name, // Name of this section
+          section_type,
+          sectionPtr->VirtualAddress,      // File VM address == addresses as
+                                           // they are found in the object file
+          sectionPtr->SectionSize,         // VM size in bytes of this section
+          sectionPtr->FileOffsetToRawData, // Offset to the data for this
+                                           // section in the file
+          sectionPtr->SectionSize, // Size in bytes of this section as found in
+                                   // the file
+          0,                       // FIXME: alignment
+          sectionPtr->Flags));     // Flags for this section
+
+      uint32_t permissions = 0;
+      permissions |= ePermissionsReadable;
+      if (sectionPtr->Flags & (XCOFF::STYP_DATA | XCOFF::STYP_BSS))
+        permissions |= ePermissionsWritable;
+      if (sectionPtr->Flags & XCOFF::STYP_TEXT)
+        permissions |= ePermissionsExecutable;
+      section_sp->SetPermissions(permissions);
+
+      m_sections_up->AddSection(section_sp);
+      unified_section_list.AddSection(section_sp);
+    }
+  }
 }
+  void ObjectFileXCOFF::Dump(Stream * s) {}
 
-UUID ObjectFileXCOFF::GetUUID() { return UUID(); }
+  ArchSpec ObjectFileXCOFF::GetArchitecture() {
+    ArchSpec arch_spec =
+        ArchSpec(eArchTypeXCOFF, XCOFF::TCPU_PPC64, LLDB_INVALID_CPUTYPE);
+    return arch_spec;
+  }
 
-uint32_t ObjectFileXCOFF::GetDependentModules(FileSpecList &files) { return 0; }
+  UUID ObjectFileXCOFF::GetUUID() { return UUID(); }
 
-ObjectFile::Type ObjectFileXCOFF::CalculateType() {
-  if (m_binary->fileHeader64()->Flags & XCOFF::F_EXEC)
-    return eTypeExecutable;
-  else if (m_binary->fileHeader64()->Flags & XCOFF::F_SHROBJ)
-    return eTypeSharedLibrary;
-  return eTypeUnknown;
-}
+  uint32_t ObjectFileXCOFF::GetDependentModules(FileSpecList & files) {
+    return 0;
+  }
 
-ObjectFile::Strata ObjectFileXCOFF::CalculateStrata() { return eStrataUnknown; }
+  ObjectFile::Type ObjectFileXCOFF::CalculateType() {
+    if (m_binary->fileHeader64()->Flags & XCOFF::F_EXEC)
+      return eTypeExecutable;
+    else if (m_binary->fileHeader64()->Flags & XCOFF::F_SHROBJ)
+      return eTypeSharedLibrary;
+    return eTypeUnknown;
+  }
 
-lldb::WritableDataBufferSP
-ObjectFileXCOFF::MapFileDataWritable(const FileSpec &file, uint64_t Size,
-                                     uint64_t Offset) {
-  return FileSystem::Instance().CreateWritableDataBuffer(file.GetPath(), Size,
-                                                         Offset);
-}
+  ObjectFile::Strata ObjectFileXCOFF::CalculateStrata() {
+    return eStrataUnknown;
+  }
 
-ObjectFileXCOFF::ObjectFileXCOFF(const lldb::ModuleSP &module_sp,
-                                 DataBufferSP data_sp,
-                                 lldb::offset_t data_offset,
-                                 const FileSpec *file,
-                                 lldb::offset_t file_offset,
-                                 lldb::offset_t length)
-    : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset) {
-  if (file)
-    m_file = *file;
-}
+  lldb::WritableDataBufferSP ObjectFileXCOFF::MapFileDataWritable(
+      const FileSpec &file, uint64_t Size, uint64_t Offset) {
+    return FileSystem::Instance().CreateWritableDataBuffer(file.GetPath(), Size,
+                                                           Offset);
+  }
+
+  ObjectFileXCOFF::ObjectFileXCOFF(
+      const lldb::ModuleSP &module_sp, DataBufferSP data_sp,
+      lldb::offset_t data_offset, const FileSpec *file,
+      lldb::offset_t file_offset, lldb::offset_t length)
+      : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset) {
+    if (file)
+      m_file = *file;
+  }
 
-ObjectFileXCOFF::ObjectFileXCOFF(const lldb::ModuleSP &module_sp,
-                                 DataBufferSP header_data_sp,
-                                 const lldb::ProcessSP &process_sp,
-                                 addr_t header_addr)
-    : ObjectFile(module_sp, process_sp, header_addr, header_data_sp) {}
+  ObjectFileXCOFF::ObjectFileXCOFF(
+      const lldb::ModuleSP &module_sp, DataBufferSP header_data_sp,
+      const lldb::ProcessSP &process_sp, addr_t header_addr)
+      : ObjectFile(module_sp, process_sp, header_addr, header_data_sp) {}

@DhruvSrivastavaX
Copy link
Contributor Author

DhruvSrivastavaX commented Mar 14, 2025

Hi, @labath @DavidSpickett,
Resuming the conversation on XCOFF support. I have added support for reading XCOFF sections using existing LLVM interfaces. I know there are gaps, so please let me know your thoughts.

I'll modify my test files accordingly as well

Copy link

github-actions bot commented Mar 14, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@DhruvSrivastavaX
Copy link
Contributor Author

DhruvSrivastavaX commented Mar 18, 2025

Hi @labath @DavidSpickett,
So please let me know if I should add more apis in this PR or this much granularity is enough.
Also, we are working on an overall 32-bit implementation as well for AIX, so I am thinking of extending the xcoff for the 32 bit as well as it should not take much additional effort.
What are your thoughts?

@labath
Copy link
Collaborator

labath commented Mar 24, 2025

I think the granularity is fine. You should add/modify a test to check that the sections are being parsed correctly. (if there's something missing for that to work, feel free to add it).

I don't have an issue with adding support for 32-bit. I think it's up to you and whether you want to support it. Since llvm::XCOFFObjectFile has separate APIs for accessing 32- and 64-bit versions of the file, probably the easiest way to achieve that is to make any code which depends on that be a template function, which can them be instantiated for the right bitness.

@DhruvSrivastavaX
Copy link
Contributor Author

DhruvSrivastavaX commented Apr 3, 2025

Sure, Thanks.
I have modified my test case for this one.
Please provide your review @labath

@DhruvSrivastavaX DhruvSrivastavaX requested a review from labath May 8, 2025 08:53
@DhruvSrivastavaX DhruvSrivastavaX merged commit 39f5a42 into llvm:main May 12, 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