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
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 40 additions & 17 deletions lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ using namespace lldb;
using namespace lldb_private;

LLDB_PLUGIN_DEFINE(ObjectFileXCOFF)

// FIXME: target 64bit at this moment.

// Static methods.
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -169,17 +169,19 @@ 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->fileHeader32()->Magic == XCOFF::XCOFF32;
}

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) {
Expand All @@ -191,20 +193,37 @@ 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>
static 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);

Expand Down Expand Up @@ -253,9 +272,13 @@ 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)

const auto flags = m_binary->is64Bit() ? m_binary->fileHeader64()->Flags
: m_binary->fileHeader32()->Flags;

if (flags & XCOFF::F_EXEC)
return eTypeExecutable;
else if (m_binary->fileHeader64()->Flags & XCOFF::F_SHROBJ)
else if (flags & XCOFF::F_SHROBJ)
return eTypeSharedLibrary;
return eTypeUnknown;
}
Expand Down
12 changes: 12 additions & 0 deletions lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,18 @@ class ObjectFileXCOFF : public lldb_private::ObjectFile {

private:
bool CreateBinary();
template <typename T>
void
CreateSectionsWithBitness(lldb_private::SectionList &unified_section_list);

struct XCOFF32 {
using SectionHeader = llvm::object::XCOFFSectionHeader32;
static constexpr bool Is64Bit = false;
};
struct XCOFF64 {
using SectionHeader = llvm::object::XCOFFSectionHeader64;
static constexpr bool Is64Bit = true;
};

std::unique_ptr<llvm::object::XCOFFObjectFile> m_binary;
};
Expand Down
110 changes: 110 additions & 0 deletions lldb/test/Shell/ObjectFile/XCOFF/basic-info32.yaml
Original file line number Diff line number Diff line change
@@ -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: {}
...
Loading