[Lldb-commits] [lldb] [lldb][AIX] Added XCOFF Object File Header Parsing (PR #116337)
Dhruv Srivastava via lldb-commits
lldb-commits at lists.llvm.org
Fri Nov 15 00:22:42 PST 2024
https://github.com/DhruvSrivastavaX created https://github.com/llvm/llvm-project/pull/116337
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. https://github.com/llvm/llvm-project/issues/101657
The complete changes for porting are present in this draft PR:
https://github.com/llvm/llvm-project/pull/102601
Added XCOFF Object File Header Parsing for AIX.
This PR is an incremental PR to the base:
#111814
Details about XCOFF file format on AIX: [XCOFF](https://www.ibm.com/docs/en/aix/7.3?topic=formats-xcoff-object-file-format)
Review Request: @labath @DavidSpickett
>From 0c63800bdcbadcfceed4c9a81305eda7d5a15960 Mon Sep 17 00:00:00 2001
From: Dhruv-Srivastava <dhruv.srivastava at ibm.com>
Date: Fri, 15 Nov 2024 02:16:31 -0600
Subject: [PATCH] Added XCOFF Header Parsing
---
.../ObjectFile/XCOFF/ObjectFileXCOFF.cpp | 126 +++++++++++++++++-
.../ObjectFile/XCOFF/ObjectFileXCOFF.h | 58 ++++++++
2 files changed, 181 insertions(+), 3 deletions(-)
diff --git a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
index 3be900f9a4bc9f..c06ece4347822d 100644
--- a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
+++ b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
@@ -81,9 +81,44 @@ ObjectFile *ObjectFileXCOFF::CreateInstance(const lldb::ModuleSP &module_sp,
if (!objfile_up)
return nullptr;
+ // Cache xcoff binary.
+ if (!objfile_up->CreateBinary())
+ return nullptr;
+
+ if (!objfile_up->ParseHeader())
+ return nullptr;
+
return objfile_up.release();
}
+bool ObjectFileXCOFF::CreateBinary() {
+ if (m_binary)
+ return true;
+
+ Log *log = GetLog(LLDBLog::Object);
+
+ auto binary = llvm::object::XCOFFObjectFile::createObjectFile(
+ llvm::MemoryBufferRef(toStringRef(m_data.GetData()),
+ m_file.GetFilename().GetStringRef()),
+ file_magic::xcoff_object_64);
+ if (!binary) {
+ LLDB_LOG_ERROR(log, binary.takeError(),
+ "Failed to create binary for file ({1}): {0}", m_file);
+ return false;
+ }
+
+ // Make sure we only handle XCOFF format.
+ m_binary =
+ llvm::unique_dyn_cast<llvm::object::XCOFFObjectFile>(std::move(*binary));
+ if (!m_binary)
+ return false;
+
+ LLDB_LOG(log, "this = {0}, module = {1} ({2}), file = {3}, binary = {4}",
+ this, GetModule().get(), GetModule()->GetSpecificationDescription(),
+ m_file.GetPath(), m_binary.get());
+ return true;
+}
+
ObjectFile *ObjectFileXCOFF::CreateMemoryInstance(
const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp,
const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) {
@@ -136,13 +171,92 @@ bool ObjectFileXCOFF::MagicBytesMatch(DataBufferSP &data_sp,
return XCOFFHeaderSizeFromMagic(magic) != 0;
}
-bool ObjectFileXCOFF::ParseHeader() { return false; }
+bool ObjectFileXCOFF::ParseHeader() {
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ lldb::offset_t offset = 0;
+
+ if (ParseXCOFFHeader(m_data, &offset, m_xcoff_header)) {
+ m_data.SetAddressByteSize(GetAddressByteSize());
+ if (m_xcoff_header.auxhdrsize > 0)
+ ParseXCOFFOptionalHeader(m_data, &offset);
+ }
+ return true;
+ }
+
+ return false;
+}
+
+bool ObjectFileXCOFF::ParseXCOFFHeader(lldb_private::DataExtractor &data,
+ lldb::offset_t *offset_ptr,
+ xcoff_header_t &xcoff_header) {
+ // FIXME: data.ValidOffsetForDataOfSize
+ xcoff_header.magic = data.GetU16(offset_ptr);
+ xcoff_header.nsects = data.GetU16(offset_ptr);
+ xcoff_header.modtime = data.GetU32(offset_ptr);
+ xcoff_header.symoff = data.GetU64(offset_ptr);
+ xcoff_header.auxhdrsize = data.GetU16(offset_ptr);
+ xcoff_header.flags = data.GetU16(offset_ptr);
+ xcoff_header.nsyms = data.GetU32(offset_ptr);
+ return true;
+}
+
+bool ObjectFileXCOFF::ParseXCOFFOptionalHeader(
+ lldb_private::DataExtractor &data, lldb::offset_t *offset_ptr) {
+ lldb::offset_t init_offset = *offset_ptr;
+ // FIXME: data.ValidOffsetForDataOfSize
+ m_xcoff_aux_header.AuxMagic = data.GetU16(offset_ptr);
+ m_xcoff_aux_header.Version = data.GetU16(offset_ptr);
+ m_xcoff_aux_header.ReservedForDebugger = data.GetU32(offset_ptr);
+ m_xcoff_aux_header.TextStartAddr = data.GetU64(offset_ptr);
+ m_xcoff_aux_header.DataStartAddr = data.GetU64(offset_ptr);
+ m_xcoff_aux_header.TOCAnchorAddr = data.GetU64(offset_ptr);
+ m_xcoff_aux_header.SecNumOfEntryPoint = data.GetU16(offset_ptr);
+ m_xcoff_aux_header.SecNumOfText = data.GetU16(offset_ptr);
+ m_xcoff_aux_header.SecNumOfData = data.GetU16(offset_ptr);
+ m_xcoff_aux_header.SecNumOfTOC = data.GetU16(offset_ptr);
+ m_xcoff_aux_header.SecNumOfLoader = data.GetU16(offset_ptr);
+ m_xcoff_aux_header.SecNumOfBSS = data.GetU16(offset_ptr);
+ m_xcoff_aux_header.MaxAlignOfText = data.GetU16(offset_ptr);
+ m_xcoff_aux_header.MaxAlignOfData = data.GetU16(offset_ptr);
+ m_xcoff_aux_header.ModuleType = data.GetU16(offset_ptr);
+ m_xcoff_aux_header.CpuFlag = data.GetU8(offset_ptr);
+ m_xcoff_aux_header.CpuType = data.GetU8(offset_ptr);
+ m_xcoff_aux_header.TextPageSize = data.GetU8(offset_ptr);
+ m_xcoff_aux_header.DataPageSize = data.GetU8(offset_ptr);
+ m_xcoff_aux_header.StackPageSize = data.GetU8(offset_ptr);
+ m_xcoff_aux_header.FlagAndTDataAlignment = data.GetU8(offset_ptr);
+ m_xcoff_aux_header.TextSize = data.GetU64(offset_ptr);
+ m_xcoff_aux_header.InitDataSize = data.GetU64(offset_ptr);
+ m_xcoff_aux_header.BssDataSize = data.GetU64(offset_ptr);
+ m_xcoff_aux_header.EntryPointAddr = data.GetU64(offset_ptr);
+ m_xcoff_aux_header.MaxStackSize = data.GetU64(offset_ptr);
+ m_xcoff_aux_header.MaxDataSize = data.GetU64(offset_ptr);
+ m_xcoff_aux_header.SecNumOfTData = data.GetU16(offset_ptr);
+ m_xcoff_aux_header.SecNumOfTBSS = data.GetU16(offset_ptr);
+ m_xcoff_aux_header.XCOFF64Flag = data.GetU16(offset_ptr);
+ lldb::offset_t last_offset = *offset_ptr;
+ if ((last_offset - init_offset) < m_xcoff_header.auxhdrsize)
+ *offset_ptr += (m_xcoff_header.auxhdrsize - (last_offset - init_offset));
+ return true;
+}
ByteOrder ObjectFileXCOFF::GetByteOrder() const { return eByteOrderBig; }
bool ObjectFileXCOFF::IsExecutable() const { return true; }
-uint32_t ObjectFileXCOFF::GetAddressByteSize() const { return 8; }
+uint32_t ObjectFileXCOFF::GetAddressByteSize() const {
+ if (m_xcoff_header.magic == XCOFF::XCOFF64)
+ return 8;
+ else if (m_xcoff_header.magic == XCOFF::XCOFF32)
+ return 4;
+ return 4;
+}
+
+AddressClass ObjectFileXCOFF::GetAddressClass(addr_t file_addr) {
+ return AddressClass::eUnknown;
+}
void ObjectFileXCOFF::ParseSymtab(Symtab &lldb_symtab) {}
@@ -162,7 +276,13 @@ UUID ObjectFileXCOFF::GetUUID() { return UUID(); }
uint32_t ObjectFileXCOFF::GetDependentModules(FileSpecList &files) { return 0; }
-ObjectFile::Type ObjectFileXCOFF::CalculateType() { return eTypeExecutable; }
+ObjectFile::Type ObjectFileXCOFF::CalculateType() {
+ if (m_xcoff_header.flags & XCOFF::F_EXEC)
+ return eTypeExecutable;
+ else if (m_xcoff_header.flags & XCOFF::F_SHROBJ)
+ return eTypeSharedLibrary;
+ return eTypeUnknown;
+}
ObjectFile::Strata ObjectFileXCOFF::CalculateStrata() { return eStrataUnknown; }
diff --git a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h
index 3a33b97b9e8da1..a155441135bfcb 100644
--- a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h
+++ b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h
@@ -70,6 +70,8 @@ class ObjectFileXCOFF : public lldb_private::ObjectFile {
uint32_t GetAddressByteSize() const override;
+ lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override;
+
void ParseSymtab(lldb_private::Symtab &symtab) override;
bool IsStripped() override;
@@ -98,9 +100,65 @@ class ObjectFileXCOFF : public lldb_private::ObjectFile {
const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
protected:
+ typedef struct xcoff_header {
+ uint16_t magic;
+ uint16_t nsects;
+ uint32_t modtime;
+ uint64_t symoff;
+ uint32_t nsyms;
+ uint16_t auxhdrsize;
+ uint16_t flags;
+ } xcoff_header_t;
+
+ typedef struct xcoff_aux_header {
+ uint16_t AuxMagic;
+ uint16_t Version;
+ uint32_t ReservedForDebugger;
+ uint64_t TextStartAddr;
+ uint64_t DataStartAddr;
+ uint64_t TOCAnchorAddr;
+ uint16_t SecNumOfEntryPoint;
+ uint16_t SecNumOfText;
+ uint16_t SecNumOfData;
+ uint16_t SecNumOfTOC;
+ uint16_t SecNumOfLoader;
+ uint16_t SecNumOfBSS;
+ uint16_t MaxAlignOfText;
+ uint16_t MaxAlignOfData;
+ uint16_t ModuleType;
+ uint8_t CpuFlag;
+ uint8_t CpuType;
+ uint8_t TextPageSize;
+ uint8_t DataPageSize;
+ uint8_t StackPageSize;
+ uint8_t FlagAndTDataAlignment;
+ uint64_t TextSize;
+ uint64_t InitDataSize;
+ uint64_t BssDataSize;
+ uint64_t EntryPointAddr;
+ uint64_t MaxStackSize;
+ uint64_t MaxDataSize;
+ uint16_t SecNumOfTData;
+ uint16_t SecNumOfTBSS;
+ uint16_t XCOFF64Flag;
+ } xcoff_aux_header_t;
+
+ static bool ParseXCOFFHeader(lldb_private::DataExtractor &data,
+ lldb::offset_t *offset_ptr,
+ xcoff_header_t &xcoff_header);
+ bool ParseXCOFFOptionalHeader(lldb_private::DataExtractor &data,
+ lldb::offset_t *offset_ptr);
+
static lldb::WritableDataBufferSP
MapFileDataWritable(const lldb_private::FileSpec &file, uint64_t Size,
uint64_t Offset);
+
+private:
+ bool CreateBinary();
+
+ xcoff_header_t m_xcoff_header;
+ xcoff_aux_header_t m_xcoff_aux_header;
+ std::unique_ptr<llvm::object::XCOFFObjectFile> m_binary;
};
#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_XCOFF_OBJECTFILE_H
More information about the lldb-commits
mailing list