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