23
23
#include " llvm/Support/raw_ostream.h"
24
24
25
25
using namespace llvm ;
26
+ using namespace llvm ::object;
26
27
27
28
namespace {
28
29
@@ -56,14 +57,14 @@ class XCOFFWriter {
56
57
bool writeSymbols ();
57
58
void writeStringTable ();
58
59
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);
60
+ bool writeAuxSymbol (const XCOFFYAML::CsectAuxEnt &AuxSym);
61
+ bool writeAuxSymbol (const XCOFFYAML::FileAuxEnt &AuxSym);
62
+ bool writeAuxSymbol (const XCOFFYAML::FunctionAuxEnt &AuxSym);
63
+ bool writeAuxSymbol (const XCOFFYAML::ExcpetionAuxEnt &AuxSym);
64
+ bool writeAuxSymbol (const XCOFFYAML::BlockAuxEnt &AuxSym);
65
+ bool writeAuxSymbol (const XCOFFYAML::SectAuxEntForDWARF &AuxSym);
66
+ bool writeAuxSymbol (const XCOFFYAML::SectAuxEntForStat &AuxSym);
67
+ bool writeAuxSymbol (const std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym);
67
68
68
69
XCOFFYAML::Object &Obj;
69
70
bool Is64Bit = false ;
@@ -181,7 +182,7 @@ bool XCOFFWriter::initStringTable() {
181
182
StrTblBuilder.clear ();
182
183
183
184
if (Obj.StrTbl .Strings ) {
184
- // All specified strings should be added to the string table.
185
+ // Add all specified strings to the string table.
185
186
for (StringRef StringEnt : *Obj.StrTbl .Strings )
186
187
StrTblBuilder.add (StringEnt);
187
188
@@ -524,12 +525,44 @@ bool XCOFFWriter::writeRelocations() {
524
525
return true ;
525
526
}
526
527
527
- void XCOFFWriter::writeAuxSymbol (const XCOFFYAML::CsectAuxEnt &AuxSym) {
528
+ bool XCOFFWriter::writeAuxSymbol (const XCOFFYAML::CsectAuxEnt &AuxSym) {
529
+ uint8_t SymAlignAndType = 0 ;
530
+ if (AuxSym.SymbolAlignmentAndType ) {
531
+ if (AuxSym.SymbolType || AuxSym.SymbolAlignment ) {
532
+ ErrHandler (" cannot specify SymbolType or SymbolAlignment if "
533
+ " SymbolAlignmentAndType is specified" );
534
+ return false ;
535
+ }
536
+ SymAlignAndType = *AuxSym.SymbolAlignmentAndType ;
537
+ } else {
538
+ if (AuxSym.SymbolType ) {
539
+ uint8_t SymbolType = *AuxSym.SymbolType ;
540
+ if (SymbolType & ~XCOFFCsectAuxRef::SymbolTypeMask) {
541
+ ErrHandler (" symbol type must be less than " +
542
+ Twine (1 + XCOFFCsectAuxRef::SymbolTypeMask));
543
+ return false ;
544
+ }
545
+ SymAlignAndType = SymbolType;
546
+ }
547
+ if (AuxSym.SymbolAlignment ) {
548
+ const uint8_t ShiftedSymbolAlignmentMask =
549
+ XCOFFCsectAuxRef::SymbolAlignmentMask >>
550
+ XCOFFCsectAuxRef::SymbolAlignmentBitOffset;
551
+
552
+ if (*AuxSym.SymbolAlignment & ~ShiftedSymbolAlignmentMask) {
553
+ ErrHandler (" symbol alignment must be less than " +
554
+ Twine (1 + ShiftedSymbolAlignmentMask));
555
+ return false ;
556
+ }
557
+ SymAlignAndType |= (*AuxSym.SymbolAlignment
558
+ << XCOFFCsectAuxRef::SymbolAlignmentBitOffset);
559
+ }
560
+ }
528
561
if (Is64Bit) {
529
562
W.write <uint32_t >(AuxSym.SectionOrLengthLo .value_or (0 ));
530
563
W.write <uint32_t >(AuxSym.ParameterHashIndex .value_or (0 ));
531
564
W.write <uint16_t >(AuxSym.TypeChkSectNum .value_or (0 ));
532
- W.write <uint8_t >(AuxSym. SymbolAlignmentAndType . value_or ( 0 ) );
565
+ W.write <uint8_t >(SymAlignAndType );
533
566
W.write <uint8_t >(AuxSym.StorageMappingClass .value_or (XCOFF::XMC_PR));
534
567
W.write <uint32_t >(AuxSym.SectionOrLengthHi .value_or (0 ));
535
568
W.write <uint8_t >(0 );
@@ -538,23 +571,25 @@ void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::CsectAuxEnt &AuxSym) {
538
571
W.write <uint32_t >(AuxSym.SectionOrLength .value_or (0 ));
539
572
W.write <uint32_t >(AuxSym.ParameterHashIndex .value_or (0 ));
540
573
W.write <uint16_t >(AuxSym.TypeChkSectNum .value_or (0 ));
541
- W.write <uint8_t >(AuxSym. SymbolAlignmentAndType . value_or ( 0 ) );
574
+ W.write <uint8_t >(SymAlignAndType );
542
575
W.write <uint8_t >(AuxSym.StorageMappingClass .value_or (XCOFF::XMC_PR));
543
576
W.write <uint32_t >(AuxSym.StabInfoIndex .value_or (0 ));
544
577
W.write <uint16_t >(AuxSym.StabSectNum .value_or (0 ));
545
578
}
579
+ return true ;
546
580
}
547
581
548
- void XCOFFWriter::writeAuxSymbol (const XCOFFYAML::ExcpetionAuxEnt &AuxSym) {
582
+ bool XCOFFWriter::writeAuxSymbol (const XCOFFYAML::ExcpetionAuxEnt &AuxSym) {
549
583
assert (Is64Bit && " can't write the exception auxiliary symbol for XCOFF32" );
550
584
W.write <uint64_t >(AuxSym.OffsetToExceptionTbl .value_or (0 ));
551
585
W.write <uint32_t >(AuxSym.SizeOfFunction .value_or (0 ));
552
586
W.write <uint32_t >(AuxSym.SymIdxOfNextBeyond .value_or (0 ));
553
587
W.write <uint8_t >(0 );
554
588
W.write <uint8_t >(XCOFF::AUX_EXCEPT);
589
+ return true ;
555
590
}
556
591
557
- void XCOFFWriter::writeAuxSymbol (const XCOFFYAML::FunctionAuxEnt &AuxSym) {
592
+ bool XCOFFWriter::writeAuxSymbol (const XCOFFYAML::FunctionAuxEnt &AuxSym) {
558
593
if (Is64Bit) {
559
594
W.write <uint64_t >(AuxSym.PtrToLineNum .value_or (0 ));
560
595
W.write <uint32_t >(AuxSym.SizeOfFunction .value_or (0 ));
@@ -568,9 +603,10 @@ void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::FunctionAuxEnt &AuxSym) {
568
603
W.write <uint32_t >(AuxSym.SymIdxOfNextBeyond .value_or (0 ));
569
604
W.OS .write_zeros (2 );
570
605
}
606
+ return true ;
571
607
}
572
608
573
- void XCOFFWriter::writeAuxSymbol (const XCOFFYAML::FileAuxEnt &AuxSym) {
609
+ bool XCOFFWriter::writeAuxSymbol (const XCOFFYAML::FileAuxEnt &AuxSym) {
574
610
StringRef FileName = AuxSym.FileNameOrString .value_or (" " );
575
611
if (nameShouldBeInStringTable (FileName)) {
576
612
W.write <int32_t >(0 );
@@ -586,9 +622,10 @@ void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::FileAuxEnt &AuxSym) {
586
622
} else {
587
623
W.OS .write_zeros (3 );
588
624
}
625
+ return true ;
589
626
}
590
627
591
- void XCOFFWriter::writeAuxSymbol (const XCOFFYAML::BlockAuxEnt &AuxSym) {
628
+ bool XCOFFWriter::writeAuxSymbol (const XCOFFYAML::BlockAuxEnt &AuxSym) {
592
629
if (Is64Bit) {
593
630
W.write <uint32_t >(AuxSym.LineNum .value_or (0 ));
594
631
W.OS .write_zeros (13 );
@@ -599,9 +636,10 @@ void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::BlockAuxEnt &AuxSym) {
599
636
W.write <uint16_t >(AuxSym.LineNumLo .value_or (0 ));
600
637
W.OS .write_zeros (12 );
601
638
}
639
+ return true ;
602
640
}
603
641
604
- void XCOFFWriter::writeAuxSymbol (const XCOFFYAML::SectAuxEntForDWARF &AuxSym) {
642
+ bool XCOFFWriter::writeAuxSymbol (const XCOFFYAML::SectAuxEntForDWARF &AuxSym) {
605
643
if (Is64Bit) {
606
644
W.write <uint64_t >(AuxSym.LengthOfSectionPortion .value_or (0 ));
607
645
W.write <uint64_t >(AuxSym.NumberOfRelocEnt .value_or (0 ));
@@ -613,34 +651,36 @@ void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::SectAuxEntForDWARF &AuxSym) {
613
651
W.write <uint32_t >(AuxSym.NumberOfRelocEnt .value_or (0 ));
614
652
W.OS .write_zeros (6 );
615
653
}
654
+ return true ;
616
655
}
617
656
618
- void XCOFFWriter::writeAuxSymbol (const XCOFFYAML::SectAuxEntForStat &AuxSym) {
657
+ bool XCOFFWriter::writeAuxSymbol (const XCOFFYAML::SectAuxEntForStat &AuxSym) {
619
658
assert (!Is64Bit && " can't write the stat auxiliary symbol for XCOFF64" );
620
659
W.write <uint32_t >(AuxSym.SectionLength .value_or (0 ));
621
660
W.write <uint16_t >(AuxSym.NumberOfRelocEnt .value_or (0 ));
622
661
W.write <uint16_t >(AuxSym.NumberOfLineNum .value_or (0 ));
623
662
W.OS .write_zeros (10 );
663
+ return true ;
624
664
}
625
665
626
- void XCOFFWriter::writeAuxSymbol (
666
+ bool XCOFFWriter::writeAuxSymbol (
627
667
const std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym) {
628
668
if (auto AS = dyn_cast<XCOFFYAML::CsectAuxEnt>(AuxSym.get ()))
629
- writeAuxSymbol (*AS);
669
+ return writeAuxSymbol (*AS);
630
670
else if (auto AS = dyn_cast<XCOFFYAML::FunctionAuxEnt>(AuxSym.get ()))
631
- writeAuxSymbol (*AS);
671
+ return writeAuxSymbol (*AS);
632
672
else if (auto AS = dyn_cast<XCOFFYAML::ExcpetionAuxEnt>(AuxSym.get ()))
633
- writeAuxSymbol (*AS);
673
+ return writeAuxSymbol (*AS);
634
674
else if (auto AS = dyn_cast<XCOFFYAML::FileAuxEnt>(AuxSym.get ()))
635
- writeAuxSymbol (*AS);
675
+ return writeAuxSymbol (*AS);
636
676
else if (auto AS = dyn_cast<XCOFFYAML::BlockAuxEnt>(AuxSym.get ()))
637
- writeAuxSymbol (*AS);
677
+ return writeAuxSymbol (*AS);
638
678
else if (auto AS = dyn_cast<XCOFFYAML::SectAuxEntForDWARF>(AuxSym.get ()))
639
- writeAuxSymbol (*AS);
679
+ return writeAuxSymbol (*AS);
640
680
else if (auto AS = dyn_cast<XCOFFYAML::SectAuxEntForStat>(AuxSym.get ()))
641
- writeAuxSymbol (*AS);
642
- else
643
- llvm_unreachable ( " unknown auxiliary symbol type " ) ;
681
+ return writeAuxSymbol (*AS);
682
+ llvm_unreachable ( " unknown auxiliary symbol type " );
683
+ return false ;
644
684
}
645
685
646
686
bool XCOFFWriter::writeSymbols () {
@@ -698,7 +738,8 @@ bool XCOFFWriter::writeSymbols() {
698
738
} else {
699
739
for (const std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym :
700
740
YamlSym.AuxEntries ) {
701
- writeAuxSymbol (AuxSym);
741
+ if (!writeAuxSymbol (AuxSym))
742
+ return false ;
702
743
}
703
744
// Pad with zeros.
704
745
if (NumOfAuxSym > YamlSym.AuxEntries .size ())
0 commit comments