Coverage Report

Created: 2019-07-24 05:18

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