Skip to content

[lldb][AIX] Header Parsing for XCOFF Object File in AIX #116338

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 12 commits into from
Dec 18, 2024
61 changes: 56 additions & 5 deletions lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,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::ObjectFile::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) {
Expand All @@ -108,10 +143,9 @@ size_t ObjectFileXCOFF::GetModuleSpecifications(

static uint32_t XCOFFHeaderSizeFromMagic(uint32_t magic) {
switch (magic) {
// TODO: 32bit not supported yet
// TODO: 32bit not supported.
// case XCOFF::XCOFF32:
// return sizeof(struct llvm::object::XCOFFFileHeader32);

case XCOFF::XCOFF64:
return sizeof(struct llvm::object::XCOFFFileHeader64);
break;
Expand All @@ -127,19 +161,30 @@ bool ObjectFileXCOFF::MagicBytesMatch(DataBufferSP &data_sp,
lldb::addr_t data_length) {
lldb_private::DataExtractor data;
data.SetData(data_sp, data_offset, data_length);
// Need to set this as XCOFF is only compatible with Big Endian
data.SetByteOrder(eByteOrderBig);
lldb::offset_t offset = 0;
uint16_t magic = data.GetU16(&offset);
return XCOFFHeaderSizeFromMagic(magic) != 0;
}

bool ObjectFileXCOFF::ParseHeader() { return false; }
bool ObjectFileXCOFF::ParseHeader() {
// Only 64-bit is supported for now
return m_binary->fileHeader64()->Magic == XCOFF::XCOFF64;
}

ByteOrder ObjectFileXCOFF::GetByteOrder() const { return eByteOrderBig; }

bool ObjectFileXCOFF::IsExecutable() const { return true; }

uint32_t ObjectFileXCOFF::GetAddressByteSize() const { return 8; }
uint32_t ObjectFileXCOFF::GetAddressByteSize() const {
// 32-bit not supported. return 8 for 64-bit XCOFF::XCOFF64
return 8;
}

AddressClass ObjectFileXCOFF::GetAddressClass(addr_t file_addr) {
return AddressClass::eUnknown;
}

void ObjectFileXCOFF::ParseSymtab(Symtab &lldb_symtab) {}

Expand All @@ -159,7 +204,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_binary->fileHeader64()->Flags & XCOFF::F_EXEC)
return eTypeExecutable;
else if (m_binary->fileHeader64()->Flags & XCOFF::F_SHROBJ)
return eTypeSharedLibrary;
return eTypeUnknown;
}

ObjectFile::Strata ObjectFileXCOFF::CalculateStrata() { return eStrataUnknown; }

Expand Down
7 changes: 7 additions & 0 deletions lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,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;
Expand Down Expand Up @@ -99,6 +101,11 @@ class ObjectFileXCOFF : public lldb_private::ObjectFile {
static lldb::WritableDataBufferSP
MapFileDataWritable(const lldb_private::FileSpec &file, uint64_t Size,
uint64_t Offset);

private:
bool CreateBinary();

std::unique_ptr<llvm::object::XCOFFObjectFile> m_binary;
};

#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_XCOFF_OBJECTFILE_H
2 changes: 1 addition & 1 deletion lldb/test/Shell/ObjectFile/XCOFF/basic-info.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ FileHeader:
MagicNumber: 0x1F7
NumberOfSections: 1
CreationTime: 000000000
Flags: 0x0000
Flags: 0x0002
Sections:
- Name: .text
Address: 0x100000438
Expand Down
Loading