LLVM: lib/MC/WinCOFFObjectWriter.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
41#include
42#include
43#include
44#include
45#include
46#include
47#include
48
49using namespace llvm;
51
52#define DEBUG_TYPE "WinCOFFObjectWriter"
53
54namespace {
55
56constexpr int OffsetLabelIntervalBits = 20;
57
59
60enum AuxiliaryType { ATWeakExternal, ATFile, ATSectionDefinition };
61
62struct AuxSymbol {
65};
66
67class COFFSection;
68
69class COFFSymbol {
70public:
72
74
76 int Index = 0;
77 AuxiliarySymbols Aux;
78 COFFSymbol *Other = nullptr;
79 COFFSection *Section = nullptr;
80 int Relocations = 0;
82
83 COFFSymbol(StringRef Name) : Name(Name) {}
84
86
87 int64_t getIndex() const { return Index; }
88 void setIndex(int Value) {
90 if (MC)
92 }
93};
94
95
96struct COFFRelocation {
98 COFFSymbol *Symb = nullptr;
99
100 COFFRelocation() = default;
101
103};
104
105using relocations = std::vector;
106
107class COFFSection {
108public:
110
111 std::string Name;
114 COFFSymbol *Symbol = nullptr;
115 relocations Relocations;
116
117 COFFSection(StringRef Name) : Name(std::string(Name)) {}
118
120};
121}
122
126
127 using symbols = std::vector<std::unique_ptr>;
128 using sections = std::vector<std::unique_ptr>;
129
132
134
135
137 sections Sections;
138 symbols Symbols;
140
141
144
146
147 bool UseBigObj;
148 bool UseOffsetLabels = false;
149
150public:
156
159
167
168private:
170 COFFSymbol *GetOrCreateCOFFSymbol(const MCSymbol *Symbol);
172
174
175 COFFSymbol *getLinkedSymbol(const MCSymbol &Symbol);
177
178 void SetSymbolName(COFFSymbol &S);
179 void SetSectionName(COFFSection &S);
180
181 bool IsPhysicalSection(COFFSection *S);
182
183
184 void WriteFileHeader(const COFF::header &Header);
185 void WriteSymbol(const COFFSymbol &S);
187 void writeSectionHeaders();
190 void writeSection(MCAssembler &Asm, const COFFSection &Sec);
191
192 void createFileSymbols(MCAssembler &Asm);
193 void setWeakDefaultNames();
194 void assignSectionNumbers();
195 void assignFileOffsets(MCAssembler &Asm);
196};
197
199 std::unique_ptr MOTW, raw_pwrite_stream &OS)
200 : TargetObjectWriter(std::move(MOTW)),
204 std::unique_ptr MOTW, raw_pwrite_stream &OS,
206 : TargetObjectWriter(std::move(MOTW)),
211
214}
215
216
217
218
219
220
221
225}
226
227
228
229
233 Header.Machine = OWriter.TargetObjectWriter->getMachine();
234
235
236
237
239}
240
241COFFSymbol *WinCOFFWriter::createSymbol(StringRef Name) {
242 Symbols.push_back(std::make_unique(Name));
243 return Symbols.back().get();
244}
245
246COFFSymbol *WinCOFFWriter::GetOrCreateCOFFSymbol(const MCSymbol *Symbol) {
247 COFFSymbol *&Ret = SymbolMap[Symbol];
248 if (!Ret)
249 Ret = createSymbol(Symbol->getName());
250 return Ret;
251}
252
253COFFSection *WinCOFFWriter::createSection(StringRef Name) {
254 Sections.emplace_back(std::make_unique(Name));
255 return Sections.back().get();
256}
257
260 case 1:
262 case 2:
264 case 4:
266 case 8:
268 case 16:
270 case 32:
272 case 64:
274 case 128:
276 case 256:
278 case 512:
280 case 1024:
282 case 2048:
284 case 4096:
286 case 8192:
288 }
290}
291
292
293
294void WinCOFFWriter::defineSection(const MCAssembler &Asm,
296 COFFSection *Section = createSection(MCSec.getName());
297 COFFSymbol *Symbol = createSymbol(MCSec.getName());
302
303
306 COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(S);
307 if (COMDATSymbol->Section)
309 COMDATSymbol->Section = Section;
310 }
311 }
312
313
314 Symbol->Aux.resize(1);
316 Symbol->Aux[0].AuxType = ATSectionDefinition;
317 Symbol->Aux[0].Aux.SectionDefinition.Selection = MCSec.getSelection();
318
319
322
323
324 Section->MCSection = &MCSec;
325 SectionMap[&MCSec] = Section;
326
327 if (UseOffsetLabels) {
330 for (uint32_t Off = Interval, E = Asm.getSectionAddressSize(MCSec); Off < E;
333 COFFSymbol *Label = createSymbol(Name);
337 Section->OffsetSymbols.push_back(Label);
338 }
339 }
340}
341
343 if (Symbol.isCommon() && Symbol.isExternal())
344 return Symbol.getCommonSize();
345
347 if (!Asm.getSymbolOffset(Symbol, Res))
348 return 0;
349
350 return Res;
351}
352
353COFFSymbol *WinCOFFWriter::getLinkedSymbol(const MCSymbol &Symbol) {
354 if (.isVariable())
355 return nullptr;
356
358 dyn_cast(Symbol.getVariableValue());
359 if (!SymRef)
360 return nullptr;
361
364 return GetOrCreateCOFFSymbol(&Aliasee);
365 else
366 return nullptr;
367}
368
369
370
371void WinCOFFWriter::defineSymbol(const MCAssembler &Asm,
374 COFFSection *Sec = nullptr;
376 if (Base && Base->getFragment()) {
377 MCSec = cast(Base->getFragment()->getParent());
378 Sec = SectionMap[MCSec];
379 }
380
382 return;
383
384 COFFSymbol *Sym = GetOrCreateCOFFSymbol(&MCSym);
385 COFFSymbol *Local = nullptr;
386 if (cast(MCSym).getWeakExternalCharacteristics()) {
388 Sym->Section = nullptr;
389
390 COFFSymbol *WeakDefault = getLinkedSymbol(MCSym);
391 if (!WeakDefault) {
392 std::string WeakName = (".weak." + MCSym.getName() + ".default").str();
393 WeakDefault = createSymbol(WeakName);
394 if (!Sec)
396 else
397 WeakDefault->Section = Sec;
398 WeakDefaults.insert(WeakDefault);
399 Local = WeakDefault;
400 }
401
402 Sym->Other = WeakDefault;
403
404
405 Sym->Aux.resize(1);
406 memset(&Sym->Aux[0], 0, sizeof(Sym->Aux[0]));
407 Sym->Aux[0].AuxType = ATWeakExternal;
408 Sym->Aux[0].Aux.WeakExternal.TagIndex = 0;
409 Sym->Aux[0].Aux.WeakExternal.Characteristics =
410 cast(MCSym).getWeakExternalCharacteristics();
411 } else {
414 else
415 Sym->Section = Sec;
417 }
418
421
422 const MCSymbolCOFF &SymbolCOFF = cast(MCSym);
424 Local->Data.StorageClass = SymbolCOFF.getClass();
425
426
428 bool IsExternal =
430
433 }
434 }
435
436 Sym->MC = &MCSym;
437}
438
439void WinCOFFWriter::SetSectionName(COFFSection &S) {
441 std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size());
442 return;
443 }
444
448}
449
450void WinCOFFWriter::SetSymbolName(COFFSymbol &S) {
452 S.set_name_offset(Strings.getOffset(S.Name));
453 else
454 std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size());
455}
456
457bool WinCOFFWriter::IsPhysicalSection(COFFSection *S) {
459 0;
460}
461
462
463
464
465void WinCOFFWriter::WriteFileHeader(const COFF::header &Header) {
466 if (UseBigObj) {
480 } else {
482 W.write<uint16_t>(static_cast<int16_t>(Header.NumberOfSections));
488 }
489}
490
491void WinCOFFWriter::WriteSymbol(const COFFSymbol &S) {
494 if (UseBigObj)
496 else
497 W.write<uint16_t>(static_cast<int16_t>(S.Data.SectionNumber));
499 W.OS << char(S.Data.StorageClass);
500 W.OS << char(S.Data.NumberOfAuxSymbols);
501 WriteAuxiliarySymbols(S.Aux);
502}
503
504void WinCOFFWriter::WriteAuxiliarySymbols(
506 for (const AuxSymbol &i : S) {
507 switch (i.AuxType) {
508 case ATWeakExternal:
510 W.write<uint32_t>(i.Aux.WeakExternal.Characteristics);
511 W.OS.write_zeros(sizeof(i.Aux.WeakExternal.unused));
512 if (UseBigObj)
514 break;
515 case ATFile:
516 W.OS.write(reinterpret_cast<const char *>(&i.Aux),
518 break;
519 case ATSectionDefinition:
520 W.write<uint32_t>(i.Aux.SectionDefinition.Length);
521 W.write<uint16_t>(i.Aux.SectionDefinition.NumberOfRelocations);
522 W.write<uint16_t>(i.Aux.SectionDefinition.NumberOfLinenumbers);
523 W.write<uint32_t>(i.Aux.SectionDefinition.CheckSum);
524 W.write<uint16_t>(static_cast<int16_t>(i.Aux.SectionDefinition.Number));
525 W.OS << char(i.Aux.SectionDefinition.Selection);
526 W.OS.write_zeros(sizeof(i.Aux.SectionDefinition.unused));
528 static_cast<int16_t>(i.Aux.SectionDefinition.Number >> 16));
529 if (UseBigObj)
531 break;
532 }
533 }
534}
535
536
537void WinCOFFWriter::writeSectionHeaders() {
538
539
540
541 std::vector<COFFSection *> Arr;
542 for (auto &Section : Sections)
543 Arr.push_back(Section.get());
544 llvm::sort(Arr, [](const COFFSection *A, const COFFSection *B) {
545 return A->Number < B->Number;
546 });
547
548 for (auto &Section : Arr) {
549 if (Section->Number == -1)
550 continue;
551
553 if (Section->Relocations.size() >= 0xffff)
565 }
566}
567
568void WinCOFFWriter::WriteRelocation(const COFF::relocation &R) {
572}
573
574
575
576
579
580
583 Asm.writeSectionData(VecOS, &MCSec);
584
585
586 W.OS << Buf;
587
588
589
590 JamCRC JC(0);
592 return JC.getCRC();
593}
594
595void WinCOFFWriter::writeSection(MCAssembler &Asm, const COFFSection &Sec) {
596 if (Sec.Number == -1)
597 return;
598
599
600 if (Sec.Header.PointerToRawData != 0) {
601 assert(W.OS.tell() == Sec.Header.PointerToRawData &&
602 "Section::PointerToRawData is insane!");
603
604 uint32_t CRC = writeSectionContents(Asm, *Sec.MCSection);
605
606
608 assert(AuxSyms.size() == 1 && AuxSyms[0].AuxType == ATSectionDefinition);
609 AuxSymbol &SecDef = AuxSyms[0];
610 SecDef.Aux.SectionDefinition.CheckSum = CRC;
611 }
612
613
614 if (Sec.Relocations.empty()) {
615 assert(Sec.Header.PointerToRelocations == 0 &&
616 "Section::PointerToRelocations is insane!");
617 return;
618 }
619
620 assert(W.OS.tell() == Sec.Header.PointerToRelocations &&
621 "Section::PointerToRelocations is insane!");
622
623 if (Sec.Relocations.size() >= 0xffff) {
624
625
627 R.VirtualAddress = Sec.Relocations.size() + 1;
628 R.SymbolTableIndex = 0;
629 R.Type = 0;
630 WriteRelocation(R);
631 }
632
633 for (const auto &Relocation : Sec.Relocations)
634 WriteRelocation(Relocation.Data);
635}
636
637
638void WinCOFFWriter::createFileSymbols(MCAssembler &Asm) {
639 for (const std::pair<std::string, size_t> &It : OWriter.getFileNames()) {
640
641 const std::string &Name = It.first;
643 unsigned Count = (Name.size() + SymbolSize - 1) / SymbolSize;
644
645 COFFSymbol *File = createSymbol(".file");
648 File->Aux.resize(Count);
649
652 for (auto &Aux : File->Aux) {
653 Aux.AuxType = ATFile;
654
655 if (Length > SymbolSize) {
656 memcpy(&Aux.Aux, Name.c_str() + Offset, SymbolSize);
658 } else {
660 memset((char *)&Aux.Aux + Length, 0, SymbolSize - Length);
661 break;
662 }
663
664 Offset += SymbolSize;
665 }
666 }
667}
668
669void WinCOFFWriter::setWeakDefaultNames() {
670 if (WeakDefaults.empty())
671 return;
672
673
674
675
676
677
678
679
680 COFFSymbol *Unique = nullptr;
681 for (bool AllowComdat : {false, true}) {
682 for (auto &Sym : Symbols) {
683
684 if (WeakDefaults.count(Sym.get()))
685 continue;
686
688 continue;
689
691 continue;
692 if (!AllowComdat && Sym->Section &&
694 continue;
695 Unique = Sym.get();
696 break;
697 }
698 if (Unique)
699 break;
700 }
701
702 if (!Unique)
703 return;
704 for (auto *Sym : WeakDefaults) {
705 Sym->Name.append(".");
706 Sym->Name.append(Unique->Name);
707 }
708}
709
711 return Section.Symbol->Aux[0].Aux.SectionDefinition.Selection ==
713}
714
715void WinCOFFWriter::assignSectionNumbers() {
716 size_t I = 1;
719 Section.Symbol->Data.SectionNumber = I;
720 Section.Symbol->Aux[0].Aux.SectionDefinition.Number = I;
721 ++I;
722 };
723
724
725
726
727 for (const std::unique_ptr &Section : Sections)
730 for (const std::unique_ptr &Section : Sections)
733}
734
735
736void WinCOFFWriter::assignFileOffsets(MCAssembler &Asm) {
738
741
742 for (const auto &Section : Asm) {
743 COFFSection *Sec = SectionMap[&Section];
744
745 if (!Sec || Sec->Number == -1)
746 continue;
747
748 Sec->Header.SizeOfRawData = Asm.getSectionAddressSize(Section);
749
750 if (IsPhysicalSection(Sec)) {
751 Sec->Header.PointerToRawData = Offset;
752 Offset += Sec->Header.SizeOfRawData;
753 }
754
755 if (!Sec->Relocations.empty()) {
756 bool RelocationsOverflow = Sec->Relocations.size() >= 0xffff;
757
758 if (RelocationsOverflow) {
759
760
761 Sec->Header.NumberOfRelocations = 0xffff;
762 } else {
763 Sec->Header.NumberOfRelocations = Sec->Relocations.size();
764 }
765 Sec->Header.PointerToRelocations = Offset;
766
767 if (RelocationsOverflow) {
768
770 }
771
773
774 for (auto &Relocation : Sec->Relocations) {
775 assert(Relocation.Symb->getIndex() != -1);
778 Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex();
779 }
780 }
781 }
782
783 assert(Sec->Symbol->Aux.size() == 1 &&
784 "Section's symbol must have one aux!");
785 AuxSymbol &Aux = Sec->Symbol->Aux[0];
786 assert(Aux.AuxType == ATSectionDefinition &&
787 "Section's symbol's aux symbol must be a Section Definition!");
788 Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData;
789 Aux.Aux.SectionDefinition.NumberOfRelocations =
790 Sec->Header.NumberOfRelocations;
791 Aux.Aux.SectionDefinition.NumberOfLinenumbers =
792 Sec->Header.NumberOfLineNumbers;
793 }
794
795 Header.PointerToSymbolTable = Offset;
796}
797
799 memset(&Header, 0, sizeof(Header));
800 Header.Machine = OWriter.TargetObjectWriter->getMachine();
801 Sections.clear();
802 Symbols.clear();
804 SectionMap.clear();
805 SymbolMap.clear();
806 WeakDefaults.clear();
807}
808
810
811
812 for (const auto &Section : Asm) {
815 continue;
816 defineSection(Asm, static_cast<const MCSectionCOFF &>(Section));
817 }
818
820 for (const MCSymbol &Symbol : Asm.symbols())
821
822 if (!Symbol.isTemporary() ||
824 defineSymbol(Asm, Symbol);
825
827 Header.NumberOfSections = Sections.size();
828 Header.NumberOfSymbols = 0;
829 if (Sections.size() > INT32_MAX)
831 "PE COFF object files can't have more than 2147483647 sections");
832
833 assignSectionNumbers();
834}
835
840 assert(Target.getSymA() && "Relocation must reference a symbol!");
841
843 if (.isRegistered()) {
844 Asm.getContext().reportError(Fixup.getLoc(), Twine("symbol '") +
845 A.getName() +
846 "' can not be undefined");
847 return;
848 }
849 if (A.isTemporary() && A.isUndefined()) {
850 Asm.getContext().reportError(Fixup.getLoc(), Twine("assembler label '") +
851 A.getName() +
852 "' can not be undefined");
853 return;
854 }
855
857
858
860 "Section must already have been defined in executePostLayoutBinding!");
861
862 COFFSection *Sec = SectionMap[MCSec];
864
865 if (SymB) {
867 if (->getFragment()) {
868 Asm.getContext().reportError(
870 Twine("symbol '") + B->getName() +
871 "' can not be undefined in a subtraction expression");
872 return;
873 }
874
875
876 int64_t OffsetOfB = Asm.getSymbolOffset(*B);
877
878
879 int64_t OffsetOfRelocation =
880 Asm.getFragmentOffset(*Fragment) + Fixup.getOffset();
881
882 FixedValue = (OffsetOfRelocation - OffsetOfB) + Target.getConstant();
883 } else {
884 FixedValue = Target.getConstant();
885 }
886
887 COFFRelocation Reloc;
888
889 Reloc.Data.SymbolTableIndex = 0;
890 Reloc.Data.VirtualAddress = Asm.getFragmentOffset(*Fragment);
891
892
893 if (A.isTemporary() && !SymbolMap[&A]) {
894 MCSection *TargetSection = &A.getSection();
896 SectionMap.contains(TargetSection) &&
897 "Section must already have been defined in executePostLayoutBinding!");
898 COFFSection *Section = SectionMap[TargetSection];
899 Reloc.Symb = Section->Symbol;
900 FixedValue += Asm.getSymbolOffset(A);
901
902
903
904
905 if (UseOffsetLabels && !Section->OffsetSymbols.empty()) {
906 uint64_t LabelIndex = FixedValue >> OffsetLabelIntervalBits;
907 if (LabelIndex > 0) {
908 if (LabelIndex <= Section->OffsetSymbols.size())
909 Reloc.Symb = Section->OffsetSymbols[LabelIndex - 1];
910 else
911 Reloc.Symb = Section->OffsetSymbols.back();
912 FixedValue -= Reloc.Symb->Data.Value;
913 }
914 }
915 } else {
918 "Symbol must already have been defined in executePostLayoutBinding!");
919 Reloc.Symb = SymbolMap[&A];
920 }
921
922 ++Reloc.Symb->Relocations;
923
924 Reloc.Data.VirtualAddress += Fixup.getOffset();
925 Reloc.Data.Type = OWriter.TargetObjectWriter->getRelocType(
926 Asm.getContext(), Target, Fixup, SymB, Asm.getBackend());
927
928
929
938 FixedValue += 4;
939
941 switch (Reloc.Data.Type) {
948 break;
951
952
953
957
958
959
960
961
963 break;
965 break;
969
970
971
972
973 FixedValue = FixedValue + 4;
974 break;
975 }
976 }
977
978
980 FixedValue = 0;
981
982 if (OWriter.TargetObjectWriter->recordRelocation(Fixup)) {
983 Sec->Relocations.push_back(Reloc);
987
988
989 auto RelocPair = Reloc;
991 Sec->Relocations.push_back(RelocPair);
992 }
993 }
994}
995
997 std::time_t Now = time(nullptr);
998 if (Now < 0 || !isUInt<32>(Now))
999 return UINT32_MAX;
1000 return Now;
1001}
1002
1005
1006 setWeakDefaultNames();
1008 createFileSymbols(Asm);
1009
1010 for (auto &Symbol : Symbols) {
1011
1012 if (Symbol->Section)
1013 Symbol->Data.SectionNumber = Symbol->Section->Number;
1014 Symbol->setIndex(Header.NumberOfSymbols++);
1015
1016 Symbol->Data.NumberOfAuxSymbols = Symbol->Aux.size();
1017 Header.NumberOfSymbols += Symbol->Data.NumberOfAuxSymbols;
1018 }
1019
1020
1021 for (const auto &S : Sections)
1024 for (const auto &S : Symbols)
1028
1029
1030 for (const auto &S : Sections)
1031 SetSectionName(*S);
1032 for (auto &S : Symbols)
1033 SetSymbolName(*S);
1034
1035
1036 for (auto &Symbol : Symbols) {
1037 if (Symbol->Other) {
1038 assert(Symbol->getIndex() != -1);
1039 assert(Symbol->Aux.size() == 1 && "Symbol must contain one aux symbol!");
1040 assert(Symbol->Aux[0].AuxType == ATWeakExternal &&
1041 "Symbol's aux symbol must be a Weak External!");
1042 Symbol->Aux[0].Aux.WeakExternal.TagIndex = Symbol->Other->getIndex();
1043 }
1044 }
1045
1046
1047 for (auto &Section : Sections) {
1048 if (Section->Symbol->Aux[0].Aux.SectionDefinition.Selection !=
1050 continue;
1051
1052 const MCSectionCOFF &MCSec = *Section->MCSection;
1055
1056
1057
1059 Asm.getContext().reportError(
1061 Twine(" associative with sectionless symbol ") +
1063 continue;
1064 }
1065
1066 const auto *AssocMCSec = cast(&AssocMCSym->getSection());
1068 COFFSection *AssocSec = SectionMap[AssocMCSec];
1069
1070
1071 if (AssocSec->Number == -1)
1072 continue;
1073
1074 Section->Symbol->Aux[0].Aux.SectionDefinition.Number = AssocSec->Number;
1075 }
1076
1077
1079 auto *Sec = Asm.getContext().getCOFFSection(
1081 auto *Frag = cast(Sec->curFragList()->Head);
1085 continue;
1088 continue;
1089 }
1090
1093 "Section must already have been defined in "
1094 "executePostLayoutBinding!");
1095 encodeULEB128(SectionMap[TargetSection]->Symbol->getIndex(), OS);
1096 }
1097 }
1098
1099
1101 auto *Sec = Asm.getContext().getCOFFSection(
1103 auto *Frag = cast(Sec->curFragList()->Head);
1105 for (const auto &CGPE : OWriter.getCGProfile()) {
1106 uint32_t FromIndex = CGPE.From->getSymbol().getIndex();
1107 uint32_t ToIndex = CGPE.To->getSymbol().getIndex();
1111 }
1112 }
1113
1114 assignFileOffsets(Asm);
1115
1116
1117
1118 if (OWriter.IncrementalLinkerCompatible) {
1119 Header.TimeDateStamp = getTime();
1120 } else {
1121
1122 Header.TimeDateStamp = 0;
1123 }
1124
1125
1126 WriteFileHeader(Header);
1127 writeSectionHeaders();
1128
1129#ifndef NDEBUG
1130 sections::iterator I = Sections.begin();
1131 sections::iterator IE = Sections.end();
1132 auto J = Asm.begin();
1133 auto JE = Asm.end();
1134 for (; I != IE && J != JE; ++I, ++J) {
1137 ++J;
1138 assert(J != JE && (**I).MCSection == &*J && "Wrong bound MCSection");
1139 }
1140#endif
1141
1142
1143 for (std::unique_ptr &Sec : Sections)
1144 writeSection(Asm, *Sec);
1145
1146 assert(W.OS.tell() == Header.PointerToSymbolTable &&
1147 "Header::PointerToSymbolTable is insane!");
1148
1149
1150 for (auto &Symbol : Symbols)
1151 if (Symbol->getIndex() != -1)
1152 WriteSymbol(*Symbol);
1153
1154
1156
1157 return W.OS.tell() - StartOffset;
1158}
1159
1161 return SectionMap.at(&Section)->Number;
1162}
1163
1164
1165
1166
1167
1168
1169
1171 IncrementalLinkerCompatible = false;
1172 ObjWriter->reset();
1173 if (DwoWriter)
1174 DwoWriter->reset();
1176}
1177
1180 bool InSet, bool IsPCRel) const {
1181
1182
1183
1184
1185
1186
1187 uint16_t Type = cast(SymA).getType();
1189 return false;
1191}
1192
1194 ObjWriter->executePostLayoutBinding(Asm);
1195 if (DwoWriter)
1196 DwoWriter->executePostLayoutBinding(Asm);
1197}
1198
1204 "No relocation in Dwo sections");
1205 ObjWriter->recordRelocation(Asm, Fragment, Fixup, Target, FixedValue);
1206}
1207
1209
1210
1211 if (Asm.getContext().hadError())
1212 return 0;
1213
1214 uint64_t TotalSize = ObjWriter->writeObject(Asm);
1215 if (DwoWriter)
1216 TotalSize += DwoWriter->writeObject(Asm);
1217 return TotalSize;
1218}
1219
1221 return ObjWriter->getSectionNumber(Section);
1222}
1223
1226
1227
1228void MCWinCOFFObjectTargetWriter::anchor() {}
1229
1230
1231
1232
1234 std::unique_ptr MOTW, raw_pwrite_stream &OS) {
1235 return std::make_unique(std::move(MOTW), OS);
1236}
1237
1239 std::unique_ptr MOTW, raw_pwrite_stream &OS,
1241 return std::make_unique(std::move(MOTW), OS, DwoOS);
1242}
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
COFFYAML::AuxSymbolType AuxType
COFF::MachineTypes Machine
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
std::optional< std::vector< StOtherPiece > > Other
std::pair< uint64_t, uint64_t > Interval
PowerPC TLS Dynamic Call Fixup
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallString class.
This file defines the SmallVector class.
static uint64_t getSymbolValue(const MCSymbol &Symbol, const MCAssembler &Asm)
static uint32_t getAlignment(const MCSectionCOFF &Sec)
static bool isAssociative(const COFFSection &Section)
static bool isDwoSection(const MCSection &Sec)
static std::time_t getTime()
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
const ValueT & at(const_arg_type_t< KeyT > Val) const
at - Return the entry for the specified key, or abort if no such entry exists.
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
MCSection * getParent() const
MutableArrayRef< std::pair< std::string, size_t > > getFileNames()
bool getEmitAddrsigSection()
virtual void reset()
lifetime management
SmallVector< CGProfileEntry, 0 > & getCGProfile()
std::vector< const MCSymbol * > AddrsigSyms
This represents a section on Windows.
MCSymbol * getCOMDATSymbol() const
unsigned getCharacteristics() const
Instances of this class represent a uniqued identifier for a section in the current translation unit.
StringRef getName() const
MCSymbol * getBeginSymbol()
uint16_t getClass() const
Represent a reference to a symbol from inside an expression.
const MCSymbol & getSymbol() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
bool isRegistered() const
void setIndex(uint32_t Value) const
Set the (implementation defined) index.
bool isUndefined(bool SetUsed=true) const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
uint32_t getIndex() const
Get the (implementation defined) index.
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
MCFragment * getFragment(bool SetUsed=true) const
This represents an "assembler immediate".
MCWinCOFFObjectTargetWriter(unsigned Machine_)
Represents a location in source code.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
Utility for building string tables with deduplicated suffixes.
size_t getOffset(CachedHashStringRef S) const
Get the offest of a string in the string table.
void write(raw_ostream &OS) const
size_t add(CachedHashStringRef S)
Add a string to the builder.
void finalize()
Analyze the strings and build the final table.
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
void reset() override
lifetime management
void recordRelocation(MCAssembler &Asm, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) override
Record a relocation entry.
int getSectionNumber(const MCSection &Section) const
WinCOFFObjectWriter(std::unique_ptr< MCWinCOFFObjectTargetWriter > MOTW, raw_pwrite_stream &OS)
bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB, bool InSet, bool IsPCRel) const override
void executePostLayoutBinding(MCAssembler &Asm) override
Perform any late binding of symbols (for example, to assign symbol indices for use when generating re...
uint64_t writeObject(MCAssembler &Asm) override
Write the object file and returns the number of bytes written.
uint64_t writeObject(MCAssembler &Asm)
WinCOFFWriter(WinCOFFObjectWriter &OWriter, raw_pwrite_stream &OS, DwoMode Mode)
enum llvm::WinCOFFWriter::DwoMode Mode
void recordRelocation(MCAssembler &Asm, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue)
int getSectionNumber(const MCSection &Section) const
void executePostLayoutBinding(MCAssembler &Asm)
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
uint64_t tell() const
tell - Return the current offset with the file.
raw_ostream & write(unsigned char C)
An abstract base class for streams implementations that also support a pwrite operation.
A raw_ostream that writes to an SmallVector or SmallString.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ IMAGE_REL_MIPS_SECRELHI
@ IMAGE_FILE_MACHINE_UNKNOWN
@ IMAGE_FILE_MACHINE_AMD64
@ IMAGE_FILE_MACHINE_R4000
@ IMAGE_FILE_MACHINE_I386
@ IMAGE_FILE_MACHINE_ARMNT
@ IMAGE_SCN_ALIGN_64BYTES
@ IMAGE_SCN_ALIGN_128BYTES
@ IMAGE_SCN_ALIGN_256BYTES
@ IMAGE_SCN_ALIGN_1024BYTES
@ IMAGE_SCN_ALIGN_512BYTES
@ IMAGE_SCN_CNT_UNINITIALIZED_DATA
@ IMAGE_SCN_ALIGN_4096BYTES
@ IMAGE_SCN_ALIGN_8192BYTES
@ IMAGE_SCN_LNK_NRELOC_OVFL
@ IMAGE_SCN_ALIGN_16BYTES
@ IMAGE_SCN_ALIGN_32BYTES
@ IMAGE_SCN_ALIGN_2048BYTES
bool isAnyArm64(T Machine)
@ IMAGE_SYM_CLASS_EXTERNAL
External symbol.
@ IMAGE_SYM_CLASS_LABEL
Label.
@ IMAGE_SYM_CLASS_FILE
File name.
@ IMAGE_SYM_CLASS_NULL
No symbol.
@ IMAGE_SYM_CLASS_WEAK_EXTERNAL
Duplicate tag.
@ IMAGE_SYM_CLASS_STATIC
Static.
bool encodeSectionName(char *Out, uint64_t Offset)
Encode section name based on string table offset.
@ IMAGE_COMDAT_SELECT_ASSOCIATIVE
@ IMAGE_REL_ARM_BRANCH20T
@ IMAGE_REL_ARM_BRANCH24T
const int32_t MaxNumberOfSections16
static const char BigObjMagic[]
@ IMAGE_SYM_DTYPE_FUNCTION
A function that returns a base type.
@ SCT_COMPLEX_TYPE_SHIFT
Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
void write32le(void *P, uint32_t V)
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
void sort(IteratorTy Start, IteratorTy End)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
std::unique_ptr< MCObjectWriter > createWinCOFFDwoObjectWriter(std::unique_ptr< MCWinCOFFObjectTargetWriter > MOTW, raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS)
@ FK_SecRel_2
A two-byte section relative fixup.
std::unique_ptr< MCObjectWriter > createWinCOFFObjectWriter(std::unique_ptr< MCWinCOFFObjectTargetWriter > MOTW, raw_pwrite_stream &OS)
Construct a new Win COFF writer instance.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
Implement std::hash so that hash_code can be used in STL containers.
uint64_t value() const
This is a hole in the type system and should not be abused.
uint32_t PointerToRelocations
uint16_t NumberOfLineNumbers
uint32_t PointerToRawData
uint16_t NumberOfRelocations
uint32_t PointerToLineNumbers
Adapter to write values to a stream in a particular byte order.
void write(ArrayRef< value_type > Val)