[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