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