LLVM 19.0.0git
WinCOFFObjectWriter.cpp
Go to the documentation of this file.
1//===- llvm/MC/WinCOFFObjectWriter.cpp ------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains an implementation of a Win32 COFF object file writer.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/ADT/DenseMap.h"
14#include "llvm/ADT/DenseSet.h"
15#include "llvm/ADT/STLExtras.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/ADT/Twine.h"
21#include "llvm/MC/MCAsmLayout.h"
22#include "llvm/MC/MCAssembler.h"
23#include "llvm/MC/MCContext.h"
24#include "llvm/MC/MCExpr.h"
25#include "llvm/MC/MCFixup.h"
26#include "llvm/MC/MCFragment.h"
28#include "llvm/MC/MCSection.h"
30#include "llvm/MC/MCSymbol.h"
32#include "llvm/MC/MCValue.h"
35#include "llvm/Support/CRC.h"
39#include "llvm/Support/LEB128.h"
42#include <algorithm>
43#include <cassert>
44#include <cstdint>
45#include <cstring>
46#include <ctime>
47#include <memory>
48#include <string>
49#include <vector>
50
51using namespace llvm;
53
54#define DEBUG_TYPE "WinCOFFObjectWriter"
55
56namespace {
57
58constexpr int OffsetLabelIntervalBits = 20;
59
61
62enum AuxiliaryType { ATWeakExternal, ATFile, ATSectionDefinition };
63
64struct AuxSymbol {
65 AuxiliaryType AuxType;
67};
68
69class COFFSection;
70
71class COFFSymbol {
72public:
73 COFF::symbol Data = {};
74
75 using AuxiliarySymbols = SmallVector<AuxSymbol, 1>;
76
77 name Name;
78 int Index = 0;
79 AuxiliarySymbols Aux;
80 COFFSymbol *Other = nullptr;
81 COFFSection *Section = nullptr;
82 int Relocations = 0;
83 const MCSymbol *MC = nullptr;
84
85 COFFSymbol(StringRef Name) : Name(Name) {}
86
87 void set_name_offset(uint32_t Offset);
88
89 int64_t getIndex() const { return Index; }
90 void setIndex(int Value) {
91 Index = Value;
92 if (MC)
93 MC->setIndex(static_cast<uint32_t>(Value));
94 }
95};
96
97// This class contains staging data for a COFF relocation entry.
98struct COFFRelocation {
100 COFFSymbol *Symb = nullptr;
101
102 COFFRelocation() = default;
103
104 static size_t size() { return COFF::RelocationSize; }
105};
106
107using relocations = std::vector<COFFRelocation>;
108
109class COFFSection {
110public:
111 COFF::section Header = {};
112
113 std::string Name;
114 int Number = 0;
115 MCSectionCOFF const *MCSection = nullptr;
116 COFFSymbol *Symbol = nullptr;
117 relocations Relocations;
118
119 COFFSection(StringRef Name) : Name(std::string(Name)) {}
120
121 SmallVector<COFFSymbol *, 1> OffsetSymbols;
122};
123
124class WinCOFFObjectWriter;
125
126class WinCOFFWriter {
127 WinCOFFObjectWriter &OWriter;
129
130 using symbols = std::vector<std::unique_ptr<COFFSymbol>>;
131 using sections = std::vector<std::unique_ptr<COFFSection>>;
132
135
136 using symbol_list = DenseSet<COFFSymbol *>;
137
138 // Root level file contents.
139 COFF::header Header = {};
140 sections Sections;
141 symbols Symbols;
143
144 // Maps used during object file creation.
145 section_map SectionMap;
146 symbol_map SymbolMap;
147
148 symbol_list WeakDefaults;
149
150 bool UseBigObj;
151 bool UseOffsetLabels = false;
152
153public:
154 enum DwoMode {
155 AllSections,
156 NonDwoOnly,
157 DwoOnly,
158 } Mode;
159
160 WinCOFFWriter(WinCOFFObjectWriter &OWriter, raw_pwrite_stream &OS,
161 DwoMode Mode);
162
163 void reset();
164 void executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout);
165 void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
166 const MCFragment *Fragment, const MCFixup &Fixup,
167 MCValue Target, uint64_t &FixedValue);
168 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout);
169
170private:
171 COFFSymbol *createSymbol(StringRef Name);
172 COFFSymbol *GetOrCreateCOFFSymbol(const MCSymbol *Symbol);
173 COFFSection *createSection(StringRef Name);
174
175 void defineSection(MCSectionCOFF const &Sec, const MCAsmLayout &Layout);
176
177 COFFSymbol *getLinkedSymbol(const MCSymbol &Symbol);
178 void DefineSymbol(const MCSymbol &Symbol, MCAssembler &Assembler,
179 const MCAsmLayout &Layout);
180
181 void SetSymbolName(COFFSymbol &S);
182 void SetSectionName(COFFSection &S);
183
184 bool IsPhysicalSection(COFFSection *S);
185
186 // Entity writing methods.
187 void WriteFileHeader(const COFF::header &Header);
188 void WriteSymbol(const COFFSymbol &S);
189 void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols &S);
190 void writeSectionHeaders();
191 void WriteRelocation(const COFF::relocation &R);
192 uint32_t writeSectionContents(MCAssembler &Asm, const MCAsmLayout &Layout,
193 const MCSection &MCSec);
194 void writeSection(MCAssembler &Asm, const MCAsmLayout &Layout,
195 const COFFSection &Sec);
196
197 void createFileSymbols(MCAssembler &Asm);
198 void setWeakDefaultNames();
199 void assignSectionNumbers();
200 void assignFileOffsets(MCAssembler &Asm, const MCAsmLayout &Layout);
201};
202
203class WinCOFFObjectWriter : public MCObjectWriter {
204 friend class WinCOFFWriter;
205
206 std::unique_ptr<MCWinCOFFObjectTargetWriter> TargetObjectWriter;
207 std::unique_ptr<WinCOFFWriter> ObjWriter, DwoWriter;
208
209public:
210 WinCOFFObjectWriter(std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW,
212 : TargetObjectWriter(std::move(MOTW)),
213 ObjWriter(std::make_unique<WinCOFFWriter>(*this, OS,
214 WinCOFFWriter::AllSections)) {
215 }
216 WinCOFFObjectWriter(std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW,
218 : TargetObjectWriter(std::move(MOTW)),
219 ObjWriter(std::make_unique<WinCOFFWriter>(*this, OS,
220 WinCOFFWriter::NonDwoOnly)),
221 DwoWriter(std::make_unique<WinCOFFWriter>(*this, DwoOS,
222 WinCOFFWriter::DwoOnly)) {}
223
224 // MCObjectWriter interface implementation.
225 void reset() override;
227 const MCAsmLayout &Layout) override;
229 const MCSymbol &SymA,
230 const MCFragment &FB, bool InSet,
231 bool IsPCRel) const override;
232 void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
233 const MCFragment *Fragment, const MCFixup &Fixup,
234 MCValue Target, uint64_t &FixedValue) override;
235 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
236};
237
238} // end anonymous namespace
239
240static bool isDwoSection(const MCSection &Sec) {
241 return Sec.getName().ends_with(".dwo");
242}
243
244//------------------------------------------------------------------------------
245// Symbol class implementation
246
247// In the case that the name does not fit within 8 bytes, the offset
248// into the string table is stored in the last 4 bytes instead, leaving
249// the first 4 bytes as 0.
250void COFFSymbol::set_name_offset(uint32_t Offset) {
251 write32le(Data.Name + 0, 0);
252 write32le(Data.Name + 4, Offset);
253}
254
255//------------------------------------------------------------------------------
256// WinCOFFWriter class implementation
257
258WinCOFFWriter::WinCOFFWriter(WinCOFFObjectWriter &OWriter,
259 raw_pwrite_stream &OS, DwoMode Mode)
260 : OWriter(OWriter), W(OS, llvm::endianness::little), Mode(Mode) {
261 Header.Machine = OWriter.TargetObjectWriter->getMachine();
262 // Some relocations on ARM64 (the 21 bit ADRP relocations) have a slightly
263 // limited range for the immediate offset (+/- 1 MB); create extra offset
264 // label symbols with regular intervals to allow referencing a
265 // non-temporary symbol that is close enough.
266 UseOffsetLabels = COFF::isAnyArm64(Header.Machine);
267}
268
269COFFSymbol *WinCOFFWriter::createSymbol(StringRef Name) {
270 Symbols.push_back(std::make_unique<COFFSymbol>(Name));
271 return Symbols.back().get();
272}
273
274COFFSymbol *WinCOFFWriter::GetOrCreateCOFFSymbol(const MCSymbol *Symbol) {
275 COFFSymbol *&Ret = SymbolMap[Symbol];
276 if (!Ret)
277 Ret = createSymbol(Symbol->getName());
278 return Ret;
279}
280
281COFFSection *WinCOFFWriter::createSection(StringRef Name) {
282 Sections.emplace_back(std::make_unique<COFFSection>(Name));
283 return Sections.back().get();
284}
285
287 switch (Sec.getAlign().value()) {
288 case 1:
290 case 2:
292 case 4:
294 case 8:
296 case 16:
298 case 32:
300 case 64:
302 case 128:
304 case 256:
306 case 512:
308 case 1024:
310 case 2048:
312 case 4096:
314 case 8192:
316 }
317 llvm_unreachable("unsupported section alignment");
318}
319
320/// This function takes a section data object from the assembler
321/// and creates the associated COFF section staging object.
322void WinCOFFWriter::defineSection(const MCSectionCOFF &MCSec,
323 const MCAsmLayout &Layout) {
324 COFFSection *Section = createSection(MCSec.getName());
325 COFFSymbol *Symbol = createSymbol(MCSec.getName());
326 Section->Symbol = Symbol;
328 Symbol->Section = Section;
329 Symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_STATIC;
330
331 // Create a COMDAT symbol if needed.
333 if (const MCSymbol *S = MCSec.getCOMDATSymbol()) {
334 COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(S);
335 if (COMDATSymbol->Section)
336 report_fatal_error("two sections have the same comdat");
337 COMDATSymbol->Section = Section;
338 }
339 }
340
341 // In this case the auxiliary symbol is a Section Definition.
342 Symbol->Aux.resize(1);
343 Symbol->Aux[0] = {};
344 Symbol->Aux[0].AuxType = ATSectionDefinition;
345 Symbol->Aux[0].Aux.SectionDefinition.Selection = MCSec.getSelection();
346
347 // Set section alignment.
348 Section->Header.Characteristics = MCSec.getCharacteristics();
349 Section->Header.Characteristics |= getAlignment(MCSec);
350
351 // Bind internal COFF section to MC section.
352 Section->MCSection = &MCSec;
353 SectionMap[&MCSec] = Section;
354
355 if (UseOffsetLabels && !MCSec.empty()) {
356 const uint32_t Interval = 1 << OffsetLabelIntervalBits;
357 uint32_t N = 1;
358 for (uint32_t Off = Interval, E = Layout.getSectionAddressSize(&MCSec);
359 Off < E; Off += Interval) {
360 auto Name = ("$L" + MCSec.getName() + "_" + Twine(N++)).str();
361 COFFSymbol *Label = createSymbol(Name);
362 Label->Section = Section;
363 Label->Data.StorageClass = COFF::IMAGE_SYM_CLASS_LABEL;
364 Label->Data.Value = Off;
365 Section->OffsetSymbols.push_back(Label);
366 }
367 }
368}
369
370static uint64_t getSymbolValue(const MCSymbol &Symbol,
371 const MCAsmLayout &Layout) {
372 if (Symbol.isCommon() && Symbol.isExternal())
373 return Symbol.getCommonSize();
374
375 uint64_t Res;
376 if (!Layout.getSymbolOffset(Symbol, Res))
377 return 0;
378
379 return Res;
380}
381
382COFFSymbol *WinCOFFWriter::getLinkedSymbol(const MCSymbol &Symbol) {
383 if (!Symbol.isVariable())
384 return nullptr;
385
386 const MCSymbolRefExpr *SymRef =
387 dyn_cast<MCSymbolRefExpr>(Symbol.getVariableValue());
388 if (!SymRef)
389 return nullptr;
390
391 const MCSymbol &Aliasee = SymRef->getSymbol();
392 if (Aliasee.isUndefined() || Aliasee.isExternal())
393 return GetOrCreateCOFFSymbol(&Aliasee);
394 else
395 return nullptr;
396}
397
398/// This function takes a symbol data object from the assembler
399/// and creates the associated COFF symbol staging object.
400void WinCOFFWriter::DefineSymbol(const MCSymbol &MCSym, MCAssembler &Assembler,
401 const MCAsmLayout &Layout) {
402 const MCSymbol *Base = Layout.getBaseSymbol(MCSym);
403 COFFSection *Sec = nullptr;
404 MCSectionCOFF *MCSec = nullptr;
405 if (Base && Base->getFragment()) {
406 MCSec = cast<MCSectionCOFF>(Base->getFragment()->getParent());
407 Sec = SectionMap[MCSec];
408 }
409
410 if (Mode == NonDwoOnly && MCSec && isDwoSection(*MCSec))
411 return;
412
413 COFFSymbol *Sym = GetOrCreateCOFFSymbol(&MCSym);
414 COFFSymbol *Local = nullptr;
415 if (cast<MCSymbolCOFF>(MCSym).getWeakExternalCharacteristics()) {
416 Sym->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
417 Sym->Section = nullptr;
418
419 COFFSymbol *WeakDefault = getLinkedSymbol(MCSym);
420 if (!WeakDefault) {
421 std::string WeakName = (".weak." + MCSym.getName() + ".default").str();
422 WeakDefault = createSymbol(WeakName);
423 if (!Sec)
424 WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
425 else
426 WeakDefault->Section = Sec;
427 WeakDefaults.insert(WeakDefault);
428 Local = WeakDefault;
429 }
430
431 Sym->Other = WeakDefault;
432
433 // Setup the Weak External auxiliary symbol.
434 Sym->Aux.resize(1);
435 memset(&Sym->Aux[0], 0, sizeof(Sym->Aux[0]));
436 Sym->Aux[0].AuxType = ATWeakExternal;
437 Sym->Aux[0].Aux.WeakExternal.TagIndex = 0; // Filled in later
438 Sym->Aux[0].Aux.WeakExternal.Characteristics =
439 cast<MCSymbolCOFF>(MCSym).getWeakExternalCharacteristics();
440 } else {
441 if (!Base)
442 Sym->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
443 else
444 Sym->Section = Sec;
445 Local = Sym;
446 }
447
448 if (Local) {
449 Local->Data.Value = getSymbolValue(MCSym, Layout);
450
451 const MCSymbolCOFF &SymbolCOFF = cast<MCSymbolCOFF>(MCSym);
452 Local->Data.Type = SymbolCOFF.getType();
453 Local->Data.StorageClass = SymbolCOFF.getClass();
454
455 // If no storage class was specified in the streamer, define it here.
456 if (Local->Data.StorageClass == COFF::IMAGE_SYM_CLASS_NULL) {
457 bool IsExternal =
458 MCSym.isExternal() || (!MCSym.getFragment() && !MCSym.isVariable());
459
460 Local->Data.StorageClass = IsExternal ? COFF::IMAGE_SYM_CLASS_EXTERNAL
462 }
463 }
464
465 Sym->MC = &MCSym;
466}
467
468void WinCOFFWriter::SetSectionName(COFFSection &S) {
469 if (S.Name.size() <= COFF::NameSize) {
470 std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size());
471 return;
472 }
473
474 uint64_t StringTableEntry = Strings.getOffset(S.Name);
475 if (!COFF::encodeSectionName(S.Header.Name, StringTableEntry))
476 report_fatal_error("COFF string table is greater than 64 GB.");
477}
478
479void WinCOFFWriter::SetSymbolName(COFFSymbol &S) {
480 if (S.Name.size() > COFF::NameSize)
481 S.set_name_offset(Strings.getOffset(S.Name));
482 else
483 std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size());
484}
485
486bool WinCOFFWriter::IsPhysicalSection(COFFSection *S) {
487 return (S->Header.Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) ==
488 0;
489}
490
491//------------------------------------------------------------------------------
492// entity writing methods
493
494void WinCOFFWriter::WriteFileHeader(const COFF::header &Header) {
495 if (UseBigObj) {
497 W.write<uint16_t>(0xFFFF);
499 W.write<uint16_t>(Header.Machine);
500 W.write<uint32_t>(Header.TimeDateStamp);
501 W.OS.write(COFF::BigObjMagic, sizeof(COFF::BigObjMagic));
502 W.write<uint32_t>(0);
503 W.write<uint32_t>(0);
504 W.write<uint32_t>(0);
505 W.write<uint32_t>(0);
506 W.write<uint32_t>(Header.NumberOfSections);
507 W.write<uint32_t>(Header.PointerToSymbolTable);
508 W.write<uint32_t>(Header.NumberOfSymbols);
509 } else {
510 W.write<uint16_t>(Header.Machine);
511 W.write<uint16_t>(static_cast<int16_t>(Header.NumberOfSections));
512 W.write<uint32_t>(Header.TimeDateStamp);
513 W.write<uint32_t>(Header.PointerToSymbolTable);
514 W.write<uint32_t>(Header.NumberOfSymbols);
515 W.write<uint16_t>(Header.SizeOfOptionalHeader);
516 W.write<uint16_t>(Header.Characteristics);
517 }
518}
519
520void WinCOFFWriter::WriteSymbol(const COFFSymbol &S) {
521 W.OS.write(S.Data.Name, COFF::NameSize);
522 W.write<uint32_t>(S.Data.Value);
523 if (UseBigObj)
524 W.write<uint32_t>(S.Data.SectionNumber);
525 else
526 W.write<uint16_t>(static_cast<int16_t>(S.Data.SectionNumber));
527 W.write<uint16_t>(S.Data.Type);
528 W.OS << char(S.Data.StorageClass);
529 W.OS << char(S.Data.NumberOfAuxSymbols);
530 WriteAuxiliarySymbols(S.Aux);
531}
532
533void WinCOFFWriter::WriteAuxiliarySymbols(
535 for (const AuxSymbol &i : S) {
536 switch (i.AuxType) {
537 case ATWeakExternal:
538 W.write<uint32_t>(i.Aux.WeakExternal.TagIndex);
539 W.write<uint32_t>(i.Aux.WeakExternal.Characteristics);
540 W.OS.write_zeros(sizeof(i.Aux.WeakExternal.unused));
541 if (UseBigObj)
542 W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size);
543 break;
544 case ATFile:
545 W.OS.write(reinterpret_cast<const char *>(&i.Aux),
547 break;
548 case ATSectionDefinition:
549 W.write<uint32_t>(i.Aux.SectionDefinition.Length);
550 W.write<uint16_t>(i.Aux.SectionDefinition.NumberOfRelocations);
551 W.write<uint16_t>(i.Aux.SectionDefinition.NumberOfLinenumbers);
552 W.write<uint32_t>(i.Aux.SectionDefinition.CheckSum);
553 W.write<uint16_t>(static_cast<int16_t>(i.Aux.SectionDefinition.Number));
554 W.OS << char(i.Aux.SectionDefinition.Selection);
555 W.OS.write_zeros(sizeof(i.Aux.SectionDefinition.unused));
556 W.write<uint16_t>(
557 static_cast<int16_t>(i.Aux.SectionDefinition.Number >> 16));
558 if (UseBigObj)
559 W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size);
560 break;
561 }
562 }
563}
564
565// Write the section header.
566void WinCOFFWriter::writeSectionHeaders() {
567 // Section numbers must be monotonically increasing in the section
568 // header, but our Sections array is not sorted by section number,
569 // so make a copy of Sections and sort it.
570 std::vector<COFFSection *> Arr;
571 for (auto &Section : Sections)
572 Arr.push_back(Section.get());
573 llvm::sort(Arr, [](const COFFSection *A, const COFFSection *B) {
574 return A->Number < B->Number;
575 });
576
577 for (auto &Section : Arr) {
578 if (Section->Number == -1)
579 continue;
580
581 COFF::section &S = Section->Header;
582 if (Section->Relocations.size() >= 0xffff)
584 W.OS.write(S.Name, COFF::NameSize);
585 W.write<uint32_t>(S.VirtualSize);
586 W.write<uint32_t>(S.VirtualAddress);
587 W.write<uint32_t>(S.SizeOfRawData);
588 W.write<uint32_t>(S.PointerToRawData);
593 W.write<uint32_t>(S.Characteristics);
594 }
595}
596
597void WinCOFFWriter::WriteRelocation(const COFF::relocation &R) {
598 W.write<uint32_t>(R.VirtualAddress);
599 W.write<uint32_t>(R.SymbolTableIndex);
600 W.write<uint16_t>(R.Type);
601}
602
603// Write MCSec's contents. What this function does is essentially
604// "Asm.writeSectionData(&MCSec, Layout)", but it's a bit complicated
605// because it needs to compute a CRC.
606uint32_t WinCOFFWriter::writeSectionContents(MCAssembler &Asm,
607 const MCAsmLayout &Layout,
608 const MCSection &MCSec) {
609 // Save the contents of the section to a temporary buffer, we need this
610 // to CRC the data before we dump it into the object file.
612 raw_svector_ostream VecOS(Buf);
613 Asm.writeSectionData(VecOS, &MCSec, Layout);
614
615 // Write the section contents to the object file.
616 W.OS << Buf;
617
618 // Calculate our CRC with an initial value of '0', this is not how
619 // JamCRC is specified but it aligns with the expected output.
620 JamCRC JC(/*Init=*/0);
621 JC.update(ArrayRef(reinterpret_cast<uint8_t *>(Buf.data()), Buf.size()));
622 return JC.getCRC();
623}
624
625void WinCOFFWriter::writeSection(MCAssembler &Asm, const MCAsmLayout &Layout,
626 const COFFSection &Sec) {
627 if (Sec.Number == -1)
628 return;
629
630 // Write the section contents.
631 if (Sec.Header.PointerToRawData != 0) {
632 assert(W.OS.tell() == Sec.Header.PointerToRawData &&
633 "Section::PointerToRawData is insane!");
634
635 uint32_t CRC = writeSectionContents(Asm, Layout, *Sec.MCSection);
636
637 // Update the section definition auxiliary symbol to record the CRC.
638 COFFSymbol::AuxiliarySymbols &AuxSyms = Sec.Symbol->Aux;
639 assert(AuxSyms.size() == 1 && AuxSyms[0].AuxType == ATSectionDefinition);
640 AuxSymbol &SecDef = AuxSyms[0];
641 SecDef.Aux.SectionDefinition.CheckSum = CRC;
642 }
643
644 // Write relocations for this section.
645 if (Sec.Relocations.empty()) {
646 assert(Sec.Header.PointerToRelocations == 0 &&
647 "Section::PointerToRelocations is insane!");
648 return;
649 }
650
651 assert(W.OS.tell() == Sec.Header.PointerToRelocations &&
652 "Section::PointerToRelocations is insane!");
653
654 if (Sec.Relocations.size() >= 0xffff) {
655 // In case of overflow, write actual relocation count as first
656 // relocation. Including the synthetic reloc itself (+ 1).
658 R.VirtualAddress = Sec.Relocations.size() + 1;
659 R.SymbolTableIndex = 0;
660 R.Type = 0;
661 WriteRelocation(R);
662 }
663
664 for (const auto &Relocation : Sec.Relocations)
665 WriteRelocation(Relocation.Data);
666}
667
668// Create .file symbols.
669void WinCOFFWriter::createFileSymbols(MCAssembler &Asm) {
670 for (const std::pair<std::string, size_t> &It : Asm.getFileNames()) {
671 // round up to calculate the number of auxiliary symbols required
672 const std::string &Name = It.first;
673 unsigned SymbolSize = UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size;
674 unsigned Count = (Name.size() + SymbolSize - 1) / SymbolSize;
675
676 COFFSymbol *File = createSymbol(".file");
677 File->Data.SectionNumber = COFF::IMAGE_SYM_DEBUG;
678 File->Data.StorageClass = COFF::IMAGE_SYM_CLASS_FILE;
679 File->Aux.resize(Count);
680
681 unsigned Offset = 0;
682 unsigned Length = Name.size();
683 for (auto &Aux : File->Aux) {
684 Aux.AuxType = ATFile;
685
686 if (Length > SymbolSize) {
687 memcpy(&Aux.Aux, Name.c_str() + Offset, SymbolSize);
688 Length = Length - SymbolSize;
689 } else {
690 memcpy(&Aux.Aux, Name.c_str() + Offset, Length);
691 memset((char *)&Aux.Aux + Length, 0, SymbolSize - Length);
692 break;
693 }
694
695 Offset += SymbolSize;
696 }
697 }
698}
699
700void WinCOFFWriter::setWeakDefaultNames() {
701 if (WeakDefaults.empty())
702 return;
703
704 // If multiple object files use a weak symbol (either with a regular
705 // defined default, or an absolute zero symbol as default), the defaults
706 // cause duplicate definitions unless their names are made unique. Look
707 // for a defined extern symbol, that isn't comdat - that should be unique
708 // unless there are other duplicate definitions. And if none is found,
709 // allow picking a comdat symbol, as that's still better than nothing.
710
711 COFFSymbol *Unique = nullptr;
712 for (bool AllowComdat : {false, true}) {
713 for (auto &Sym : Symbols) {
714 // Don't include the names of the defaults themselves
715 if (WeakDefaults.count(Sym.get()))
716 continue;
717 // Only consider external symbols
718 if (Sym->Data.StorageClass != COFF::IMAGE_SYM_CLASS_EXTERNAL)
719 continue;
720 // Only consider symbols defined in a section or that are absolute
721 if (!Sym->Section && Sym->Data.SectionNumber != COFF::IMAGE_SYM_ABSOLUTE)
722 continue;
723 if (!AllowComdat && Sym->Section &&
724 Sym->Section->Header.Characteristics & COFF::IMAGE_SCN_LNK_COMDAT)
725 continue;
726 Unique = Sym.get();
727 break;
728 }
729 if (Unique)
730 break;
731 }
732 // If we didn't find any unique symbol to use for the names, just skip this.
733 if (!Unique)
734 return;
735 for (auto *Sym : WeakDefaults) {
736 Sym->Name.append(".");
737 Sym->Name.append(Unique->Name);
738 }
739}
740
741static bool isAssociative(const COFFSection &Section) {
742 return Section.Symbol->Aux[0].Aux.SectionDefinition.Selection ==
744}
745
746void WinCOFFWriter::assignSectionNumbers() {
747 size_t I = 1;
748 auto Assign = [&](COFFSection &Section) {
749 Section.Number = I;
750 Section.Symbol->Data.SectionNumber = I;
751 Section.Symbol->Aux[0].Aux.SectionDefinition.Number = I;
752 ++I;
753 };
754
755 // Although it is not explicitly requested by the Microsoft COFF spec,
756 // we should avoid emitting forward associative section references,
757 // because MSVC link.exe as of 2017 cannot handle that.
758 for (const std::unique_ptr<COFFSection> &Section : Sections)
759 if (!isAssociative(*Section))
760 Assign(*Section);
761 for (const std::unique_ptr<COFFSection> &Section : Sections)
762 if (isAssociative(*Section))
763 Assign(*Section);
764}
765
766// Assign file offsets to COFF object file structures.
767void WinCOFFWriter::assignFileOffsets(MCAssembler &Asm,
768 const MCAsmLayout &Layout) {
769 unsigned Offset = W.OS.tell();
770
772 Offset += COFF::SectionSize * Header.NumberOfSections;
773
774 for (const auto &Section : Asm) {
775 COFFSection *Sec = SectionMap[&Section];
776
777 if (!Sec || Sec->Number == -1)
778 continue;
779
780 Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(&Section);
781
782 if (IsPhysicalSection(Sec)) {
783 Sec->Header.PointerToRawData = Offset;
784 Offset += Sec->Header.SizeOfRawData;
785 }
786
787 if (!Sec->Relocations.empty()) {
788 bool RelocationsOverflow = Sec->Relocations.size() >= 0xffff;
789
790 if (RelocationsOverflow) {
791 // Signal overflow by setting NumberOfRelocations to max value. Actual
792 // size is found in reloc #0. Microsoft tools understand this.
793 Sec->Header.NumberOfRelocations = 0xffff;
794 } else {
795 Sec->Header.NumberOfRelocations = Sec->Relocations.size();
796 }
797 Sec->Header.PointerToRelocations = Offset;
798
799 if (RelocationsOverflow) {
800 // Reloc #0 will contain actual count, so make room for it.
802 }
803
804 Offset += COFF::RelocationSize * Sec->Relocations.size();
805
806 for (auto &Relocation : Sec->Relocations) {
807 assert(Relocation.Symb->getIndex() != -1);
808 Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex();
809 }
810 }
811
812 assert(Sec->Symbol->Aux.size() == 1 &&
813 "Section's symbol must have one aux!");
814 AuxSymbol &Aux = Sec->Symbol->Aux[0];
815 assert(Aux.AuxType == ATSectionDefinition &&
816 "Section's symbol's aux symbol must be a Section Definition!");
817 Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData;
818 Aux.Aux.SectionDefinition.NumberOfRelocations =
819 Sec->Header.NumberOfRelocations;
820 Aux.Aux.SectionDefinition.NumberOfLinenumbers =
821 Sec->Header.NumberOfLineNumbers;
822 }
823
824 Header.PointerToSymbolTable = Offset;
825}
826
827void WinCOFFWriter::reset() {
828 memset(&Header, 0, sizeof(Header));
829 Header.Machine = OWriter.TargetObjectWriter->getMachine();
830 Sections.clear();
831 Symbols.clear();
832 Strings.clear();
833 SectionMap.clear();
835 WeakDefaults.clear();
836}
837
838void WinCOFFWriter::executePostLayoutBinding(MCAssembler &Asm,
839 const MCAsmLayout &Layout) {
840 // "Define" each section & symbol. This creates section & symbol
841 // entries in the staging area.
842 for (const auto &Section : Asm) {
843 if ((Mode == NonDwoOnly && isDwoSection(Section)) ||
844 (Mode == DwoOnly && !isDwoSection(Section)))
845 continue;
846 defineSection(static_cast<const MCSectionCOFF &>(Section), Layout);
847 }
848
849 if (Mode != DwoOnly)
850 for (const MCSymbol &Symbol : Asm.symbols())
851 // Define non-temporary or temporary static (private-linkage) symbols
852 if (!Symbol.isTemporary() ||
853 cast<MCSymbolCOFF>(Symbol).getClass() == COFF::IMAGE_SYM_CLASS_STATIC)
854 DefineSymbol(Symbol, Asm, Layout);
855}
856
857void WinCOFFWriter::recordRelocation(MCAssembler &Asm,
858 const MCAsmLayout &Layout,
859 const MCFragment *Fragment,
860 const MCFixup &Fixup, MCValue Target,
861 uint64_t &FixedValue) {
862 assert(Target.getSymA() && "Relocation must reference a symbol!");
863
864 const MCSymbol &A = Target.getSymA()->getSymbol();
865 if (!A.isRegistered()) {
866 Asm.getContext().reportError(Fixup.getLoc(), Twine("symbol '") +
867 A.getName() +
868 "' can not be undefined");
869 return;
870 }
871 if (A.isTemporary() && A.isUndefined()) {
872 Asm.getContext().reportError(Fixup.getLoc(), Twine("assembler label '") +
873 A.getName() +
874 "' can not be undefined");
875 return;
876 }
877
878 MCSection *MCSec = Fragment->getParent();
879
880 // Mark this symbol as requiring an entry in the symbol table.
881 assert(SectionMap.contains(MCSec) &&
882 "Section must already have been defined in executePostLayoutBinding!");
883
884 COFFSection *Sec = SectionMap[MCSec];
885 const MCSymbolRefExpr *SymB = Target.getSymB();
886
887 if (SymB) {
888 const MCSymbol *B = &SymB->getSymbol();
889 if (!B->getFragment()) {
890 Asm.getContext().reportError(
891 Fixup.getLoc(),
892 Twine("symbol '") + B->getName() +
893 "' can not be undefined in a subtraction expression");
894 return;
895 }
896
897 // Offset of the symbol in the section
898 int64_t OffsetOfB = Layout.getSymbolOffset(*B);
899
900 // Offset of the relocation in the section
901 int64_t OffsetOfRelocation =
902 Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
903
904 FixedValue = (OffsetOfRelocation - OffsetOfB) + Target.getConstant();
905 } else {
906 FixedValue = Target.getConstant();
907 }
908
909 COFFRelocation Reloc;
910
911 Reloc.Data.SymbolTableIndex = 0;
912 Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment);
913
914 // Turn relocations for temporary symbols into section relocations.
915 if (A.isTemporary() && !SymbolMap[&A]) {
916 MCSection *TargetSection = &A.getSection();
917 assert(
918 SectionMap.contains(TargetSection) &&
919 "Section must already have been defined in executePostLayoutBinding!");
920 COFFSection *Section = SectionMap[TargetSection];
921 Reloc.Symb = Section->Symbol;
922 FixedValue += Layout.getSymbolOffset(A);
923 // Technically, we should do the final adjustments of FixedValue (below)
924 // before picking an offset symbol, otherwise we might choose one which
925 // is slightly too far away. The relocations where it really matters
926 // (arm64 adrp relocations) don't get any offset though.
927 if (UseOffsetLabels && !Section->OffsetSymbols.empty()) {
928 uint64_t LabelIndex = FixedValue >> OffsetLabelIntervalBits;
929 if (LabelIndex > 0) {
930 if (LabelIndex <= Section->OffsetSymbols.size())
931 Reloc.Symb = Section->OffsetSymbols[LabelIndex - 1];
932 else
933 Reloc.Symb = Section->OffsetSymbols.back();
934 FixedValue -= Reloc.Symb->Data.Value;
935 }
936 }
937 } else {
938 assert(
939 SymbolMap.contains(&A) &&
940 "Symbol must already have been defined in executePostLayoutBinding!");
941 Reloc.Symb = SymbolMap[&A];
942 }
943
944 ++Reloc.Symb->Relocations;
945
946 Reloc.Data.VirtualAddress += Fixup.getOffset();
947 Reloc.Data.Type = OWriter.TargetObjectWriter->getRelocType(
948 Asm.getContext(), Target, Fixup, SymB, Asm.getBackend());
949
950 // The *_REL32 relocations are relative to the end of the relocation,
951 // not to the start.
952 if ((Header.Machine == COFF::IMAGE_FILE_MACHINE_AMD64 &&
953 Reloc.Data.Type == COFF::IMAGE_REL_AMD64_REL32) ||
954 (Header.Machine == COFF::IMAGE_FILE_MACHINE_I386 &&
955 Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32) ||
956 (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT &&
957 Reloc.Data.Type == COFF::IMAGE_REL_ARM_REL32) ||
958 (COFF::isAnyArm64(Header.Machine) &&
959 Reloc.Data.Type == COFF::IMAGE_REL_ARM64_REL32))
960 FixedValue += 4;
961
962 if (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT) {
963 switch (Reloc.Data.Type) {
970 break;
973 // IMAGE_REL_ARM_BRANCH11 and IMAGE_REL_ARM_BLX11 are only used for
974 // pre-ARMv7, which implicitly rules it out of ARMNT (it would be valid
975 // for Windows CE).
979 // IMAGE_REL_ARM_BRANCH24, IMAGE_REL_ARM_BLX24, IMAGE_REL_ARM_MOV32A are
980 // only used for ARM mode code, which is documented as being unsupported
981 // by Windows on ARM. Empirical proof indicates that masm is able to
982 // generate the relocations however the rest of the MSVC toolchain is
983 // unable to handle it.
984 llvm_unreachable("unsupported relocation");
985 break;
987 break;
991 // IMAGE_REL_BRANCH20T, IMAGE_REL_ARM_BRANCH24T, IMAGE_REL_ARM_BLX23T all
992 // perform a 4 byte adjustment to the relocation. Relative branches are
993 // offset by 4 on ARM, however, because there is no RELA relocations, all
994 // branches are offset by 4.
995 FixedValue = FixedValue + 4;
996 break;
997 }
998 }
999
1000 // The fixed value never makes sense for section indices, ignore it.
1001 if (Fixup.getKind() == FK_SecRel_2)
1002 FixedValue = 0;
1003
1004 if (OWriter.TargetObjectWriter->recordRelocation(Fixup))
1005 Sec->Relocations.push_back(Reloc);
1006}
1007
1008static std::time_t getTime() {
1009 std::time_t Now = time(nullptr);
1010 if (Now < 0 || !isUInt<32>(Now))
1011 return UINT32_MAX;
1012 return Now;
1013}
1014
1015uint64_t WinCOFFWriter::writeObject(MCAssembler &Asm,
1016 const MCAsmLayout &Layout) {
1017 uint64_t StartOffset = W.OS.tell();
1018
1019 if (Sections.size() > INT32_MAX)
1021 "PE COFF object files can't have more than 2147483647 sections");
1022
1023 UseBigObj = Sections.size() > COFF::MaxNumberOfSections16;
1024 Header.NumberOfSections = Sections.size();
1025 Header.NumberOfSymbols = 0;
1026
1027 setWeakDefaultNames();
1028 assignSectionNumbers();
1029 if (Mode != DwoOnly)
1030 createFileSymbols(Asm);
1031
1032 for (auto &Symbol : Symbols) {
1033 // Update section number & offset for symbols that have them.
1034 if (Symbol->Section)
1035 Symbol->Data.SectionNumber = Symbol->Section->Number;
1036 Symbol->setIndex(Header.NumberOfSymbols++);
1037 // Update auxiliary symbol info.
1038 Symbol->Data.NumberOfAuxSymbols = Symbol->Aux.size();
1039 Header.NumberOfSymbols += Symbol->Data.NumberOfAuxSymbols;
1040 }
1041
1042 // Build string table.
1043 for (const auto &S : Sections)
1044 if (S->Name.size() > COFF::NameSize)
1045 Strings.add(S->Name);
1046 for (const auto &S : Symbols)
1047 if (S->Name.size() > COFF::NameSize)
1048 Strings.add(S->Name);
1049 Strings.finalize();
1050
1051 // Set names.
1052 for (const auto &S : Sections)
1053 SetSectionName(*S);
1054 for (auto &S : Symbols)
1055 SetSymbolName(*S);
1056
1057 // Fixup weak external references.
1058 for (auto &Symbol : Symbols) {
1059 if (Symbol->Other) {
1060 assert(Symbol->getIndex() != -1);
1061 assert(Symbol->Aux.size() == 1 && "Symbol must contain one aux symbol!");
1062 assert(Symbol->Aux[0].AuxType == ATWeakExternal &&
1063 "Symbol's aux symbol must be a Weak External!");
1064 Symbol->Aux[0].Aux.WeakExternal.TagIndex = Symbol->Other->getIndex();
1065 }
1066 }
1067
1068 // Fixup associative COMDAT sections.
1069 for (auto &Section : Sections) {
1070 if (Section->Symbol->Aux[0].Aux.SectionDefinition.Selection !=
1072 continue;
1073
1074 const MCSectionCOFF &MCSec = *Section->MCSection;
1075 const MCSymbol *AssocMCSym = MCSec.getCOMDATSymbol();
1076 assert(AssocMCSym);
1077
1078 // It's an error to try to associate with an undefined symbol or a symbol
1079 // without a section.
1080 if (!AssocMCSym->isInSection()) {
1081 Asm.getContext().reportError(
1082 SMLoc(), Twine("cannot make section ") + MCSec.getName() +
1083 Twine(" associative with sectionless symbol ") +
1084 AssocMCSym->getName());
1085 continue;
1086 }
1087
1088 const auto *AssocMCSec = cast<MCSectionCOFF>(&AssocMCSym->getSection());
1089 assert(SectionMap.count(AssocMCSec));
1090 COFFSection *AssocSec = SectionMap[AssocMCSec];
1091
1092 // Skip this section if the associated section is unused.
1093 if (AssocSec->Number == -1)
1094 continue;
1095
1096 Section->Symbol->Aux[0].Aux.SectionDefinition.Number = AssocSec->Number;
1097 }
1098
1099 // Create the contents of the .llvm_addrsig section.
1100 if (Mode != DwoOnly && OWriter.getEmitAddrsigSection()) {
1101 auto *Sec = Asm.getContext().getCOFFSection(
1102 ".llvm_addrsig", COFF::IMAGE_SCN_LNK_REMOVE);
1103 auto *Frag = cast<MCDataFragment>(Sec->curFragList()->Head);
1104 raw_svector_ostream OS(Frag->getContents());
1105 for (const MCSymbol *S : OWriter.AddrsigSyms) {
1106 if (!S->isRegistered())
1107 continue;
1108 if (!S->isTemporary()) {
1109 encodeULEB128(S->getIndex(), OS);
1110 continue;
1111 }
1112
1113 MCSection *TargetSection = &S->getSection();
1114 assert(SectionMap.contains(TargetSection) &&
1115 "Section must already have been defined in "
1116 "executePostLayoutBinding!");
1117 encodeULEB128(SectionMap[TargetSection]->Symbol->getIndex(), OS);
1118 }
1119 }
1120
1121 // Create the contents of the .llvm.call-graph-profile section.
1122 if (Mode != DwoOnly && !Asm.CGProfile.empty()) {
1123 auto *Sec = Asm.getContext().getCOFFSection(
1124 ".llvm.call-graph-profile", COFF::IMAGE_SCN_LNK_REMOVE);
1125 auto *Frag = cast<MCDataFragment>(Sec->curFragList()->Head);
1126 raw_svector_ostream OS(Frag->getContents());
1127 for (const MCAssembler::CGProfileEntry &CGPE : Asm.CGProfile) {
1128 uint32_t FromIndex = CGPE.From->getSymbol().getIndex();
1129 uint32_t ToIndex = CGPE.To->getSymbol().getIndex();
1130 support::endian::write(OS, FromIndex, W.Endian);
1131 support::endian::write(OS, ToIndex, W.Endian);
1132 support::endian::write(OS, CGPE.Count, W.Endian);
1133 }
1134 }
1135
1136 assignFileOffsets(Asm, Layout);
1137
1138 // MS LINK expects to be able to use this timestamp to implement their
1139 // /INCREMENTAL feature.
1140 if (Asm.isIncrementalLinkerCompatible()) {
1141 Header.TimeDateStamp = getTime();
1142 } else {
1143 // Have deterministic output if /INCREMENTAL isn't needed. Also matches GNU.
1144 Header.TimeDateStamp = 0;
1145 }
1146
1147 // Write it all to disk...
1148 WriteFileHeader(Header);
1149 writeSectionHeaders();
1150
1151#ifndef NDEBUG
1152 sections::iterator I = Sections.begin();
1153 sections::iterator IE = Sections.end();
1154 MCAssembler::iterator J = Asm.begin();
1155 MCAssembler::iterator JE = Asm.end();
1156 for (; I != IE && J != JE; ++I, ++J) {
1157 while (J != JE && ((Mode == NonDwoOnly && isDwoSection(*J)) ||
1158 (Mode == DwoOnly && !isDwoSection(*J))))
1159 ++J;
1160 assert(J != JE && (**I).MCSection == &*J && "Wrong bound MCSection");
1161 }
1162#endif
1163
1164 // Write section contents.
1165 for (std::unique_ptr<COFFSection> &Sec : Sections)
1166 writeSection(Asm, Layout, *Sec);
1167
1168 assert(W.OS.tell() == Header.PointerToSymbolTable &&
1169 "Header::PointerToSymbolTable is insane!");
1170
1171 // Write a symbol table.
1172 for (auto &Symbol : Symbols)
1173 if (Symbol->getIndex() != -1)
1174 WriteSymbol(*Symbol);
1175
1176 // Write a string table, which completes the entire COFF file.
1177 Strings.write(W.OS);
1178
1179 return W.OS.tell() - StartOffset;
1180}
1181
1182//------------------------------------------------------------------------------
1183// WinCOFFObjectWriter class implementation
1184
1185////////////////////////////////////////////////////////////////////////////////
1186// MCObjectWriter interface implementations
1187
1188void WinCOFFObjectWriter::reset() {
1189 ObjWriter->reset();
1190 if (DwoWriter)
1191 DwoWriter->reset();
1193}
1194
1195bool WinCOFFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
1196 const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB,
1197 bool InSet, bool IsPCRel) const {
1198 // Don't drop relocations between functions, even if they are in the same text
1199 // section. Multiple Visual C++ linker features depend on having the
1200 // relocations present. The /INCREMENTAL flag will cause these relocations to
1201 // point to thunks, and the /GUARD:CF flag assumes that it can use relocations
1202 // to approximate the set of all address taken functions. LLD's implementation
1203 // of /GUARD:CF also relies on the existance of these relocations.
1204 uint16_t Type = cast<MCSymbolCOFF>(SymA).getType();
1206 return false;
1208 InSet, IsPCRel);
1209}
1210
1211void WinCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
1212 const MCAsmLayout &Layout) {
1213 ObjWriter->executePostLayoutBinding(Asm, Layout);
1214 if (DwoWriter)
1215 DwoWriter->executePostLayoutBinding(Asm, Layout);
1216}
1217
1218void WinCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
1219 const MCAsmLayout &Layout,
1220 const MCFragment *Fragment,
1221 const MCFixup &Fixup, MCValue Target,
1222 uint64_t &FixedValue) {
1223 assert(!isDwoSection(*Fragment->getParent()) &&
1224 "No relocation in Dwo sections");
1225 ObjWriter->recordRelocation(Asm, Layout, Fragment, Fixup, Target, FixedValue);
1226}
1227
1228uint64_t WinCOFFObjectWriter::writeObject(MCAssembler &Asm,
1229 const MCAsmLayout &Layout) {
1230 uint64_t TotalSize = ObjWriter->writeObject(Asm, Layout);
1231 if (DwoWriter)
1232 TotalSize += DwoWriter->writeObject(Asm, Layout);
1233 return TotalSize;
1234}
1235
1237 : Machine(Machine_) {}
1238
1239// Pin the vtable to this file.
1240void MCWinCOFFObjectTargetWriter::anchor() {}
1241
1242//------------------------------------------------------------------------------
1243// WinCOFFObjectWriter factory function
1244
1245std::unique_ptr<MCObjectWriter> llvm::createWinCOFFObjectWriter(
1246 std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS) {
1247 return std::make_unique<WinCOFFObjectWriter>(std::move(MOTW), OS);
1248}
1249
1250std::unique_ptr<MCObjectWriter> llvm::createWinCOFFDwoObjectWriter(
1251 std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS,
1252 raw_pwrite_stream &DwoOS) {
1253 return std::make_unique<WinCOFFObjectWriter>(std::move(MOTW), OS, DwoOS);
1254}
bbsections Prepares for basic block sections
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
COFFYAML::AuxSymbolType AuxType
Definition: COFFYAML.cpp:353
COFF::MachineTypes Machine
Definition: COFFYAML.cpp:371
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
std::string Name
std::optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1293
Symbol * Sym
Definition: ELF_riscv.cpp:479
#define I(x, y, z)
Definition: MD5.cpp:58
std::pair< uint64_t, uint64_t > Interval
PowerPC TLS Dynamic Call Fixup
uint32_t Number
Definition: Profile.cpp:47
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const char * name
Definition: SMEABIPass.cpp:49
This file contains some templates that are useful if you are working with the STL at all.
raw_pwrite_stream & OS
This file defines the SmallString class.
This file defines the SmallVector class.
static uint32_t getAlignment(const MCSectionCOFF &Sec)
static bool isAssociative(const COFFSection &Section)
static uint64_t getSymbolValue(const MCSymbol &Symbol, const MCAsmLayout &Layout)
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),...
Definition: ArrayRef.h:41
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition: DenseMap.h:145
Implements a dense probed hash-table based set.
Definition: DenseSet.h:271
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:28
const MCSymbol * getBaseSymbol(const MCSymbol &Symbol) const
If this symbol is equivalent to A + Constant, return A.
Definition: MCFragment.cpp:107
uint64_t getSectionAddressSize(const MCSection *Sec) const
Get the address space size of the given section, as it effects layout.
Definition: MCFragment.cpp:143
bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const
Get the offset of the given symbol, as computed in the current layout.
Definition: MCFragment.cpp:97
uint64_t getFragmentOffset(const MCFragment *F) const
Get the offset of the given fragment inside its containing section.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:71
MCSection * getParent() const
Definition: MCFragment.h:94
Defines the object file and target independent interfaces used by the assembler backend to write nati...
virtual uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout)=0
Write the object file and returns the number of bytes written.
virtual void executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout)=0
Perform any late binding of symbols (for example, to assign symbol indices for use when generating re...
virtual void reset()
lifetime management
virtual bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbol &A, const MCSymbol &B, bool InSet) const
virtual void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue)=0
Record a relocation entry.
This represents a section on Windows.
Definition: MCSectionCOFF.h:27
MCSymbol * getCOMDATSymbol() const
Definition: MCSectionCOFF.h:70
unsigned getCharacteristics() const
Definition: MCSectionCOFF.h:69
int getSelection() const
Definition: MCSectionCOFF.h:71
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:36
Align getAlign() const
Definition: MCSection.h:158
StringRef getName() const
Definition: MCSection.h:142
bool empty() const
Definition: MCSection.h:199
MCSymbol * getBeginSymbol()
Definition: MCSection.h:147
uint16_t getType() const
Definition: MCSymbolCOFF.h:36
uint16_t getClass() const
Definition: MCSymbolCOFF.h:43
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
const MCSymbol & getSymbol() const
Definition: MCExpr.h:410
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).
Definition: MCSymbol.h:254
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:205
bool isVariable() const
isVariable - Check if this is a variable symbol.
Definition: MCSymbol.h:300
bool isRegistered() const
Definition: MCSymbol.h:212
void setIndex(uint32_t Value) const
Set the (implementation defined) index.
Definition: MCSymbol.h:321
bool isUndefined(bool SetUsed=true) const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
Definition: MCSymbol.h:259
uint32_t getIndex() const
Get the (implementation defined) index.
Definition: MCSymbol.h:316
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
Definition: MCSymbol.h:269
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
Definition: MCSymbol.h:222
bool isExternal() const
Definition: MCSymbol.h:406
MCFragment * getFragment(bool SetUsed=true) const
Definition: MCSymbol.h:397
This represents an "assembler immediate".
Definition: MCValue.h:36
Represents a location in source code.
Definition: SMLoc.h:23
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
size_t size() const
Definition: SmallVector.h:91
pointer data()
Return a pointer to the vector's buffer, even if empty().
Definition: SmallVector.h:299
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:270
Utility for building string tables with deduplicated suffixes.
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
An abstract base class for streams implementations that also support a pwrite operation.
Definition: raw_ostream.h:445
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:691
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ IMAGE_FILE_MACHINE_UNKNOWN
Definition: COFF.h:95
@ IMAGE_FILE_MACHINE_AMD64
Definition: COFF.h:97
@ IMAGE_FILE_MACHINE_I386
Definition: COFF.h:104
@ IMAGE_FILE_MACHINE_ARMNT
Definition: COFF.h:99
@ IMAGE_SCN_ALIGN_64BYTES
Definition: COFF.h:320
@ IMAGE_SCN_ALIGN_128BYTES
Definition: COFF.h:321
@ IMAGE_SCN_ALIGN_256BYTES
Definition: COFF.h:322
@ IMAGE_SCN_ALIGN_1024BYTES
Definition: COFF.h:324
@ IMAGE_SCN_ALIGN_1BYTES
Definition: COFF.h:314
@ IMAGE_SCN_LNK_REMOVE
Definition: COFF.h:307
@ IMAGE_SCN_ALIGN_512BYTES
Definition: COFF.h:323
@ IMAGE_SCN_CNT_UNINITIALIZED_DATA
Definition: COFF.h:304
@ IMAGE_SCN_ALIGN_4096BYTES
Definition: COFF.h:326
@ IMAGE_SCN_ALIGN_8192BYTES
Definition: COFF.h:327
@ IMAGE_SCN_LNK_NRELOC_OVFL
Definition: COFF.h:329
@ IMAGE_SCN_ALIGN_16BYTES
Definition: COFF.h:318
@ IMAGE_SCN_LNK_COMDAT
Definition: COFF.h:308
@ IMAGE_SCN_ALIGN_8BYTES
Definition: COFF.h:317
@ IMAGE_SCN_ALIGN_4BYTES
Definition: COFF.h:316
@ IMAGE_SCN_ALIGN_32BYTES
Definition: COFF.h:319
@ IMAGE_SCN_ALIGN_2BYTES
Definition: COFF.h:315
@ IMAGE_SCN_ALIGN_2048BYTES
Definition: COFF.h:325
bool isAnyArm64(T Machine)
Definition: COFF.h:129
@ IMAGE_REL_ARM64_REL32
Definition: COFF.h:417
@ IMAGE_REL_AMD64_REL32
Definition: COFF.h:364
@ IMAGE_SYM_CLASS_EXTERNAL
External symbol.
Definition: COFF.h:223
@ IMAGE_SYM_CLASS_LABEL
Label.
Definition: COFF.h:227
@ IMAGE_SYM_CLASS_FILE
File name.
Definition: COFF.h:245
@ IMAGE_SYM_CLASS_NULL
No symbol.
Definition: COFF.h:221
@ IMAGE_SYM_CLASS_WEAK_EXTERNAL
Duplicate tag.
Definition: COFF.h:248
@ IMAGE_SYM_CLASS_STATIC
Static.
Definition: COFF.h:224
bool encodeSectionName(char *Out, uint64_t Offset)
Encode section name based on string table offset.
Definition: COFF.cpp:39
@ IMAGE_COMDAT_SELECT_ASSOCIATIVE
Definition: COFF.h:425
@ NameSize
Definition: COFF.h:57
@ Header16Size
Definition: COFF.h:55
@ Symbol16Size
Definition: COFF.h:58
@ Header32Size
Definition: COFF.h:56
@ SectionSize
Definition: COFF.h:60
@ Symbol32Size
Definition: COFF.h:59
@ RelocationSize
Definition: COFF.h:61
@ IMAGE_REL_ARM_MOV32A
Definition: COFF.h:391
@ IMAGE_REL_ARM_BRANCH20T
Definition: COFF.h:393
@ IMAGE_REL_ARM_BRANCH24
Definition: COFF.h:383
@ IMAGE_REL_ARM_ADDR32NB
Definition: COFF.h:382
@ IMAGE_REL_ARM_BRANCH11
Definition: COFF.h:384
@ IMAGE_REL_ARM_BLX24
Definition: COFF.h:386
@ IMAGE_REL_ARM_ADDR32
Definition: COFF.h:381
@ IMAGE_REL_ARM_MOV32T
Definition: COFF.h:392
@ IMAGE_REL_ARM_BRANCH24T
Definition: COFF.h:394
@ IMAGE_REL_ARM_ABSOLUTE
Definition: COFF.h:380
@ IMAGE_REL_ARM_REL32
Definition: COFF.h:388
@ IMAGE_REL_ARM_BLX23T
Definition: COFF.h:395
@ IMAGE_REL_ARM_SECREL
Definition: COFF.h:390
@ IMAGE_REL_ARM_SECTION
Definition: COFF.h:389
@ IMAGE_REL_ARM_BLX11
Definition: COFF.h:387
@ IMAGE_REL_ARM_TOKEN
Definition: COFF.h:385
const int32_t MaxNumberOfSections16
Definition: COFF.h:32
@ IMAGE_REL_I386_REL32
Definition: COFF.h:356
static const char BigObjMagic[]
Definition: COFF.h:37
@ IMAGE_SYM_DEBUG
Definition: COFF.h:211
@ IMAGE_SYM_ABSOLUTE
Definition: COFF.h:212
@ IMAGE_SYM_DTYPE_FUNCTION
A function that returns a base type.
Definition: COFF.h:275
@ SCT_COMPLEX_TYPE_SHIFT
Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
Definition: COFF.h:279
DenseMap< SymbolStringPtr, ExecutorSymbolDef > SymbolMap
A map from symbol names (as SymbolStringPtrs) to JITSymbols (address/flags pairs).
Definition: Core.h:121
void write32le(void *P, uint32_t V)
Definition: Endian.h:468
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
Definition: Endian.h:92
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
@ Length
Definition: DWP.cpp:480
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.
Definition: STLExtras.h:1680
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1647
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
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.
Definition: MCFixup.h:41
std::unique_ptr< MCObjectWriter > createWinCOFFObjectWriter(std::unique_ptr< MCWinCOFFObjectTargetWriter > MOTW, raw_pwrite_stream &OS)
Construct a new Win COFF writer instance.
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
Definition: LEB128.h:80
endianness
Definition: bit.h:70
#define N
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
uint32_t VirtualSize
Definition: COFF.h:286
uint32_t PointerToRelocations
Definition: COFF.h:290
uint16_t NumberOfLineNumbers
Definition: COFF.h:293
uint32_t PointerToRawData
Definition: COFF.h:289
uint32_t SizeOfRawData
Definition: COFF.h:288
uint32_t Characteristics
Definition: COFF.h:294
uint16_t NumberOfRelocations
Definition: COFF.h:292
char Name[NameSize]
Definition: COFF.h:285
uint32_t VirtualAddress
Definition: COFF.h:287
uint32_t PointerToLineNumbers
Definition: COFF.h:291
const MCSymbolRefExpr * From
Definition: MCAssembler.h:467
const MCSymbolRefExpr * To
Definition: MCAssembler.h:468
An iterator type that allows iterating over the pointees via some other iterator.
Definition: iterator.h:324
Adapter to write values to a stream in a particular byte order.
Definition: EndianStream.h:67