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