LLVM  4.0.0
WinCOFFObjectWriter.cpp
Go to the documentation of this file.
1 //===-- llvm/MC/WinCOFFObjectWriter.cpp -------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains an implementation of a Win32 COFF object file writer.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "llvm/ADT/DenseMap.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/StringMap.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/ADT/Twine.h"
20 #include "llvm/Config/config.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"
26 #include "llvm/MC/MCObjectWriter.h"
27 #include "llvm/MC/MCSection.h"
28 #include "llvm/MC/MCSectionCOFF.h"
29 #include "llvm/MC/MCSymbolCOFF.h"
30 #include "llvm/MC/MCValue.h"
32 #include "llvm/Support/COFF.h"
33 #include "llvm/Support/Debug.h"
34 #include "llvm/Support/Endian.h"
36 #include "llvm/Support/JamCRC.h"
37 #include <cstdio>
38 #include <ctime>
39 
40 using namespace llvm;
41 
42 #define DEBUG_TYPE "WinCOFFObjectWriter"
43 
44 namespace {
46 
48  ATFunctionDefinition,
49  ATbfAndefSymbol,
50  ATWeakExternal,
51  ATFile,
52  ATSectionDefinition
53 };
54 
55 struct AuxSymbol {
57  COFF::Auxiliary Aux;
58 };
59 
60 class COFFSymbol;
61 class COFFSection;
62 
63 class COFFSymbol {
64 public:
66 
67  typedef SmallVector<AuxSymbol, 1> AuxiliarySymbols;
68 
69  name Name;
70  int Index;
71  AuxiliarySymbols Aux;
72  COFFSymbol *Other;
73  COFFSection *Section;
74  int Relocations;
75 
76  const MCSymbol *MC;
77 
78  COFFSymbol(StringRef name);
79  void set_name_offset(uint32_t Offset);
80 
81  int64_t getIndex() const { return Index; }
82  void setIndex(int Value) {
83  Index = Value;
84  if (MC)
85  MC->setIndex(static_cast<uint32_t>(Value));
86  }
87 };
88 
89 // This class contains staging data for a COFF relocation entry.
90 struct COFFRelocation {
92  COFFSymbol *Symb;
93 
94  COFFRelocation() : Symb(nullptr) {}
95  static size_t size() { return COFF::RelocationSize; }
96 };
97 
98 typedef std::vector<COFFRelocation> relocations;
99 
100 class COFFSection {
101 public:
102  COFF::section Header;
103 
104  std::string Name;
105  int Number;
106  MCSectionCOFF const *MCSection;
107  COFFSymbol *Symbol;
108  relocations Relocations;
109 
110  COFFSection(StringRef name);
111 };
112 
113 class WinCOFFObjectWriter : public MCObjectWriter {
114 public:
115  typedef std::vector<std::unique_ptr<COFFSymbol>> symbols;
116  typedef std::vector<std::unique_ptr<COFFSection>> sections;
117 
118  typedef DenseMap<MCSymbol const *, COFFSymbol *> symbol_map;
119  typedef DenseMap<MCSection const *, COFFSection *> section_map;
120 
121  std::unique_ptr<MCWinCOFFObjectTargetWriter> TargetObjectWriter;
122 
123  // Root level file contents.
124  COFF::header Header;
125  sections Sections;
126  symbols Symbols;
128 
129  // Maps used during object file creation.
130  section_map SectionMap;
131  symbol_map SymbolMap;
132 
133  bool UseBigObj;
134 
135  WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, raw_pwrite_stream &OS);
136 
137  void reset() override {
138  memset(&Header, 0, sizeof(Header));
139  Header.Machine = TargetObjectWriter->getMachine();
140  Sections.clear();
141  Symbols.clear();
142  Strings.clear();
143  SectionMap.clear();
144  SymbolMap.clear();
146  }
147 
148  COFFSymbol *createSymbol(StringRef Name);
149  COFFSymbol *GetOrCreateCOFFSymbol(const MCSymbol *Symbol);
150  COFFSection *createSection(StringRef Name);
151 
152  template <typename object_t, typename list_t>
153  object_t *createCOFFEntity(StringRef Name, list_t &List);
154 
155  void defineSection(MCSectionCOFF const &Sec);
156 
157  COFFSymbol *getLinkedSymbol(const MCSymbol &Symbol);
158  void DefineSymbol(const MCSymbol &Symbol, MCAssembler &Assembler,
159  const MCAsmLayout &Layout);
160 
161  void SetSymbolName(COFFSymbol &S);
162  void SetSectionName(COFFSection &S);
163 
164  bool IsPhysicalSection(COFFSection *S);
165 
166  // Entity writing methods.
167 
168  void WriteFileHeader(const COFF::header &Header);
169  void WriteSymbol(const COFFSymbol &S);
170  void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols &S);
171  void writeSectionHeader(const COFF::section &S);
172  void WriteRelocation(const COFF::relocation &R);
173 
174  // MCObjectWriter interface implementation.
175 
176  void executePostLayoutBinding(MCAssembler &Asm,
177  const MCAsmLayout &Layout) override;
178 
179  bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
180  const MCSymbol &SymA,
181  const MCFragment &FB, bool InSet,
182  bool IsPCRel) const override;
183 
184  bool isWeak(const MCSymbol &Sym) const override;
185 
186  void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
187  const MCFragment *Fragment, const MCFixup &Fixup,
188  MCValue Target, bool &IsPCRel,
189  uint64_t &FixedValue) override;
190 
191  void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
192 };
193 }
194 
195 static inline void write_uint32_le(void *Data, uint32_t Value) {
196  support::endian::write<uint32_t, support::little, support::unaligned>(Data,
197  Value);
198 }
199 
200 //------------------------------------------------------------------------------
201 // Symbol class implementation
202 
203 COFFSymbol::COFFSymbol(StringRef name)
204  : Name(name.begin(), name.end()), Other(nullptr), Section(nullptr),
205  Relocations(0), MC(nullptr) {
206  memset(&Data, 0, sizeof(Data));
207 }
208 
209 // In the case that the name does not fit within 8 bytes, the offset
210 // into the string table is stored in the last 4 bytes instead, leaving
211 // the first 4 bytes as 0.
212 void COFFSymbol::set_name_offset(uint32_t Offset) {
213  write_uint32_le(Data.Name + 0, 0);
214  write_uint32_le(Data.Name + 4, Offset);
215 }
216 
217 //------------------------------------------------------------------------------
218 // Section class implementation
219 
220 COFFSection::COFFSection(StringRef name)
221  : Name(name), MCSection(nullptr), Symbol(nullptr) {
222  memset(&Header, 0, sizeof(Header));
223 }
224 
225 //------------------------------------------------------------------------------
226 // WinCOFFObjectWriter class implementation
227 
228 WinCOFFObjectWriter::WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW,
229  raw_pwrite_stream &OS)
230  : MCObjectWriter(OS, true), TargetObjectWriter(MOTW) {
231  memset(&Header, 0, sizeof(Header));
232 
233  Header.Machine = TargetObjectWriter->getMachine();
234 }
235 
236 COFFSymbol *WinCOFFObjectWriter::createSymbol(StringRef Name) {
237  return createCOFFEntity<COFFSymbol>(Name, Symbols);
238 }
239 
240 COFFSymbol *WinCOFFObjectWriter::GetOrCreateCOFFSymbol(const MCSymbol *Symbol) {
241  symbol_map::iterator i = SymbolMap.find(Symbol);
242  if (i != SymbolMap.end())
243  return i->second;
244  COFFSymbol *RetSymbol =
245  createCOFFEntity<COFFSymbol>(Symbol->getName(), Symbols);
246  SymbolMap[Symbol] = RetSymbol;
247  return RetSymbol;
248 }
249 
250 COFFSection *WinCOFFObjectWriter::createSection(StringRef Name) {
251  return createCOFFEntity<COFFSection>(Name, Sections);
252 }
253 
254 /// A template used to lookup or create a symbol/section, and initialize it if
255 /// needed.
256 template <typename object_t, typename list_t>
257 object_t *WinCOFFObjectWriter::createCOFFEntity(StringRef Name, list_t &List) {
258  List.push_back(make_unique<object_t>(Name));
259 
260  return List.back().get();
261 }
262 
263 /// This function takes a section data object from the assembler
264 /// and creates the associated COFF section staging object.
265 void WinCOFFObjectWriter::defineSection(MCSectionCOFF const &Sec) {
266  COFFSection *coff_section = createSection(Sec.getSectionName());
267  COFFSymbol *coff_symbol = createSymbol(Sec.getSectionName());
269  if (const MCSymbol *S = Sec.getCOMDATSymbol()) {
270  COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(S);
271  if (COMDATSymbol->Section)
272  report_fatal_error("two sections have the same comdat");
273  COMDATSymbol->Section = coff_section;
274  }
275  }
276 
277  coff_section->Symbol = coff_symbol;
278  coff_symbol->Section = coff_section;
279  coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_STATIC;
280 
281  // In this case the auxiliary symbol is a Section Definition.
282  coff_symbol->Aux.resize(1);
283  memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0]));
284  coff_symbol->Aux[0].AuxType = ATSectionDefinition;
285  coff_symbol->Aux[0].Aux.SectionDefinition.Selection = Sec.getSelection();
286 
287  coff_section->Header.Characteristics = Sec.getCharacteristics();
288 
289  uint32_t &Characteristics = coff_section->Header.Characteristics;
290  switch (Sec.getAlignment()) {
291  case 1:
292  Characteristics |= COFF::IMAGE_SCN_ALIGN_1BYTES;
293  break;
294  case 2:
295  Characteristics |= COFF::IMAGE_SCN_ALIGN_2BYTES;
296  break;
297  case 4:
298  Characteristics |= COFF::IMAGE_SCN_ALIGN_4BYTES;
299  break;
300  case 8:
301  Characteristics |= COFF::IMAGE_SCN_ALIGN_8BYTES;
302  break;
303  case 16:
304  Characteristics |= COFF::IMAGE_SCN_ALIGN_16BYTES;
305  break;
306  case 32:
307  Characteristics |= COFF::IMAGE_SCN_ALIGN_32BYTES;
308  break;
309  case 64:
310  Characteristics |= COFF::IMAGE_SCN_ALIGN_64BYTES;
311  break;
312  case 128:
313  Characteristics |= COFF::IMAGE_SCN_ALIGN_128BYTES;
314  break;
315  case 256:
316  Characteristics |= COFF::IMAGE_SCN_ALIGN_256BYTES;
317  break;
318  case 512:
319  Characteristics |= COFF::IMAGE_SCN_ALIGN_512BYTES;
320  break;
321  case 1024:
322  Characteristics |= COFF::IMAGE_SCN_ALIGN_1024BYTES;
323  break;
324  case 2048:
325  Characteristics |= COFF::IMAGE_SCN_ALIGN_2048BYTES;
326  break;
327  case 4096:
328  Characteristics |= COFF::IMAGE_SCN_ALIGN_4096BYTES;
329  break;
330  case 8192:
331  Characteristics |= COFF::IMAGE_SCN_ALIGN_8192BYTES;
332  break;
333  default:
334  llvm_unreachable("unsupported section alignment");
335  }
336 
337  // Bind internal COFF section to MC section.
338  coff_section->MCSection = &Sec;
339  SectionMap[&Sec] = coff_section;
340 }
341 
342 static uint64_t getSymbolValue(const MCSymbol &Symbol,
343  const MCAsmLayout &Layout) {
344  if (Symbol.isCommon() && Symbol.isExternal())
345  return Symbol.getCommonSize();
346 
347  uint64_t Res;
348  if (!Layout.getSymbolOffset(Symbol, Res))
349  return 0;
350 
351  return Res;
352 }
353 
354 COFFSymbol *WinCOFFObjectWriter::getLinkedSymbol(const MCSymbol &Symbol) {
355  if (!Symbol.isVariable())
356  return nullptr;
357 
358  const MCSymbolRefExpr *SymRef =
360  if (!SymRef)
361  return nullptr;
362 
363  const MCSymbol &Aliasee = SymRef->getSymbol();
364  if (!Aliasee.isUndefined())
365  return nullptr;
366  return GetOrCreateCOFFSymbol(&Aliasee);
367 }
368 
369 /// This function takes a symbol data object from the assembler
370 /// and creates the associated COFF symbol staging object.
371 void WinCOFFObjectWriter::DefineSymbol(const MCSymbol &Symbol,
372  MCAssembler &Assembler,
373  const MCAsmLayout &Layout) {
374  COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&Symbol);
375  const MCSymbol *Base = Layout.getBaseSymbol(Symbol);
376  COFFSection *Sec = nullptr;
377  if (Base && Base->getFragment()) {
378  Sec = SectionMap[Base->getFragment()->getParent()];
379  if (coff_symbol->Section && coff_symbol->Section != Sec)
380  report_fatal_error("conflicting sections for symbol");
381  }
382 
383  COFFSymbol *Local = nullptr;
384  if (cast<MCSymbolCOFF>(Symbol).isWeakExternal()) {
385  coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
386 
387  COFFSymbol *WeakDefault = getLinkedSymbol(Symbol);
388  if (!WeakDefault) {
389  std::string WeakName = (".weak." + Symbol.getName() + ".default").str();
390  WeakDefault = createSymbol(WeakName);
391  if (!Sec)
392  WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
393  else
394  WeakDefault->Section = Sec;
395  Local = WeakDefault;
396  }
397 
398  coff_symbol->Other = WeakDefault;
399 
400  // Setup the Weak External auxiliary symbol.
401  coff_symbol->Aux.resize(1);
402  memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0]));
403  coff_symbol->Aux[0].AuxType = ATWeakExternal;
404  coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = 0;
405  coff_symbol->Aux[0].Aux.WeakExternal.Characteristics =
407  } else {
408  if (!Base)
409  coff_symbol->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
410  else
411  coff_symbol->Section = Sec;
412  Local = coff_symbol;
413  }
414 
415  if (Local) {
416  Local->Data.Value = getSymbolValue(Symbol, Layout);
417 
418  const MCSymbolCOFF &SymbolCOFF = cast<MCSymbolCOFF>(Symbol);
419  Local->Data.Type = SymbolCOFF.getType();
420  Local->Data.StorageClass = SymbolCOFF.getClass();
421 
422  // If no storage class was specified in the streamer, define it here.
423  if (Local->Data.StorageClass == COFF::IMAGE_SYM_CLASS_NULL) {
424  bool IsExternal = Symbol.isExternal() ||
425  (!Symbol.getFragment() && !Symbol.isVariable());
426 
427  Local->Data.StorageClass = IsExternal ? COFF::IMAGE_SYM_CLASS_EXTERNAL
429  }
430  }
431 
432  coff_symbol->MC = &Symbol;
433 }
434 
435 // Maximum offsets for different string table entry encodings.
436 enum : unsigned { Max7DecimalOffset = 9999999U };
437 enum : uint64_t { MaxBase64Offset = 0xFFFFFFFFFULL }; // 64^6, including 0
438 
439 // Encode a string table entry offset in base 64, padded to 6 chars, and
440 // prefixed with a double slash: '//AAAAAA', '//AAAAAB', ...
441 // Buffer must be at least 8 bytes large. No terminating null appended.
442 static void encodeBase64StringEntry(char *Buffer, uint64_t Value) {
443  assert(Value > Max7DecimalOffset && Value <= MaxBase64Offset &&
444  "Illegal section name encoding for value");
445 
446  static const char Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
447  "abcdefghijklmnopqrstuvwxyz"
448  "0123456789+/";
449 
450  Buffer[0] = '/';
451  Buffer[1] = '/';
452 
453  char *Ptr = Buffer + 7;
454  for (unsigned i = 0; i < 6; ++i) {
455  unsigned Rem = Value % 64;
456  Value /= 64;
457  *(Ptr--) = Alphabet[Rem];
458  }
459 }
460 
461 void WinCOFFObjectWriter::SetSectionName(COFFSection &S) {
462  if (S.Name.size() > COFF::NameSize) {
463  uint64_t StringTableEntry = Strings.getOffset(S.Name);
464 
465  if (StringTableEntry <= Max7DecimalOffset) {
467  Twine('/').concat(Twine(StringTableEntry)).toVector(Buffer);
468  assert(Buffer.size() <= COFF::NameSize && Buffer.size() >= 2);
469 
470  std::memcpy(S.Header.Name, Buffer.data(), Buffer.size());
471  } else if (StringTableEntry <= MaxBase64Offset) {
472  // Starting with 10,000,000, offsets are encoded as base64.
473  encodeBase64StringEntry(S.Header.Name, StringTableEntry);
474  } else {
475  report_fatal_error("COFF string table is greater than 64 GB.");
476  }
477  } else {
478  std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size());
479  }
480 }
481 
482 void WinCOFFObjectWriter::SetSymbolName(COFFSymbol &S) {
483  if (S.Name.size() > COFF::NameSize)
484  S.set_name_offset(Strings.getOffset(S.Name));
485  else
486  std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size());
487 }
488 
489 bool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) {
490  return (S->Header.Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) ==
491  0;
492 }
493 
494 //------------------------------------------------------------------------------
495 // entity writing methods
496 
497 void WinCOFFObjectWriter::WriteFileHeader(const COFF::header &Header) {
498  if (UseBigObj) {
500  writeLE16(0xFFFF);
501  writeLE16(COFF::BigObjHeader::MinBigObjectVersion);
502  writeLE16(Header.Machine);
503  writeLE32(Header.TimeDateStamp);
504  writeBytes(StringRef(COFF::BigObjMagic, sizeof(COFF::BigObjMagic)));
505  writeLE32(0);
506  writeLE32(0);
507  writeLE32(0);
508  writeLE32(0);
509  writeLE32(Header.NumberOfSections);
510  writeLE32(Header.PointerToSymbolTable);
511  writeLE32(Header.NumberOfSymbols);
512  } else {
513  writeLE16(Header.Machine);
514  writeLE16(static_cast<int16_t>(Header.NumberOfSections));
515  writeLE32(Header.TimeDateStamp);
516  writeLE32(Header.PointerToSymbolTable);
517  writeLE32(Header.NumberOfSymbols);
518  writeLE16(Header.SizeOfOptionalHeader);
519  writeLE16(Header.Characteristics);
520  }
521 }
522 
523 void WinCOFFObjectWriter::WriteSymbol(const COFFSymbol &S) {
524  writeBytes(StringRef(S.Data.Name, COFF::NameSize));
525  writeLE32(S.Data.Value);
526  if (UseBigObj)
527  writeLE32(S.Data.SectionNumber);
528  else
529  writeLE16(static_cast<int16_t>(S.Data.SectionNumber));
530  writeLE16(S.Data.Type);
531  write8(S.Data.StorageClass);
532  write8(S.Data.NumberOfAuxSymbols);
533  WriteAuxiliarySymbols(S.Aux);
534 }
535 
536 void WinCOFFObjectWriter::WriteAuxiliarySymbols(
537  const COFFSymbol::AuxiliarySymbols &S) {
538  for (const AuxSymbol &i : S) {
539  switch (i.AuxType) {
540  case ATFunctionDefinition:
541  writeLE32(i.Aux.FunctionDefinition.TagIndex);
542  writeLE32(i.Aux.FunctionDefinition.TotalSize);
543  writeLE32(i.Aux.FunctionDefinition.PointerToLinenumber);
544  writeLE32(i.Aux.FunctionDefinition.PointerToNextFunction);
545  WriteZeros(sizeof(i.Aux.FunctionDefinition.unused));
546  if (UseBigObj)
548  break;
549  case ATbfAndefSymbol:
550  WriteZeros(sizeof(i.Aux.bfAndefSymbol.unused1));
551  writeLE16(i.Aux.bfAndefSymbol.Linenumber);
552  WriteZeros(sizeof(i.Aux.bfAndefSymbol.unused2));
553  writeLE32(i.Aux.bfAndefSymbol.PointerToNextFunction);
554  WriteZeros(sizeof(i.Aux.bfAndefSymbol.unused3));
555  if (UseBigObj)
557  break;
558  case ATWeakExternal:
559  writeLE32(i.Aux.WeakExternal.TagIndex);
560  writeLE32(i.Aux.WeakExternal.Characteristics);
561  WriteZeros(sizeof(i.Aux.WeakExternal.unused));
562  if (UseBigObj)
564  break;
565  case ATFile:
566  writeBytes(
567  StringRef(reinterpret_cast<const char *>(&i.Aux),
568  UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size));
569  break;
570  case ATSectionDefinition:
571  writeLE32(i.Aux.SectionDefinition.Length);
572  writeLE16(i.Aux.SectionDefinition.NumberOfRelocations);
573  writeLE16(i.Aux.SectionDefinition.NumberOfLinenumbers);
574  writeLE32(i.Aux.SectionDefinition.CheckSum);
575  writeLE16(static_cast<int16_t>(i.Aux.SectionDefinition.Number));
576  write8(i.Aux.SectionDefinition.Selection);
577  WriteZeros(sizeof(i.Aux.SectionDefinition.unused));
578  writeLE16(static_cast<int16_t>(i.Aux.SectionDefinition.Number >> 16));
579  if (UseBigObj)
581  break;
582  }
583  }
584 }
585 
586 void WinCOFFObjectWriter::writeSectionHeader(const COFF::section &S) {
587  writeBytes(StringRef(S.Name, COFF::NameSize));
588 
589  writeLE32(S.VirtualSize);
590  writeLE32(S.VirtualAddress);
591  writeLE32(S.SizeOfRawData);
592  writeLE32(S.PointerToRawData);
593  writeLE32(S.PointerToRelocations);
594  writeLE32(S.PointerToLineNumbers);
595  writeLE16(S.NumberOfRelocations);
596  writeLE16(S.NumberOfLineNumbers);
597  writeLE32(S.Characteristics);
598 }
599 
600 void WinCOFFObjectWriter::WriteRelocation(const COFF::relocation &R) {
601  writeLE32(R.VirtualAddress);
602  writeLE32(R.SymbolTableIndex);
603  writeLE16(R.Type);
604 }
605 
606 ////////////////////////////////////////////////////////////////////////////////
607 // MCObjectWriter interface implementations
608 
609 void WinCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
610  const MCAsmLayout &Layout) {
611  // "Define" each section & symbol. This creates section & symbol
612  // entries in the staging area.
613  for (const auto &Section : Asm)
614  defineSection(static_cast<const MCSectionCOFF &>(Section));
615 
616  for (const MCSymbol &Symbol : Asm.symbols())
617  if (!Symbol.isTemporary())
618  DefineSymbol(Symbol, Asm, Layout);
619 }
620 
621 bool WinCOFFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
622  const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB,
623  bool InSet, bool IsPCRel) const {
624  // MS LINK expects to be able to replace all references to a function with a
625  // thunk to implement their /INCREMENTAL feature. Make sure we don't optimize
626  // away any relocations to functions.
627  uint16_t Type = cast<MCSymbolCOFF>(SymA).getType();
628  if (Asm.isIncrementalLinkerCompatible() &&
630  return false;
631  return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB,
632  InSet, IsPCRel);
633 }
634 
635 bool WinCOFFObjectWriter::isWeak(const MCSymbol &Sym) const {
636  if (!Sym.isExternal())
637  return false;
638 
639  if (!Sym.isInSection())
640  return false;
641 
642  const auto &Sec = cast<MCSectionCOFF>(Sym.getSection());
643  if (!Sec.getCOMDATSymbol())
644  return false;
645 
646  // It looks like for COFF it is invalid to replace a reference to a global
647  // in a comdat with a reference to a local.
648  // FIXME: Add a specification reference if available.
649  return true;
650 }
651 
652 void WinCOFFObjectWriter::recordRelocation(
653  MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment,
654  const MCFixup &Fixup, MCValue Target, bool &IsPCRel, uint64_t &FixedValue) {
655  assert(Target.getSymA() && "Relocation must reference a symbol!");
656 
657  const MCSymbol &A = Target.getSymA()->getSymbol();
658  if (!A.isRegistered()) {
659  Asm.getContext().reportError(Fixup.getLoc(),
660  Twine("symbol '") + A.getName() +
661  "' can not be undefined");
662  return;
663  }
664  if (A.isTemporary() && A.isUndefined()) {
665  Asm.getContext().reportError(Fixup.getLoc(),
666  Twine("assembler label '") + A.getName() +
667  "' can not be undefined");
668  return;
669  }
670 
671  MCSection *Section = Fragment->getParent();
672 
673  // Mark this symbol as requiring an entry in the symbol table.
674  assert(SectionMap.find(Section) != SectionMap.end() &&
675  "Section must already have been defined in executePostLayoutBinding!");
676 
677  COFFSection *coff_section = SectionMap[Section];
678  const MCSymbolRefExpr *SymB = Target.getSymB();
679  bool CrossSection = false;
680 
681  if (SymB) {
682  const MCSymbol *B = &SymB->getSymbol();
683  if (!B->getFragment()) {
684  Asm.getContext().reportError(
685  Fixup.getLoc(),
686  Twine("symbol '") + B->getName() +
687  "' can not be undefined in a subtraction expression");
688  return;
689  }
690 
691  if (!A.getFragment()) {
692  Asm.getContext().reportError(
693  Fixup.getLoc(),
694  Twine("symbol '") + A.getName() +
695  "' can not be undefined in a subtraction expression");
696  return;
697  }
698 
699  CrossSection = &A.getSection() != &B->getSection();
700 
701  // Offset of the symbol in the section
702  int64_t OffsetOfB = Layout.getSymbolOffset(*B);
703 
704  // In the case where we have SymbA and SymB, we just need to store the delta
705  // between the two symbols. Update FixedValue to account for the delta, and
706  // skip recording the relocation.
707  if (!CrossSection) {
708  int64_t OffsetOfA = Layout.getSymbolOffset(A);
709  FixedValue = (OffsetOfA - OffsetOfB) + Target.getConstant();
710  return;
711  }
712 
713  // Offset of the relocation in the section
714  int64_t OffsetOfRelocation =
715  Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
716 
717  FixedValue = (OffsetOfRelocation - OffsetOfB) + Target.getConstant();
718  } else {
719  FixedValue = Target.getConstant();
720  }
721 
722  COFFRelocation Reloc;
723 
724  Reloc.Data.SymbolTableIndex = 0;
725  Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment);
726 
727  // Turn relocations for temporary symbols into section relocations.
728  if (A.isTemporary() || CrossSection) {
729  MCSection *TargetSection = &A.getSection();
730  assert(
731  SectionMap.find(TargetSection) != SectionMap.end() &&
732  "Section must already have been defined in executePostLayoutBinding!");
733  Reloc.Symb = SectionMap[TargetSection]->Symbol;
734  FixedValue += Layout.getSymbolOffset(A);
735  } else {
736  assert(
737  SymbolMap.find(&A) != SymbolMap.end() &&
738  "Symbol must already have been defined in executePostLayoutBinding!");
739  Reloc.Symb = SymbolMap[&A];
740  }
741 
742  ++Reloc.Symb->Relocations;
743 
744  Reloc.Data.VirtualAddress += Fixup.getOffset();
745  Reloc.Data.Type = TargetObjectWriter->getRelocType(
746  Target, Fixup, CrossSection, Asm.getBackend());
747 
748  // FIXME: Can anyone explain what this does other than adjust for the size
749  // of the offset?
750  if ((Header.Machine == COFF::IMAGE_FILE_MACHINE_AMD64 &&
751  Reloc.Data.Type == COFF::IMAGE_REL_AMD64_REL32) ||
753  Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32))
754  FixedValue += 4;
755 
756  if (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT) {
757  switch (Reloc.Data.Type) {
764  break;
767  // IMAGE_REL_ARM_BRANCH11 and IMAGE_REL_ARM_BLX11 are only used for
768  // pre-ARMv7, which implicitly rules it out of ARMNT (it would be valid
769  // for Windows CE).
773  // IMAGE_REL_ARM_BRANCH24, IMAGE_REL_ARM_BLX24, IMAGE_REL_ARM_MOV32A are
774  // only used for ARM mode code, which is documented as being unsupported
775  // by Windows on ARM. Empirical proof indicates that masm is able to
776  // generate the relocations however the rest of the MSVC toolchain is
777  // unable to handle it.
778  llvm_unreachable("unsupported relocation");
779  break;
781  break;
785  // IMAGE_REL_BRANCH20T, IMAGE_REL_ARM_BRANCH24T, IMAGE_REL_ARM_BLX23T all
786  // perform a 4 byte adjustment to the relocation. Relative branches are
787  // offset by 4 on ARM, however, because there is no RELA relocations, all
788  // branches are offset by 4.
789  FixedValue = FixedValue + 4;
790  break;
791  }
792  }
793 
794  // The fixed value never makes sense for section indices, ignore it.
795  if (Fixup.getKind() == FK_SecRel_2)
796  FixedValue = 0;
797 
798  if (TargetObjectWriter->recordRelocation(Fixup))
799  coff_section->Relocations.push_back(Reloc);
800 }
801 
802 void WinCOFFObjectWriter::writeObject(MCAssembler &Asm,
803  const MCAsmLayout &Layout) {
804  size_t SectionsSize = Sections.size();
805  if (SectionsSize > static_cast<size_t>(INT32_MAX))
807  "PE COFF object files can't have more than 2147483647 sections");
808 
809  // Assign symbol and section indexes and offsets.
810  int32_t NumberOfSections = static_cast<int32_t>(SectionsSize);
811 
812  UseBigObj = NumberOfSections > COFF::MaxNumberOfSections16;
813 
814  // Assign section numbers.
815  size_t Number = 1;
816  for (const auto &Section : Sections) {
817  Section->Number = Number;
818  Section->Symbol->Data.SectionNumber = Number;
819  Section->Symbol->Aux[0].Aux.SectionDefinition.Number = Number;
820  ++Number;
821  }
822 
823  Header.NumberOfSections = NumberOfSections;
824  Header.NumberOfSymbols = 0;
825 
826  for (const std::string &Name : Asm.getFileNames()) {
827  // round up to calculate the number of auxiliary symbols required
828  unsigned SymbolSize = UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size;
829  unsigned Count = (Name.size() + SymbolSize - 1) / SymbolSize;
830 
831  COFFSymbol *file = createSymbol(".file");
832  file->Data.SectionNumber = COFF::IMAGE_SYM_DEBUG;
833  file->Data.StorageClass = COFF::IMAGE_SYM_CLASS_FILE;
834  file->Aux.resize(Count);
835 
836  unsigned Offset = 0;
837  unsigned Length = Name.size();
838  for (auto &Aux : file->Aux) {
839  Aux.AuxType = ATFile;
840 
841  if (Length > SymbolSize) {
842  memcpy(&Aux.Aux, Name.c_str() + Offset, SymbolSize);
843  Length = Length - SymbolSize;
844  } else {
845  memcpy(&Aux.Aux, Name.c_str() + Offset, Length);
846  memset((char *)&Aux.Aux + Length, 0, SymbolSize - Length);
847  break;
848  }
849 
850  Offset += SymbolSize;
851  }
852  }
853 
854  for (auto &Symbol : Symbols) {
855  // Update section number & offset for symbols that have them.
856  if (Symbol->Section)
857  Symbol->Data.SectionNumber = Symbol->Section->Number;
858  Symbol->setIndex(Header.NumberOfSymbols++);
859  // Update auxiliary symbol info.
860  Symbol->Data.NumberOfAuxSymbols = Symbol->Aux.size();
861  Header.NumberOfSymbols += Symbol->Data.NumberOfAuxSymbols;
862  }
863 
864  // Build string table.
865  for (const auto &S : Sections)
866  if (S->Name.size() > COFF::NameSize)
867  Strings.add(S->Name);
868  for (const auto &S : Symbols)
869  if (S->Name.size() > COFF::NameSize)
870  Strings.add(S->Name);
871  Strings.finalize();
872 
873  // Set names.
874  for (const auto &S : Sections)
875  SetSectionName(*S);
876  for (auto &S : Symbols)
877  SetSymbolName(*S);
878 
879  // Fixup weak external references.
880  for (auto &Symbol : Symbols) {
881  if (Symbol->Other) {
882  assert(Symbol->getIndex() != -1);
883  assert(Symbol->Aux.size() == 1 && "Symbol must contain one aux symbol!");
884  assert(Symbol->Aux[0].AuxType == ATWeakExternal &&
885  "Symbol's aux symbol must be a Weak External!");
886  Symbol->Aux[0].Aux.WeakExternal.TagIndex = Symbol->Other->getIndex();
887  }
888  }
889 
890  // Fixup associative COMDAT sections.
891  for (auto &Section : Sections) {
892  if (Section->Symbol->Aux[0].Aux.SectionDefinition.Selection !=
894  continue;
895 
896  const MCSectionCOFF &MCSec = *Section->MCSection;
897 
898  const MCSymbol *COMDAT = MCSec.getCOMDATSymbol();
899  assert(COMDAT);
900  COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(COMDAT);
901  assert(COMDATSymbol);
902  COFFSection *Assoc = COMDATSymbol->Section;
903  if (!Assoc)
905  Twine("Missing associated COMDAT section for section ") +
906  MCSec.getSectionName());
907 
908  // Skip this section if the associated section is unused.
909  if (Assoc->Number == -1)
910  continue;
911 
912  Section->Symbol->Aux[0].Aux.SectionDefinition.Number = Assoc->Number;
913  }
914 
915  // Assign file offsets to COFF object file structures.
916 
917  unsigned offset = getInitialOffset();
918 
919  if (UseBigObj)
920  offset += COFF::Header32Size;
921  else
922  offset += COFF::Header16Size;
923  offset += COFF::SectionSize * Header.NumberOfSections;
924 
925  for (const auto &Section : Asm) {
926  COFFSection *Sec = SectionMap[&Section];
927 
928  if (Sec->Number == -1)
929  continue;
930 
931  Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(&Section);
932 
933  if (IsPhysicalSection(Sec)) {
934  // Align the section data to a four byte boundary.
935  offset = alignTo(offset, 4);
936  Sec->Header.PointerToRawData = offset;
937 
938  offset += Sec->Header.SizeOfRawData;
939  }
940 
941  if (Sec->Relocations.size() > 0) {
942  bool RelocationsOverflow = Sec->Relocations.size() >= 0xffff;
943 
944  if (RelocationsOverflow) {
945  // Signal overflow by setting NumberOfRelocations to max value. Actual
946  // size is found in reloc #0. Microsoft tools understand this.
947  Sec->Header.NumberOfRelocations = 0xffff;
948  } else {
949  Sec->Header.NumberOfRelocations = Sec->Relocations.size();
950  }
951  Sec->Header.PointerToRelocations = offset;
952 
953  if (RelocationsOverflow) {
954  // Reloc #0 will contain actual count, so make room for it.
955  offset += COFF::RelocationSize;
956  }
957 
958  offset += COFF::RelocationSize * Sec->Relocations.size();
959 
960  for (auto &Relocation : Sec->Relocations) {
961  assert(Relocation.Symb->getIndex() != -1);
962  Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex();
963  }
964  }
965 
966  assert(Sec->Symbol->Aux.size() == 1 &&
967  "Section's symbol must have one aux!");
968  AuxSymbol &Aux = Sec->Symbol->Aux[0];
969  assert(Aux.AuxType == ATSectionDefinition &&
970  "Section's symbol's aux symbol must be a Section Definition!");
971  Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData;
972  Aux.Aux.SectionDefinition.NumberOfRelocations =
973  Sec->Header.NumberOfRelocations;
974  Aux.Aux.SectionDefinition.NumberOfLinenumbers =
975  Sec->Header.NumberOfLineNumbers;
976  }
977 
978  Header.PointerToSymbolTable = offset;
979 
980  // MS LINK expects to be able to use this timestamp to implement their
981  // /INCREMENTAL feature.
982  if (Asm.isIncrementalLinkerCompatible()) {
983  std::time_t Now = time(nullptr);
984  if (Now < 0 || !isUInt<32>(Now))
985  Now = UINT32_MAX;
986  Header.TimeDateStamp = Now;
987  } else {
988  // Have deterministic output if /INCREMENTAL isn't needed. Also matches GNU.
989  Header.TimeDateStamp = 0;
990  }
991 
992  // Write it all to disk...
993  WriteFileHeader(Header);
994 
995  {
996  sections::iterator i, ie;
997  MCAssembler::iterator j, je;
998 
999  for (auto &Section : Sections) {
1000  if (Section->Number != -1) {
1001  if (Section->Relocations.size() >= 0xffff)
1002  Section->Header.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL;
1003  writeSectionHeader(Section->Header);
1004  }
1005  }
1006 
1007  SmallVector<char, 128> SectionContents;
1008  for (i = Sections.begin(), ie = Sections.end(), j = Asm.begin(),
1009  je = Asm.end();
1010  (i != ie) && (j != je); ++i, ++j) {
1011 
1012  if ((*i)->Number == -1)
1013  continue;
1014 
1015  if ((*i)->Header.PointerToRawData != 0) {
1016  assert(getStream().tell() <= (*i)->Header.PointerToRawData &&
1017  "Section::PointerToRawData is insane!");
1018 
1019  unsigned SectionDataPadding =
1020  (*i)->Header.PointerToRawData - getStream().tell();
1021  assert(SectionDataPadding < 4 &&
1022  "Should only need at most three bytes of padding!");
1023 
1024  WriteZeros(SectionDataPadding);
1025 
1026  // Save the contents of the section to a temporary buffer, we need this
1027  // to CRC the data before we dump it into the object file.
1028  SectionContents.clear();
1029  raw_svector_ostream VecOS(SectionContents);
1030  raw_pwrite_stream &OldStream = getStream();
1031  // Redirect the output stream to our buffer.
1032  setStream(VecOS);
1033  // Fill our buffer with the section data.
1034  Asm.writeSectionData(&*j, Layout);
1035  // Reset the stream back to what it was before.
1036  setStream(OldStream);
1037 
1038  // Calculate our CRC with an initial value of '0', this is not how
1039  // JamCRC is specified but it aligns with the expected output.
1040  JamCRC JC(/*Init=*/0x00000000U);
1041  JC.update(SectionContents);
1042 
1043  // Write the section contents to the object file.
1044  getStream() << SectionContents;
1045 
1046  // Update the section definition auxiliary symbol to record the CRC.
1047  COFFSection *Sec = SectionMap[&*j];
1048  COFFSymbol::AuxiliarySymbols &AuxSyms = Sec->Symbol->Aux;
1049  assert(AuxSyms.size() == 1 &&
1050  AuxSyms[0].AuxType == ATSectionDefinition);
1051  AuxSymbol &SecDef = AuxSyms[0];
1052  SecDef.Aux.SectionDefinition.CheckSum = JC.getCRC();
1053  }
1054 
1055  if ((*i)->Relocations.size() > 0) {
1056  assert(getStream().tell() == (*i)->Header.PointerToRelocations &&
1057  "Section::PointerToRelocations is insane!");
1058 
1059  if ((*i)->Relocations.size() >= 0xffff) {
1060  // In case of overflow, write actual relocation count as first
1061  // relocation. Including the synthetic reloc itself (+ 1).
1062  COFF::relocation r;
1063  r.VirtualAddress = (*i)->Relocations.size() + 1;
1064  r.SymbolTableIndex = 0;
1065  r.Type = 0;
1066  WriteRelocation(r);
1067  }
1068 
1069  for (const auto &Relocation : (*i)->Relocations)
1070  WriteRelocation(Relocation.Data);
1071  } else
1072  assert((*i)->Header.PointerToRelocations == 0 &&
1073  "Section::PointerToRelocations is insane!");
1074  }
1075  }
1076 
1077  assert(getStream().tell() == Header.PointerToSymbolTable &&
1078  "Header::PointerToSymbolTable is insane!");
1079 
1080  for (auto &Symbol : Symbols)
1081  if (Symbol->getIndex() != -1)
1082  WriteSymbol(*Symbol);
1083 
1084  Strings.write(getStream());
1085 }
1086 
1087 MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_)
1088  : Machine(Machine_) {}
1089 
1090 // Pin the vtable to this file.
1091 void MCWinCOFFObjectTargetWriter::anchor() {}
1092 
1093 //------------------------------------------------------------------------------
1094 // WinCOFFObjectWriter factory function
1095 
1098  raw_pwrite_stream &OS) {
1099  return new WinCOFFObjectWriter(MOTW, OS);
1100 }
void toVector(SmallVectorImpl< char > &Out) const
Append the concatenated string into the given SmallString or SmallVector.
Definition: Twine.cpp:32
constexpr bool isUInt< 32 >(uint64_t x)
Definition: MathExtras.h:315
Instances of this class represent a uniqued identifier for a section in the current translation unit...
Definition: MCSection.h:40
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:241
static void write_uint32_le(void *Data, uint32_t Value)
static uint64_t getSymbolValue(const MCSymbol &Symbol, const MCAsmLayout &Layout)
const MCSymbol & getSymbol() const
Definition: MCExpr.h:311
SMLoc getLoc() const
Definition: MCFixup.h:112
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
size_t i
This represents an "assembler immediate".
Definition: MCValue.h:40
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:39
char Name[NameSize]
Definition: Support/COFF.h:241
static void encodeBase64StringEntry(char *Buffer, uint64_t Value)
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:130
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:490
const_iterator begin(StringRef path)
Get begin iterator over path.
Definition: Path.cpp:233
int getSelection() const
Definition: MCSectionCOFF.h:72
FunctionType * getType(LLVMContext &Context, ID id, ArrayRef< Type * > Tys=None)
Return the function type for an intrinsic.
Definition: Function.cpp:905
bool isExternal() const
Definition: MCSymbol.h:386
unsigned getAlignment() const
Definition: MCSection.h:117
MCContext & getContext() const
Definition: MCAssembler.h:258
Defines the object file and target independent interfaces used by the assembler backend to write nati...
static const char BigObjMagic[]
Definition: Support/COFF.h:39
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:66
This represents a section on Windows.
Definition: MCSectionCOFF.h:24
uint16_t Characteristics
Definition: Support/COFF.h:67
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:29
uint32_t PointerToSymbolTable
Definition: Support/COFF.h:64
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:161
void setIndex(uint32_t Value) const
Set the (implementation defined) index.
Definition: MCSymbol.h:310
const int32_t MaxNumberOfSections16
Definition: Support/COFF.h:34
ELFYAML::ELF_STO Other
Definition: ELFYAML.cpp:662
ArrayRef< std::string > getFileNames()
Definition: MCAssembler.h:403
Utility for building string tables with deduplicated suffixes.
A two-byte section relative fixup.
Definition: MCFixup.h:41
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
COFF::MachineTypes Machine
Definition: COFFYAML.cpp:303
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:135
uint32_t getOffset() const
Definition: MCFixup.h:95
uint16_t getClass() const
Definition: MCSymbolCOFF.h:39
uint16_t SizeOfOptionalHeader
Definition: Support/COFF.h:66
const MCSymbol * getBaseSymbol(const MCSymbol &Symbol) const
If this symbol is equivalent to A + Constant, return A.
Definition: MCFragment.cpp:140
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
uint32_t getIndex() const
Get the (implementation defined) index.
Definition: MCSymbol.h:305
MCSymbol * getCOMDATSymbol() const
Definition: MCSectionCOFF.h:71
Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
Definition: Support/COFF.h:233
virtual void reset()
lifetime management
uint32_t Offset
uint64_t getSectionAddressSize(const MCSection *Sec) const
Get the address space size of the given section, as it effects layout.
Definition: MCFragment.cpp:177
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:510
A function that returns a base type.
Definition: Support/COFF.h:229
dot regions Print regions of function to dot file(with no function bodies)"
bool isInSection(bool SetUsed=true) const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute)...
Definition: MCSymbol.h:251
MCFixupKind getKind() const
Definition: MCFixup.h:93
const MCSymbolRefExpr * getSymB() const
Definition: MCValue.h:48
unsigned getCharacteristics() const
Definition: MCSectionCOFF.h:70
uint16_t NumberOfLineNumbers
Definition: Support/COFF.h:249
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
uint32_t TimeDateStamp
Definition: Support/COFF.h:63
PowerPC TLS Dynamic Call Fixup
Twine concat(const Twine &Suffix) const
Definition: Twine.h:496
COFFYAML::AuxSymbolType AuxType
Definition: COFFYAML.cpp:288
uint32_t PointerToRelocations
Definition: Support/COFF.h:246
const MCSymbolRefExpr * getSymA() const
Definition: MCValue.h:47
StringRef getSectionName() const
Definition: MCSectionCOFF.h:69
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
An iterator type that allows iterating over the pointees via some other iterator. ...
Definition: iterator.h:273
MCSection * getParent() const
Definition: MCFragment.h:97
uint32_t PointerToRawData
Definition: Support/COFF.h:245
static int alignTo(int Num, int PowOf2)
Target - Wrapper for Target specific information.
static bool isWeak(const MCSymbolELF &Sym)
const MCExpr * getVariableValue(bool SetUsed=true) const
getVariableValue - Get the value for variable symbols.
Definition: MCSymbol.h:294
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
Definition: MCSymbol.h:216
uint64_t getCommonSize() const
Return the size of a 'common' symbol.
Definition: MCSymbol.h:329
MCSection & getSection(bool SetUsed=true) const
Get the section associated with a defined, non-absolute symbol.
Definition: MCSymbol.h:264
uint32_t NumberOfSymbols
Definition: Support/COFF.h:65
Basic Alias true
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:199
pointer data()
Return a pointer to the vector's buffer, even if empty().
Definition: SmallVector.h:142
int32_t NumberOfSections
Definition: Support/COFF.h:62
MCAsmBackend & getBackend() const
Definition: MCAssembler.h:260
const NodeList & List
Definition: RDFGraph.cpp:205
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:135
bool isCommon() const
Is this a 'common' symbol.
Definition: MCSymbol.h:373
COFFYAML::WeakExternalCharacteristics Characteristics
Definition: COFFYAML.cpp:270
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:287
uint64_t getFragmentOffset(const MCFragment *F) const
Get the offset of the given fragment inside its containing section.
Definition: MCFragment.cpp:78
bool isVariable() const
isVariable - Check if this is a variable symbol.
Definition: MCSymbol.h:289
uint16_t getType() const
Definition: MCSymbolCOFF.h:32
MCFragment * getFragment(bool SetUsed=true) const
Definition: MCSymbol.h:377
An abstract base class for streams implementations that also support a pwrite operation.
Definition: raw_ostream.h:333
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
uint16_t NumberOfRelocations
Definition: Support/COFF.h:248
bool isIncrementalLinkerCompatible() const
Definition: MCAssembler.h:281
int64_t getConstant() const
Definition: MCValue.h:46
LLVM Value Representation.
Definition: Value.h:71
static const char * name
MCObjectWriter * createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, raw_pwrite_stream &OS)
Construct a new Win COFF writer instance.
uint32_t PointerToLineNumbers
Definition: Support/COFF.h:247
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
int * Ptr
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
uint32_t Characteristics
Definition: Support/COFF.h:250
bool isUndefined(bool SetUsed=true) const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
Definition: MCSymbol.h:256