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