LLVM 22.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
133 using symbol_list = DenseSet<COFFSymbol *>;
134
135 // Root level file contents.
136 COFF::header Header = {};
137 sections Sections;
138 symbols Symbols;
140
141 // Maps used during object file creation.
142 section_map SectionMap;
143 symbol_map SymbolMap;
144
145 symbol_list WeakDefaults;
146
147 bool UseBigObj;
148 bool UseOffsetLabels = false;
149
150public:
156
158 DwoMode Mode);
159
160 void reset();
161 void setAssembler(MCAssembler *A) { Asm = A; }
163 void recordRelocation(const MCFragment &F, const MCFixup &Fixup,
164 MCValue Target, uint64_t &FixedValue);
166 int getSectionNumber(const MCSection &Section) const;
167
168private:
169 MCContext &getContext() const { return OWriter.getContext(); }
170 COFFSymbol *createSymbol(StringRef Name);
171 COFFSymbol *getOrCreateCOFFSymbol(const MCSymbol &Sym);
172 COFFSection *createSection(StringRef Name);
173
174 void defineSection(MCSectionCOFF const &Sec);
175
176 COFFSymbol *getLinkedSymbol(const MCSymbol &Symbol);
177 void defineSymbol(const MCSymbolCOFF &Symbol);
178
179 void SetSymbolName(COFFSymbol &S);
180 void SetSectionName(COFFSection &S);
181
182 bool isUninitializedData(const COFFSection &S);
183
184 // Entity writing methods.
185 void WriteFileHeader(const COFF::header &Header);
186 void WriteSymbol(const COFFSymbol &S);
187 void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols &S);
188 void writeSectionHeaders();
189 void WriteRelocation(const COFF::relocation &R);
190 uint32_t writeSectionContents(const MCSection &MCSec);
191 void writeSection(const COFFSection &Sec);
192
193 void createFileSymbols();
194 void setWeakDefaultNames();
195 void assignSectionNumbers();
196 void assignFileOffsets();
197};
198
200 std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS)
201 : TargetObjectWriter(std::move(MOTW)),
202 ObjWriter(std::make_unique<WinCOFFWriter>(*this, OS,
203 WinCOFFWriter::AllSections)) {}
205 std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS,
206 raw_pwrite_stream &DwoOS)
207 : TargetObjectWriter(std::move(MOTW)),
208 ObjWriter(std::make_unique<WinCOFFWriter>(*this, OS,
209 WinCOFFWriter::NonDwoOnly)),
210 DwoWriter(std::make_unique<WinCOFFWriter>(*this, DwoOS,
211 WinCOFFWriter::DwoOnly)) {}
212
213static bool isDwoSection(const MCSection &Sec) {
214 return Sec.getName().ends_with(".dwo");
215}
216
217//------------------------------------------------------------------------------
218// Symbol class implementation
219
220// In the case that the name does not fit within 8 bytes, the offset
221// into the string table is stored in the last 4 bytes instead, leaving
222// the first 4 bytes as 0.
223void COFFSymbol::set_name_offset(uint32_t Offset) {
224 write32le(Data.Name + 0, 0);
225 write32le(Data.Name + 4, Offset);
226}
227
228//------------------------------------------------------------------------------
229// WinCOFFWriter class implementation
230
233 : OWriter(OWriter), W(OS, llvm::endianness::little), Mode(Mode) {
234 Header.Machine = OWriter.TargetObjectWriter->getMachine();
235 // Some relocations on ARM64 (the 21 bit ADRP relocations) have a slightly
236 // limited range for the immediate offset (+/- 1 MB); create extra offset
237 // label symbols with regular intervals to allow referencing a
238 // non-temporary symbol that is close enough.
239 UseOffsetLabels = COFF::isAnyArm64(Header.Machine);
240}
241
242COFFSymbol *WinCOFFWriter::createSymbol(StringRef Name) {
243 Symbols.push_back(std::make_unique<COFFSymbol>(Name));
244 return Symbols.back().get();
245}
246
247COFFSymbol *WinCOFFWriter::getOrCreateCOFFSymbol(const MCSymbol &Sym) {
248 COFFSymbol *&Ret = SymbolMap[&Sym];
249 if (!Ret)
250 Ret = createSymbol(Sym.getName());
251 return Ret;
252}
253
254COFFSection *WinCOFFWriter::createSection(StringRef Name) {
255 Sections.emplace_back(std::make_unique<COFFSection>(Name));
256 return Sections.back().get();
257}
258
260 switch (Sec.getAlign().value()) {
261 case 1:
263 case 2:
265 case 4:
267 case 8:
269 case 16:
271 case 32:
273 case 64:
275 case 128:
277 case 256:
279 case 512:
281 case 1024:
283 case 2048:
285 case 4096:
287 case 8192:
289 }
290 llvm_unreachable("unsupported section alignment");
291}
292
293/// This function takes a section data object from the assembler
294/// and creates the associated COFF section staging object.
295void WinCOFFWriter::defineSection(const MCSectionCOFF &MCSec) {
296 COFFSection *Section = createSection(MCSec.getName());
297 COFFSymbol *Symbol = createSymbol(MCSec.getName());
298 Section->Symbol = Symbol;
299 SymbolMap[MCSec.getBeginSymbol()] = Symbol;
300 Symbol->Section = Section;
301 Symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_STATIC;
302
303 // Create a COMDAT symbol if needed.
305 if (const MCSymbol *S = MCSec.getCOMDATSymbol()) {
306 COFFSymbol *COMDATSymbol = getOrCreateCOFFSymbol(*S);
307 if (COMDATSymbol->Section)
308 report_fatal_error("two sections have the same comdat");
309 COMDATSymbol->Section = Section;
310 }
311 }
312
313 // In this case the auxiliary symbol is a Section Definition.
314 Symbol->Aux.resize(1);
315 Symbol->Aux[0] = {};
316 Symbol->Aux[0].AuxType = ATSectionDefinition;
317 Symbol->Aux[0].Aux.SectionDefinition.Selection = MCSec.getSelection();
318
319 // Set section alignment.
320 Section->Header.Characteristics = MCSec.getCharacteristics();
321 Section->Header.Characteristics |= getAlignment(MCSec);
322
323 // Bind internal COFF section to MC section.
324 Section->MCSection = &MCSec;
325 SectionMap[&MCSec] = Section;
326
327 if (UseOffsetLabels) {
328 const uint32_t Interval = 1 << OffsetLabelIntervalBits;
329 uint32_t N = 1;
330 for (uint32_t Off = Interval, E = Asm->getSectionAddressSize(MCSec);
331 Off < E; Off += Interval) {
332 auto Name = ("$L" + MCSec.getName() + "_" + Twine(N++)).str();
333 COFFSymbol *Label = createSymbol(Name);
334 Label->Section = Section;
335 Label->Data.StorageClass = COFF::IMAGE_SYM_CLASS_LABEL;
336 Label->Data.Value = Off;
337 Section->OffsetSymbols.push_back(Label);
338 }
339 }
340}
341
343 const MCAssembler &Asm) {
344 if (Symbol.isCommon() && Symbol.isExternal())
345 return Symbol.getCommonSize();
346
347 uint64_t Res;
348 if (!Asm.getSymbolOffset(Symbol, Res))
349 return 0;
350
351 return Res;
352}
353
354COFFSymbol *WinCOFFWriter::getLinkedSymbol(const MCSymbol &Symbol) {
355 if (!Symbol.isVariable())
356 return nullptr;
357
358 const auto *SymRef = dyn_cast<MCSymbolRefExpr>(Symbol.getVariableValue());
359 if (!SymRef)
360 return nullptr;
361
362 auto &Aliasee = static_cast<const MCSymbolCOFF &>(SymRef->getSymbol());
363 if (Aliasee.isUndefined() || Aliasee.isExternal())
364 return getOrCreateCOFFSymbol(Aliasee);
365 else
366 return nullptr;
367}
368
369/// This function takes a symbol data object from the assembler
370/// and creates the associated COFF symbol staging object.
371void WinCOFFWriter::defineSymbol(const MCSymbolCOFF &MCSym) {
372 const MCSymbol *Base = Asm->getBaseSymbol(MCSym);
373 COFFSection *Sec = nullptr;
374 MCSectionCOFF *MCSec = nullptr;
375 if (Base && Base->getFragment()) {
376 MCSec = static_cast<MCSectionCOFF *>(Base->getFragment()->getParent());
377 Sec = SectionMap[MCSec];
378 }
379
380 if (Mode == NonDwoOnly && MCSec && isDwoSection(*MCSec))
381 return;
382
383 COFFSymbol *Sym = getOrCreateCOFFSymbol(MCSym);
384 COFFSymbol *Local = nullptr;
385 if (static_cast<const MCSymbolCOFF &>(MCSym)
386 .getWeakExternalCharacteristics()) {
388 Sym->Section = nullptr;
389
390 COFFSymbol *WeakDefault = getLinkedSymbol(MCSym);
391 if (!WeakDefault) {
392 std::string WeakName = (".weak." + MCSym.getName() + ".default").str();
393 WeakDefault = createSymbol(WeakName);
394 if (!Sec)
395 WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
396 else
397 WeakDefault->Section = Sec;
398 WeakDefaults.insert(WeakDefault);
399 Local = WeakDefault;
400 }
401
402 Sym->Other = WeakDefault;
403
404 // Setup the Weak External auxiliary symbol.
405 Sym->Aux.resize(1);
406 memset(&Sym->Aux[0], 0, sizeof(Sym->Aux[0]));
407 Sym->Aux[0].AuxType = ATWeakExternal;
408 Sym->Aux[0].Aux.WeakExternal.TagIndex = 0; // Filled in later
409 Sym->Aux[0].Aux.WeakExternal.Characteristics =
410 static_cast<const MCSymbolCOFF &>(MCSym)
411 .getWeakExternalCharacteristics();
412 } else {
413 if (!Base)
415 else
416 Sym->Section = Sec;
417 Local = Sym;
418 }
419
420 if (Local) {
421 Local->Data.Value = getSymbolValue(MCSym, *Asm);
422
423 auto &SymbolCOFF = static_cast<const MCSymbolCOFF &>(MCSym);
424 Local->Data.Type = SymbolCOFF.getType();
425 Local->Data.StorageClass = SymbolCOFF.getClass();
426
427 // If no storage class was specified in the streamer, define it here.
428 if (Local->Data.StorageClass == COFF::IMAGE_SYM_CLASS_NULL) {
429 bool IsExternal =
430 MCSym.isExternal() || (!MCSym.getFragment() && !MCSym.isVariable());
431
432 Local->Data.StorageClass = IsExternal ? COFF::IMAGE_SYM_CLASS_EXTERNAL
434 }
435 }
436
437 Sym->MC = &MCSym;
438}
439
440void WinCOFFWriter::SetSectionName(COFFSection &S) {
441 if (S.Name.size() <= COFF::NameSize) {
442 std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size());
443 return;
444 }
445
446 uint64_t StringTableEntry = Strings.getOffset(S.Name);
447 if (!COFF::encodeSectionName(S.Header.Name, StringTableEntry))
448 report_fatal_error("COFF string table is greater than 64 GB.");
449}
450
451void WinCOFFWriter::SetSymbolName(COFFSymbol &S) {
452 if (S.Name.size() > COFF::NameSize)
453 S.set_name_offset(Strings.getOffset(S.Name));
454 else
455 std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size());
456}
457
458bool WinCOFFWriter::isUninitializedData(const COFFSection &S) {
460 0;
461}
462
463//------------------------------------------------------------------------------
464// entity writing methods
465
466void WinCOFFWriter::WriteFileHeader(const COFF::header &Header) {
467 if (UseBigObj) {
468 W.write<uint16_t>(COFF::IMAGE_FILE_MACHINE_UNKNOWN);
469 W.write<uint16_t>(0xFFFF);
471 W.write<uint16_t>(Header.Machine);
472 W.write<uint32_t>(Header.TimeDateStamp);
473 W.OS.write(COFF::BigObjMagic, sizeof(COFF::BigObjMagic));
474 W.write<uint32_t>(0);
475 W.write<uint32_t>(0);
476 W.write<uint32_t>(0);
477 W.write<uint32_t>(0);
478 W.write<uint32_t>(Header.NumberOfSections);
479 W.write<uint32_t>(Header.PointerToSymbolTable);
480 W.write<uint32_t>(Header.NumberOfSymbols);
481 } else {
482 W.write<uint16_t>(Header.Machine);
483 W.write<uint16_t>(static_cast<int16_t>(Header.NumberOfSections));
484 W.write<uint32_t>(Header.TimeDateStamp);
485 W.write<uint32_t>(Header.PointerToSymbolTable);
486 W.write<uint32_t>(Header.NumberOfSymbols);
487 W.write<uint16_t>(Header.SizeOfOptionalHeader);
488 W.write<uint16_t>(Header.Characteristics);
489 }
490}
491
492void WinCOFFWriter::WriteSymbol(const COFFSymbol &S) {
493 W.OS.write(S.Data.Name, COFF::NameSize);
494 W.write<uint32_t>(S.Data.Value);
495 if (UseBigObj)
496 W.write<uint32_t>(S.Data.SectionNumber);
497 else
498 W.write<uint16_t>(static_cast<int16_t>(S.Data.SectionNumber));
499 W.write<uint16_t>(S.Data.Type);
500 W.OS << char(S.Data.StorageClass);
501 W.OS << char(S.Data.NumberOfAuxSymbols);
502 WriteAuxiliarySymbols(S.Aux);
503}
504
505void WinCOFFWriter::WriteAuxiliarySymbols(
506 const COFFSymbol::AuxiliarySymbols &S) {
507 for (const AuxSymbol &i : S) {
508 switch (i.AuxType) {
509 case ATWeakExternal:
510 W.write<uint32_t>(i.Aux.WeakExternal.TagIndex);
511 W.write<uint32_t>(i.Aux.WeakExternal.Characteristics);
512 W.OS.write_zeros(sizeof(i.Aux.WeakExternal.unused));
513 if (UseBigObj)
514 W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size);
515 break;
516 case ATFile:
517 W.OS.write(reinterpret_cast<const char *>(&i.Aux),
519 break;
520 case ATSectionDefinition:
521 W.write<uint32_t>(i.Aux.SectionDefinition.Length);
522 W.write<uint16_t>(i.Aux.SectionDefinition.NumberOfRelocations);
523 W.write<uint16_t>(i.Aux.SectionDefinition.NumberOfLinenumbers);
524 W.write<uint32_t>(i.Aux.SectionDefinition.CheckSum);
525 W.write<uint16_t>(static_cast<int16_t>(i.Aux.SectionDefinition.Number));
526 W.OS << char(i.Aux.SectionDefinition.Selection);
527 W.OS.write_zeros(sizeof(i.Aux.SectionDefinition.unused));
528 W.write<uint16_t>(
529 static_cast<int16_t>(i.Aux.SectionDefinition.Number >> 16));
530 if (UseBigObj)
531 W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size);
532 break;
533 }
534 }
535}
536
537// Write the section header.
538void WinCOFFWriter::writeSectionHeaders() {
539 // Section numbers must be monotonically increasing in the section
540 // header, but our Sections array is not sorted by section number,
541 // so make a copy of Sections and sort it.
542 std::vector<COFFSection *> Arr;
543 for (auto &Section : Sections)
544 Arr.push_back(Section.get());
545 llvm::sort(Arr, [](const COFFSection *A, const COFFSection *B) {
546 return A->Number < B->Number;
547 });
548
549 for (auto &Section : Arr) {
550 if (Section->Number == -1)
551 continue;
552
553 COFF::section &S = Section->Header;
554 if (Section->Relocations.size() >= 0xffff)
556 W.OS.write(S.Name, COFF::NameSize);
557 W.write<uint32_t>(S.VirtualSize);
558 W.write<uint32_t>(S.VirtualAddress);
559 W.write<uint32_t>(S.SizeOfRawData);
560 W.write<uint32_t>(S.PointerToRawData);
561 W.write<uint32_t>(S.PointerToRelocations);
562 W.write<uint32_t>(S.PointerToLineNumbers);
563 W.write<uint16_t>(S.NumberOfRelocations);
564 W.write<uint16_t>(S.NumberOfLineNumbers);
565 W.write<uint32_t>(S.Characteristics);
566 }
567}
568
569void WinCOFFWriter::WriteRelocation(const COFF::relocation &R) {
570 W.write<uint32_t>(R.VirtualAddress);
571 W.write<uint32_t>(R.SymbolTableIndex);
572 W.write<uint16_t>(R.Type);
573}
574
575// Write MCSec's contents. What this function does is essentially
576// "Asm.writeSectionData(&MCSec)", but it's a bit complicated
577// because it needs to compute a CRC.
578uint32_t WinCOFFWriter::writeSectionContents(const MCSection &MCSec) {
579 // Save the contents of the section to a temporary buffer, we need this
580 // to CRC the data before we dump it into the object file.
581 SmallVector<char, 128> Buf;
582 raw_svector_ostream VecOS(Buf);
583 Asm->writeSectionData(VecOS, &MCSec);
584
585 // Write the section contents to the object file.
586 W.OS << Buf;
587
588 // Calculate our CRC with an initial value of '0', this is not how
589 // JamCRC is specified but it aligns with the expected output.
590 JamCRC JC(/*Init=*/0);
591 JC.update(ArrayRef(reinterpret_cast<uint8_t *>(Buf.data()), Buf.size()));
592 return JC.getCRC();
593}
594
595void WinCOFFWriter::writeSection(const COFFSection &Sec) {
596 if (Sec.Number == -1)
597 return;
598
599 // Write the section contents.
600 if (Sec.Header.PointerToRawData != 0) {
601 assert(W.OS.tell() == Sec.Header.PointerToRawData &&
602 "Section::PointerToRawData is insane!");
603
604 uint32_t CRC = writeSectionContents(*Sec.MCSection);
605
606 // Update the section definition auxiliary symbol to record the CRC.
607 COFFSymbol::AuxiliarySymbols &AuxSyms = Sec.Symbol->Aux;
608 assert(AuxSyms.size() == 1 && AuxSyms[0].AuxType == ATSectionDefinition);
609 AuxSymbol &SecDef = AuxSyms[0];
610 SecDef.Aux.SectionDefinition.CheckSum = CRC;
611 } else if (isUninitializedData(Sec)) {
612 // Error if fixups or non-zero bytes are present.
613 writeSectionContents(*Sec.MCSection);
614 }
615
616 // Write relocations for this section.
617 if (Sec.Relocations.empty()) {
618 assert(Sec.Header.PointerToRelocations == 0 &&
619 "Section::PointerToRelocations is insane!");
620 return;
621 }
622
623 assert(W.OS.tell() == Sec.Header.PointerToRelocations &&
624 "Section::PointerToRelocations is insane!");
625
626 if (Sec.Relocations.size() >= 0xffff) {
627 // In case of overflow, write actual relocation count as first
628 // relocation. Including the synthetic reloc itself (+ 1).
629 COFF::relocation R;
630 R.VirtualAddress = Sec.Relocations.size() + 1;
631 R.SymbolTableIndex = 0;
632 R.Type = 0;
633 WriteRelocation(R);
634 }
635
636 for (const auto &Relocation : Sec.Relocations)
637 WriteRelocation(Relocation.Data);
638}
639
640// Create .file symbols.
641void WinCOFFWriter::createFileSymbols() {
642 for (const std::pair<std::string, size_t> &It : OWriter.getFileNames()) {
643 // round up to calculate the number of auxiliary symbols required
644 const std::string &Name = It.first;
645 unsigned SymbolSize = UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size;
646 unsigned Count = (Name.size() + SymbolSize - 1) / SymbolSize;
647
648 COFFSymbol *File = createSymbol(".file");
649 File->Data.SectionNumber = COFF::IMAGE_SYM_DEBUG;
650 File->Data.StorageClass = COFF::IMAGE_SYM_CLASS_FILE;
651 File->Aux.resize(Count);
652
653 unsigned Offset = 0;
654 unsigned Length = Name.size();
655 for (auto &Aux : File->Aux) {
656 Aux.AuxType = ATFile;
657
658 if (Length > SymbolSize) {
659 memcpy(&Aux.Aux, Name.c_str() + Offset, SymbolSize);
660 Length = Length - SymbolSize;
661 } else {
662 memcpy(&Aux.Aux, Name.c_str() + Offset, Length);
663 memset((char *)&Aux.Aux + Length, 0, SymbolSize - Length);
664 break;
665 }
666
667 Offset += SymbolSize;
668 }
669 }
670}
671
672void WinCOFFWriter::setWeakDefaultNames() {
673 if (WeakDefaults.empty())
674 return;
675
676 // If multiple object files use a weak symbol (either with a regular
677 // defined default, or an absolute zero symbol as default), the defaults
678 // cause duplicate definitions unless their names are made unique. Look
679 // for a defined extern symbol, that isn't comdat - that should be unique
680 // unless there are other duplicate definitions. And if none is found,
681 // allow picking a comdat symbol, as that's still better than nothing.
682
683 COFFSymbol *Unique = nullptr;
684 for (bool AllowComdat : {false, true}) {
685 for (auto &Sym : Symbols) {
686 // Don't include the names of the defaults themselves
687 if (WeakDefaults.count(Sym.get()))
688 continue;
689 // Only consider external symbols
691 continue;
692 // Only consider symbols defined in a section or that are absolute
693 if (!Sym->Section && Sym->Data.SectionNumber != COFF::IMAGE_SYM_ABSOLUTE)
694 continue;
695 if (!AllowComdat && Sym->Section &&
696 Sym->Section->Header.Characteristics & COFF::IMAGE_SCN_LNK_COMDAT)
697 continue;
698 Unique = Sym.get();
699 break;
700 }
701 if (Unique)
702 break;
703 }
704 // If we didn't find any unique symbol to use for the names, just skip this.
705 if (!Unique)
706 return;
707 for (auto *Sym : WeakDefaults) {
708 Sym->Name.append(".");
709 Sym->Name.append(Unique->Name);
710 }
711}
712
713static bool isAssociative(const COFFSection &Section) {
714 return Section.Symbol->Aux[0].Aux.SectionDefinition.Selection ==
716}
717
718void WinCOFFWriter::assignSectionNumbers() {
719 size_t I = 1;
720 auto Assign = [&](COFFSection &Section) {
721 Section.Number = I;
722 Section.Symbol->Data.SectionNumber = I;
723 Section.Symbol->Aux[0].Aux.SectionDefinition.Number = I;
724 ++I;
725 };
726
727 // Although it is not explicitly requested by the Microsoft COFF spec,
728 // we should avoid emitting forward associative section references,
729 // because MSVC link.exe as of 2017 cannot handle that.
730 for (const std::unique_ptr<COFFSection> &Section : Sections)
731 if (!isAssociative(*Section))
732 Assign(*Section);
733 for (const std::unique_ptr<COFFSection> &Section : Sections)
734 if (isAssociative(*Section))
735 Assign(*Section);
736}
737
738// Assign file offsets to COFF object file structures.
739void WinCOFFWriter::assignFileOffsets() {
740 unsigned Offset = W.OS.tell();
741
743 Offset += COFF::SectionSize * Header.NumberOfSections;
744
745 for (const auto &Section : *Asm) {
746 COFFSection *Sec = SectionMap[&Section];
747
748 if (!Sec || Sec->Number == -1)
749 continue;
750
751 Sec->Header.SizeOfRawData = Asm->getSectionAddressSize(Section);
752
753 if (!isUninitializedData(*Sec)) {
754 Sec->Header.PointerToRawData = Offset;
755 Offset += Sec->Header.SizeOfRawData;
756 }
757
758 if (!Sec->Relocations.empty()) {
759 bool RelocationsOverflow = Sec->Relocations.size() >= 0xffff;
760
761 if (RelocationsOverflow) {
762 // Signal overflow by setting NumberOfRelocations to max value. Actual
763 // size is found in reloc #0. Microsoft tools understand this.
764 Sec->Header.NumberOfRelocations = 0xffff;
765 } else {
766 Sec->Header.NumberOfRelocations = Sec->Relocations.size();
767 }
768 Sec->Header.PointerToRelocations = Offset;
769
770 if (RelocationsOverflow) {
771 // Reloc #0 will contain actual count, so make room for it.
773 }
774
775 Offset += COFF::RelocationSize * Sec->Relocations.size();
776
777 for (auto &Relocation : Sec->Relocations) {
778 assert(Relocation.Symb->getIndex() != -1);
779 if (Header.Machine != COFF::IMAGE_FILE_MACHINE_R4000 ||
780 Relocation.Data.Type != COFF::IMAGE_REL_MIPS_PAIR) {
781 Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex();
782 }
783 }
784 }
785
786 assert(Sec->Symbol->Aux.size() == 1 &&
787 "Section's symbol must have one aux!");
788 AuxSymbol &Aux = Sec->Symbol->Aux[0];
789 assert(Aux.AuxType == ATSectionDefinition &&
790 "Section's symbol's aux symbol must be a Section Definition!");
791 Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData;
793 Sec->Header.NumberOfRelocations;
795 Sec->Header.NumberOfLineNumbers;
796 }
797
798 Header.PointerToSymbolTable = Offset;
799}
800
802 memset(&Header, 0, sizeof(Header));
803 Header.Machine = OWriter.TargetObjectWriter->getMachine();
804 Sections.clear();
805 Symbols.clear();
806 Strings.clear();
807 SectionMap.clear();
808 SymbolMap.clear();
809 WeakDefaults.clear();
810}
811
813 // "Define" each section & symbol. This creates section & symbol
814 // entries in the staging area.
815 for (const auto &Section : *Asm) {
816 if ((Mode == NonDwoOnly && isDwoSection(Section)) ||
817 (Mode == DwoOnly && !isDwoSection(Section)))
818 continue;
819 defineSection(static_cast<const MCSectionCOFF &>(Section));
820 }
821
822 if (Mode != DwoOnly) {
823 for (const MCSymbol &Symbol : Asm->symbols()) {
824 auto &Sym = static_cast<const MCSymbolCOFF &>(Symbol);
825 // Define non-temporary or temporary static (private-linkage) symbols
826 if (!Sym.isTemporary() || Sym.getClass() == COFF::IMAGE_SYM_CLASS_STATIC)
827 defineSymbol(Sym);
828 }
829 }
830
831 UseBigObj = Sections.size() > COFF::MaxNumberOfSections16;
832 Header.NumberOfSections = Sections.size();
833 Header.NumberOfSymbols = 0;
834 if (Sections.size() > INT32_MAX)
836 "PE COFF object files can't have more than 2147483647 sections");
837
838 assignSectionNumbers();
839}
840
842 MCValue Target, uint64_t &FixedValue) {
843 assert(Target.getAddSym() && "Relocation must reference a symbol!");
844
845 const MCSymbol &A = *Target.getAddSym();
846 if (!A.isRegistered()) {
847 getContext().reportError(Fixup.getLoc(), Twine("symbol '") + A.getName() +
848 "' can not be undefined");
849 return;
850 }
851 if (A.isTemporary() && A.isUndefined()) {
852 getContext().reportError(Fixup.getLoc(), Twine("assembler label '") +
853 A.getName() +
854 "' can not be undefined");
855 return;
856 }
857
858 MCSection *MCSec = F.getParent();
859
860 // Mark this symbol as requiring an entry in the symbol table.
861 assert(SectionMap.contains(MCSec) &&
862 "Section must already have been defined in executePostLayoutBinding!");
863
864 COFFSection *Sec = SectionMap[MCSec];
865 if (const MCSymbol *B = Target.getSubSym()) {
866 if (!B->getFragment()) {
867 getContext().reportError(
868 Fixup.getLoc(),
869 Twine("symbol '") + B->getName() +
870 "' can not be undefined in a subtraction expression");
871 return;
872 }
873
874 // Offset of the symbol in the section
875 int64_t OffsetOfB = Asm->getSymbolOffset(*B);
876
877 // Offset of the relocation in the section
878 int64_t OffsetOfRelocation = Asm->getFragmentOffset(F) + Fixup.getOffset();
879
880 FixedValue = (OffsetOfRelocation - OffsetOfB) + Target.getConstant();
881 } else {
882 FixedValue = Target.getConstant();
883 }
884
885 COFFRelocation Reloc;
886
887 Reloc.Data.SymbolTableIndex = 0;
888 Reloc.Data.VirtualAddress = Asm->getFragmentOffset(F);
889
890 // Turn relocations for temporary symbols into section relocations.
891 if (A.isTemporary() && !SymbolMap[&A]) {
892 MCSection *TargetSection = &A.getSection();
893 assert(
894 SectionMap.contains(TargetSection) &&
895 "Section must already have been defined in executePostLayoutBinding!");
896 COFFSection *Section = SectionMap[TargetSection];
897 Reloc.Symb = Section->Symbol;
898 FixedValue += Asm->getSymbolOffset(A);
899 // Technically, we should do the final adjustments of FixedValue (below)
900 // before picking an offset symbol, otherwise we might choose one which
901 // is slightly too far away. The relocations where it really matters
902 // (arm64 adrp relocations) don't get any offset though.
903 if (UseOffsetLabels && !Section->OffsetSymbols.empty()) {
904 uint64_t LabelIndex = FixedValue >> OffsetLabelIntervalBits;
905 if (LabelIndex > 0) {
906 if (LabelIndex <= Section->OffsetSymbols.size())
907 Reloc.Symb = Section->OffsetSymbols[LabelIndex - 1];
908 else
909 Reloc.Symb = Section->OffsetSymbols.back();
910 FixedValue -= Reloc.Symb->Data.Value;
911 }
912 }
913 } else {
914 assert(
915 SymbolMap.contains(&A) &&
916 "Symbol must already have been defined in executePostLayoutBinding!");
917 Reloc.Symb = SymbolMap[&A];
918 }
919
920 ++Reloc.Symb->Relocations;
921
922 Reloc.Data.VirtualAddress += Fixup.getOffset();
923 Reloc.Data.Type = OWriter.TargetObjectWriter->getRelocType(
924 getContext(), Target, Fixup, Target.getSubSym(), Asm->getBackend());
925
926 // The *_REL32 relocations are relative to the end of the relocation,
927 // not to the start.
928 if ((Header.Machine == COFF::IMAGE_FILE_MACHINE_AMD64 &&
929 Reloc.Data.Type == COFF::IMAGE_REL_AMD64_REL32) ||
930 (Header.Machine == COFF::IMAGE_FILE_MACHINE_I386 &&
931 Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32) ||
932 (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT &&
933 Reloc.Data.Type == COFF::IMAGE_REL_ARM_REL32) ||
934 (COFF::isAnyArm64(Header.Machine) &&
936 FixedValue += 4;
937
938 if (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT) {
939 switch (Reloc.Data.Type) {
946 break;
949 // IMAGE_REL_ARM_BRANCH11 and IMAGE_REL_ARM_BLX11 are only used for
950 // pre-ARMv7, which implicitly rules it out of ARMNT (it would be valid
951 // for Windows CE).
955 // IMAGE_REL_ARM_BRANCH24, IMAGE_REL_ARM_BLX24, IMAGE_REL_ARM_MOV32A are
956 // only used for ARM mode code, which is documented as being unsupported
957 // by Windows on ARM. Empirical proof indicates that masm is able to
958 // generate the relocations however the rest of the MSVC toolchain is
959 // unable to handle it.
960 llvm_unreachable("unsupported relocation");
961 break;
963 break;
967 // IMAGE_REL_BRANCH20T, IMAGE_REL_ARM_BRANCH24T, IMAGE_REL_ARM_BLX23T all
968 // perform a 4 byte adjustment to the relocation. Relative branches are
969 // offset by 4 on ARM, however, because there is no RELA relocations, all
970 // branches are offset by 4.
971 FixedValue = FixedValue + 4;
972 break;
973 }
974 }
975
976 // The fixed value never makes sense for section indices, ignore it.
977 if (Fixup.getKind() == FK_SecRel_2)
978 FixedValue = 0;
979
980 if (OWriter.TargetObjectWriter->recordRelocation(Fixup)) {
981 Sec->Relocations.push_back(Reloc);
982 if (Header.Machine == COFF::IMAGE_FILE_MACHINE_R4000 &&
983 (Reloc.Data.Type == COFF::IMAGE_REL_MIPS_REFHI ||
984 Reloc.Data.Type == COFF::IMAGE_REL_MIPS_SECRELHI)) {
985 // IMAGE_REL_MIPS_REFHI and IMAGE_REL_MIPS_SECRELHI *must*
986 // be followed by IMAGE_REL_MIPS_PAIR
987 auto RelocPair = Reloc;
988 RelocPair.Data.Type = COFF::IMAGE_REL_MIPS_PAIR;
989 Sec->Relocations.push_back(RelocPair);
990 }
991 }
992}
993
994static std::time_t getTime() {
995 std::time_t Now = time(nullptr);
996 if (Now < 0 || !isUInt<32>(Now))
997 return UINT32_MAX;
998 return Now;
999}
1000
1002 uint64_t StartOffset = W.OS.tell();
1003
1004 setWeakDefaultNames();
1005 if (Mode != DwoOnly)
1006 createFileSymbols();
1007
1008 for (auto &Symbol : Symbols) {
1009 // Update section number & offset for symbols that have them.
1010 if (Symbol->Section)
1011 Symbol->Data.SectionNumber = Symbol->Section->Number;
1012 Symbol->setIndex(Header.NumberOfSymbols++);
1013 // Update auxiliary symbol info.
1014 Symbol->Data.NumberOfAuxSymbols = Symbol->Aux.size();
1015 Header.NumberOfSymbols += Symbol->Data.NumberOfAuxSymbols;
1016 }
1017
1018 // Build string table.
1019 for (const auto &S : Sections)
1020 if (S->Name.size() > COFF::NameSize)
1021 Strings.add(S->Name);
1022 for (const auto &S : Symbols)
1023 if (S->Name.size() > COFF::NameSize)
1024 Strings.add(S->Name);
1025 Strings.finalize();
1026
1027 // Set names.
1028 for (const auto &S : Sections)
1029 SetSectionName(*S);
1030 for (auto &S : Symbols)
1031 SetSymbolName(*S);
1032
1033 // Fixup weak external references.
1034 for (auto &Symbol : Symbols) {
1035 if (Symbol->Other) {
1036 assert(Symbol->getIndex() != -1);
1037 assert(Symbol->Aux.size() == 1 && "Symbol must contain one aux symbol!");
1038 assert(Symbol->Aux[0].AuxType == ATWeakExternal &&
1039 "Symbol's aux symbol must be a Weak External!");
1040 Symbol->Aux[0].Aux.WeakExternal.TagIndex = Symbol->Other->getIndex();
1041 }
1042 }
1043
1044 // Fixup associative COMDAT sections.
1045 for (auto &Section : Sections) {
1046 if (Section->Symbol->Aux[0].Aux.SectionDefinition.Selection !=
1048 continue;
1049
1050 const MCSectionCOFF &MCSec = *Section->MCSection;
1051 const MCSymbol *AssocMCSym = MCSec.getCOMDATSymbol();
1052 assert(AssocMCSym);
1053
1054 // It's an error to try to associate with an undefined symbol or a symbol
1055 // without a section.
1056 if (!AssocMCSym->isInSection()) {
1057 getContext().reportError(
1058 SMLoc(), Twine("cannot make section ") + MCSec.getName() +
1059 Twine(" associative with sectionless symbol ") +
1060 AssocMCSym->getName());
1061 continue;
1062 }
1063
1064 const auto *AssocMCSec =
1065 static_cast<const MCSectionCOFF *>(&AssocMCSym->getSection());
1066 assert(SectionMap.count(AssocMCSec));
1067 COFFSection *AssocSec = SectionMap[AssocMCSec];
1068
1069 // Skip this section if the associated section is unused.
1070 if (AssocSec->Number == -1)
1071 continue;
1072
1073 Section->Symbol->Aux[0].Aux.SectionDefinition.Number = AssocSec->Number;
1074 }
1075
1076 // Create the contents of the .llvm_addrsig section.
1077 if (Mode != DwoOnly && OWriter.getEmitAddrsigSection()) {
1078 SmallString<0> Content;
1079 raw_svector_ostream OS(Content);
1080 for (const MCSymbol *S : OWriter.AddrsigSyms) {
1081 if (!S->isRegistered())
1082 continue;
1083 if (!S->isTemporary()) {
1084 encodeULEB128(S->getIndex(), OS);
1085 continue;
1086 }
1087
1088 MCSection *TargetSection = &S->getSection();
1089 assert(SectionMap.contains(TargetSection) &&
1090 "Section must already have been defined in "
1091 "executePostLayoutBinding!");
1092 encodeULEB128(SectionMap[TargetSection]->Symbol->getIndex(), OS);
1093 }
1094 auto *Sec = getContext().getCOFFSection(".llvm_addrsig",
1096 Sec->curFragList()->Tail->setVarContents(OS.str());
1097 }
1098
1099 // Create the contents of the .llvm.call-graph-profile section.
1100 if (Mode != DwoOnly && !OWriter.getCGProfile().empty()) {
1101 SmallString<0> Content;
1102 raw_svector_ostream OS(Content);
1103 for (const auto &CGPE : OWriter.getCGProfile()) {
1104 uint32_t FromIndex = CGPE.From->getSymbol().getIndex();
1105 uint32_t ToIndex = CGPE.To->getSymbol().getIndex();
1106 support::endian::write(OS, FromIndex, W.Endian);
1107 support::endian::write(OS, ToIndex, W.Endian);
1108 support::endian::write(OS, CGPE.Count, W.Endian);
1109 }
1110 auto *Sec = getContext().getCOFFSection(".llvm.call-graph-profile",
1112 Sec->curFragList()->Tail->setVarContents(OS.str());
1113 }
1114
1115 assignFileOffsets();
1116
1117 // MS LINK expects to be able to use this timestamp to implement their
1118 // /INCREMENTAL feature.
1119 if (OWriter.IncrementalLinkerCompatible) {
1120 Header.TimeDateStamp = getTime();
1121 } else {
1122 // Have deterministic output if /INCREMENTAL isn't needed. Also matches GNU.
1123 Header.TimeDateStamp = 0;
1124 }
1125
1126 // Write it all to disk...
1127 WriteFileHeader(Header);
1128 writeSectionHeaders();
1129
1130#ifndef NDEBUG
1131 sections::iterator I = Sections.begin();
1132 sections::iterator IE = Sections.end();
1133 auto J = Asm->begin();
1134 auto JE = Asm->end();
1135 for (; I != IE && J != JE; ++I, ++J) {
1136 while (J != JE && ((Mode == NonDwoOnly && isDwoSection(*J)) ||
1137 (Mode == DwoOnly && !isDwoSection(*J))))
1138 ++J;
1139 assert(J != JE && (**I).MCSection == &*J && "Wrong bound MCSection");
1140 }
1141#endif
1142
1143 // Write section contents.
1144 for (std::unique_ptr<COFFSection> &Sec : Sections)
1145 writeSection(*Sec);
1146
1147 assert(W.OS.tell() == Header.PointerToSymbolTable &&
1148 "Header::PointerToSymbolTable is insane!");
1149
1150 // Write a symbol table.
1151 for (auto &Symbol : Symbols)
1152 if (Symbol->getIndex() != -1)
1153 WriteSymbol(*Symbol);
1154
1155 // Write a string table, which completes the entire COFF file.
1156 Strings.write(W.OS);
1157
1158 return W.OS.tell() - StartOffset;
1159}
1160
1162 return SectionMap.at(&Section)->Number;
1163}
1164
1165//------------------------------------------------------------------------------
1166// WinCOFFObjectWriter class implementation
1167
1168////////////////////////////////////////////////////////////////////////////////
1169// MCObjectWriter interface implementations
1170
1172 IncrementalLinkerCompatible = false;
1173 ObjWriter->reset();
1174 if (DwoWriter)
1175 DwoWriter->reset();
1177}
1178
1181 ObjWriter->setAssembler(Asm);
1182 if (DwoWriter)
1183 DwoWriter->setAssembler(Asm);
1184}
1185
1187 const MCSymbol &SymA, const MCFragment &FB, bool InSet,
1188 bool IsPCRel) const {
1189 // Don't drop relocations between functions, even if they are in the same text
1190 // section. Multiple Visual C++ linker features depend on having the
1191 // relocations present. The /INCREMENTAL flag will cause these relocations to
1192 // point to thunks, and the /GUARD:CF flag assumes that it can use relocations
1193 // to approximate the set of all address taken functions. LLD's implementation
1194 // of /GUARD:CF also relies on the existance of these relocations.
1195 uint16_t Type = static_cast<const MCSymbolCOFF &>(SymA).getType();
1197 return false;
1198 return &SymA.getSection() == FB.getParent();
1199}
1200
1202 ObjWriter->executePostLayoutBinding();
1203 if (DwoWriter)
1204 DwoWriter->executePostLayoutBinding();
1205}
1206
1208 const MCFixup &Fixup, MCValue Target,
1209 uint64_t &FixedValue) {
1210 assert(!isDwoSection(*F.getParent()) && "No relocation in Dwo sections");
1211 ObjWriter->recordRelocation(F, Fixup, Target, FixedValue);
1212}
1213
1215 // If the assember had an error, then layout will not have completed, so we
1216 // cannot write an object file.
1217 if (getContext().hadError())
1218 return 0;
1219
1220 uint64_t TotalSize = ObjWriter->writeObject();
1221 if (DwoWriter)
1222 TotalSize += DwoWriter->writeObject();
1223 return TotalSize;
1224}
1225
1227 return ObjWriter->getSectionNumber(Section);
1228}
1229
1231 : Machine(Machine_) {}
1232
1233// Pin the vtable to this file.
1234void MCWinCOFFObjectTargetWriter::anchor() {}
1235
1236//------------------------------------------------------------------------------
1237// WinCOFFObjectWriter factory function
1238
1239std::unique_ptr<MCObjectWriter> llvm::createWinCOFFObjectWriter(
1240 std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS) {
1241 return std::make_unique<WinCOFFObjectWriter>(std::move(MOTW), OS);
1242}
1243
1244std::unique_ptr<MCObjectWriter> llvm::createWinCOFFDwoObjectWriter(
1245 std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS,
1246 raw_pwrite_stream &DwoOS) {
1247 return std::make_unique<WinCOFFObjectWriter>(std::move(MOTW), OS, DwoOS);
1248}
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:55
#define I(x, y, z)
Definition MD5.cpp:58
std::pair< uint64_t, uint64_t > Interval
PowerPC TLS Dynamic Call Fixup
static const char * name
This file contains some templates that are useful if you are working with the STL at all.
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:471
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:261
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:158
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:496
Align getAlign() const
Definition MCSection.h:579
StringRef getName() const
Definition MCSection.h:565
MCSymbol * getBeginSymbol()
Definition MCSection.h:568
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:346
uint64_t getOffset() const
Definition MCSymbol.h:289
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
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.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition StringRef.h:281
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:45
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_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:471
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.
@ Offset
Definition DWP.cpp:477
@ Length
Definition DWP.cpp:477
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:1665
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1632
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:167
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:198
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:189
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:1849
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:81
endianness
Definition bit.h:71
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:851
#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: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