@@ -165,6 +165,11 @@ GOFFObjectFile::GOFFObjectFile(MemoryBufferRef Object, Error &Err)
165
165
LLVM_DEBUG (dbgs () << " -- ESD " << EsdId << " \n " );
166
166
break ;
167
167
}
168
+ case GOFF::RT_TXT:
169
+ // Save TXT records.
170
+ TextPtrs.emplace_back (I);
171
+ LLVM_DEBUG (dbgs () << " -- TXT\n " );
172
+ break ;
168
173
case GOFF::RT_END:
169
174
LLVM_DEBUG (dbgs () << " -- END (GOFF record type) unhandled\n " );
170
175
break ;
@@ -361,6 +366,13 @@ GOFFObjectFile::getSymbolSection(DataRefImpl Symb) const {
361
366
std::to_string (SymEdId));
362
367
}
363
368
369
+ uint64_t GOFFObjectFile::getSymbolSize (DataRefImpl Symb) const {
370
+ const uint8_t *Record = getSymbolEsdRecord (Symb);
371
+ uint32_t Length;
372
+ ESDRecord::getLength (Record, Length);
373
+ return Length;
374
+ }
375
+
364
376
const uint8_t *GOFFObjectFile::getSectionEdEsdRecord (DataRefImpl &Sec) const {
365
377
SectionEntryImpl EsdIds = SectionList[Sec.d .a ];
366
378
const uint8_t *EsdRecord = EsdPtrs[EsdIds.d .a ];
@@ -391,6 +403,154 @@ GOFFObjectFile::getSectionPrEsdRecord(uint32_t SectionIndex) const {
391
403
return EsdRecord;
392
404
}
393
405
406
+ uint32_t GOFFObjectFile::getSectionDefEsdId (DataRefImpl &Sec) const {
407
+ const uint8_t *EsdRecord = getSectionEdEsdRecord (Sec);
408
+ uint32_t Length;
409
+ ESDRecord::getLength (EsdRecord, Length);
410
+ if (Length == 0 ) {
411
+ const uint8_t *PrEsdRecord = getSectionPrEsdRecord (Sec);
412
+ if (PrEsdRecord)
413
+ EsdRecord = PrEsdRecord;
414
+ }
415
+
416
+ uint32_t DefEsdId;
417
+ ESDRecord::getEsdId (EsdRecord, DefEsdId);
418
+ LLVM_DEBUG (dbgs () << " Got def EsdId: " << DefEsdId << ' \n ' );
419
+ return DefEsdId;
420
+ }
421
+
422
+ void GOFFObjectFile::moveSectionNext (DataRefImpl &Sec) const {
423
+ Sec.d .a ++;
424
+ if ((Sec.d .a ) >= SectionList.size ())
425
+ Sec.d .a = 0 ;
426
+ }
427
+
428
+ Expected<StringRef> GOFFObjectFile::getSectionName (DataRefImpl Sec) const {
429
+ DataRefImpl EdSym;
430
+ SectionEntryImpl EsdIds = SectionList[Sec.d .a ];
431
+ EdSym.d .a = EsdIds.d .a ;
432
+ Expected<StringRef> Name = getSymbolName (EdSym);
433
+ if (Name) {
434
+ StringRef Res = *Name;
435
+ LLVM_DEBUG (dbgs () << " Got section: " << Res << ' \n ' );
436
+ LLVM_DEBUG (dbgs () << " Final section name: " << Res << ' \n ' );
437
+ Name = Res;
438
+ }
439
+ return Name;
440
+ }
441
+
442
+ uint64_t GOFFObjectFile::getSectionAddress (DataRefImpl Sec) const {
443
+ uint32_t Offset;
444
+ const uint8_t *EsdRecord = getSectionEdEsdRecord (Sec);
445
+ ESDRecord::getOffset (EsdRecord, Offset);
446
+ return Offset;
447
+ }
448
+
449
+ uint64_t GOFFObjectFile::getSectionSize (DataRefImpl Sec) const {
450
+ uint32_t Length;
451
+ uint32_t DefEsdId = getSectionDefEsdId (Sec);
452
+ const uint8_t *EsdRecord = EsdPtrs[DefEsdId];
453
+ ESDRecord::getLength (EsdRecord, Length);
454
+ LLVM_DEBUG (dbgs () << " Got section size: " << Length << ' \n ' );
455
+ return static_cast <uint64_t >(Length);
456
+ }
457
+
458
+ // Unravel TXT records and expand fill characters to produce
459
+ // a contiguous sequence of bytes.
460
+ Expected<ArrayRef<uint8_t >>
461
+ GOFFObjectFile::getSectionContents (DataRefImpl Sec) const {
462
+ if (SectionDataCache.count (Sec.d .a )) {
463
+ auto &Buf = SectionDataCache[Sec.d .a ];
464
+ return ArrayRef<uint8_t >(Buf);
465
+ }
466
+ uint64_t SectionSize = getSectionSize (Sec);
467
+ uint32_t DefEsdId = getSectionDefEsdId (Sec);
468
+
469
+ const uint8_t *EdEsdRecord = getSectionEdEsdRecord (Sec);
470
+ bool FillBytePresent;
471
+ ESDRecord::getFillBytePresent (EdEsdRecord, FillBytePresent);
472
+ uint8_t FillByte = ' \0 ' ;
473
+ if (FillBytePresent)
474
+ ESDRecord::getFillByteValue (EdEsdRecord, FillByte);
475
+
476
+ // Initialize section with fill byte.
477
+ SmallVector<uint8_t > Data (SectionSize, FillByte);
478
+
479
+ // Replace section with content from text records.
480
+ for (const uint8_t *TxtRecordInt : TextPtrs) {
481
+ const uint8_t *TxtRecordPtr = TxtRecordInt;
482
+ uint32_t TxtEsdId;
483
+ TXTRecord::getElementEsdId (TxtRecordPtr, TxtEsdId);
484
+ LLVM_DEBUG (dbgs () << " Got txt EsdId: " << TxtEsdId << ' \n ' );
485
+
486
+ if (TxtEsdId != DefEsdId)
487
+ continue ;
488
+
489
+ uint32_t TxtDataOffset;
490
+ TXTRecord::getOffset (TxtRecordPtr, TxtDataOffset);
491
+
492
+ uint16_t TxtDataSize;
493
+ TXTRecord::getDataLength (TxtRecordPtr, TxtDataSize);
494
+
495
+ LLVM_DEBUG (dbgs () << " Record offset " << TxtDataOffset << " , data size "
496
+ << TxtDataSize << " \n " );
497
+
498
+ SmallString<256 > CompleteData;
499
+ CompleteData.reserve (TxtDataSize);
500
+ if (Error Err = TXTRecord::getData (TxtRecordPtr, CompleteData))
501
+ return std::move (Err);
502
+ assert (CompleteData.size () == TxtDataSize && " Wrong length of data" );
503
+ std::copy (CompleteData.data (), CompleteData.data () + TxtDataSize,
504
+ Data.begin () + TxtDataOffset);
505
+ }
506
+ SectionDataCache[Sec.d .a ] = Data;
507
+ return ArrayRef<uint8_t >(SectionDataCache[Sec.d .a ]);
508
+ }
509
+
510
+ uint64_t GOFFObjectFile::getSectionAlignment (DataRefImpl Sec) const {
511
+ const uint8_t *EsdRecord = getSectionEdEsdRecord (Sec);
512
+ GOFF::ESDAlignment Pow2Alignment;
513
+ ESDRecord::getAlignment (EsdRecord, Pow2Alignment);
514
+ return 1 << static_cast <uint64_t >(Pow2Alignment);
515
+ }
516
+
517
+ bool GOFFObjectFile::isSectionText (DataRefImpl Sec) const {
518
+ const uint8_t *EsdRecord = getSectionEdEsdRecord (Sec);
519
+ GOFF::ESDExecutable Executable;
520
+ ESDRecord::getExecutable (EsdRecord, Executable);
521
+ return Executable == GOFF::ESD_EXE_CODE;
522
+ }
523
+
524
+ bool GOFFObjectFile::isSectionData (DataRefImpl Sec) const {
525
+ const uint8_t *EsdRecord = getSectionEdEsdRecord (Sec);
526
+ GOFF::ESDExecutable Executable;
527
+ ESDRecord::getExecutable (EsdRecord, Executable);
528
+ return Executable == GOFF::ESD_EXE_DATA;
529
+ }
530
+
531
+ bool GOFFObjectFile::isSectionNoLoad (DataRefImpl Sec) const {
532
+ const uint8_t *EsdRecord = getSectionEdEsdRecord (Sec);
533
+ GOFF::ESDLoadingBehavior LoadingBehavior;
534
+ ESDRecord::getLoadingBehavior (EsdRecord, LoadingBehavior);
535
+ return LoadingBehavior == GOFF::ESD_LB_NoLoad;
536
+ }
537
+
538
+ bool GOFFObjectFile::isSectionReadOnlyData (DataRefImpl Sec) const {
539
+ if (!isSectionData (Sec))
540
+ return false ;
541
+
542
+ const uint8_t *EsdRecord = getSectionEdEsdRecord (Sec);
543
+ GOFF::ESDLoadingBehavior LoadingBehavior;
544
+ ESDRecord::getLoadingBehavior (EsdRecord, LoadingBehavior);
545
+ return LoadingBehavior == GOFF::ESD_LB_Initial;
546
+ }
547
+
548
+ bool GOFFObjectFile::isSectionZeroInit (DataRefImpl Sec) const {
549
+ // GOFF uses fill characters and fill characters are applied
550
+ // on getSectionContents() - so we say false to zero init.
551
+ return false ;
552
+ }
553
+
394
554
section_iterator GOFFObjectFile::section_begin () const {
395
555
DataRefImpl Sec;
396
556
moveSectionNext (Sec);
@@ -473,6 +633,13 @@ Error ESDRecord::getData(const uint8_t *Record,
473
633
return getContinuousData (Record, DataSize, 72 , CompleteData);
474
634
}
475
635
636
+ Error TXTRecord::getData (const uint8_t *Record,
637
+ SmallString<256 > &CompleteData) {
638
+ uint16_t Length;
639
+ getDataLength (Record, Length);
640
+ return getContinuousData (Record, Length, 24 , CompleteData);
641
+ }
642
+
476
643
Error ENDRecord::getData (const uint8_t *Record,
477
644
SmallString<256 > &CompleteData) {
478
645
uint16_t Length = getNameLength (Record);
0 commit comments