@@ -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+
87122ObjectFile *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
141245ByteOrder ObjectFileXCOFF::GetByteOrder () const { return eByteOrderBig; }
142246
143247bool 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
147261void ObjectFileXCOFF::ParseSymtab (Symtab &lldb_symtab) {}
148262
@@ -162,7 +276,13 @@ UUID ObjectFileXCOFF::GetUUID() { return UUID(); }
162276
163277uint32_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
167287ObjectFile::Strata ObjectFileXCOFF::CalculateStrata () { return eStrataUnknown; }
168288
0 commit comments