[Lldb-commits] [lldb] ca4cd08 - [lldb][AIX] Added XCOFF Object File Header for AIX (#111814)

via lldb-commits lldb-commits at lists.llvm.org
Tue Nov 12 00:34:29 PST 2024


Author: Dhruv Srivastava
Date: 2024-11-12T09:34:25+01:00
New Revision: ca4cd08fb9d7a03fbd00bca05d5dbfa87cd6db4e

URL: https://github.com/llvm/llvm-project/commit/ca4cd08fb9d7a03fbd00bca05d5dbfa87cd6db4e
DIFF: https://github.com/llvm/llvm-project/commit/ca4cd08fb9d7a03fbd00bca05d5dbfa87cd6db4e.diff

LOG: [lldb][AIX] Added XCOFF Object File Header for AIX (#111814)

Added XCOFF Object File Header for AIX.

Added base functionality for XCOFF support. Will enhance the files in
incremental PRs

Details about XCOFF file format on AIX:
[XCOFF](https://www.ibm.com/docs/en/aix/7.3?topic=formats-xcoff-object-file-format)

Added: 
    lldb/source/Plugins/ObjectFile/XCOFF/CMakeLists.txt
    lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
    lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h
    lldb/test/Shell/ObjectFile/XCOFF/basic-info.yaml

Modified: 
    lldb/source/Plugins/ObjectFile/CMakeLists.txt
    lldb/tools/lldb-server/CMakeLists.txt
    lldb/tools/lldb-server/SystemInitializerLLGS.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/ObjectFile/CMakeLists.txt b/lldb/source/Plugins/ObjectFile/CMakeLists.txt
index 773241c8944c8a..7abd0c96f4fd74 100644
--- a/lldb/source/Plugins/ObjectFile/CMakeLists.txt
+++ b/lldb/source/Plugins/ObjectFile/CMakeLists.txt
@@ -6,5 +6,6 @@ add_subdirectory(Mach-O)
 add_subdirectory(Minidump)
 add_subdirectory(PDB)
 add_subdirectory(PECOFF)
+add_subdirectory(XCOFF)
 add_subdirectory(Placeholder)
 add_subdirectory(wasm)

diff  --git a/lldb/source/Plugins/ObjectFile/XCOFF/CMakeLists.txt b/lldb/source/Plugins/ObjectFile/XCOFF/CMakeLists.txt
new file mode 100644
index 00000000000000..8840248574c886
--- /dev/null
+++ b/lldb/source/Plugins/ObjectFile/XCOFF/CMakeLists.txt
@@ -0,0 +1,13 @@
+add_lldb_library(lldbPluginObjectFileXCOFF PLUGIN
+  ObjectFileXCOFF.cpp
+
+  LINK_LIBS
+    lldbCore
+    lldbHost
+    lldbSymbol
+    lldbTarget
+  LINK_COMPONENTS
+    BinaryFormat
+    Object
+    Support
+  )

diff  --git a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
new file mode 100644
index 00000000000000..3be900f9a4bc9f
--- /dev/null
+++ b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
@@ -0,0 +1,191 @@
+//===-- ObjectFileXCOFF.cpp
+//-------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ObjectFileXCOFF.h"
+
+#include <algorithm>
+#include <cassert>
+#include <cstring>
+#include <unordered_map>
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/FileSpecList.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RangeMap.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/Utility/Stream.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/XCOFF.h"
+#include "llvm/Object/XCOFFObjectFile.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+using namespace llvm;
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE(ObjectFileXCOFF)
+
+// FIXME: target 64bit at this moment.
+
+// Static methods.
+void ObjectFileXCOFF::Initialize() {
+  PluginManager::RegisterPlugin(GetPluginNameStatic(),
+                                GetPluginDescriptionStatic(), CreateInstance,
+                                CreateMemoryInstance, GetModuleSpecifications);
+}
+
+void ObjectFileXCOFF::Terminate() {
+  PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+ObjectFile *ObjectFileXCOFF::CreateInstance(const lldb::ModuleSP &module_sp,
+                                            DataBufferSP data_sp,
+                                            lldb::offset_t data_offset,
+                                            const lldb_private::FileSpec *file,
+                                            lldb::offset_t file_offset,
+                                            lldb::offset_t length) {
+  if (!data_sp) {
+    data_sp = MapFileData(*file, length, file_offset);
+    if (!data_sp)
+      return nullptr;
+    data_offset = 0;
+  }
+  if (!ObjectFileXCOFF::MagicBytesMatch(data_sp, data_offset, length))
+    return nullptr;
+  // Update the data to contain the entire file if it doesn't already
+  if (data_sp->GetByteSize() < length) {
+    data_sp = MapFileData(*file, length, file_offset);
+    if (!data_sp)
+      return nullptr;
+    data_offset = 0;
+  }
+  auto objfile_up = std::make_unique<ObjectFileXCOFF>(
+      module_sp, data_sp, data_offset, file, file_offset, length);
+  if (!objfile_up)
+    return nullptr;
+
+  return objfile_up.release();
+}
+
+ObjectFile *ObjectFileXCOFF::CreateMemoryInstance(
+    const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp,
+    const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) {
+  return nullptr;
+}
+
+size_t ObjectFileXCOFF::GetModuleSpecifications(
+    const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
+    lldb::offset_t data_offset, lldb::offset_t file_offset,
+    lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
+  const size_t initial_count = specs.GetSize();
+
+  if (ObjectFileXCOFF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) {
+    ArchSpec arch_spec =
+        ArchSpec(eArchTypeXCOFF, XCOFF::TCPU_PPC64, LLDB_INVALID_CPUTYPE);
+    ModuleSpec spec(file, arch_spec);
+    spec.GetArchitecture().SetArchitecture(eArchTypeXCOFF, XCOFF::TCPU_PPC64,
+                                           LLDB_INVALID_CPUTYPE,
+                                           llvm::Triple::AIX);
+    specs.Append(spec);
+  }
+  return specs.GetSize() - initial_count;
+}
+
+static uint32_t XCOFFHeaderSizeFromMagic(uint32_t magic) {
+  switch (magic) {
+    /* TODO: 32bit not supported yet
+    case XCOFF::XCOFF32:
+      return sizeof(struct llvm::object::XCOFFFileHeader32);
+    */
+
+  case XCOFF::XCOFF64:
+    return sizeof(struct llvm::object::XCOFFFileHeader64);
+    break;
+
+  default:
+    break;
+  }
+  return 0;
+}
+
+bool ObjectFileXCOFF::MagicBytesMatch(DataBufferSP &data_sp,
+                                      lldb::addr_t data_offset,
+                                      lldb::addr_t data_length) {
+  lldb_private::DataExtractor data;
+  data.SetData(data_sp, data_offset, data_length);
+  data.SetByteOrder(eByteOrderBig);
+  lldb::offset_t offset = 0;
+  uint16_t magic = data.GetU16(&offset);
+  return XCOFFHeaderSizeFromMagic(magic) != 0;
+}
+
+bool ObjectFileXCOFF::ParseHeader() { return false; }
+
+ByteOrder ObjectFileXCOFF::GetByteOrder() const { return eByteOrderBig; }
+
+bool ObjectFileXCOFF::IsExecutable() const { return true; }
+
+uint32_t ObjectFileXCOFF::GetAddressByteSize() const { return 8; }
+
+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;
+}
+
+UUID ObjectFileXCOFF::GetUUID() { return UUID(); }
+
+uint32_t ObjectFileXCOFF::GetDependentModules(FileSpecList &files) { return 0; }
+
+ObjectFile::Type ObjectFileXCOFF::CalculateType() { return eTypeExecutable; }
+
+ObjectFile::Strata ObjectFileXCOFF::CalculateStrata() { return eStrataUnknown; }
+
+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) {}

diff  --git a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h
new file mode 100644
index 00000000000000..3a33b97b9e8da1
--- /dev/null
+++ b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h
@@ -0,0 +1,106 @@
+//===-- ObjectFileXCOFF.h --------------------------------------- -*- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_XCOFF_OBJECTFILEXCOFF_H
+#define LLDB_SOURCE_PLUGINS_OBJECTFILE_XCOFF_OBJECTFILEXCOFF_H
+
+#include <cstdint>
+
+#include <vector>
+
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/UUID.h"
+#include "lldb/lldb-private.h"
+#include "llvm/Object/XCOFFObjectFile.h"
+
+/// \class ObjectFileXCOFF
+/// Generic XCOFF object file reader.
+///
+/// This class provides a generic XCOFF (32/64 bit) reader plugin implementing
+/// the ObjectFile protocol.
+class ObjectFileXCOFF : public lldb_private::ObjectFile {
+public:
+  // Static Functions
+  static void Initialize();
+
+  static void Terminate();
+
+  static llvm::StringRef GetPluginNameStatic() { return "xcoff"; }
+
+  static llvm::StringRef GetPluginDescriptionStatic() {
+    return "XCOFF object file reader.";
+  }
+
+  static lldb_private::ObjectFile *
+  CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
+                 lldb::offset_t data_offset, const lldb_private::FileSpec *file,
+                 lldb::offset_t file_offset, lldb::offset_t length);
+
+  static lldb_private::ObjectFile *CreateMemoryInstance(
+      const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp,
+      const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
+
+  static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
+                                        lldb::DataBufferSP &data_sp,
+                                        lldb::offset_t data_offset,
+                                        lldb::offset_t file_offset,
+                                        lldb::offset_t length,
+                                        lldb_private::ModuleSpecList &specs);
+
+  static bool MagicBytesMatch(lldb::DataBufferSP &data_sp, lldb::addr_t offset,
+                              lldb::addr_t length);
+
+  // PluginInterface protocol
+  llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+
+  // ObjectFile Protocol.
+  bool ParseHeader() override;
+
+  lldb::ByteOrder GetByteOrder() const override;
+
+  bool IsExecutable() const override;
+
+  uint32_t GetAddressByteSize() const override;
+
+  void ParseSymtab(lldb_private::Symtab &symtab) override;
+
+  bool IsStripped() override;
+
+  void CreateSections(lldb_private::SectionList &unified_section_list) override;
+
+  void Dump(lldb_private::Stream *s) override;
+
+  lldb_private::ArchSpec GetArchitecture() override;
+
+  lldb_private::UUID GetUUID() override;
+
+  uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
+
+  ObjectFile::Type CalculateType() override;
+
+  ObjectFile::Strata CalculateStrata() override;
+
+  ObjectFileXCOFF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp,
+                  lldb::offset_t data_offset,
+                  const lldb_private::FileSpec *file, lldb::offset_t offset,
+                  lldb::offset_t length);
+
+  ObjectFileXCOFF(const lldb::ModuleSP &module_sp,
+                  lldb::DataBufferSP header_data_sp,
+                  const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
+
+protected:
+  static lldb::WritableDataBufferSP
+  MapFileDataWritable(const lldb_private::FileSpec &file, uint64_t Size,
+                      uint64_t Offset);
+};
+
+#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_XCOFF_OBJECTFILE_H

diff  --git a/lldb/test/Shell/ObjectFile/XCOFF/basic-info.yaml b/lldb/test/Shell/ObjectFile/XCOFF/basic-info.yaml
new file mode 100644
index 00000000000000..761d66a6045d93
--- /dev/null
+++ b/lldb/test/Shell/ObjectFile/XCOFF/basic-info.yaml
@@ -0,0 +1,27 @@
+# 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
+
+--- !XCOFF
+FileHeader:
+  MagicNumber:     0x1F7
+  NumberOfSections: 1 
+  CreationTime:    000000000
+  Flags:           0x0000
+Sections:
+  - Name:            .text
+    Address:         0x100000438
+    Size:            0x38
+    FileOffsetToData: 0x0
+    FileOffsetToLineNumbers: 0x0
+    NumberOfLineNumbers: 0x0
+    Flags:           [ STYP_TEXT ]
+    SectionData:     E8C20000E94204  
+StringTable:     {}
+...

diff  --git a/lldb/tools/lldb-server/CMakeLists.txt b/lldb/tools/lldb-server/CMakeLists.txt
index e6d88a8579885c..8d6843ec5ddd88 100644
--- a/lldb/tools/lldb-server/CMakeLists.txt
+++ b/lldb/tools/lldb-server/CMakeLists.txt
@@ -20,6 +20,8 @@ if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
   list(APPEND LLDB_PLUGINS lldbPluginObjectFileMachO)
 elseif(CMAKE_SYSTEM_NAME MATCHES "Windows")
   list(APPEND LLDB_PLUGINS lldbPluginObjectFilePECOFF)
+elseif(CMAKE_SYSTEM_NAME MATCHES "AIX")
+  list(APPEND LLDB_PLUGINS lldbPluginObjectFileXCOFF)
 else()
   list(APPEND LLDB_PLUGINS lldbPluginObjectFileELF)
 endif()

diff  --git a/lldb/tools/lldb-server/SystemInitializerLLGS.cpp b/lldb/tools/lldb-server/SystemInitializerLLGS.cpp
index 4233252a84dfc7..5b280d6cf5280f 100644
--- a/lldb/tools/lldb-server/SystemInitializerLLGS.cpp
+++ b/lldb/tools/lldb-server/SystemInitializerLLGS.cpp
@@ -14,6 +14,9 @@ using HostObjectFile = ObjectFileMachO;
 #elif defined(_WIN32)
 #include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
 using HostObjectFile = ObjectFilePECOFF;
+#elif defined(_AIX)
+#include "Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h"
+using HostObjectFile = ObjectFileXCOFF;
 #else
 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
 using HostObjectFile = ObjectFileELF;


        


More information about the lldb-commits mailing list