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