Skip to content

Commit 0c68606

Browse files
[lldb][AIX] Header Parsing for XCOFF Object File in AIX (llvm#116338)
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. llvm#101657 The complete changes for porting are present in this draft PR: llvm#102601 Added XCOFF Object File Header Parsing for AIX. Details about XCOFF file format on AIX: [XCOFF](https://www.ibm.com/docs/en/aix/7.3?topic=formats-xcoff-object-file-format)
1 parent 6f68010 commit 0c68606

File tree

3 files changed

+64
-6
lines changed

3 files changed

+64
-6
lines changed

lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp

+56-5
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,44 @@ ObjectFile *ObjectFileXCOFF::CreateInstance(const lldb::ModuleSP &module_sp,
7979
if (!objfile_up)
8080
return nullptr;
8181

82+
// Cache xcoff binary.
83+
if (!objfile_up->CreateBinary())
84+
return nullptr;
85+
86+
if (!objfile_up->ParseHeader())
87+
return nullptr;
88+
8289
return objfile_up.release();
8390
}
8491

92+
bool ObjectFileXCOFF::CreateBinary() {
93+
if (m_binary)
94+
return true;
95+
96+
Log *log = GetLog(LLDBLog::Object);
97+
98+
auto binary = llvm::object::ObjectFile::createObjectFile(
99+
llvm::MemoryBufferRef(toStringRef(m_data.GetData()),
100+
m_file.GetFilename().GetStringRef()),
101+
file_magic::xcoff_object_64);
102+
if (!binary) {
103+
LLDB_LOG_ERROR(log, binary.takeError(),
104+
"Failed to create binary for file ({1}): {0}", m_file);
105+
return false;
106+
}
107+
// Make sure we only handle XCOFF format.
108+
m_binary =
109+
llvm::unique_dyn_cast<llvm::object::XCOFFObjectFile>(std::move(*binary));
110+
if (!m_binary)
111+
return false;
112+
113+
LLDB_LOG(log, "this = {0}, module = {1} ({2}), file = {3}, binary = {4}",
114+
this, GetModule().get(), GetModule()->GetSpecificationDescription(),
115+
m_file.GetPath(), m_binary.get());
116+
117+
return true;
118+
}
119+
85120
ObjectFile *ObjectFileXCOFF::CreateMemoryInstance(
86121
const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp,
87122
const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) {
@@ -108,10 +143,9 @@ size_t ObjectFileXCOFF::GetModuleSpecifications(
108143

109144
static uint32_t XCOFFHeaderSizeFromMagic(uint32_t magic) {
110145
switch (magic) {
111-
// TODO: 32bit not supported yet
146+
// TODO: 32bit not supported.
112147
// case XCOFF::XCOFF32:
113148
// return sizeof(struct llvm::object::XCOFFFileHeader32);
114-
115149
case XCOFF::XCOFF64:
116150
return sizeof(struct llvm::object::XCOFFFileHeader64);
117151
break;
@@ -127,19 +161,30 @@ bool ObjectFileXCOFF::MagicBytesMatch(DataBufferSP &data_sp,
127161
lldb::addr_t data_length) {
128162
lldb_private::DataExtractor data;
129163
data.SetData(data_sp, data_offset, data_length);
164+
// Need to set this as XCOFF is only compatible with Big Endian
130165
data.SetByteOrder(eByteOrderBig);
131166
lldb::offset_t offset = 0;
132167
uint16_t magic = data.GetU16(&offset);
133168
return XCOFFHeaderSizeFromMagic(magic) != 0;
134169
}
135170

136-
bool ObjectFileXCOFF::ParseHeader() { return false; }
171+
bool ObjectFileXCOFF::ParseHeader() {
172+
// Only 64-bit is supported for now
173+
return m_binary->fileHeader64()->Magic == XCOFF::XCOFF64;
174+
}
137175

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

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

142-
uint32_t ObjectFileXCOFF::GetAddressByteSize() const { return 8; }
180+
uint32_t ObjectFileXCOFF::GetAddressByteSize() const {
181+
// 32-bit not supported. return 8 for 64-bit XCOFF::XCOFF64
182+
return 8;
183+
}
184+
185+
AddressClass ObjectFileXCOFF::GetAddressClass(addr_t file_addr) {
186+
return AddressClass::eUnknown;
187+
}
143188

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

@@ -159,7 +204,13 @@ UUID ObjectFileXCOFF::GetUUID() { return UUID(); }
159204

160205
uint32_t ObjectFileXCOFF::GetDependentModules(FileSpecList &files) { return 0; }
161206

162-
ObjectFile::Type ObjectFileXCOFF::CalculateType() { return eTypeExecutable; }
207+
ObjectFile::Type ObjectFileXCOFF::CalculateType() {
208+
if (m_binary->fileHeader64()->Flags & XCOFF::F_EXEC)
209+
return eTypeExecutable;
210+
else if (m_binary->fileHeader64()->Flags & XCOFF::F_SHROBJ)
211+
return eTypeSharedLibrary;
212+
return eTypeUnknown;
213+
}
163214

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

lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.h

+7
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ class ObjectFileXCOFF : public lldb_private::ObjectFile {
6868

6969
uint32_t GetAddressByteSize() const override;
7070

71+
lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override;
72+
7173
void ParseSymtab(lldb_private::Symtab &symtab) override;
7274

7375
bool IsStripped() override;
@@ -99,6 +101,11 @@ class ObjectFileXCOFF : public lldb_private::ObjectFile {
99101
static lldb::WritableDataBufferSP
100102
MapFileDataWritable(const lldb_private::FileSpec &file, uint64_t Size,
101103
uint64_t Offset);
104+
105+
private:
106+
bool CreateBinary();
107+
108+
std::unique_ptr<llvm::object::XCOFFObjectFile> m_binary;
102109
};
103110

104111
#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_XCOFF_OBJECTFILE_H

lldb/test/Shell/ObjectFile/XCOFF/basic-info.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ FileHeader:
1313
MagicNumber: 0x1F7
1414
NumberOfSections: 1
1515
CreationTime: 000000000
16-
Flags: 0x0000
16+
Flags: 0x0002
1717
Sections:
1818
- Name: .text
1919
Address: 0x100000438

0 commit comments

Comments
 (0)