Skip to content
80 changes: 71 additions & 9 deletions lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@
//===----------------------------------------------------------------------===//

#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"
Expand All @@ -35,6 +29,10 @@
#include "llvm/BinaryFormat/XCOFF.h"
#include "llvm/Object/XCOFFObjectFile.h"
#include "llvm/Support/MemoryBuffer.h"
#include <algorithm>
#include <cassert>
#include <cstring>
#include <unordered_map>

using namespace llvm;
using namespace lldb;
Expand Down Expand Up @@ -81,9 +79,45 @@ 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) {
Expand Down Expand Up @@ -130,19 +164,41 @@ 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() {

bool retVal = false;
ModuleSP module_sp(GetModule());
if (module_sp) {
// Only 64-bit is supported for now
if (m_binary->fileHeader64()->Magic == XCOFF::XCOFF64)
retVal = true;
}

return retVal;
}

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

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

uint32_t ObjectFileXCOFF::GetAddressByteSize() const { return 8; }
uint32_t ObjectFileXCOFF::GetAddressByteSize() const {

/* TODO: Need to handle 32-bit support, until then
* 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 @@ -162,7 +218,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
13 changes: 9 additions & 4 deletions lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,14 @@
#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"
#include <cstdint>
#include <vector>

/// \class ObjectFileXCOFF
/// Generic XCOFF object file reader.
Expand Down Expand Up @@ -70,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 @@ -101,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