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