@@ -188,7 +188,258 @@ bool ObjectFileXCOFF::ParseHeader() {
188188 if (module_sp) {
189189 std::lock_guard<std::recursive_mutex> guard (module_sp->GetMutex ());
190190 m_sect_headers.clear ();
191- lldb::offs
191+ lldb::offset_t offset = 0 ;
192+
193+ if (ParseXCOFFHeader (m_data, &offset, m_xcoff_header)) {
194+ m_data.SetAddressByteSize (GetAddressByteSize ());
195+ if (m_xcoff_header.auxhdrsize > 0 )
196+ ParseXCOFFOptionalHeader (m_data, &offset);
197+ ParseSectionHeaders (offset);
198+ }
199+ return true ;
200+ }
201+
202+ return false ;
203+ }
204+
205+ bool ObjectFileXCOFF::ParseXCOFFHeader (lldb_private::DataExtractor &data,
206+ lldb::offset_t *offset_ptr,
207+ xcoff_header_t &xcoff_header) {
208+ // FIXME: data.ValidOffsetForDataOfSize
209+ xcoff_header.magic = data.GetU16 (offset_ptr);
210+ xcoff_header.nsects = data.GetU16 (offset_ptr);
211+ xcoff_header.modtime = data.GetU32 (offset_ptr);
212+ xcoff_header.symoff = data.GetU64 (offset_ptr);
213+ xcoff_header.auxhdrsize = data.GetU16 (offset_ptr);
214+ xcoff_header.flags = data.GetU16 (offset_ptr);
215+ xcoff_header.nsyms = data.GetU32 (offset_ptr);
216+ return true ;
217+ }
218+
219+ bool ObjectFileXCOFF::ParseXCOFFOptionalHeader (lldb_private::DataExtractor &data,
220+ lldb::offset_t *offset_ptr) {
221+ lldb::offset_t init_offset = *offset_ptr;
222+ // FIXME: data.ValidOffsetForDataOfSize
223+ m_xcoff_aux_header.AuxMagic = data.GetU16 (offset_ptr);
224+ m_xcoff_aux_header.Version = data.GetU16 (offset_ptr);
225+ m_xcoff_aux_header.ReservedForDebugger = data.GetU32 (offset_ptr);
226+ m_xcoff_aux_header.TextStartAddr = data.GetU64 (offset_ptr);
227+ m_xcoff_aux_header.DataStartAddr = data.GetU64 (offset_ptr);
228+ m_xcoff_aux_header.TOCAnchorAddr = data.GetU64 (offset_ptr);
229+ m_xcoff_aux_header.SecNumOfEntryPoint = data.GetU16 (offset_ptr);
230+ m_xcoff_aux_header.SecNumOfText = data.GetU16 (offset_ptr);
231+ m_xcoff_aux_header.SecNumOfData = data.GetU16 (offset_ptr);
232+ m_xcoff_aux_header.SecNumOfTOC = data.GetU16 (offset_ptr);
233+ m_xcoff_aux_header.SecNumOfLoader = data.GetU16 (offset_ptr);
234+ m_xcoff_aux_header.SecNumOfBSS = data.GetU16 (offset_ptr);
235+ m_xcoff_aux_header.MaxAlignOfText = data.GetU16 (offset_ptr);
236+ m_xcoff_aux_header.MaxAlignOfData = data.GetU16 (offset_ptr);
237+ m_xcoff_aux_header.ModuleType = data.GetU16 (offset_ptr);
238+ m_xcoff_aux_header.CpuFlag = data.GetU8 (offset_ptr);
239+ m_xcoff_aux_header.CpuType = data.GetU8 (offset_ptr);
240+ m_xcoff_aux_header.TextPageSize = data.GetU8 (offset_ptr);
241+ m_xcoff_aux_header.DataPageSize = data.GetU8 (offset_ptr);
242+ m_xcoff_aux_header.StackPageSize = data.GetU8 (offset_ptr);
243+ m_xcoff_aux_header.FlagAndTDataAlignment = data.GetU8 (offset_ptr);
244+ m_xcoff_aux_header.TextSize = data.GetU64 (offset_ptr);
245+ m_xcoff_aux_header.InitDataSize = data.GetU64 (offset_ptr);
246+ m_xcoff_aux_header.BssDataSize = data.GetU64 (offset_ptr);
247+ m_xcoff_aux_header.EntryPointAddr = data.GetU64 (offset_ptr);
248+ m_xcoff_aux_header.MaxStackSize = data.GetU64 (offset_ptr);
249+ m_xcoff_aux_header.MaxDataSize = data.GetU64 (offset_ptr);
250+ m_xcoff_aux_header.SecNumOfTData = data.GetU16 (offset_ptr);
251+ m_xcoff_aux_header.SecNumOfTBSS = data.GetU16 (offset_ptr);
252+ m_xcoff_aux_header.XCOFF64Flag = data.GetU16 (offset_ptr);
253+ lldb::offset_t last_offset = *offset_ptr;
254+ if ((last_offset - init_offset) < m_xcoff_header.auxhdrsize )
255+ *offset_ptr += (m_xcoff_header.auxhdrsize - (last_offset - init_offset));
256+ return true ;
257+ }
258+
259+ bool ObjectFileXCOFF::ParseSectionHeaders (
260+ uint32_t section_header_data_offset) {
261+ const uint32_t nsects = m_xcoff_header.nsects ;
262+ m_sect_headers.clear ();
263+
264+ if (nsects > 0 ) {
265+ const size_t section_header_byte_size = nsects * m_binary->getSectionHeaderSize ();
266+ lldb_private::DataExtractor section_header_data =
267+ ReadImageData (section_header_data_offset, section_header_byte_size);
268+
269+ lldb::offset_t offset = 0 ;
270+ // FIXME: section_header_data.ValidOffsetForDataOfSize
271+ m_sect_headers.resize (nsects);
272+
273+ for (uint32_t idx = 0 ; idx < nsects; ++idx) {
274+ const void *name_data = section_header_data.GetData (&offset, 8 );
275+ if (name_data) {
276+ memcpy (m_sect_headers[idx].name , name_data, 8 );
277+ m_sect_headers[idx].phyaddr = section_header_data.GetU64 (&offset);
278+ m_sect_headers[idx].vmaddr = section_header_data.GetU64 (&offset);
279+ m_sect_headers[idx].size = section_header_data.GetU64 (&offset);
280+ m_sect_headers[idx].offset = section_header_data.GetU64 (&offset);
281+ m_sect_headers[idx].reloff = section_header_data.GetU64 (&offset);
282+ m_sect_headers[idx].lineoff = section_header_data.GetU64 (&offset);
283+ m_sect_headers[idx].nreloc = section_header_data.GetU32 (&offset);
284+ m_sect_headers[idx].nline = section_header_data.GetU32 (&offset);
285+ m_sect_headers[idx].flags = section_header_data.GetU32 (&offset);
286+ offset += 4 ;
287+ } else {
288+ offset += (m_binary->getSectionHeaderSize () - 8 );
289+ }
290+ }
291+ }
292+
293+ return !m_sect_headers.empty ();
294+ }
295+
296+ lldb_private::DataExtractor ObjectFileXCOFF::ReadImageData (uint32_t offset, size_t size) {
297+ if (!size)
298+ return {};
299+
300+ if (m_data.ValidOffsetForDataOfSize (offset, size))
301+ return lldb_private::DataExtractor (m_data, offset, size);
302+
303+ assert (0 );
304+ ProcessSP process_sp (m_process_wp.lock ());
305+ lldb_private::DataExtractor data;
306+ if (process_sp) {
307+ auto data_up = std::make_unique<DataBufferHeap>(size, 0 );
308+ Status readmem_error;
309+ size_t bytes_read =
310+ process_sp->ReadMemory (offset, data_up->GetBytes (),
311+ data_up->GetByteSize (), readmem_error);
312+ if (bytes_read == size) {
313+ DataBufferSP buffer_sp (data_up.release ());
314+ data.SetData (buffer_sp, 0 , buffer_sp->GetByteSize ());
315+ }
316+ }
317+ return data;
318+ }
319+
320+ bool ObjectFileXCOFF::SetLoadAddress (Target &target, lldb::addr_t value,
321+ bool value_is_offset) {
322+ bool changed = false ;
323+ ModuleSP module_sp = GetModule ();
324+ if (module_sp) {
325+ size_t num_loaded_sections = 0 ;
326+ SectionList *section_list = GetSectionList ();
327+ if (section_list) {
328+ const size_t num_sections = section_list->GetSize ();
329+ size_t sect_idx = 0 ;
330+
331+ for (sect_idx = 0 ; sect_idx < num_sections; ++sect_idx) {
332+ // Iterate through the object file sections to find all of the sections
333+ // that have SHF_ALLOC in their flag bits.
334+ SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
335+ if (section_sp && !section_sp->IsThreadSpecific ()) {
336+ bool use_offset = false ;
337+ if (strcmp (section_sp->GetName ().AsCString (), " .text" ) == 0 ||
338+ strcmp (section_sp->GetName ().AsCString (), " .data" ) == 0 ||
339+ strcmp (section_sp->GetName ().AsCString (), " .bss" ) == 0 )
340+ use_offset = true ;
341+
342+ if (target.GetSectionLoadList ().SetSectionLoadAddress (
343+ section_sp, (use_offset ?
344+ (section_sp->GetFileOffset () + value) : (section_sp->GetFileAddress () + value))))
345+ ++num_loaded_sections;
346+ }
347+ }
348+ changed = num_loaded_sections > 0 ;
349+ }
350+ }
351+ return changed;
352+ }
353+
354+ bool ObjectFileXCOFF::SetLoadAddressByType (Target &target, lldb::addr_t value,
355+ bool value_is_offset, int type_id) {
356+ bool changed = false ;
357+ ModuleSP module_sp = GetModule ();
358+ if (module_sp) {
359+ size_t num_loaded_sections = 0 ;
360+ SectionList *section_list = GetSectionList ();
361+ if (section_list) {
362+ const size_t num_sections = section_list->GetSize ();
363+ size_t sect_idx = 0 ;
364+
365+ for (sect_idx = 0 ; sect_idx < num_sections; ++sect_idx) {
366+ // Iterate through the object file sections to find all of the sections
367+ // that have SHF_ALLOC in their flag bits.
368+ SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
369+ if (type_id == 1 && section_sp && strcmp (section_sp->GetName ().AsCString (), " .text" ) == 0 ) {
370+ if (!section_sp->IsThreadSpecific ()) {
371+ if (target.GetSectionLoadList ().SetSectionLoadAddress (
372+ section_sp, section_sp->GetFileOffset () + value))
373+ ++num_loaded_sections;
374+ }
375+ } else if (type_id == 2 && section_sp && strcmp (section_sp->GetName ().AsCString (), " .data" ) == 0 ) {
376+ if (!section_sp->IsThreadSpecific ()) {
377+ if (target.GetSectionLoadList ().SetSectionLoadAddress (
378+ section_sp, section_sp->GetFileAddress () + value))
379+ ++num_loaded_sections;
380+ }
381+ }
382+ }
383+ changed = num_loaded_sections > 0 ;
384+ }
385+ }
386+ return changed;
387+ }
388+
389+ ByteOrder ObjectFileXCOFF::GetByteOrder () const {
390+ return eByteOrderBig;
391+ }
392+
393+ bool ObjectFileXCOFF::IsExecutable () const {
394+ return true ;
395+ }
396+
397+ uint32_t ObjectFileXCOFF::GetAddressByteSize () const {
398+ if (m_xcoff_header.magic == XCOFF::XCOFF64)
399+ return 8 ;
400+ else if (m_xcoff_header.magic == XCOFF::XCOFF32)
401+ return 4 ;
402+ return 4 ;
403+ }
404+
405+ AddressClass ObjectFileXCOFF::GetAddressClass (addr_t file_addr) {
406+ return AddressClass::eUnknown;
407+ }
408+
409+ lldb::SymbolType ObjectFileXCOFF::MapSymbolType (llvm::object::SymbolRef::Type sym_type) {
410+ if (sym_type == llvm::object::SymbolRef::ST_Function)
411+ return lldb::eSymbolTypeCode;
412+ else if (sym_type == llvm::object::SymbolRef::ST_Data)
413+ return lldb::eSymbolTypeData;
414+ return lldb::eSymbolTypeInvalid;
415+ }
416+
417+ void ObjectFileXCOFF::ParseSymtab (Symtab &lldb_symtab) {
418+ SectionList *sect_list = GetSectionList ();
419+ const uint32_t num_syms = m_xcoff_header.nsyms ;
420+ uint32_t sidx = 0 ;
421+ if (num_syms > 0 && m_xcoff_header.symoff > 0 ) {
422+ const uint32_t symbol_size = XCOFF::SymbolTableEntrySize;
423+ const size_t symbol_data_size = num_syms * symbol_size;
424+ lldb_private::DataExtractor symtab_data =
425+ ReadImageData (m_xcoff_header.symoff , symbol_data_size);
426+
427+ lldb::offset_t offset = 0 ;
428+ std::string symbol_name;
429+ Symbol *symbols = lldb_symtab.Resize (num_syms);
430+ llvm::object::symbol_iterator SI = m_binary->symbol_begin ();
431+ for (uint32_t i = 0 ; i < num_syms; ++i, ++SI) {
432+ xcoff_symbol_t symbol;
433+ const uint32_t symbol_offset = offset;
434+ symbol.value = symtab_data.GetU64 (&offset);
435+ symbol.offset = symtab_data.GetU32 (&offset);
436+ Expected<StringRef> symbol_name_or_err = m_binary->getStringTableEntry (symbol.offset );
437+ if (!symbol_name_or_err) {
438+ consumeError (symbol_name_or_err.takeError ());
439+ return ;
440+ }
441+ StringRef symbol_name_str = symbol_name_or_err.get ();
442+ symbol_name.assign (symbol_name_str.data ());
192443 symbol.sect = symtab_data.GetU16 (&offset);
193444 symbol.type = symtab_data.GetU16 (&offset);
194445 symbol.storage = symtab_data.GetU8 (&offset);
0 commit comments