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