Line data Source code
1 : //===- llvm/MC/WinCOFFObjectWriter.cpp ------------------------------------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file contains an implementation of a Win32 COFF object file writer.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "llvm/ADT/DenseMap.h"
15 : #include "llvm/ADT/STLExtras.h"
16 : #include "llvm/ADT/SmallString.h"
17 : #include "llvm/ADT/SmallVector.h"
18 : #include "llvm/ADT/StringRef.h"
19 : #include "llvm/ADT/Twine.h"
20 : #include "llvm/BinaryFormat/COFF.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"
27 : #include "llvm/MC/MCObjectWriter.h"
28 : #include "llvm/MC/MCSection.h"
29 : #include "llvm/MC/MCSectionCOFF.h"
30 : #include "llvm/MC/MCSymbol.h"
31 : #include "llvm/MC/MCSymbolCOFF.h"
32 : #include "llvm/MC/MCValue.h"
33 : #include "llvm/MC/MCWinCOFFObjectWriter.h"
34 : #include "llvm/MC/StringTableBuilder.h"
35 : #include "llvm/Support/Casting.h"
36 : #include "llvm/Support/Endian.h"
37 : #include "llvm/Support/ErrorHandling.h"
38 : #include "llvm/Support/JamCRC.h"
39 : #include "llvm/Support/LEB128.h"
40 : #include "llvm/Support/MathExtras.h"
41 : #include "llvm/Support/raw_ostream.h"
42 : #include <algorithm>
43 : #include <cassert>
44 : #include <cstddef>
45 : #include <cstdint>
46 : #include <cstring>
47 : #include <ctime>
48 : #include <memory>
49 : #include <string>
50 : #include <vector>
51 :
52 : using namespace llvm;
53 : using llvm::support::endian::write32le;
54 :
55 : #define DEBUG_TYPE "WinCOFFObjectWriter"
56 :
57 : namespace {
58 :
59 : using name = SmallString<COFF::NameSize>;
60 :
61 : enum AuxiliaryType {
62 : ATWeakExternal,
63 : ATFile,
64 : ATSectionDefinition
65 : };
66 :
67 : struct AuxSymbol {
68 : AuxiliaryType AuxType;
69 : COFF::Auxiliary Aux;
70 : };
71 :
72 : class COFFSection;
73 :
74 : class COFFSymbol {
75 : public:
76 : COFF::symbol Data = {};
77 :
78 : using AuxiliarySymbols = SmallVector<AuxSymbol, 1>;
79 :
80 : name Name;
81 : int Index;
82 : AuxiliarySymbols Aux;
83 : COFFSymbol *Other = nullptr;
84 : COFFSection *Section = nullptr;
85 : int Relocations = 0;
86 : const MCSymbol *MC = nullptr;
87 :
88 4211 : COFFSymbol(StringRef Name) : Name(Name) {}
89 :
90 : void set_name_offset(uint32_t Offset);
91 :
92 0 : int64_t getIndex() const { return Index; }
93 0 : void setIndex(int Value) {
94 4195 : Index = Value;
95 0 : if (MC)
96 0 : MC->setIndex(static_cast<uint32_t>(Value));
97 0 : }
98 : };
99 :
100 : // This class contains staging data for a COFF relocation entry.
101 : struct COFFRelocation {
102 : COFF::relocation Data;
103 : COFFSymbol *Symb = nullptr;
104 :
105 2782 : COFFRelocation() = default;
106 :
107 : static size_t size() { return COFF::RelocationSize; }
108 : };
109 :
110 : using relocations = std::vector<COFFRelocation>;
111 :
112 : class COFFSection {
113 : public:
114 : COFF::section Header = {};
115 :
116 : std::string Name;
117 : int Number;
118 : MCSectionCOFF const *MCSection = nullptr;
119 : COFFSymbol *Symbol = nullptr;
120 : relocations Relocations;
121 :
122 2472 : COFFSection(StringRef Name) : Name(Name) {}
123 : };
124 :
125 0 : class WinCOFFObjectWriter : public MCObjectWriter {
126 : public:
127 : support::endian::Writer W;
128 :
129 : using symbols = std::vector<std::unique_ptr<COFFSymbol>>;
130 : using sections = std::vector<std::unique_ptr<COFFSection>>;
131 :
132 : using symbol_map = DenseMap<MCSymbol const *, COFFSymbol *>;
133 : using section_map = DenseMap<MCSection const *, COFFSection *>;
134 :
135 : std::unique_ptr<MCWinCOFFObjectTargetWriter> TargetObjectWriter;
136 :
137 : // Root level file contents.
138 : COFF::header Header = {};
139 : sections Sections;
140 : symbols Symbols;
141 : StringTableBuilder Strings{StringTableBuilder::WinCOFF};
142 :
143 : // Maps used during object file creation.
144 : section_map SectionMap;
145 : symbol_map SymbolMap;
146 :
147 : bool UseBigObj;
148 :
149 : bool EmitAddrsigSection = false;
150 : MCSectionCOFF *AddrsigSection;
151 : std::vector<const MCSymbol *> AddrsigSyms;
152 :
153 : WinCOFFObjectWriter(std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW,
154 : raw_pwrite_stream &OS);
155 :
156 198 : void reset() override {
157 198 : memset(&Header, 0, sizeof(Header));
158 198 : Header.Machine = TargetObjectWriter->getMachine();
159 : Sections.clear();
160 : Symbols.clear();
161 198 : Strings.clear();
162 198 : SectionMap.clear();
163 198 : SymbolMap.clear();
164 : MCObjectWriter::reset();
165 198 : }
166 :
167 : COFFSymbol *createSymbol(StringRef Name);
168 : COFFSymbol *GetOrCreateCOFFSymbol(const MCSymbol *Symbol);
169 : COFFSection *createSection(StringRef Name);
170 :
171 : void defineSection(MCSectionCOFF const &Sec);
172 :
173 : COFFSymbol *getLinkedSymbol(const MCSymbol &Symbol);
174 : void DefineSymbol(const MCSymbol &Symbol, MCAssembler &Assembler,
175 : const MCAsmLayout &Layout);
176 :
177 : void SetSymbolName(COFFSymbol &S);
178 : void SetSectionName(COFFSection &S);
179 :
180 : bool IsPhysicalSection(COFFSection *S);
181 :
182 : // Entity writing methods.
183 :
184 : void WriteFileHeader(const COFF::header &Header);
185 : void WriteSymbol(const COFFSymbol &S);
186 : void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols &S);
187 : void writeSectionHeaders();
188 : void WriteRelocation(const COFF::relocation &R);
189 : uint32_t writeSectionContents(MCAssembler &Asm, const MCAsmLayout &Layout,
190 : const MCSection &MCSec);
191 : void writeSection(MCAssembler &Asm, const MCAsmLayout &Layout,
192 : const COFFSection &Sec, const MCSection &MCSec);
193 :
194 : // MCObjectWriter interface implementation.
195 :
196 : void executePostLayoutBinding(MCAssembler &Asm,
197 : const MCAsmLayout &Layout) override;
198 :
199 : bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
200 : const MCSymbol &SymA,
201 : const MCFragment &FB, bool InSet,
202 : bool IsPCRel) const override;
203 :
204 : void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
205 : const MCFragment *Fragment, const MCFixup &Fixup,
206 : MCValue Target, uint64_t &FixedValue) override;
207 :
208 : void createFileSymbols(MCAssembler &Asm);
209 : void assignSectionNumbers();
210 : void assignFileOffsets(MCAssembler &Asm, const MCAsmLayout &Layout);
211 :
212 25 : void emitAddrsigSection() override { EmitAddrsigSection = true; }
213 6 : void addAddrsigSymbol(const MCSymbol *Sym) override {
214 6 : AddrsigSyms.push_back(Sym);
215 6 : }
216 :
217 : uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
218 : };
219 :
220 : } // end anonymous namespace
221 :
222 : //------------------------------------------------------------------------------
223 : // Symbol class implementation
224 :
225 : // In the case that the name does not fit within 8 bytes, the offset
226 : // into the string table is stored in the last 4 bytes instead, leaving
227 : // the first 4 bytes as 0.
228 : void COFFSymbol::set_name_offset(uint32_t Offset) {
229 : write32le(Data.Name + 0, 0);
230 : write32le(Data.Name + 4, Offset);
231 : }
232 :
233 : //------------------------------------------------------------------------------
234 : // WinCOFFObjectWriter class implementation
235 :
236 1033 : WinCOFFObjectWriter::WinCOFFObjectWriter(
237 1033 : std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS)
238 3099 : : W(OS, support::little), TargetObjectWriter(std::move(MOTW)) {
239 1033 : Header.Machine = TargetObjectWriter->getMachine();
240 1033 : }
241 :
242 4211 : COFFSymbol *WinCOFFObjectWriter::createSymbol(StringRef Name) {
243 8422 : Symbols.push_back(make_unique<COFFSymbol>(Name));
244 4211 : return Symbols.back().get();
245 : }
246 :
247 2000 : COFFSymbol *WinCOFFObjectWriter::GetOrCreateCOFFSymbol(const MCSymbol *Symbol) {
248 2000 : COFFSymbol *&Ret = SymbolMap[Symbol];
249 2000 : if (!Ret)
250 3428 : Ret = createSymbol(Symbol->getName());
251 2000 : return Ret;
252 : }
253 :
254 2472 : COFFSection *WinCOFFObjectWriter::createSection(StringRef Name) {
255 2472 : Sections.emplace_back(make_unique<COFFSection>(Name));
256 2472 : return Sections.back().get();
257 : }
258 :
259 2471 : static uint32_t getAlignment(const MCSectionCOFF &Sec) {
260 2471 : switch (Sec.getAlignment()) {
261 : case 1:
262 : return COFF::IMAGE_SCN_ALIGN_1BYTES;
263 3 : case 2:
264 3 : return COFF::IMAGE_SCN_ALIGN_2BYTES;
265 1628 : case 4:
266 1628 : return COFF::IMAGE_SCN_ALIGN_4BYTES;
267 47 : case 8:
268 47 : return COFF::IMAGE_SCN_ALIGN_8BYTES;
269 299 : case 16:
270 299 : return COFF::IMAGE_SCN_ALIGN_16BYTES;
271 2 : case 32:
272 2 : return COFF::IMAGE_SCN_ALIGN_32BYTES;
273 0 : case 64:
274 0 : return COFF::IMAGE_SCN_ALIGN_64BYTES;
275 0 : case 128:
276 0 : return COFF::IMAGE_SCN_ALIGN_128BYTES;
277 0 : case 256:
278 0 : return COFF::IMAGE_SCN_ALIGN_256BYTES;
279 0 : case 512:
280 0 : return COFF::IMAGE_SCN_ALIGN_512BYTES;
281 0 : case 1024:
282 0 : return COFF::IMAGE_SCN_ALIGN_1024BYTES;
283 0 : case 2048:
284 0 : return COFF::IMAGE_SCN_ALIGN_2048BYTES;
285 0 : case 4096:
286 0 : return COFF::IMAGE_SCN_ALIGN_4096BYTES;
287 36 : case 8192:
288 36 : return COFF::IMAGE_SCN_ALIGN_8192BYTES;
289 : }
290 0 : 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.
295 2472 : void WinCOFFObjectWriter::defineSection(const MCSectionCOFF &MCSec) {
296 2472 : COFFSection *Section = createSection(MCSec.getSectionName());
297 2472 : COFFSymbol *Symbol = createSymbol(MCSec.getSectionName());
298 2472 : Section->Symbol = Symbol;
299 2472 : Symbol->Section = Section;
300 2472 : Symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_STATIC;
301 :
302 : // Create a COMDAT symbol if needed.
303 2472 : if (MCSec.getSelection() != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
304 2354 : if (const MCSymbol *S = MCSec.getCOMDATSymbol()) {
305 286 : COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(S);
306 286 : if (COMDATSymbol->Section)
307 1 : report_fatal_error("two sections have the same comdat");
308 285 : COMDATSymbol->Section = Section;
309 : }
310 : }
311 :
312 : // In this case the auxiliary symbol is a Section Definition.
313 2471 : Symbol->Aux.resize(1);
314 2471 : Symbol->Aux[0] = {};
315 2471 : Symbol->Aux[0].AuxType = ATSectionDefinition;
316 2471 : Symbol->Aux[0].Aux.SectionDefinition.Selection = MCSec.getSelection();
317 :
318 : // Set section alignment.
319 2471 : Section->Header.Characteristics = MCSec.getCharacteristics();
320 2471 : Section->Header.Characteristics |= getAlignment(MCSec);
321 :
322 : // Bind internal COFF section to MC section.
323 2471 : Section->MCSection = &MCSec;
324 2471 : SectionMap[&MCSec] = Section;
325 2471 : }
326 :
327 1711 : static uint64_t getSymbolValue(const MCSymbol &Symbol,
328 : const MCAsmLayout &Layout) {
329 1711 : if (Symbol.isCommon() && Symbol.isExternal())
330 20 : return Symbol.getCommonSize();
331 :
332 : uint64_t Res;
333 1691 : if (!Layout.getSymbolOffset(Symbol, Res))
334 : return 0;
335 :
336 1424 : return Res;
337 : }
338 :
339 8 : COFFSymbol *WinCOFFObjectWriter::getLinkedSymbol(const MCSymbol &Symbol) {
340 8 : if (!Symbol.isVariable())
341 : return nullptr;
342 :
343 : const MCSymbolRefExpr *SymRef =
344 : dyn_cast<MCSymbolRefExpr>(Symbol.getVariableValue());
345 : if (!SymRef)
346 : return nullptr;
347 :
348 4 : const MCSymbol &Aliasee = SymRef->getSymbol();
349 4 : if (!Aliasee.isUndefined())
350 : return nullptr;
351 1 : return GetOrCreateCOFFSymbol(&Aliasee);
352 : }
353 :
354 : /// This function takes a symbol data object from the assembler
355 : /// and creates the associated COFF symbol staging object.
356 0 : void WinCOFFObjectWriter::DefineSymbol(const MCSymbol &MCSym,
357 : MCAssembler &Assembler,
358 : const MCAsmLayout &Layout) {
359 0 : COFFSymbol *Sym = GetOrCreateCOFFSymbol(&MCSym);
360 0 : const MCSymbol *Base = Layout.getBaseSymbol(MCSym);
361 : COFFSection *Sec = nullptr;
362 0 : if (Base && Base->getFragment()) {
363 0 : Sec = SectionMap[Base->getFragment()->getParent()];
364 0 : if (Sym->Section && Sym->Section != Sec)
365 0 : report_fatal_error("conflicting sections for symbol");
366 : }
367 :
368 : COFFSymbol *Local = nullptr;
369 0 : if (cast<MCSymbolCOFF>(MCSym).isWeakExternal()) {
370 0 : Sym->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
371 :
372 0 : COFFSymbol *WeakDefault = getLinkedSymbol(MCSym);
373 0 : if (!WeakDefault) {
374 0 : std::string WeakName = (".weak." + MCSym.getName() + ".default").str();
375 0 : WeakDefault = createSymbol(WeakName);
376 0 : if (!Sec)
377 0 : WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
378 : else
379 0 : WeakDefault->Section = Sec;
380 : Local = WeakDefault;
381 : }
382 :
383 0 : Sym->Other = WeakDefault;
384 :
385 : // Setup the Weak External auxiliary symbol.
386 0 : Sym->Aux.resize(1);
387 0 : memset(&Sym->Aux[0], 0, sizeof(Sym->Aux[0]));
388 0 : Sym->Aux[0].AuxType = ATWeakExternal;
389 0 : Sym->Aux[0].Aux.WeakExternal.TagIndex = 0;
390 0 : Sym->Aux[0].Aux.WeakExternal.Characteristics =
391 : COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY;
392 : } else {
393 0 : if (!Base)
394 0 : Sym->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
395 : else
396 0 : Sym->Section = Sec;
397 : Local = Sym;
398 : }
399 :
400 0 : if (Local) {
401 0 : Local->Data.Value = getSymbolValue(MCSym, Layout);
402 :
403 : const MCSymbolCOFF &SymbolCOFF = cast<MCSymbolCOFF>(MCSym);
404 0 : Local->Data.Type = SymbolCOFF.getType();
405 0 : Local->Data.StorageClass = SymbolCOFF.getClass();
406 :
407 : // If no storage class was specified in the streamer, define it here.
408 0 : if (Local->Data.StorageClass == COFF::IMAGE_SYM_CLASS_NULL) {
409 0 : bool IsExternal = MCSym.isExternal() ||
410 0 : (!MCSym.getFragment() && !MCSym.isVariable());
411 :
412 0 : Local->Data.StorageClass = IsExternal ? COFF::IMAGE_SYM_CLASS_EXTERNAL
413 : : COFF::IMAGE_SYM_CLASS_STATIC;
414 : }
415 : }
416 :
417 0 : Sym->MC = &MCSym;
418 0 : }
419 :
420 : // Maximum offsets for different string table entry encodings.
421 : enum : unsigned { Max7DecimalOffset = 9999999U };
422 : enum : uint64_t { MaxBase64Offset = 0xFFFFFFFFFULL }; // 64^6, including 0
423 :
424 : // Encode a string table entry offset in base 64, padded to 6 chars, and
425 : // prefixed with a double slash: '//AAAAAA', '//AAAAAB', ...
426 : // Buffer must be at least 8 bytes large. No terminating null appended.
427 : static void encodeBase64StringEntry(char *Buffer, uint64_t Value) {
428 : assert(Value > Max7DecimalOffset && Value <= MaxBase64Offset &&
429 : "Illegal section name encoding for value");
430 :
431 : static const char Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
432 : "abcdefghijklmnopqrstuvwxyz"
433 : "0123456789+/";
434 :
435 1 : Buffer[0] = '/';
436 1 : Buffer[1] = '/';
437 :
438 1 : char *Ptr = Buffer + 7;
439 7 : for (unsigned i = 0; i < 6; ++i) {
440 6 : unsigned Rem = Value % 64;
441 6 : Value /= 64;
442 6 : *(Ptr--) = Alphabet[Rem];
443 : }
444 : }
445 :
446 2459 : void WinCOFFObjectWriter::SetSectionName(COFFSection &S) {
447 2459 : if (S.Name.size() <= COFF::NameSize) {
448 2198 : std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size());
449 2198 : return;
450 : }
451 :
452 522 : uint64_t StringTableEntry = Strings.getOffset(S.Name);
453 261 : if (StringTableEntry <= Max7DecimalOffset) {
454 : SmallVector<char, COFF::NameSize> Buffer;
455 260 : Twine('/').concat(Twine(StringTableEntry)).toVector(Buffer);
456 : assert(Buffer.size() <= COFF::NameSize && Buffer.size() >= 2);
457 520 : std::memcpy(S.Header.Name, Buffer.data(), Buffer.size());
458 : return;
459 : }
460 1 : if (StringTableEntry <= MaxBase64Offset) {
461 : // Starting with 10,000,000, offsets are encoded as base64.
462 : encodeBase64StringEntry(S.Header.Name, StringTableEntry);
463 : return;
464 : }
465 0 : report_fatal_error("COFF string table is greater than 64 GB.");
466 : }
467 :
468 4195 : void WinCOFFObjectWriter::SetSymbolName(COFFSymbol &S) {
469 8390 : if (S.Name.size() > COFF::NameSize)
470 1766 : S.set_name_offset(Strings.getOffset(S.Name));
471 : else
472 3312 : std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size());
473 4195 : }
474 :
475 0 : bool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) {
476 2459 : return (S->Header.Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) ==
477 0 : 0;
478 : }
479 :
480 : //------------------------------------------------------------------------------
481 : // entity writing methods
482 :
483 445 : void WinCOFFObjectWriter::WriteFileHeader(const COFF::header &Header) {
484 445 : if (UseBigObj) {
485 : W.write<uint16_t>(COFF::IMAGE_FILE_MACHINE_UNKNOWN);
486 : W.write<uint16_t>(0xFFFF);
487 : W.write<uint16_t>(COFF::BigObjHeader::MinBigObjectVersion);
488 0 : W.write<uint16_t>(Header.Machine);
489 0 : W.write<uint32_t>(Header.TimeDateStamp);
490 0 : W.OS.write(COFF::BigObjMagic, sizeof(COFF::BigObjMagic));
491 0 : W.write<uint32_t>(0);
492 0 : W.write<uint32_t>(0);
493 0 : W.write<uint32_t>(0);
494 0 : W.write<uint32_t>(0);
495 0 : W.write<uint32_t>(Header.NumberOfSections);
496 0 : W.write<uint32_t>(Header.PointerToSymbolTable);
497 0 : W.write<uint32_t>(Header.NumberOfSymbols);
498 : } else {
499 445 : W.write<uint16_t>(Header.Machine);
500 445 : W.write<uint16_t>(static_cast<int16_t>(Header.NumberOfSections));
501 445 : W.write<uint32_t>(Header.TimeDateStamp);
502 445 : W.write<uint32_t>(Header.PointerToSymbolTable);
503 445 : W.write<uint32_t>(Header.NumberOfSymbols);
504 445 : W.write<uint16_t>(Header.SizeOfOptionalHeader);
505 445 : W.write<uint16_t>(Header.Characteristics);
506 : }
507 445 : }
508 :
509 4195 : void WinCOFFObjectWriter::WriteSymbol(const COFFSymbol &S) {
510 4195 : W.OS.write(S.Data.Name, COFF::NameSize);
511 4195 : W.write<uint32_t>(S.Data.Value);
512 4195 : if (UseBigObj)
513 0 : W.write<uint32_t>(S.Data.SectionNumber);
514 : else
515 4195 : W.write<uint16_t>(static_cast<int16_t>(S.Data.SectionNumber));
516 4195 : W.write<uint16_t>(S.Data.Type);
517 4195 : W.OS << char(S.Data.StorageClass);
518 4195 : W.OS << char(S.Data.NumberOfAuxSymbols);
519 4195 : WriteAuxiliarySymbols(S.Aux);
520 4195 : }
521 :
522 4195 : void WinCOFFObjectWriter::WriteAuxiliarySymbols(
523 : const COFFSymbol::AuxiliarySymbols &S) {
524 6689 : for (const AuxSymbol &i : S) {
525 2494 : switch (i.AuxType) {
526 8 : case ATWeakExternal:
527 8 : W.write<uint32_t>(i.Aux.WeakExternal.TagIndex);
528 8 : W.write<uint32_t>(i.Aux.WeakExternal.Characteristics);
529 8 : W.OS.write_zeros(sizeof(i.Aux.WeakExternal.unused));
530 8 : if (UseBigObj)
531 0 : W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size);
532 : break;
533 27 : case ATFile:
534 54 : W.OS.write(reinterpret_cast<const char *>(&i.Aux),
535 54 : UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size);
536 27 : break;
537 2459 : case ATSectionDefinition:
538 2459 : W.write<uint32_t>(i.Aux.SectionDefinition.Length);
539 2459 : W.write<uint16_t>(i.Aux.SectionDefinition.NumberOfRelocations);
540 2459 : W.write<uint16_t>(i.Aux.SectionDefinition.NumberOfLinenumbers);
541 2459 : W.write<uint32_t>(i.Aux.SectionDefinition.CheckSum);
542 2459 : W.write<uint16_t>(static_cast<int16_t>(i.Aux.SectionDefinition.Number));
543 2459 : W.OS << char(i.Aux.SectionDefinition.Selection);
544 2459 : W.OS.write_zeros(sizeof(i.Aux.SectionDefinition.unused));
545 2459 : W.write<uint16_t>(static_cast<int16_t>(i.Aux.SectionDefinition.Number >> 16));
546 2459 : if (UseBigObj)
547 0 : W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size);
548 : break;
549 : }
550 : }
551 4195 : }
552 :
553 : // Write the section header.
554 445 : void WinCOFFObjectWriter::writeSectionHeaders() {
555 : // Section numbers must be monotonically increasing in the section
556 : // header, but our Sections array is not sorted by section number,
557 : // so make a copy of Sections and sort it.
558 : std::vector<COFFSection *> Arr;
559 2904 : for (auto &Section : Sections)
560 2459 : Arr.push_back(Section.get());
561 : llvm::sort(Arr, [](const COFFSection *A, const COFFSection *B) {
562 0 : return A->Number < B->Number;
563 : });
564 :
565 2904 : for (auto &Section : Arr) {
566 2459 : if (Section->Number == -1)
567 : continue;
568 :
569 : COFF::section &S = Section->Header;
570 4918 : if (Section->Relocations.size() >= 0xffff)
571 0 : S.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL;
572 2459 : W.OS.write(S.Name, COFF::NameSize);
573 2459 : W.write<uint32_t>(S.VirtualSize);
574 2459 : W.write<uint32_t>(S.VirtualAddress);
575 2459 : W.write<uint32_t>(S.SizeOfRawData);
576 2459 : W.write<uint32_t>(S.PointerToRawData);
577 2459 : W.write<uint32_t>(S.PointerToRelocations);
578 2459 : W.write<uint32_t>(S.PointerToLineNumbers);
579 2459 : W.write<uint16_t>(S.NumberOfRelocations);
580 2459 : W.write<uint16_t>(S.NumberOfLineNumbers);
581 2459 : W.write<uint32_t>(S.Characteristics);
582 : }
583 445 : }
584 :
585 2767 : void WinCOFFObjectWriter::WriteRelocation(const COFF::relocation &R) {
586 2767 : W.write<uint32_t>(R.VirtualAddress);
587 2767 : W.write<uint32_t>(R.SymbolTableIndex);
588 2767 : W.write<uint16_t>(R.Type);
589 2767 : }
590 :
591 : // Write MCSec's contents. What this function does is essentially
592 : // "Asm.writeSectionData(&MCSec, Layout)", but it's a bit complicated
593 : // because it needs to compute a CRC.
594 0 : uint32_t WinCOFFObjectWriter::writeSectionContents(MCAssembler &Asm,
595 : const MCAsmLayout &Layout,
596 : const MCSection &MCSec) {
597 : // Save the contents of the section to a temporary buffer, we need this
598 : // to CRC the data before we dump it into the object file.
599 : SmallVector<char, 128> Buf;
600 : raw_svector_ostream VecOS(Buf);
601 0 : Asm.writeSectionData(VecOS, &MCSec, Layout);
602 :
603 : // Write the section contents to the object file.
604 0 : W.OS << Buf;
605 :
606 : // Calculate our CRC with an initial value of '0', this is not how
607 : // JamCRC is specified but it aligns with the expected output.
608 : JamCRC JC(/*Init=*/0);
609 0 : JC.update(Buf);
610 0 : return JC.getCRC();
611 : }
612 :
613 2459 : void WinCOFFObjectWriter::writeSection(MCAssembler &Asm,
614 : const MCAsmLayout &Layout,
615 : const COFFSection &Sec,
616 : const MCSection &MCSec) {
617 2459 : if (Sec.Number == -1)
618 : return;
619 :
620 : // Write the section contents.
621 2459 : if (Sec.Header.PointerToRawData != 0) {
622 : assert(W.OS.tell() == Sec.Header.PointerToRawData &&
623 : "Section::PointerToRawData is insane!");
624 :
625 2010 : uint32_t CRC = writeSectionContents(Asm, Layout, MCSec);
626 :
627 : // Update the section definition auxiliary symbol to record the CRC.
628 2010 : COFFSection *Sec = SectionMap[&MCSec];
629 2010 : COFFSymbol::AuxiliarySymbols &AuxSyms = Sec->Symbol->Aux;
630 : assert(AuxSyms.size() == 1 && AuxSyms[0].AuxType == ATSectionDefinition);
631 : AuxSymbol &SecDef = AuxSyms[0];
632 2010 : SecDef.Aux.SectionDefinition.CheckSum = CRC;
633 : }
634 :
635 : // Write relocations for this section.
636 2459 : if (Sec.Relocations.empty()) {
637 : assert(Sec.Header.PointerToRelocations == 0 &&
638 : "Section::PointerToRelocations is insane!");
639 : return;
640 : }
641 :
642 : assert(W.OS.tell() == Sec.Header.PointerToRelocations &&
643 : "Section::PointerToRelocations is insane!");
644 :
645 670 : if (Sec.Relocations.size() >= 0xffff) {
646 : // In case of overflow, write actual relocation count as first
647 : // relocation. Including the synthetic reloc itself (+ 1).
648 : COFF::relocation R;
649 0 : R.VirtualAddress = Sec.Relocations.size() + 1;
650 0 : R.SymbolTableIndex = 0;
651 0 : R.Type = 0;
652 0 : WriteRelocation(R);
653 : }
654 :
655 3437 : for (const auto &Relocation : Sec.Relocations)
656 2767 : WriteRelocation(Relocation.Data);
657 : }
658 :
659 : ////////////////////////////////////////////////////////////////////////////////
660 : // MCObjectWriter interface implementations
661 :
662 448 : void WinCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
663 : const MCAsmLayout &Layout) {
664 448 : if (EmitAddrsigSection) {
665 50 : AddrsigSection = Asm.getContext().getCOFFSection(
666 : ".llvm_addrsig", COFF::IMAGE_SCN_LNK_REMOVE,
667 : SectionKind::getMetadata());
668 25 : Asm.registerSection(*AddrsigSection);
669 : }
670 :
671 : // "Define" each section & symbol. This creates section & symbol
672 : // entries in the staging area.
673 2919 : for (const auto &Section : Asm)
674 2472 : defineSection(static_cast<const MCSectionCOFF &>(Section));
675 :
676 8369 : for (const MCSymbol &Symbol : Asm.symbols())
677 7923 : if (!Symbol.isTemporary())
678 1713 : DefineSymbol(Symbol, Asm, Layout);
679 446 : }
680 :
681 4200 : bool WinCOFFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
682 : const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB,
683 : bool InSet, bool IsPCRel) const {
684 : // Don't drop relocations between functions, even if they are in the same text
685 : // section. Multiple Visual C++ linker features depend on having the
686 : // relocations present. The /INCREMENTAL flag will cause these relocations to
687 : // point to thunks, and the /GUARD:CF flag assumes that it can use relocations
688 : // to approximate the set of all address taken functions. LLD's implementation
689 : // of /GUARD:CF also relies on the existance of these relocations.
690 4200 : uint16_t Type = cast<MCSymbolCOFF>(SymA).getType();
691 4200 : if ((Type >> COFF::SCT_COMPLEX_TYPE_SHIFT) == COFF::IMAGE_SYM_DTYPE_FUNCTION)
692 : return false;
693 4131 : return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB,
694 4131 : InSet, IsPCRel);
695 : }
696 :
697 2785 : void WinCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
698 : const MCAsmLayout &Layout,
699 : const MCFragment *Fragment,
700 : const MCFixup &Fixup, MCValue Target,
701 : uint64_t &FixedValue) {
702 : assert(Target.getSymA() && "Relocation must reference a symbol!");
703 :
704 2785 : const MCSymbol &A = Target.getSymA()->getSymbol();
705 2785 : if (!A.isRegistered()) {
706 0 : Asm.getContext().reportError(Fixup.getLoc(),
707 0 : Twine("symbol '") + A.getName() +
708 0 : "' can not be undefined");
709 3 : return;
710 : }
711 3647 : if (A.isTemporary() && A.isUndefined()) {
712 4 : Asm.getContext().reportError(Fixup.getLoc(),
713 2 : Twine("assembler label '") + A.getName() +
714 2 : "' can not be undefined");
715 2 : return;
716 : }
717 :
718 2783 : MCSection *MCSec = Fragment->getParent();
719 :
720 : // Mark this symbol as requiring an entry in the symbol table.
721 : assert(SectionMap.find(MCSec) != SectionMap.end() &&
722 : "Section must already have been defined in executePostLayoutBinding!");
723 :
724 2783 : COFFSection *Sec = SectionMap[MCSec];
725 2783 : const MCSymbolRefExpr *SymB = Target.getSymB();
726 :
727 2783 : if (SymB) {
728 16 : const MCSymbol *B = &SymB->getSymbol();
729 16 : if (!B->getFragment()) {
730 2 : Asm.getContext().reportError(
731 : Fixup.getLoc(),
732 1 : Twine("symbol '") + B->getName() +
733 1 : "' can not be undefined in a subtraction expression");
734 1 : return;
735 : }
736 :
737 : // Offset of the symbol in the section
738 15 : int64_t OffsetOfB = Layout.getSymbolOffset(*B);
739 :
740 : // Offset of the relocation in the section
741 : int64_t OffsetOfRelocation =
742 15 : Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
743 :
744 15 : FixedValue = (OffsetOfRelocation - OffsetOfB) + Target.getConstant();
745 : } else {
746 2767 : FixedValue = Target.getConstant();
747 : }
748 :
749 : COFFRelocation Reloc;
750 :
751 2782 : Reloc.Data.SymbolTableIndex = 0;
752 2782 : Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment);
753 :
754 : // Turn relocations for temporary symbols into section relocations.
755 2782 : if (A.isTemporary()) {
756 : MCSection *TargetSection = &A.getSection();
757 : assert(
758 : SectionMap.find(TargetSection) != SectionMap.end() &&
759 : "Section must already have been defined in executePostLayoutBinding!");
760 860 : Reloc.Symb = SectionMap[TargetSection]->Symbol;
761 860 : FixedValue += Layout.getSymbolOffset(A);
762 : } else {
763 : assert(
764 : SymbolMap.find(&A) != SymbolMap.end() &&
765 : "Symbol must already have been defined in executePostLayoutBinding!");
766 1922 : Reloc.Symb = SymbolMap[&A];
767 : }
768 :
769 2782 : ++Reloc.Symb->Relocations;
770 :
771 2782 : Reloc.Data.VirtualAddress += Fixup.getOffset();
772 2782 : Reloc.Data.Type = TargetObjectWriter->getRelocType(
773 2782 : Asm.getContext(), Target, Fixup, SymB, Asm.getBackend());
774 :
775 : // FIXME: Can anyone explain what this does other than adjust for the size
776 : // of the offset?
777 2781 : if ((Header.Machine == COFF::IMAGE_FILE_MACHINE_AMD64 &&
778 2504 : Reloc.Data.Type == COFF::IMAGE_REL_AMD64_REL32) ||
779 969 : (Header.Machine == COFF::IMAGE_FILE_MACHINE_I386 &&
780 : Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32))
781 398 : FixedValue += 4;
782 :
783 2781 : if (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT) {
784 : switch (Reloc.Data.Type) {
785 : case COFF::IMAGE_REL_ARM_ABSOLUTE:
786 : case COFF::IMAGE_REL_ARM_ADDR32:
787 : case COFF::IMAGE_REL_ARM_ADDR32NB:
788 : case COFF::IMAGE_REL_ARM_TOKEN:
789 : case COFF::IMAGE_REL_ARM_SECTION:
790 : case COFF::IMAGE_REL_ARM_SECREL:
791 : break;
792 : case COFF::IMAGE_REL_ARM_BRANCH11:
793 : case COFF::IMAGE_REL_ARM_BLX11:
794 : // IMAGE_REL_ARM_BRANCH11 and IMAGE_REL_ARM_BLX11 are only used for
795 : // pre-ARMv7, which implicitly rules it out of ARMNT (it would be valid
796 : // for Windows CE).
797 : case COFF::IMAGE_REL_ARM_BRANCH24:
798 : case COFF::IMAGE_REL_ARM_BLX24:
799 : case COFF::IMAGE_REL_ARM_MOV32A:
800 : // IMAGE_REL_ARM_BRANCH24, IMAGE_REL_ARM_BLX24, IMAGE_REL_ARM_MOV32A are
801 : // only used for ARM mode code, which is documented as being unsupported
802 : // by Windows on ARM. Empirical proof indicates that masm is able to
803 : // generate the relocations however the rest of the MSVC toolchain is
804 : // unable to handle it.
805 : llvm_unreachable("unsupported relocation");
806 : break;
807 : case COFF::IMAGE_REL_ARM_MOV32T:
808 : break;
809 51 : case COFF::IMAGE_REL_ARM_BRANCH20T:
810 : case COFF::IMAGE_REL_ARM_BRANCH24T:
811 : case COFF::IMAGE_REL_ARM_BLX23T:
812 : // IMAGE_REL_BRANCH20T, IMAGE_REL_ARM_BRANCH24T, IMAGE_REL_ARM_BLX23T all
813 : // perform a 4 byte adjustment to the relocation. Relative branches are
814 : // offset by 4 on ARM, however, because there is no RELA relocations, all
815 : // branches are offset by 4.
816 51 : FixedValue = FixedValue + 4;
817 51 : break;
818 : }
819 : }
820 :
821 : // The fixed value never makes sense for section indices, ignore it.
822 2781 : if (Fixup.getKind() == FK_SecRel_2)
823 597 : FixedValue = 0;
824 :
825 2781 : if (TargetObjectWriter->recordRelocation(Fixup))
826 2767 : Sec->Relocations.push_back(Reloc);
827 : }
828 :
829 : static std::time_t getTime() {
830 26 : std::time_t Now = time(nullptr);
831 26 : if (Now < 0 || !isUInt<32>(Now))
832 : return UINT32_MAX;
833 : return Now;
834 : }
835 :
836 : // Create .file symbols.
837 445 : void WinCOFFObjectWriter::createFileSymbols(MCAssembler &Asm) {
838 463 : for (const std::string &Name : Asm.getFileNames()) {
839 : // round up to calculate the number of auxiliary symbols required
840 18 : unsigned SymbolSize = UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size;
841 18 : unsigned Count = (Name.size() + SymbolSize - 1) / SymbolSize;
842 :
843 18 : COFFSymbol *File = createSymbol(".file");
844 18 : File->Data.SectionNumber = COFF::IMAGE_SYM_DEBUG;
845 18 : File->Data.StorageClass = COFF::IMAGE_SYM_CLASS_FILE;
846 18 : File->Aux.resize(Count);
847 :
848 : unsigned Offset = 0;
849 18 : unsigned Length = Name.size();
850 27 : for (auto &Aux : File->Aux) {
851 27 : Aux.AuxType = ATFile;
852 :
853 27 : if (Length > SymbolSize) {
854 9 : memcpy(&Aux.Aux, Name.c_str() + Offset, SymbolSize);
855 9 : Length = Length - SymbolSize;
856 : } else {
857 18 : memcpy(&Aux.Aux, Name.c_str() + Offset, Length);
858 18 : memset((char *)&Aux.Aux + Length, 0, SymbolSize - Length);
859 18 : break;
860 : }
861 :
862 9 : Offset += SymbolSize;
863 : }
864 : }
865 445 : }
866 :
867 0 : static bool isAssociative(const COFFSection &Section) {
868 4918 : return Section.Symbol->Aux[0].Aux.SectionDefinition.Selection ==
869 0 : COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE;
870 : }
871 :
872 445 : void WinCOFFObjectWriter::assignSectionNumbers() {
873 445 : size_t I = 1;
874 : auto Assign = [&](COFFSection &Section) {
875 2459 : Section.Number = I;
876 2459 : Section.Symbol->Data.SectionNumber = I;
877 2459 : Section.Symbol->Aux[0].Aux.SectionDefinition.Number = I;
878 2459 : ++I;
879 : };
880 :
881 : // Although it is not explicitly requested by the Microsoft COFF spec,
882 : // we should avoid emitting forward associative section references,
883 : // because MSVC link.exe as of 2017 cannot handle that.
884 2904 : for (const std::unique_ptr<COFFSection> &Section : Sections)
885 4918 : if (!isAssociative(*Section))
886 : Assign(*Section);
887 2904 : for (const std::unique_ptr<COFFSection> &Section : Sections)
888 4918 : if (isAssociative(*Section))
889 : Assign(*Section);
890 445 : }
891 :
892 : // Assign file offsets to COFF object file structures.
893 445 : void WinCOFFObjectWriter::assignFileOffsets(MCAssembler &Asm,
894 : const MCAsmLayout &Layout) {
895 445 : unsigned Offset = W.OS.tell();
896 :
897 445 : Offset += UseBigObj ? COFF::Header32Size : COFF::Header16Size;
898 445 : Offset += COFF::SectionSize * Header.NumberOfSections;
899 :
900 2904 : for (const auto &Section : Asm) {
901 2459 : COFFSection *Sec = SectionMap[&Section];
902 :
903 2459 : if (Sec->Number == -1)
904 : continue;
905 :
906 2459 : Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(&Section);
907 :
908 2459 : if (IsPhysicalSection(Sec)) {
909 2010 : Sec->Header.PointerToRawData = Offset;
910 2010 : Offset += Sec->Header.SizeOfRawData;
911 : }
912 :
913 2459 : if (!Sec->Relocations.empty()) {
914 : bool RelocationsOverflow = Sec->Relocations.size() >= 0xffff;
915 :
916 670 : if (RelocationsOverflow) {
917 : // Signal overflow by setting NumberOfRelocations to max value. Actual
918 : // size is found in reloc #0. Microsoft tools understand this.
919 0 : Sec->Header.NumberOfRelocations = 0xffff;
920 : } else {
921 670 : Sec->Header.NumberOfRelocations = Sec->Relocations.size();
922 : }
923 670 : Sec->Header.PointerToRelocations = Offset;
924 :
925 670 : if (RelocationsOverflow) {
926 : // Reloc #0 will contain actual count, so make room for it.
927 0 : Offset += COFF::RelocationSize;
928 : }
929 :
930 1340 : Offset += COFF::RelocationSize * Sec->Relocations.size();
931 :
932 3437 : for (auto &Relocation : Sec->Relocations) {
933 : assert(Relocation.Symb->getIndex() != -1);
934 2767 : Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex();
935 : }
936 : }
937 :
938 : assert(Sec->Symbol->Aux.size() == 1 &&
939 : "Section's symbol must have one aux!");
940 2459 : AuxSymbol &Aux = Sec->Symbol->Aux[0];
941 : assert(Aux.AuxType == ATSectionDefinition &&
942 : "Section's symbol's aux symbol must be a Section Definition!");
943 2459 : Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData;
944 2459 : Aux.Aux.SectionDefinition.NumberOfRelocations =
945 2459 : Sec->Header.NumberOfRelocations;
946 2459 : Aux.Aux.SectionDefinition.NumberOfLinenumbers =
947 2459 : Sec->Header.NumberOfLineNumbers;
948 : }
949 :
950 445 : Header.PointerToSymbolTable = Offset;
951 445 : }
952 :
953 445 : uint64_t WinCOFFObjectWriter::writeObject(MCAssembler &Asm,
954 : const MCAsmLayout &Layout) {
955 445 : uint64_t StartOffset = W.OS.tell();
956 :
957 890 : if (Sections.size() > INT32_MAX)
958 0 : report_fatal_error(
959 : "PE COFF object files can't have more than 2147483647 sections");
960 :
961 445 : UseBigObj = Sections.size() > COFF::MaxNumberOfSections16;
962 445 : Header.NumberOfSections = Sections.size();
963 445 : Header.NumberOfSymbols = 0;
964 :
965 445 : assignSectionNumbers();
966 445 : createFileSymbols(Asm);
967 :
968 4640 : for (auto &Symbol : Symbols) {
969 : // Update section number & offset for symbols that have them.
970 4195 : if (Symbol->Section)
971 3651 : Symbol->Data.SectionNumber = Symbol->Section->Number;
972 4195 : Symbol->setIndex(Header.NumberOfSymbols++);
973 : // Update auxiliary symbol info.
974 4195 : Symbol->Data.NumberOfAuxSymbols = Symbol->Aux.size();
975 4195 : Header.NumberOfSymbols += Symbol->Data.NumberOfAuxSymbols;
976 : }
977 :
978 : // Build string table.
979 2904 : for (const auto &S : Sections)
980 2459 : if (S->Name.size() > COFF::NameSize)
981 522 : Strings.add(S->Name);
982 4640 : for (const auto &S : Symbols)
983 8390 : if (S->Name.size() > COFF::NameSize)
984 1766 : Strings.add(S->Name);
985 445 : Strings.finalize();
986 :
987 : // Set names.
988 2904 : for (const auto &S : Sections)
989 2459 : SetSectionName(*S);
990 4640 : for (auto &S : Symbols)
991 4195 : SetSymbolName(*S);
992 :
993 : // Fixup weak external references.
994 4640 : for (auto &Symbol : Symbols) {
995 4195 : if (Symbol->Other) {
996 : assert(Symbol->getIndex() != -1);
997 : assert(Symbol->Aux.size() == 1 && "Symbol must contain one aux symbol!");
998 : assert(Symbol->Aux[0].AuxType == ATWeakExternal &&
999 : "Symbol's aux symbol must be a Weak External!");
1000 16 : Symbol->Aux[0].Aux.WeakExternal.TagIndex = Symbol->Other->getIndex();
1001 : }
1002 : }
1003 :
1004 : // Fixup associative COMDAT sections.
1005 2904 : for (auto &Section : Sections) {
1006 4918 : if (Section->Symbol->Aux[0].Aux.SectionDefinition.Selection !=
1007 : COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
1008 : continue;
1009 :
1010 118 : const MCSectionCOFF &MCSec = *Section->MCSection;
1011 118 : const MCSymbol *AssocMCSym = MCSec.getCOMDATSymbol();
1012 : assert(AssocMCSym);
1013 :
1014 : // It's an error to try to associate with an undefined symbol or a symbol
1015 : // without a section.
1016 118 : if (!AssocMCSym->isInSection()) {
1017 1 : Asm.getContext().reportError(
1018 1 : SMLoc(), Twine("cannot make section ") + MCSec.getSectionName() +
1019 2 : Twine(" associative with sectionless symbol ") +
1020 2 : AssocMCSym->getName());
1021 1 : continue;
1022 : }
1023 :
1024 : const auto *AssocMCSec = cast<MCSectionCOFF>(&AssocMCSym->getSection());
1025 : assert(SectionMap.count(AssocMCSec));
1026 117 : COFFSection *AssocSec = SectionMap[AssocMCSec];
1027 :
1028 : // Skip this section if the associated section is unused.
1029 117 : if (AssocSec->Number == -1)
1030 : continue;
1031 :
1032 234 : Section->Symbol->Aux[0].Aux.SectionDefinition.Number = AssocSec->Number;
1033 : }
1034 :
1035 : // Create the contents of the .llvm_addrsig section.
1036 445 : if (EmitAddrsigSection) {
1037 25 : auto Frag = new MCDataFragment(AddrsigSection);
1038 : Frag->setLayoutOrder(0);
1039 : raw_svector_ostream OS(Frag->getContents());
1040 31 : for (const MCSymbol *S : AddrsigSyms) {
1041 6 : if (!S->isTemporary()) {
1042 5 : encodeULEB128(S->getIndex(), OS);
1043 5 : continue;
1044 : }
1045 :
1046 : MCSection *TargetSection = &S->getSection();
1047 : assert(SectionMap.find(TargetSection) != SectionMap.end() &&
1048 : "Section must already have been defined in "
1049 : "executePostLayoutBinding!");
1050 1 : encodeULEB128(SectionMap[TargetSection]->Symbol->getIndex(), OS);
1051 : }
1052 : }
1053 :
1054 445 : assignFileOffsets(Asm, Layout);
1055 :
1056 : // MS LINK expects to be able to use this timestamp to implement their
1057 : // /INCREMENTAL feature.
1058 445 : if (Asm.isIncrementalLinkerCompatible()) {
1059 26 : Header.TimeDateStamp = getTime();
1060 : } else {
1061 : // Have deterministic output if /INCREMENTAL isn't needed. Also matches GNU.
1062 419 : Header.TimeDateStamp = 0;
1063 : }
1064 :
1065 : // Write it all to disk...
1066 445 : WriteFileHeader(Header);
1067 445 : writeSectionHeaders();
1068 :
1069 : // Write section contents.
1070 : sections::iterator I = Sections.begin();
1071 : sections::iterator IE = Sections.end();
1072 : MCAssembler::iterator J = Asm.begin();
1073 : MCAssembler::iterator JE = Asm.end();
1074 2904 : for (; I != IE && J != JE; ++I, ++J)
1075 2459 : writeSection(Asm, Layout, **I, *J);
1076 :
1077 : assert(W.OS.tell() == Header.PointerToSymbolTable &&
1078 : "Header::PointerToSymbolTable is insane!");
1079 :
1080 : // Write a symbol table.
1081 4640 : for (auto &Symbol : Symbols)
1082 4195 : if (Symbol->getIndex() != -1)
1083 4195 : WriteSymbol(*Symbol);
1084 :
1085 : // Write a string table, which completes the entire COFF file.
1086 445 : Strings.write(W.OS);
1087 :
1088 445 : return W.OS.tell() - StartOffset;
1089 : }
1090 :
1091 1033 : MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_)
1092 1033 : : Machine(Machine_) {}
1093 :
1094 : // Pin the vtable to this file.
1095 0 : void MCWinCOFFObjectTargetWriter::anchor() {}
1096 :
1097 : //------------------------------------------------------------------------------
1098 : // WinCOFFObjectWriter factory function
1099 :
1100 1033 : std::unique_ptr<MCObjectWriter> llvm::createWinCOFFObjectWriter(
1101 : std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS) {
1102 1033 : return llvm::make_unique<WinCOFFObjectWriter>(std::move(MOTW), OS);
1103 : }
|