Skip to content
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