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