Skip to content

Commit 0c63800

Browse files
Added XCOFF Header Parsing
1 parent 5845688 commit 0c63800

File tree

2 files changed

+181
-3
lines changed

2 files changed

+181
-3
lines changed

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

Lines changed: 123 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,44 @@ ObjectFile *ObjectFileXCOFF::CreateInstance(const lldb::ModuleSP &module_sp,
8181
if (!objfile_up)
8282
return nullptr;
8383

84+
// Cache xcoff binary.
85+
if (!objfile_up->CreateBinary())
86+
return nullptr;
87+
88+
if (!objfile_up->ParseHeader())
89+
return nullptr;
90+
8491
return objfile_up.release();
8592
}
8693

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

139-
bool ObjectFileXCOFF::ParseHeader() { return false; }
174+
bool ObjectFileXCOFF::ParseHeader() {
175+
ModuleSP module_sp(GetModule());
176+
if (module_sp) {
177+
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
178+
lldb::offset_t offset = 0;
179+
180+
if (ParseXCOFFHeader(m_data, &offset, m_xcoff_header)) {
181+
m_data.SetAddressByteSize(GetAddressByteSize());
182+
if (m_xcoff_header.auxhdrsize > 0)
183+
ParseXCOFFOptionalHeader(m_data, &offset);
184+
}
185+
return true;
186+
}
187+
188+
return false;
189+
}
190+
191+
bool ObjectFileXCOFF::ParseXCOFFHeader(lldb_private::DataExtractor &data,
192+
lldb::offset_t *offset_ptr,
193+
xcoff_header_t &xcoff_header) {
194+
// FIXME: data.ValidOffsetForDataOfSize
195+
xcoff_header.magic = data.GetU16(offset_ptr);
196+
xcoff_header.nsects = data.GetU16(offset_ptr);
197+
xcoff_header.modtime = data.GetU32(offset_ptr);
198+
xcoff_header.symoff = data.GetU64(offset_ptr);
199+
xcoff_header.auxhdrsize = data.GetU16(offset_ptr);
200+
xcoff_header.flags = data.GetU16(offset_ptr);
201+
xcoff_header.nsyms = data.GetU32(offset_ptr);
202+
return true;
203+
}
204+
205+
bool ObjectFileXCOFF::ParseXCOFFOptionalHeader(
206+
lldb_private::DataExtractor &data, lldb::offset_t *offset_ptr) {
207+
lldb::offset_t init_offset = *offset_ptr;
208+
// FIXME: data.ValidOffsetForDataOfSize
209+
m_xcoff_aux_header.AuxMagic = data.GetU16(offset_ptr);
210+
m_xcoff_aux_header.Version = data.GetU16(offset_ptr);
211+
m_xcoff_aux_header.ReservedForDebugger = data.GetU32(offset_ptr);
212+
m_xcoff_aux_header.TextStartAddr = data.GetU64(offset_ptr);
213+
m_xcoff_aux_header.DataStartAddr = data.GetU64(offset_ptr);
214+
m_xcoff_aux_header.TOCAnchorAddr = data.GetU64(offset_ptr);
215+
m_xcoff_aux_header.SecNumOfEntryPoint = data.GetU16(offset_ptr);
216+
m_xcoff_aux_header.SecNumOfText = data.GetU16(offset_ptr);
217+
m_xcoff_aux_header.SecNumOfData = data.GetU16(offset_ptr);
218+
m_xcoff_aux_header.SecNumOfTOC = data.GetU16(offset_ptr);
219+
m_xcoff_aux_header.SecNumOfLoader = data.GetU16(offset_ptr);
220+
m_xcoff_aux_header.SecNumOfBSS = data.GetU16(offset_ptr);
221+
m_xcoff_aux_header.MaxAlignOfText = data.GetU16(offset_ptr);
222+
m_xcoff_aux_header.MaxAlignOfData = data.GetU16(offset_ptr);
223+
m_xcoff_aux_header.ModuleType = data.GetU16(offset_ptr);
224+
m_xcoff_aux_header.CpuFlag = data.GetU8(offset_ptr);
225+
m_xcoff_aux_header.CpuType = data.GetU8(offset_ptr);
226+
m_xcoff_aux_header.TextPageSize = data.GetU8(offset_ptr);
227+
m_xcoff_aux_header.DataPageSize = data.GetU8(offset_ptr);
228+
m_xcoff_aux_header.StackPageSize = data.GetU8(offset_ptr);
229+
m_xcoff_aux_header.FlagAndTDataAlignment = data.GetU8(offset_ptr);
230+
m_xcoff_aux_header.TextSize = data.GetU64(offset_ptr);
231+
m_xcoff_aux_header.InitDataSize = data.GetU64(offset_ptr);
232+
m_xcoff_aux_header.BssDataSize = data.GetU64(offset_ptr);
233+
m_xcoff_aux_header.EntryPointAddr = data.GetU64(offset_ptr);
234+
m_xcoff_aux_header.MaxStackSize = data.GetU64(offset_ptr);
235+
m_xcoff_aux_header.MaxDataSize = data.GetU64(offset_ptr);
236+
m_xcoff_aux_header.SecNumOfTData = data.GetU16(offset_ptr);
237+
m_xcoff_aux_header.SecNumOfTBSS = data.GetU16(offset_ptr);
238+
m_xcoff_aux_header.XCOFF64Flag = data.GetU16(offset_ptr);
239+
lldb::offset_t last_offset = *offset_ptr;
240+
if ((last_offset - init_offset) < m_xcoff_header.auxhdrsize)
241+
*offset_ptr += (m_xcoff_header.auxhdrsize - (last_offset - init_offset));
242+
return true;
243+
}
140244

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

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

145-
uint32_t ObjectFileXCOFF::GetAddressByteSize() const { return 8; }
249+
uint32_t ObjectFileXCOFF::GetAddressByteSize() const {
250+
if (m_xcoff_header.magic == XCOFF::XCOFF64)
251+
return 8;
252+
else if (m_xcoff_header.magic == XCOFF::XCOFF32)
253+
return 4;
254+
return 4;
255+
}
256+
257+
AddressClass ObjectFileXCOFF::GetAddressClass(addr_t file_addr) {
258+
return AddressClass::eUnknown;
259+
}
146260

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

@@ -162,7 +276,13 @@ UUID ObjectFileXCOFF::GetUUID() { return UUID(); }
162276

163277
uint32_t ObjectFileXCOFF::GetDependentModules(FileSpecList &files) { return 0; }
164278

165-
ObjectFile::Type ObjectFileXCOFF::CalculateType() { return eTypeExecutable; }
279+
ObjectFile::Type ObjectFileXCOFF::CalculateType() {
280+
if (m_xcoff_header.flags & XCOFF::F_EXEC)
281+
return eTypeExecutable;
282+
else if (m_xcoff_header.flags & XCOFF::F_SHROBJ)
283+
return eTypeSharedLibrary;
284+
return eTypeUnknown;
285+
}
166286

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

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

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ class ObjectFileXCOFF : public lldb_private::ObjectFile {
7070

7171
uint32_t GetAddressByteSize() const override;
7272

73+
lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override;
74+
7375
void ParseSymtab(lldb_private::Symtab &symtab) override;
7476

7577
bool IsStripped() override;
@@ -98,9 +100,65 @@ class ObjectFileXCOFF : public lldb_private::ObjectFile {
98100
const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
99101

100102
protected:
103+
typedef struct xcoff_header {
104+
uint16_t magic;
105+
uint16_t nsects;
106+
uint32_t modtime;
107+
uint64_t symoff;
108+
uint32_t nsyms;
109+
uint16_t auxhdrsize;
110+
uint16_t flags;
111+
} xcoff_header_t;
112+
113+
typedef struct xcoff_aux_header {
114+
uint16_t AuxMagic;
115+
uint16_t Version;
116+
uint32_t ReservedForDebugger;
117+
uint64_t TextStartAddr;
118+
uint64_t DataStartAddr;
119+
uint64_t TOCAnchorAddr;
120+
uint16_t SecNumOfEntryPoint;
121+
uint16_t SecNumOfText;
122+
uint16_t SecNumOfData;
123+
uint16_t SecNumOfTOC;
124+
uint16_t SecNumOfLoader;
125+
uint16_t SecNumOfBSS;
126+
uint16_t MaxAlignOfText;
127+
uint16_t MaxAlignOfData;
128+
uint16_t ModuleType;
129+
uint8_t CpuFlag;
130+
uint8_t CpuType;
131+
uint8_t TextPageSize;
132+
uint8_t DataPageSize;
133+
uint8_t StackPageSize;
134+
uint8_t FlagAndTDataAlignment;
135+
uint64_t TextSize;
136+
uint64_t InitDataSize;
137+
uint64_t BssDataSize;
138+
uint64_t EntryPointAddr;
139+
uint64_t MaxStackSize;
140+
uint64_t MaxDataSize;
141+
uint16_t SecNumOfTData;
142+
uint16_t SecNumOfTBSS;
143+
uint16_t XCOFF64Flag;
144+
} xcoff_aux_header_t;
145+
146+
static bool ParseXCOFFHeader(lldb_private::DataExtractor &data,
147+
lldb::offset_t *offset_ptr,
148+
xcoff_header_t &xcoff_header);
149+
bool ParseXCOFFOptionalHeader(lldb_private::DataExtractor &data,
150+
lldb::offset_t *offset_ptr);
151+
101152
static lldb::WritableDataBufferSP
102153
MapFileDataWritable(const lldb_private::FileSpec &file, uint64_t Size,
103154
uint64_t Offset);
155+
156+
private:
157+
bool CreateBinary();
158+
159+
xcoff_header_t m_xcoff_header;
160+
xcoff_aux_header_t m_xcoff_aux_header;
161+
std::unique_ptr<llvm::object::XCOFFObjectFile> m_binary;
104162
};
105163

106164
#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_XCOFF_OBJECTFILE_H

0 commit comments

Comments
 (0)