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