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" 33 #include "llvm/MC/MCWinCOFFObjectWriter.h" 34 #include "llvm/MC/StringTableBuilder.h" 35 #include "llvm/Support/CRC.h" 36 #include "llvm/Support/Casting.h" 37 #include "llvm/Support/EndianStream.h" 38 #include "llvm/Support/ErrorHandling.h" 39 #include "llvm/Support/LEB128.h" 40 #include "llvm/Support/MathExtras.h" 41 #include "llvm/Support/raw_ostream.h" 42 #include <algorithm> 43 #include <cassert> 44 #include <cstdint> 45 #include <cstring> 46 #include <ctime> 47 #include <memory> 48 #include <string> 49 #include <vector> 50 51 using namespace llvm; 52 using llvm::support::endian::write32le; 53 54 #define DEBUG_TYPE "WinCOFFObjectWriter" 55 56 namespace { 57 58 constexpr int OffsetLabelIntervalBits = 20; 59 60 using name = SmallString<COFF::NameSize>; 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 { 103 COFF::relocation Data; 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: 130 support::endian::Writer W; 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; 146 StringTableBuilder Strings{StringTableBuilder::WinCOFF}; 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 bool EmitAddrsigSection = false; 158 MCSectionCOFF *AddrsigSection; 159 std::vector<const MCSymbol *> AddrsigSyms; 160 161 MCSectionCOFF *CGProfileSection = nullptr; 162 163 WinCOFFObjectWriter(std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW, 164 raw_pwrite_stream &OS); 165 166 void reset() override { 167 memset(&Header, 0, sizeof(Header)); 168 Header.Machine = TargetObjectWriter->getMachine(); 169 Sections.clear(); 170 Symbols.clear(); 171 Strings.clear(); 172 SectionMap.clear(); 173 SymbolMap.clear(); 174 MCObjectWriter::reset(); 175 } 176 177 COFFSymbol *createSymbol(StringRef Name); 178 COFFSymbol *GetOrCreateCOFFSymbol(const MCSymbol *Symbol); 179 COFFSection *createSection(StringRef Name); 180 181 void defineSection(MCSectionCOFF const &Sec, const MCAsmLayout &Layout); 182 183 COFFSymbol *getLinkedSymbol(const MCSymbol &Symbol); 184 void DefineSymbol(const MCSymbol &Symbol, MCAssembler &Assembler, 185 const MCAsmLayout &Layout); 186 187 void SetSymbolName(COFFSymbol &S); 188 void SetSectionName(COFFSection &S); 189 190 bool IsPhysicalSection(COFFSection *S); 191 192 // Entity writing methods. 193 194 void WriteFileHeader(const COFF::header &Header); 195 void WriteSymbol(const COFFSymbol &S); 196 void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols &S); 197 void writeSectionHeaders(); 198 void WriteRelocation(const COFF::relocation &R); 199 uint32_t writeSectionContents(MCAssembler &Asm, const MCAsmLayout &Layout, 200 const MCSection &MCSec); 201 void writeSection(MCAssembler &Asm, const MCAsmLayout &Layout, 202 const COFFSection &Sec, const MCSection &MCSec); 203 204 // MCObjectWriter interface implementation. 205 206 void executePostLayoutBinding(MCAssembler &Asm, 207 const MCAsmLayout &Layout) override; 208 209 bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, 210 const MCSymbol &SymA, 211 const MCFragment &FB, bool InSet, 212 bool IsPCRel) const override; 213 214 void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, 215 const MCFragment *Fragment, const MCFixup &Fixup, 216 MCValue Target, uint64_t &FixedValue) override; 217 218 void createFileSymbols(MCAssembler &Asm); 219 void setWeakDefaultNames(); 220 void assignSectionNumbers(); 221 void assignFileOffsets(MCAssembler &Asm, const MCAsmLayout &Layout); 222 223 void emitAddrsigSection() override { EmitAddrsigSection = true; } 224 void addAddrsigSymbol(const MCSymbol *Sym) override { 225 AddrsigSyms.push_back(Sym); 226 } 227 228 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; 229 }; 230 231 } // end anonymous namespace 232 233 //------------------------------------------------------------------------------ 234 // Symbol class implementation 235 236 // In the case that the name does not fit within 8 bytes, the offset 237 // into the string table is stored in the last 4 bytes instead, leaving 238 // the first 4 bytes as 0. 239 void COFFSymbol::set_name_offset(uint32_t Offset) { 240 write32le(Data.Name + 0, 0); 241 write32le(Data.Name + 4, Offset); 242 } 243 244 //------------------------------------------------------------------------------ 245 // WinCOFFObjectWriter class implementation 246 247 WinCOFFObjectWriter::WinCOFFObjectWriter( 248 std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS) 249 : W(OS, support::little), TargetObjectWriter(std::move(MOTW)) { 250 Header.Machine = TargetObjectWriter->getMachine(); 251 // Some relocations on ARM64 (the 21 bit ADRP relocations) have a slightly 252 // limited range for the immediate offset (+/- 1 MB); create extra offset 253 // label symbols with regular intervals to allow referencing a 254 // non-temporary symbol that is close enough. 255 UseOffsetLabels = Header.Machine == COFF::IMAGE_FILE_MACHINE_ARM64; 256 } 257 258 COFFSymbol *WinCOFFObjectWriter::createSymbol(StringRef Name) { 259 Symbols.push_back(std::make_unique<COFFSymbol>(Name)); 260 return Symbols.back().get(); 261 } 262 263 COFFSymbol *WinCOFFObjectWriter::GetOrCreateCOFFSymbol(const MCSymbol *Symbol) { 264 COFFSymbol *&Ret = SymbolMap[Symbol]; 265 if (!Ret) 266 Ret = createSymbol(Symbol->getName()); 267 return Ret; 268 } 269 270 COFFSection *WinCOFFObjectWriter::createSection(StringRef Name) { 271 Sections.emplace_back(std::make_unique<COFFSection>(Name)); 272 return Sections.back().get(); 273 } 274 275 static uint32_t getAlignment(const MCSectionCOFF &Sec) { 276 switch (Sec.getAlignment()) { 277 case 1: 278 return COFF::IMAGE_SCN_ALIGN_1BYTES; 279 case 2: 280 return COFF::IMAGE_SCN_ALIGN_2BYTES; 281 case 4: 282 return COFF::IMAGE_SCN_ALIGN_4BYTES; 283 case 8: 284 return COFF::IMAGE_SCN_ALIGN_8BYTES; 285 case 16: 286 return COFF::IMAGE_SCN_ALIGN_16BYTES; 287 case 32: 288 return COFF::IMAGE_SCN_ALIGN_32BYTES; 289 case 64: 290 return COFF::IMAGE_SCN_ALIGN_64BYTES; 291 case 128: 292 return COFF::IMAGE_SCN_ALIGN_128BYTES; 293 case 256: 294 return COFF::IMAGE_SCN_ALIGN_256BYTES; 295 case 512: 296 return COFF::IMAGE_SCN_ALIGN_512BYTES; 297 case 1024: 298 return COFF::IMAGE_SCN_ALIGN_1024BYTES; 299 case 2048: 300 return COFF::IMAGE_SCN_ALIGN_2048BYTES; 301 case 4096: 302 return COFF::IMAGE_SCN_ALIGN_4096BYTES; 303 case 8192: 304 return COFF::IMAGE_SCN_ALIGN_8192BYTES; 305 } 306 llvm_unreachable("unsupported section alignment"); 307 } 308 309 /// This function takes a section data object from the assembler 310 /// and creates the associated COFF section staging object. 311 void WinCOFFObjectWriter::defineSection(const MCSectionCOFF &MCSec, 312 const MCAsmLayout &Layout) { 313 COFFSection *Section = createSection(MCSec.getName()); 314 COFFSymbol *Symbol = createSymbol(MCSec.getName()); 315 Section->Symbol = Symbol; 316 Symbol->Section = Section; 317 Symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_STATIC; 318 319 // Create a COMDAT symbol if needed. 320 if (MCSec.getSelection() != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) { 321 if (const MCSymbol *S = MCSec.getCOMDATSymbol()) { 322 COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(S); 323 if (COMDATSymbol->Section) 324 report_fatal_error("two sections have the same comdat"); 325 COMDATSymbol->Section = Section; 326 } 327 } 328 329 // In this case the auxiliary symbol is a Section Definition. 330 Symbol->Aux.resize(1); 331 Symbol->Aux[0] = {}; 332 Symbol->Aux[0].AuxType = ATSectionDefinition; 333 Symbol->Aux[0].Aux.SectionDefinition.Selection = MCSec.getSelection(); 334 335 // Set section alignment. 336 Section->Header.Characteristics = MCSec.getCharacteristics(); 337 Section->Header.Characteristics |= getAlignment(MCSec); 338 339 // Bind internal COFF section to MC section. 340 Section->MCSection = &MCSec; 341 SectionMap[&MCSec] = Section; 342 343 if (UseOffsetLabels && !MCSec.getFragmentList().empty()) { 344 const uint32_t Interval = 1 << OffsetLabelIntervalBits; 345 uint32_t N = 1; 346 for (uint32_t Off = Interval, E = Layout.getSectionAddressSize(&MCSec); 347 Off < E; Off += Interval) { 348 auto Name = ("$L" + MCSec.getName() + "_" + Twine(N++)).str(); 349 COFFSymbol *Label = createSymbol(Name); 350 Label->Section = Section; 351 Label->Data.StorageClass = COFF::IMAGE_SYM_CLASS_LABEL; 352 Label->Data.Value = Off; 353 Section->OffsetSymbols.push_back(Label); 354 } 355 } 356 } 357 358 static uint64_t getSymbolValue(const MCSymbol &Symbol, 359 const MCAsmLayout &Layout) { 360 if (Symbol.isCommon() && Symbol.isExternal()) 361 return Symbol.getCommonSize(); 362 363 uint64_t Res; 364 if (!Layout.getSymbolOffset(Symbol, Res)) 365 return 0; 366 367 return Res; 368 } 369 370 COFFSymbol *WinCOFFObjectWriter::getLinkedSymbol(const MCSymbol &Symbol) { 371 if (!Symbol.isVariable()) 372 return nullptr; 373 374 const MCSymbolRefExpr *SymRef = 375 dyn_cast<MCSymbolRefExpr>(Symbol.getVariableValue()); 376 if (!SymRef) 377 return nullptr; 378 379 const MCSymbol &Aliasee = SymRef->getSymbol(); 380 if (Aliasee.isUndefined() || Aliasee.isExternal()) 381 return GetOrCreateCOFFSymbol(&Aliasee); 382 else 383 return nullptr; 384 } 385 386 /// This function takes a symbol data object from the assembler 387 /// and creates the associated COFF symbol staging object. 388 void WinCOFFObjectWriter::DefineSymbol(const MCSymbol &MCSym, 389 MCAssembler &Assembler, 390 const MCAsmLayout &Layout) { 391 COFFSymbol *Sym = GetOrCreateCOFFSymbol(&MCSym); 392 const MCSymbol *Base = Layout.getBaseSymbol(MCSym); 393 COFFSection *Sec = nullptr; 394 if (Base && Base->getFragment()) { 395 Sec = SectionMap[Base->getFragment()->getParent()]; 396 if (Sym->Section && Sym->Section != Sec) 397 report_fatal_error("conflicting sections for symbol"); 398 } 399 400 COFFSymbol *Local = nullptr; 401 if (cast<MCSymbolCOFF>(MCSym).isWeakExternal()) { 402 Sym->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL; 403 Sym->Section = nullptr; 404 405 COFFSymbol *WeakDefault = getLinkedSymbol(MCSym); 406 if (!WeakDefault) { 407 std::string WeakName = (".weak." + MCSym.getName() + ".default").str(); 408 WeakDefault = createSymbol(WeakName); 409 if (!Sec) 410 WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE; 411 else 412 WeakDefault->Section = Sec; 413 WeakDefaults.insert(WeakDefault); 414 Local = WeakDefault; 415 } 416 417 Sym->Other = WeakDefault; 418 419 // Setup the Weak External auxiliary symbol. 420 Sym->Aux.resize(1); 421 memset(&Sym->Aux[0], 0, sizeof(Sym->Aux[0])); 422 Sym->Aux[0].AuxType = ATWeakExternal; 423 Sym->Aux[0].Aux.WeakExternal.TagIndex = 0; 424 Sym->Aux[0].Aux.WeakExternal.Characteristics = 425 COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS; 426 } else { 427 if (!Base) 428 Sym->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE; 429 else 430 Sym->Section = Sec; 431 Local = Sym; 432 } 433 434 if (Local) { 435 Local->Data.Value = getSymbolValue(MCSym, Layout); 436 437 const MCSymbolCOFF &SymbolCOFF = cast<MCSymbolCOFF>(MCSym); 438 Local->Data.Type = SymbolCOFF.getType(); 439 Local->Data.StorageClass = SymbolCOFF.getClass(); 440 441 // If no storage class was specified in the streamer, define it here. 442 if (Local->Data.StorageClass == COFF::IMAGE_SYM_CLASS_NULL) { 443 bool IsExternal = MCSym.isExternal() || 444 (!MCSym.getFragment() && !MCSym.isVariable()); 445 446 Local->Data.StorageClass = IsExternal ? COFF::IMAGE_SYM_CLASS_EXTERNAL 447 : COFF::IMAGE_SYM_CLASS_STATIC; 448 } 449 } 450 451 Sym->MC = &MCSym; 452 } 453 454 void WinCOFFObjectWriter::SetSectionName(COFFSection &S) { 455 if (S.Name.size() <= COFF::NameSize) { 456 std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size()); 457 return; 458 } 459 460 uint64_t StringTableEntry = Strings.getOffset(S.Name); 461 if (!COFF::encodeSectionName(S.Header.Name, StringTableEntry)) 462 report_fatal_error("COFF string table is greater than 64 GB."); 463 } 464 465 void WinCOFFObjectWriter::SetSymbolName(COFFSymbol &S) { 466 if (S.Name.size() > COFF::NameSize) 467 S.set_name_offset(Strings.getOffset(S.Name)); 468 else 469 std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size()); 470 } 471 472 bool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) { 473 return (S->Header.Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 474 0; 475 } 476 477 //------------------------------------------------------------------------------ 478 // entity writing methods 479 480 void WinCOFFObjectWriter::WriteFileHeader(const COFF::header &Header) { 481 if (UseBigObj) { 482 W.write<uint16_t>(COFF::IMAGE_FILE_MACHINE_UNKNOWN); 483 W.write<uint16_t>(0xFFFF); 484 W.write<uint16_t>(COFF::BigObjHeader::MinBigObjectVersion); 485 W.write<uint16_t>(Header.Machine); 486 W.write<uint32_t>(Header.TimeDateStamp); 487 W.OS.write(COFF::BigObjMagic, sizeof(COFF::BigObjMagic)); 488 W.write<uint32_t>(0); 489 W.write<uint32_t>(0); 490 W.write<uint32_t>(0); 491 W.write<uint32_t>(0); 492 W.write<uint32_t>(Header.NumberOfSections); 493 W.write<uint32_t>(Header.PointerToSymbolTable); 494 W.write<uint32_t>(Header.NumberOfSymbols); 495 } else { 496 W.write<uint16_t>(Header.Machine); 497 W.write<uint16_t>(static_cast<int16_t>(Header.NumberOfSections)); 498 W.write<uint32_t>(Header.TimeDateStamp); 499 W.write<uint32_t>(Header.PointerToSymbolTable); 500 W.write<uint32_t>(Header.NumberOfSymbols); 501 W.write<uint16_t>(Header.SizeOfOptionalHeader); 502 W.write<uint16_t>(Header.Characteristics); 503 } 504 } 505 506 void WinCOFFObjectWriter::WriteSymbol(const COFFSymbol &S) { 507 W.OS.write(S.Data.Name, COFF::NameSize); 508 W.write<uint32_t>(S.Data.Value); 509 if (UseBigObj) 510 W.write<uint32_t>(S.Data.SectionNumber); 511 else 512 W.write<uint16_t>(static_cast<int16_t>(S.Data.SectionNumber)); 513 W.write<uint16_t>(S.Data.Type); 514 W.OS << char(S.Data.StorageClass); 515 W.OS << char(S.Data.NumberOfAuxSymbols); 516 WriteAuxiliarySymbols(S.Aux); 517 } 518 519 void WinCOFFObjectWriter::WriteAuxiliarySymbols( 520 const COFFSymbol::AuxiliarySymbols &S) { 521 for (const AuxSymbol &i : S) { 522 switch (i.AuxType) { 523 case ATWeakExternal: 524 W.write<uint32_t>(i.Aux.WeakExternal.TagIndex); 525 W.write<uint32_t>(i.Aux.WeakExternal.Characteristics); 526 W.OS.write_zeros(sizeof(i.Aux.WeakExternal.unused)); 527 if (UseBigObj) 528 W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size); 529 break; 530 case ATFile: 531 W.OS.write(reinterpret_cast<const char *>(&i.Aux), 532 UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size); 533 break; 534 case ATSectionDefinition: 535 W.write<uint32_t>(i.Aux.SectionDefinition.Length); 536 W.write<uint16_t>(i.Aux.SectionDefinition.NumberOfRelocations); 537 W.write<uint16_t>(i.Aux.SectionDefinition.NumberOfLinenumbers); 538 W.write<uint32_t>(i.Aux.SectionDefinition.CheckSum); 539 W.write<uint16_t>(static_cast<int16_t>(i.Aux.SectionDefinition.Number)); 540 W.OS << char(i.Aux.SectionDefinition.Selection); 541 W.OS.write_zeros(sizeof(i.Aux.SectionDefinition.unused)); 542 W.write<uint16_t>(static_cast<int16_t>(i.Aux.SectionDefinition.Number >> 16)); 543 if (UseBigObj) 544 W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size); 545 break; 546 } 547 } 548 } 549 550 // Write the section header. 551 void WinCOFFObjectWriter::writeSectionHeaders() { 552 // Section numbers must be monotonically increasing in the section 553 // header, but our Sections array is not sorted by section number, 554 // so make a copy of Sections and sort it. 555 std::vector<COFFSection *> Arr; 556 for (auto &Section : Sections) 557 Arr.push_back(Section.get()); 558 llvm::sort(Arr, [](const COFFSection *A, const COFFSection *B) { 559 return A->Number < B->Number; 560 }); 561 562 for (auto &Section : Arr) { 563 if (Section->Number == -1) 564 continue; 565 566 COFF::section &S = Section->Header; 567 if (Section->Relocations.size() >= 0xffff) 568 S.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL; 569 W.OS.write(S.Name, COFF::NameSize); 570 W.write<uint32_t>(S.VirtualSize); 571 W.write<uint32_t>(S.VirtualAddress); 572 W.write<uint32_t>(S.SizeOfRawData); 573 W.write<uint32_t>(S.PointerToRawData); 574 W.write<uint32_t>(S.PointerToRelocations); 575 W.write<uint32_t>(S.PointerToLineNumbers); 576 W.write<uint16_t>(S.NumberOfRelocations); 577 W.write<uint16_t>(S.NumberOfLineNumbers); 578 W.write<uint32_t>(S.Characteristics); 579 } 580 } 581 582 void WinCOFFObjectWriter::WriteRelocation(const COFF::relocation &R) { 583 W.write<uint32_t>(R.VirtualAddress); 584 W.write<uint32_t>(R.SymbolTableIndex); 585 W.write<uint16_t>(R.Type); 586 } 587 588 // Write MCSec's contents. What this function does is essentially 589 // "Asm.writeSectionData(&MCSec, Layout)", but it's a bit complicated 590 // because it needs to compute a CRC. 591 uint32_t WinCOFFObjectWriter::writeSectionContents(MCAssembler &Asm, 592 const MCAsmLayout &Layout, 593 const MCSection &MCSec) { 594 // Save the contents of the section to a temporary buffer, we need this 595 // to CRC the data before we dump it into the object file. 596 SmallVector<char, 128> Buf; 597 raw_svector_ostream VecOS(Buf); 598 Asm.writeSectionData(VecOS, &MCSec, Layout); 599 600 // Write the section contents to the object file. 601 W.OS << Buf; 602 603 // Calculate our CRC with an initial value of '0', this is not how 604 // JamCRC is specified but it aligns with the expected output. 605 JamCRC JC(/*Init=*/0); 606 JC.update(makeArrayRef(reinterpret_cast<uint8_t*>(Buf.data()), Buf.size())); 607 return JC.getCRC(); 608 } 609 610 void WinCOFFObjectWriter::writeSection(MCAssembler &Asm, 611 const MCAsmLayout &Layout, 612 const COFFSection &Sec, 613 const MCSection &MCSec) { 614 if (Sec.Number == -1) 615 return; 616 617 // Write the section contents. 618 if (Sec.Header.PointerToRawData != 0) { 619 assert(W.OS.tell() == Sec.Header.PointerToRawData && 620 "Section::PointerToRawData is insane!"); 621 622 uint32_t CRC = writeSectionContents(Asm, Layout, MCSec); 623 624 // Update the section definition auxiliary symbol to record the CRC. 625 COFFSection *Sec = SectionMap[&MCSec]; 626 COFFSymbol::AuxiliarySymbols &AuxSyms = Sec->Symbol->Aux; 627 assert(AuxSyms.size() == 1 && AuxSyms[0].AuxType == ATSectionDefinition); 628 AuxSymbol &SecDef = AuxSyms[0]; 629 SecDef.Aux.SectionDefinition.CheckSum = CRC; 630 } 631 632 // Write relocations for this section. 633 if (Sec.Relocations.empty()) { 634 assert(Sec.Header.PointerToRelocations == 0 && 635 "Section::PointerToRelocations is insane!"); 636 return; 637 } 638 639 assert(W.OS.tell() == Sec.Header.PointerToRelocations && 640 "Section::PointerToRelocations is insane!"); 641 642 if (Sec.Relocations.size() >= 0xffff) { 643 // In case of overflow, write actual relocation count as first 644 // relocation. Including the synthetic reloc itself (+ 1). 645 COFF::relocation R; 646 R.VirtualAddress = Sec.Relocations.size() + 1; 647 R.SymbolTableIndex = 0; 648 R.Type = 0; 649 WriteRelocation(R); 650 } 651 652 for (const auto &Relocation : Sec.Relocations) 653 WriteRelocation(Relocation.Data); 654 } 655 656 //////////////////////////////////////////////////////////////////////////////// 657 // MCObjectWriter interface implementations 658 659 void WinCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm, 660 const MCAsmLayout &Layout) { 661 if (EmitAddrsigSection) { 662 AddrsigSection = Asm.getContext().getCOFFSection( 663 ".llvm_addrsig", COFF::IMAGE_SCN_LNK_REMOVE, 664 SectionKind::getMetadata()); 665 Asm.registerSection(*AddrsigSection); 666 } 667 668 if (!Asm.CGProfile.empty()) { 669 CGProfileSection = Asm.getContext().getCOFFSection( 670 ".llvm.call-graph-profile", COFF::IMAGE_SCN_LNK_REMOVE, 671 SectionKind::getMetadata()); 672 Asm.registerSection(*CGProfileSection); 673 } 674 675 // "Define" each section & symbol. This creates section & symbol 676 // entries in the staging area. 677 for (const auto &Section : Asm) 678 defineSection(static_cast<const MCSectionCOFF &>(Section), Layout); 679 680 for (const MCSymbol &Symbol : Asm.symbols()) 681 if (!Symbol.isTemporary()) 682 DefineSymbol(Symbol, Asm, Layout); 683 } 684 685 bool WinCOFFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl( 686 const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB, 687 bool InSet, bool IsPCRel) const { 688 // Don't drop relocations between functions, even if they are in the same text 689 // section. Multiple Visual C++ linker features depend on having the 690 // relocations present. The /INCREMENTAL flag will cause these relocations to 691 // point to thunks, and the /GUARD:CF flag assumes that it can use relocations 692 // to approximate the set of all address taken functions. LLD's implementation 693 // of /GUARD:CF also relies on the existance of these relocations. 694 uint16_t Type = cast<MCSymbolCOFF>(SymA).getType(); 695 if ((Type >> COFF::SCT_COMPLEX_TYPE_SHIFT) == COFF::IMAGE_SYM_DTYPE_FUNCTION) 696 return false; 697 return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB, 698 InSet, IsPCRel); 699 } 700 701 void WinCOFFObjectWriter::recordRelocation(MCAssembler &Asm, 702 const MCAsmLayout &Layout, 703 const MCFragment *Fragment, 704 const MCFixup &Fixup, MCValue Target, 705 uint64_t &FixedValue) { 706 assert(Target.getSymA() && "Relocation must reference a symbol!"); 707 708 const MCSymbol &A = Target.getSymA()->getSymbol(); 709 if (!A.isRegistered()) { 710 Asm.getContext().reportError(Fixup.getLoc(), 711 Twine("symbol '") + A.getName() + 712 "' can not be undefined"); 713 return; 714 } 715 if (A.isTemporary() && A.isUndefined()) { 716 Asm.getContext().reportError(Fixup.getLoc(), 717 Twine("assembler label '") + A.getName() + 718 "' can not be undefined"); 719 return; 720 } 721 722 MCSection *MCSec = Fragment->getParent(); 723 724 // Mark this symbol as requiring an entry in the symbol table. 725 assert(SectionMap.find(MCSec) != SectionMap.end() && 726 "Section must already have been defined in executePostLayoutBinding!"); 727 728 COFFSection *Sec = SectionMap[MCSec]; 729 const MCSymbolRefExpr *SymB = Target.getSymB(); 730 731 if (SymB) { 732 const MCSymbol *B = &SymB->getSymbol(); 733 if (!B->getFragment()) { 734 Asm.getContext().reportError( 735 Fixup.getLoc(), 736 Twine("symbol '") + B->getName() + 737 "' can not be undefined in a subtraction expression"); 738 return; 739 } 740 741 // Offset of the symbol in the section 742 int64_t OffsetOfB = Layout.getSymbolOffset(*B); 743 744 // Offset of the relocation in the section 745 int64_t OffsetOfRelocation = 746 Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); 747 748 FixedValue = (OffsetOfRelocation - OffsetOfB) + Target.getConstant(); 749 } else { 750 FixedValue = Target.getConstant(); 751 } 752 753 COFFRelocation Reloc; 754 755 Reloc.Data.SymbolTableIndex = 0; 756 Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment); 757 758 // Turn relocations for temporary symbols into section relocations. 759 if (A.isTemporary()) { 760 MCSection *TargetSection = &A.getSection(); 761 assert( 762 SectionMap.find(TargetSection) != SectionMap.end() && 763 "Section must already have been defined in executePostLayoutBinding!"); 764 COFFSection *Section = SectionMap[TargetSection]; 765 Reloc.Symb = Section->Symbol; 766 FixedValue += Layout.getSymbolOffset(A); 767 // Technically, we should do the final adjustments of FixedValue (below) 768 // before picking an offset symbol, otherwise we might choose one which 769 // is slightly too far away. The relocations where it really matters 770 // (arm64 adrp relocations) don't get any offset though. 771 if (UseOffsetLabels && !Section->OffsetSymbols.empty()) { 772 uint64_t LabelIndex = FixedValue >> OffsetLabelIntervalBits; 773 if (LabelIndex > 0) { 774 if (LabelIndex <= Section->OffsetSymbols.size()) 775 Reloc.Symb = Section->OffsetSymbols[LabelIndex - 1]; 776 else 777 Reloc.Symb = Section->OffsetSymbols.back(); 778 FixedValue -= Reloc.Symb->Data.Value; 779 } 780 } 781 } else { 782 assert( 783 SymbolMap.find(&A) != SymbolMap.end() && 784 "Symbol must already have been defined in executePostLayoutBinding!"); 785 Reloc.Symb = SymbolMap[&A]; 786 } 787 788 ++Reloc.Symb->Relocations; 789 790 Reloc.Data.VirtualAddress += Fixup.getOffset(); 791 Reloc.Data.Type = TargetObjectWriter->getRelocType( 792 Asm.getContext(), Target, Fixup, SymB, Asm.getBackend()); 793 794 // The *_REL32 relocations are relative to the end of the relocation, 795 // not to the start. 796 if ((Header.Machine == COFF::IMAGE_FILE_MACHINE_AMD64 && 797 Reloc.Data.Type == COFF::IMAGE_REL_AMD64_REL32) || 798 (Header.Machine == COFF::IMAGE_FILE_MACHINE_I386 && 799 Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32) || 800 (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT && 801 Reloc.Data.Type == COFF::IMAGE_REL_ARM_REL32) || 802 (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARM64 && 803 Reloc.Data.Type == COFF::IMAGE_REL_ARM64_REL32)) 804 FixedValue += 4; 805 806 if (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT) { 807 switch (Reloc.Data.Type) { 808 case COFF::IMAGE_REL_ARM_ABSOLUTE: 809 case COFF::IMAGE_REL_ARM_ADDR32: 810 case COFF::IMAGE_REL_ARM_ADDR32NB: 811 case COFF::IMAGE_REL_ARM_TOKEN: 812 case COFF::IMAGE_REL_ARM_SECTION: 813 case COFF::IMAGE_REL_ARM_SECREL: 814 break; 815 case COFF::IMAGE_REL_ARM_BRANCH11: 816 case COFF::IMAGE_REL_ARM_BLX11: 817 // IMAGE_REL_ARM_BRANCH11 and IMAGE_REL_ARM_BLX11 are only used for 818 // pre-ARMv7, which implicitly rules it out of ARMNT (it would be valid 819 // for Windows CE). 820 case COFF::IMAGE_REL_ARM_BRANCH24: 821 case COFF::IMAGE_REL_ARM_BLX24: 822 case COFF::IMAGE_REL_ARM_MOV32A: 823 // IMAGE_REL_ARM_BRANCH24, IMAGE_REL_ARM_BLX24, IMAGE_REL_ARM_MOV32A are 824 // only used for ARM mode code, which is documented as being unsupported 825 // by Windows on ARM. Empirical proof indicates that masm is able to 826 // generate the relocations however the rest of the MSVC toolchain is 827 // unable to handle it. 828 llvm_unreachable("unsupported relocation"); 829 break; 830 case COFF::IMAGE_REL_ARM_MOV32T: 831 break; 832 case COFF::IMAGE_REL_ARM_BRANCH20T: 833 case COFF::IMAGE_REL_ARM_BRANCH24T: 834 case COFF::IMAGE_REL_ARM_BLX23T: 835 // IMAGE_REL_BRANCH20T, IMAGE_REL_ARM_BRANCH24T, IMAGE_REL_ARM_BLX23T all 836 // perform a 4 byte adjustment to the relocation. Relative branches are 837 // offset by 4 on ARM, however, because there is no RELA relocations, all 838 // branches are offset by 4. 839 FixedValue = FixedValue + 4; 840 break; 841 } 842 } 843 844 // The fixed value never makes sense for section indices, ignore it. 845 if (Fixup.getKind() == FK_SecRel_2) 846 FixedValue = 0; 847 848 if (TargetObjectWriter->recordRelocation(Fixup)) 849 Sec->Relocations.push_back(Reloc); 850 } 851 852 static std::time_t getTime() { 853 std::time_t Now = time(nullptr); 854 if (Now < 0 || !isUInt<32>(Now)) 855 return UINT32_MAX; 856 return Now; 857 } 858 859 // Create .file symbols. 860 void WinCOFFObjectWriter::createFileSymbols(MCAssembler &Asm) { 861 for (const std::pair<std::string, size_t> &It : Asm.getFileNames()) { 862 // round up to calculate the number of auxiliary symbols required 863 const std::string &Name = It.first; 864 unsigned SymbolSize = UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size; 865 unsigned Count = (Name.size() + SymbolSize - 1) / SymbolSize; 866 867 COFFSymbol *File = createSymbol(".file"); 868 File->Data.SectionNumber = COFF::IMAGE_SYM_DEBUG; 869 File->Data.StorageClass = COFF::IMAGE_SYM_CLASS_FILE; 870 File->Aux.resize(Count); 871 872 unsigned Offset = 0; 873 unsigned Length = Name.size(); 874 for (auto &Aux : File->Aux) { 875 Aux.AuxType = ATFile; 876 877 if (Length > SymbolSize) { 878 memcpy(&Aux.Aux, Name.c_str() + Offset, SymbolSize); 879 Length = Length - SymbolSize; 880 } else { 881 memcpy(&Aux.Aux, Name.c_str() + Offset, Length); 882 memset((char *)&Aux.Aux + Length, 0, SymbolSize - Length); 883 break; 884 } 885 886 Offset += SymbolSize; 887 } 888 } 889 } 890 891 void WinCOFFObjectWriter::setWeakDefaultNames() { 892 if (WeakDefaults.empty()) 893 return; 894 895 // If multiple object files use a weak symbol (either with a regular 896 // defined default, or an absolute zero symbol as default), the defaults 897 // cause duplicate definitions unless their names are made unique. Look 898 // for a defined extern symbol, that isn't comdat - that should be unique 899 // unless there are other duplicate definitions. And if none is found, 900 // allow picking a comdat symbol, as that's still better than nothing. 901 902 COFFSymbol *Unique = nullptr; 903 for (bool AllowComdat : {false, true}) { 904 for (auto &Sym : Symbols) { 905 // Don't include the names of the defaults themselves 906 if (WeakDefaults.count(Sym.get())) 907 continue; 908 // Only consider external symbols 909 if (Sym->Data.StorageClass != COFF::IMAGE_SYM_CLASS_EXTERNAL) 910 continue; 911 // Only consider symbols defined in a section or that are absolute 912 if (!Sym->Section && Sym->Data.SectionNumber != COFF::IMAGE_SYM_ABSOLUTE) 913 continue; 914 if (!AllowComdat && Sym->Section && 915 Sym->Section->Header.Characteristics & COFF::IMAGE_SCN_LNK_COMDAT) 916 continue; 917 Unique = Sym.get(); 918 break; 919 } 920 if (Unique) 921 break; 922 } 923 // If we didn't find any unique symbol to use for the names, just skip this. 924 if (!Unique) 925 return; 926 for (auto *Sym : WeakDefaults) { 927 Sym->Name.append("."); 928 Sym->Name.append(Unique->Name); 929 } 930 } 931 932 static bool isAssociative(const COFFSection &Section) { 933 return Section.Symbol->Aux[0].Aux.SectionDefinition.Selection == 934 COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE; 935 } 936 937 void WinCOFFObjectWriter::assignSectionNumbers() { 938 size_t I = 1; 939 auto Assign = [&](COFFSection &Section) { 940 Section.Number = I; 941 Section.Symbol->Data.SectionNumber = I; 942 Section.Symbol->Aux[0].Aux.SectionDefinition.Number = I; 943 ++I; 944 }; 945 946 // Although it is not explicitly requested by the Microsoft COFF spec, 947 // we should avoid emitting forward associative section references, 948 // because MSVC link.exe as of 2017 cannot handle that. 949 for (const std::unique_ptr<COFFSection> &Section : Sections) 950 if (!isAssociative(*Section)) 951 Assign(*Section); 952 for (const std::unique_ptr<COFFSection> &Section : Sections) 953 if (isAssociative(*Section)) 954 Assign(*Section); 955 } 956 957 // Assign file offsets to COFF object file structures. 958 void WinCOFFObjectWriter::assignFileOffsets(MCAssembler &Asm, 959 const MCAsmLayout &Layout) { 960 unsigned Offset = W.OS.tell(); 961 962 Offset += UseBigObj ? COFF::Header32Size : COFF::Header16Size; 963 Offset += COFF::SectionSize * Header.NumberOfSections; 964 965 for (const auto &Section : Asm) { 966 COFFSection *Sec = SectionMap[&Section]; 967 968 if (Sec->Number == -1) 969 continue; 970 971 Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(&Section); 972 973 if (IsPhysicalSection(Sec)) { 974 Sec->Header.PointerToRawData = Offset; 975 Offset += Sec->Header.SizeOfRawData; 976 } 977 978 if (!Sec->Relocations.empty()) { 979 bool RelocationsOverflow = Sec->Relocations.size() >= 0xffff; 980 981 if (RelocationsOverflow) { 982 // Signal overflow by setting NumberOfRelocations to max value. Actual 983 // size is found in reloc #0. Microsoft tools understand this. 984 Sec->Header.NumberOfRelocations = 0xffff; 985 } else { 986 Sec->Header.NumberOfRelocations = Sec->Relocations.size(); 987 } 988 Sec->Header.PointerToRelocations = Offset; 989 990 if (RelocationsOverflow) { 991 // Reloc #0 will contain actual count, so make room for it. 992 Offset += COFF::RelocationSize; 993 } 994 995 Offset += COFF::RelocationSize * Sec->Relocations.size(); 996 997 for (auto &Relocation : Sec->Relocations) { 998 assert(Relocation.Symb->getIndex() != -1); 999 Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex(); 1000 } 1001 } 1002 1003 assert(Sec->Symbol->Aux.size() == 1 && 1004 "Section's symbol must have one aux!"); 1005 AuxSymbol &Aux = Sec->Symbol->Aux[0]; 1006 assert(Aux.AuxType == ATSectionDefinition && 1007 "Section's symbol's aux symbol must be a Section Definition!"); 1008 Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData; 1009 Aux.Aux.SectionDefinition.NumberOfRelocations = 1010 Sec->Header.NumberOfRelocations; 1011 Aux.Aux.SectionDefinition.NumberOfLinenumbers = 1012 Sec->Header.NumberOfLineNumbers; 1013 } 1014 1015 Header.PointerToSymbolTable = Offset; 1016 } 1017 1018 uint64_t WinCOFFObjectWriter::writeObject(MCAssembler &Asm, 1019 const MCAsmLayout &Layout) { 1020 uint64_t StartOffset = W.OS.tell(); 1021 1022 if (Sections.size() > INT32_MAX) 1023 report_fatal_error( 1024 "PE COFF object files can't have more than 2147483647 sections"); 1025 1026 UseBigObj = Sections.size() > COFF::MaxNumberOfSections16; 1027 Header.NumberOfSections = Sections.size(); 1028 Header.NumberOfSymbols = 0; 1029 1030 setWeakDefaultNames(); 1031 assignSectionNumbers(); 1032 createFileSymbols(Asm); 1033 1034 for (auto &Symbol : Symbols) { 1035 // Update section number & offset for symbols that have them. 1036 if (Symbol->Section) 1037 Symbol->Data.SectionNumber = Symbol->Section->Number; 1038 Symbol->setIndex(Header.NumberOfSymbols++); 1039 // Update auxiliary symbol info. 1040 Symbol->Data.NumberOfAuxSymbols = Symbol->Aux.size(); 1041 Header.NumberOfSymbols += Symbol->Data.NumberOfAuxSymbols; 1042 } 1043 1044 // Build string table. 1045 for (const auto &S : Sections) 1046 if (S->Name.size() > COFF::NameSize) 1047 Strings.add(S->Name); 1048 for (const auto &S : Symbols) 1049 if (S->Name.size() > COFF::NameSize) 1050 Strings.add(S->Name); 1051 Strings.finalize(); 1052 1053 // Set names. 1054 for (const auto &S : Sections) 1055 SetSectionName(*S); 1056 for (auto &S : Symbols) 1057 SetSymbolName(*S); 1058 1059 // Fixup weak external references. 1060 for (auto &Symbol : Symbols) { 1061 if (Symbol->Other) { 1062 assert(Symbol->getIndex() != -1); 1063 assert(Symbol->Aux.size() == 1 && "Symbol must contain one aux symbol!"); 1064 assert(Symbol->Aux[0].AuxType == ATWeakExternal && 1065 "Symbol's aux symbol must be a Weak External!"); 1066 Symbol->Aux[0].Aux.WeakExternal.TagIndex = Symbol->Other->getIndex(); 1067 } 1068 } 1069 1070 // Fixup associative COMDAT sections. 1071 for (auto &Section : Sections) { 1072 if (Section->Symbol->Aux[0].Aux.SectionDefinition.Selection != 1073 COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) 1074 continue; 1075 1076 const MCSectionCOFF &MCSec = *Section->MCSection; 1077 const MCSymbol *AssocMCSym = MCSec.getCOMDATSymbol(); 1078 assert(AssocMCSym); 1079 1080 // It's an error to try to associate with an undefined symbol or a symbol 1081 // without a section. 1082 if (!AssocMCSym->isInSection()) { 1083 Asm.getContext().reportError( 1084 SMLoc(), Twine("cannot make section ") + MCSec.getName() + 1085 Twine(" associative with sectionless symbol ") + 1086 AssocMCSym->getName()); 1087 continue; 1088 } 1089 1090 const auto *AssocMCSec = cast<MCSectionCOFF>(&AssocMCSym->getSection()); 1091 assert(SectionMap.count(AssocMCSec)); 1092 COFFSection *AssocSec = SectionMap[AssocMCSec]; 1093 1094 // Skip this section if the associated section is unused. 1095 if (AssocSec->Number == -1) 1096 continue; 1097 1098 Section->Symbol->Aux[0].Aux.SectionDefinition.Number = AssocSec->Number; 1099 } 1100 1101 // Create the contents of the .llvm_addrsig section. 1102 if (EmitAddrsigSection) { 1103 auto Frag = new MCDataFragment(AddrsigSection); 1104 Frag->setLayoutOrder(0); 1105 raw_svector_ostream OS(Frag->getContents()); 1106 for (const MCSymbol *S : AddrsigSyms) { 1107 if (!S->isTemporary()) { 1108 encodeULEB128(S->getIndex(), OS); 1109 continue; 1110 } 1111 1112 MCSection *TargetSection = &S->getSection(); 1113 assert(SectionMap.find(TargetSection) != SectionMap.end() && 1114 "Section must already have been defined in " 1115 "executePostLayoutBinding!"); 1116 encodeULEB128(SectionMap[TargetSection]->Symbol->getIndex(), OS); 1117 } 1118 } 1119 1120 // Create the contents of the .llvm.call-graph-profile section. 1121 if (CGProfileSection) { 1122 auto *Frag = new MCDataFragment(CGProfileSection); 1123 Frag->setLayoutOrder(0); 1124 raw_svector_ostream OS(Frag->getContents()); 1125 for (const MCAssembler::CGProfileEntry &CGPE : Asm.CGProfile) { 1126 uint32_t FromIndex = CGPE.From->getSymbol().getIndex(); 1127 uint32_t ToIndex = CGPE.To->getSymbol().getIndex(); 1128 support::endian::write(OS, FromIndex, W.Endian); 1129 support::endian::write(OS, ToIndex, W.Endian); 1130 support::endian::write(OS, CGPE.Count, W.Endian); 1131 } 1132 } 1133 1134 assignFileOffsets(Asm, Layout); 1135 1136 // MS LINK expects to be able to use this timestamp to implement their 1137 // /INCREMENTAL feature. 1138 if (Asm.isIncrementalLinkerCompatible()) { 1139 Header.TimeDateStamp = getTime(); 1140 } else { 1141 // Have deterministic output if /INCREMENTAL isn't needed. Also matches GNU. 1142 Header.TimeDateStamp = 0; 1143 } 1144 1145 // Write it all to disk... 1146 WriteFileHeader(Header); 1147 writeSectionHeaders(); 1148 1149 // Write section contents. 1150 sections::iterator I = Sections.begin(); 1151 sections::iterator IE = Sections.end(); 1152 MCAssembler::iterator J = Asm.begin(); 1153 MCAssembler::iterator JE = Asm.end(); 1154 for (; I != IE && J != JE; ++I, ++J) 1155 writeSection(Asm, Layout, **I, *J); 1156 1157 assert(W.OS.tell() == Header.PointerToSymbolTable && 1158 "Header::PointerToSymbolTable is insane!"); 1159 1160 // Write a symbol table. 1161 for (auto &Symbol : Symbols) 1162 if (Symbol->getIndex() != -1) 1163 WriteSymbol(*Symbol); 1164 1165 // Write a string table, which completes the entire COFF file. 1166 Strings.write(W.OS); 1167 1168 return W.OS.tell() - StartOffset; 1169 } 1170 1171 MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_) 1172 : Machine(Machine_) {} 1173 1174 // Pin the vtable to this file. 1175 void MCWinCOFFObjectTargetWriter::anchor() {} 1176 1177 //------------------------------------------------------------------------------ 1178 // WinCOFFObjectWriter factory function 1179 1180 std::unique_ptr<MCObjectWriter> llvm::createWinCOFFObjectWriter( 1181 std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS) { 1182 return std::make_unique<WinCOFFObjectWriter>(std::move(MOTW), OS); 1183 } 1184