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