@@ -47,6 +47,7 @@ class XCOFFWriter {
47
47
bool initRelocations (uint64_t &CurrentOffset);
48
48
bool initStringTable ();
49
49
bool assignAddressesAndIndices ();
50
+
50
51
void writeFileHeader ();
51
52
void writeAuxFileHeader ();
52
53
void writeSectionHeader ();
@@ -55,6 +56,15 @@ class XCOFFWriter {
55
56
bool writeSymbols ();
56
57
void writeStringTable ();
57
58
59
+ void writeAuxSymbol (const XCOFFYAML::CsectAuxEnt &AuxSym);
60
+ void writeAuxSymbol (const XCOFFYAML::FileAuxEnt &AuxSym);
61
+ void writeAuxSymbol (const XCOFFYAML::FunctionAuxEnt &AuxSym);
62
+ void writeAuxSymbol (const XCOFFYAML::ExcpetionAuxEnt &AuxSym);
63
+ void writeAuxSymbol (const XCOFFYAML::BlockAuxEnt &AuxSym);
64
+ void writeAuxSymbol (const XCOFFYAML::SectAuxEntForDWARF &AuxSym);
65
+ void writeAuxSymbol (const XCOFFYAML::SectAuxEntForStat &AuxSym);
66
+ void writeAuxSymbol (const std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym);
67
+
58
68
XCOFFYAML::Object &Obj;
59
69
bool Is64Bit = false ;
60
70
support::endian::Writer W;
@@ -190,12 +200,23 @@ bool XCOFFWriter::initStringTable() {
190
200
}
191
201
}
192
202
} else {
193
- for (XCOFFYAML::Symbol &YamlSym : Obj.Symbols ) {
203
+ for (const XCOFFYAML::Symbol &YamlSym : Obj.Symbols ) {
194
204
if (nameShouldBeInStringTable (YamlSym.SymbolName ))
195
205
StrTblBuilder.add (YamlSym.SymbolName );
196
206
}
197
207
}
198
208
209
+ // Check if the file name in the File Auxiliary Entry should be added to the
210
+ // string table.
211
+ for (const XCOFFYAML::Symbol &YamlSym : Obj.Symbols ) {
212
+ for (const std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym :
213
+ YamlSym.AuxEntries ) {
214
+ if (auto AS = dyn_cast<XCOFFYAML::FileAuxEnt>(AuxSym.get ()))
215
+ if (nameShouldBeInStringTable (AS->FileNameOrString .getValueOr (" " )))
216
+ StrTblBuilder.add (AS->FileNameOrString .getValueOr (" " ));
217
+ }
218
+ }
219
+
199
220
StrTblBuilder.finalize ();
200
221
201
222
size_t StrTblSize = StrTblBuilder.getSize ();
@@ -216,9 +237,21 @@ bool XCOFFWriter::initFileHeader(uint64_t CurrentOffset) {
216
237
InitFileHdr.NumberOfSections = Obj.Sections .size ();
217
238
InitFileHdr.NumberOfSymTableEntries = Obj.Symbols .size ();
218
239
219
- for (const XCOFFYAML::Symbol &YamlSym : Obj.Symbols )
240
+ for (XCOFFYAML::Symbol &YamlSym : Obj.Symbols ) {
241
+ uint32_t AuxCount = YamlSym.AuxEntries .size ();
242
+ if (YamlSym.NumberOfAuxEntries && *YamlSym.NumberOfAuxEntries < AuxCount) {
243
+ ErrHandler (" specified NumberOfAuxEntries " +
244
+ Twine (static_cast <uint32_t >(*YamlSym.NumberOfAuxEntries )) +
245
+ " is less than the actual number "
246
+ " of auxiliary entries " +
247
+ Twine (AuxCount));
248
+ return false ;
249
+ }
250
+ YamlSym.NumberOfAuxEntries =
251
+ YamlSym.NumberOfAuxEntries .getValueOr (AuxCount);
220
252
// Add the number of auxiliary symbols to the total number.
221
- InitFileHdr.NumberOfSymTableEntries += YamlSym.NumberOfAuxEntries ;
253
+ InitFileHdr.NumberOfSymTableEntries += *YamlSym.NumberOfAuxEntries ;
254
+ }
222
255
223
256
// Calculate SymbolTableOffset for the file header.
224
257
if (InitFileHdr.NumberOfSymTableEntries ) {
@@ -491,6 +524,125 @@ bool XCOFFWriter::writeRelocations() {
491
524
return true ;
492
525
}
493
526
527
+ void XCOFFWriter::writeAuxSymbol (const XCOFFYAML::CsectAuxEnt &AuxSym) {
528
+ if (Is64Bit) {
529
+ W.write <uint32_t >(AuxSym.SectionOrLengthLo .getValueOr (0 ));
530
+ W.write <uint32_t >(AuxSym.ParameterHashIndex .getValueOr (0 ));
531
+ W.write <uint16_t >(AuxSym.TypeChkSectNum .getValueOr (0 ));
532
+ W.write <uint8_t >(AuxSym.SymbolAlignmentAndType .getValueOr (0 ));
533
+ W.write <uint8_t >(AuxSym.StorageMappingClass .getValueOr (XCOFF::XMC_PR));
534
+ W.write <uint32_t >(AuxSym.SectionOrLengthHi .getValueOr (0 ));
535
+ W.write <uint8_t >(0 );
536
+ W.write <uint8_t >(XCOFF::AUX_CSECT);
537
+ } else {
538
+ W.write <uint32_t >(AuxSym.SectionOrLength .getValueOr (0 ));
539
+ W.write <uint32_t >(AuxSym.ParameterHashIndex .getValueOr (0 ));
540
+ W.write <uint16_t >(AuxSym.TypeChkSectNum .getValueOr (0 ));
541
+ W.write <uint8_t >(AuxSym.SymbolAlignmentAndType .getValueOr (0 ));
542
+ W.write <uint8_t >(AuxSym.StorageMappingClass .getValueOr (XCOFF::XMC_PR));
543
+ W.write <uint32_t >(AuxSym.StabInfoIndex .getValueOr (0 ));
544
+ W.write <uint16_t >(AuxSym.StabSectNum .getValueOr (0 ));
545
+ }
546
+ }
547
+
548
+ void XCOFFWriter::writeAuxSymbol (const XCOFFYAML::ExcpetionAuxEnt &AuxSym) {
549
+ assert (Is64Bit && " can't write the exception auxiliary symbol for XCOFF32" );
550
+ W.write <uint64_t >(AuxSym.OffsetToExceptionTbl .getValueOr (0 ));
551
+ W.write <uint32_t >(AuxSym.SizeOfFunction .getValueOr (0 ));
552
+ W.write <uint32_t >(AuxSym.SymIdxOfNextBeyond .getValueOr (0 ));
553
+ W.write <uint8_t >(0 );
554
+ W.write <uint8_t >(XCOFF::AUX_EXCEPT);
555
+ }
556
+
557
+ void XCOFFWriter::writeAuxSymbol (const XCOFFYAML::FunctionAuxEnt &AuxSym) {
558
+ if (Is64Bit) {
559
+ W.write <uint64_t >(AuxSym.PtrToLineNum .getValueOr (0 ));
560
+ W.write <uint32_t >(AuxSym.SizeOfFunction .getValueOr (0 ));
561
+ W.write <uint32_t >(AuxSym.SymIdxOfNextBeyond .getValueOr (0 ));
562
+ W.write <uint8_t >(0 );
563
+ W.write <uint8_t >(XCOFF::AUX_FCN);
564
+ } else {
565
+ W.write <uint32_t >(AuxSym.OffsetToExceptionTbl .getValueOr (0 ));
566
+ W.write <uint32_t >(AuxSym.SizeOfFunction .getValueOr (0 ));
567
+ W.write <uint32_t >(AuxSym.PtrToLineNum .getValueOr (0 ));
568
+ W.write <uint32_t >(AuxSym.SymIdxOfNextBeyond .getValueOr (0 ));
569
+ W.OS .write_zeros (2 );
570
+ }
571
+ }
572
+
573
+ void XCOFFWriter::writeAuxSymbol (const XCOFFYAML::FileAuxEnt &AuxSym) {
574
+ StringRef FileName = AuxSym.FileNameOrString .getValueOr (" " );
575
+ if (nameShouldBeInStringTable (FileName)) {
576
+ W.write <int32_t >(0 );
577
+ W.write <uint32_t >(StrTblBuilder.getOffset (FileName));
578
+ } else {
579
+ writeName (FileName, W);
580
+ }
581
+ W.OS .write_zeros (XCOFF::FileNamePadSize);
582
+ W.write <uint8_t >(AuxSym.FileStringType .getValueOr (XCOFF::XFT_FN));
583
+ if (Is64Bit) {
584
+ W.OS .write_zeros (2 );
585
+ W.write <uint8_t >(XCOFF::AUX_FILE);
586
+ } else {
587
+ W.OS .write_zeros (3 );
588
+ }
589
+ }
590
+
591
+ void XCOFFWriter::writeAuxSymbol (const XCOFFYAML::BlockAuxEnt &AuxSym) {
592
+ if (Is64Bit) {
593
+ W.write <uint32_t >(AuxSym.LineNum .getValueOr (0 ));
594
+ W.OS .write_zeros (13 );
595
+ W.write <uint8_t >(XCOFF::AUX_SYM);
596
+ } else {
597
+ W.OS .write_zeros (2 );
598
+ W.write <uint16_t >(AuxSym.LineNumHi .getValueOr (0 ));
599
+ W.write <uint16_t >(AuxSym.LineNumLo .getValueOr (0 ));
600
+ W.OS .write_zeros (12 );
601
+ }
602
+ }
603
+
604
+ void XCOFFWriter::writeAuxSymbol (const XCOFFYAML::SectAuxEntForDWARF &AuxSym) {
605
+ if (Is64Bit) {
606
+ W.write <uint64_t >(AuxSym.LengthOfSectionPortion .getValueOr (0 ));
607
+ W.write <uint64_t >(AuxSym.NumberOfRelocEnt .getValueOr (0 ));
608
+ W.write <uint8_t >(0 );
609
+ W.write <uint8_t >(XCOFF::AUX_SECT);
610
+ } else {
611
+ W.write <uint32_t >(AuxSym.LengthOfSectionPortion .getValueOr (0 ));
612
+ W.OS .write_zeros (4 );
613
+ W.write <uint32_t >(AuxSym.NumberOfRelocEnt .getValueOr (0 ));
614
+ W.OS .write_zeros (6 );
615
+ }
616
+ }
617
+
618
+ void XCOFFWriter::writeAuxSymbol (const XCOFFYAML::SectAuxEntForStat &AuxSym) {
619
+ assert (!Is64Bit && " can't write the stat auxiliary symbol for XCOFF64" );
620
+ W.write <uint32_t >(AuxSym.SectionLength .getValueOr (0 ));
621
+ W.write <uint16_t >(AuxSym.NumberOfRelocEnt .getValueOr (0 ));
622
+ W.write <uint16_t >(AuxSym.NumberOfLineNum .getValueOr (0 ));
623
+ W.OS .write_zeros (10 );
624
+ }
625
+
626
+ void XCOFFWriter::writeAuxSymbol (
627
+ const std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym) {
628
+ if (auto AS = dyn_cast<XCOFFYAML::CsectAuxEnt>(AuxSym.get ()))
629
+ writeAuxSymbol (*AS);
630
+ else if (auto AS = dyn_cast<XCOFFYAML::FunctionAuxEnt>(AuxSym.get ()))
631
+ writeAuxSymbol (*AS);
632
+ else if (auto AS = dyn_cast<XCOFFYAML::ExcpetionAuxEnt>(AuxSym.get ()))
633
+ writeAuxSymbol (*AS);
634
+ else if (auto AS = dyn_cast<XCOFFYAML::FileAuxEnt>(AuxSym.get ()))
635
+ writeAuxSymbol (*AS);
636
+ else if (auto AS = dyn_cast<XCOFFYAML::BlockAuxEnt>(AuxSym.get ()))
637
+ writeAuxSymbol (*AS);
638
+ else if (auto AS = dyn_cast<XCOFFYAML::SectAuxEntForDWARF>(AuxSym.get ()))
639
+ writeAuxSymbol (*AS);
640
+ else if (auto AS = dyn_cast<XCOFFYAML::SectAuxEntForStat>(AuxSym.get ()))
641
+ writeAuxSymbol (*AS);
642
+ else
643
+ llvm_unreachable (" unknown auxiliary symbol type" );
644
+ }
645
+
494
646
bool XCOFFWriter::writeSymbols () {
495
647
int64_t PaddingSize =
496
648
(uint64_t )InitFileHdr.SymbolTableOffset - (W.OS .tell () - StartOffset);
@@ -533,16 +685,25 @@ bool XCOFFWriter::writeSymbols() {
533
685
}
534
686
W.write <uint16_t >(YamlSym.Type );
535
687
W.write <uint8_t >(YamlSym.StorageClass );
536
- W.write <uint8_t >(YamlSym.NumberOfAuxEntries );
537
-
538
- // Now output the auxiliary entry.
539
- for (uint8_t I = 0 , E = YamlSym.NumberOfAuxEntries ; I < E; ++I) {
540
- // TODO: Auxiliary entry is not supported yet.
541
- // The auxiliary entries for a symbol follow its symbol table entry. The
542
- // length of each auxiliary entry is the same as a symbol table entry (18
543
- // bytes). The format and quantity of auxiliary entries depend on the
544
- // storage class (n_sclass) and type (n_type) of the symbol table entry.
545
- W.OS .write_zeros (XCOFF::SymbolTableEntrySize);
688
+
689
+ uint8_t NumOfAuxSym = YamlSym.NumberOfAuxEntries .getValueOr (0 );
690
+ W.write <uint8_t >(NumOfAuxSym);
691
+
692
+ if (!NumOfAuxSym && !YamlSym.AuxEntries .size ())
693
+ continue ;
694
+
695
+ // Now write auxiliary entries.
696
+ if (!YamlSym.AuxEntries .size ()) {
697
+ W.OS .write_zeros (XCOFF::SymbolTableEntrySize * NumOfAuxSym);
698
+ } else {
699
+ for (const std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym :
700
+ YamlSym.AuxEntries ) {
701
+ writeAuxSymbol (AuxSym);
702
+ }
703
+ // Pad with zeros.
704
+ if (NumOfAuxSym > YamlSym.AuxEntries .size ())
705
+ W.OS .write_zeros (XCOFF::SymbolTableEntrySize *
706
+ (NumOfAuxSym - YamlSym.AuxEntries .size ()));
546
707
}
547
708
}
548
709
return true ;
0 commit comments