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 <algorithm> 42 #include <cassert> 43 #include <cstdint> 44 #include <cstring> 45 #include <ctime> 46 #include <memory> 47 #include <string> 48 #include <vector> 49 50 using namespace llvm; 51 using llvm::support::endian::write32le; 52 53 #define DEBUG_TYPE "WinCOFFObjectWriter" 54 55 namespace { 56 57 constexpr int OffsetLabelIntervalBits = 20; 58 59 using name = SmallString<COFF::NameSize>; 60 61 enum AuxiliaryType { ATWeakExternal, ATFile, ATSectionDefinition }; 62 63 struct AuxSymbol { 64 AuxiliaryType AuxType; 65 COFF::Auxiliary Aux; 66 }; 67 68 class COFFSection; 69 70 class COFFSymbol { 71 public: 72 COFF::symbol Data = {}; 73 74 using AuxiliarySymbols = SmallVector<AuxSymbol, 1>; 75 76 name Name; 77 int Index = 0; 78 AuxiliarySymbols Aux; 79 COFFSymbol *Other = nullptr; 80 COFFSection *Section = nullptr; 81 int Relocations = 0; 82 const MCSymbol *MC = nullptr; 83 84 COFFSymbol(StringRef Name) : Name(Name) {} 85 86 void set_name_offset(uint32_t Offset); 87 88 int64_t getIndex() const { return Index; } 89 void setIndex(int Value) { 90 Index = Value; 91 if (MC) 92 MC->setIndex(static_cast<uint32_t>(Value)); 93 } 94 }; 95 96 // This class contains staging data for a COFF relocation entry. 97 struct COFFRelocation { 98 COFF::relocation Data; 99 COFFSymbol *Symb = nullptr; 100 101 COFFRelocation() = default; 102 103 static size_t size() { return COFF::RelocationSize; } 104 }; 105 106 using relocations = std::vector<COFFRelocation>; 107 108 class COFFSection { 109 public: 110 COFF::section Header = {}; 111 112 std::string Name; 113 int Number = 0; 114 MCSectionCOFF const *MCSection = nullptr; 115 COFFSymbol *Symbol = nullptr; 116 relocations Relocations; 117 118 COFFSection(StringRef Name) : Name(std::string(Name)) {} 119 120 SmallVector<COFFSymbol *, 1> OffsetSymbols; 121 }; 122 } // namespace 123 124 class llvm::WinCOFFWriter { 125 WinCOFFObjectWriter &OWriter; 126 support::endian::Writer W; 127 128 using symbols = std::vector<std::unique_ptr<COFFSymbol>>; 129 using sections = std::vector<std::unique_ptr<COFFSection>>; 130 131 using symbol_map = DenseMap<MCSymbol const *, COFFSymbol *>; 132 using section_map = DenseMap<MCSection const *, COFFSection *>; 133 134 using symbol_list = DenseSet<COFFSymbol *>; 135 136 // Root level file contents. 137 COFF::header Header = {}; 138 sections Sections; 139 symbols Symbols; 140 StringTableBuilder Strings{StringTableBuilder::WinCOFF}; 141 142 // Maps used during object file creation. 143 section_map SectionMap; 144 symbol_map SymbolMap; 145 146 symbol_list WeakDefaults; 147 148 bool UseBigObj; 149 bool UseOffsetLabels = false; 150 151 public: 152 enum DwoMode { 153 AllSections, 154 NonDwoOnly, 155 DwoOnly, 156 } Mode; 157 158 WinCOFFWriter(WinCOFFObjectWriter &OWriter, raw_pwrite_stream &OS, 159 DwoMode Mode); 160 161 void reset(); 162 void executePostLayoutBinding(MCAssembler &Asm); 163 void recordRelocation(MCAssembler &Asm, const MCFragment *Fragment, 164 const MCFixup &Fixup, MCValue Target, 165 uint64_t &FixedValue); 166 uint64_t writeObject(MCAssembler &Asm); 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 && !MCSec.empty()) { 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 Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex(); 777 } 778 } 779 780 assert(Sec->Symbol->Aux.size() == 1 && 781 "Section's symbol must have one aux!"); 782 AuxSymbol &Aux = Sec->Symbol->Aux[0]; 783 assert(Aux.AuxType == ATSectionDefinition && 784 "Section's symbol's aux symbol must be a Section Definition!"); 785 Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData; 786 Aux.Aux.SectionDefinition.NumberOfRelocations = 787 Sec->Header.NumberOfRelocations; 788 Aux.Aux.SectionDefinition.NumberOfLinenumbers = 789 Sec->Header.NumberOfLineNumbers; 790 } 791 792 Header.PointerToSymbolTable = Offset; 793 } 794 795 void WinCOFFWriter::reset() { 796 memset(&Header, 0, sizeof(Header)); 797 Header.Machine = OWriter.TargetObjectWriter->getMachine(); 798 Sections.clear(); 799 Symbols.clear(); 800 Strings.clear(); 801 SectionMap.clear(); 802 SymbolMap.clear(); 803 WeakDefaults.clear(); 804 } 805 806 void WinCOFFWriter::executePostLayoutBinding(MCAssembler &Asm) { 807 // "Define" each section & symbol. This creates section & symbol 808 // entries in the staging area. 809 for (const auto &Section : Asm) { 810 if ((Mode == NonDwoOnly && isDwoSection(Section)) || 811 (Mode == DwoOnly && !isDwoSection(Section))) 812 continue; 813 defineSection(Asm, static_cast<const MCSectionCOFF &>(Section)); 814 } 815 816 if (Mode != DwoOnly) 817 for (const MCSymbol &Symbol : Asm.symbols()) 818 // Define non-temporary or temporary static (private-linkage) symbols 819 if (!Symbol.isTemporary() || 820 cast<MCSymbolCOFF>(Symbol).getClass() == COFF::IMAGE_SYM_CLASS_STATIC) 821 defineSymbol(Asm, Symbol); 822 } 823 824 void WinCOFFWriter::recordRelocation(MCAssembler &Asm, 825 const MCFragment *Fragment, 826 const MCFixup &Fixup, MCValue Target, 827 uint64_t &FixedValue) { 828 assert(Target.getSymA() && "Relocation must reference a symbol!"); 829 830 const MCSymbol &A = Target.getSymA()->getSymbol(); 831 if (!A.isRegistered()) { 832 Asm.getContext().reportError(Fixup.getLoc(), Twine("symbol '") + 833 A.getName() + 834 "' can not be undefined"); 835 return; 836 } 837 if (A.isTemporary() && A.isUndefined()) { 838 Asm.getContext().reportError(Fixup.getLoc(), Twine("assembler label '") + 839 A.getName() + 840 "' can not be undefined"); 841 return; 842 } 843 844 MCSection *MCSec = Fragment->getParent(); 845 846 // Mark this symbol as requiring an entry in the symbol table. 847 assert(SectionMap.contains(MCSec) && 848 "Section must already have been defined in executePostLayoutBinding!"); 849 850 COFFSection *Sec = SectionMap[MCSec]; 851 const MCSymbolRefExpr *SymB = Target.getSymB(); 852 853 if (SymB) { 854 const MCSymbol *B = &SymB->getSymbol(); 855 if (!B->getFragment()) { 856 Asm.getContext().reportError( 857 Fixup.getLoc(), 858 Twine("symbol '") + B->getName() + 859 "' can not be undefined in a subtraction expression"); 860 return; 861 } 862 863 // Offset of the symbol in the section 864 int64_t OffsetOfB = Asm.getSymbolOffset(*B); 865 866 // Offset of the relocation in the section 867 int64_t OffsetOfRelocation = 868 Asm.getFragmentOffset(*Fragment) + Fixup.getOffset(); 869 870 FixedValue = (OffsetOfRelocation - OffsetOfB) + Target.getConstant(); 871 } else { 872 FixedValue = Target.getConstant(); 873 } 874 875 COFFRelocation Reloc; 876 877 Reloc.Data.SymbolTableIndex = 0; 878 Reloc.Data.VirtualAddress = Asm.getFragmentOffset(*Fragment); 879 880 // Turn relocations for temporary symbols into section relocations. 881 if (A.isTemporary() && !SymbolMap[&A]) { 882 MCSection *TargetSection = &A.getSection(); 883 assert( 884 SectionMap.contains(TargetSection) && 885 "Section must already have been defined in executePostLayoutBinding!"); 886 COFFSection *Section = SectionMap[TargetSection]; 887 Reloc.Symb = Section->Symbol; 888 FixedValue += Asm.getSymbolOffset(A); 889 // Technically, we should do the final adjustments of FixedValue (below) 890 // before picking an offset symbol, otherwise we might choose one which 891 // is slightly too far away. The relocations where it really matters 892 // (arm64 adrp relocations) don't get any offset though. 893 if (UseOffsetLabels && !Section->OffsetSymbols.empty()) { 894 uint64_t LabelIndex = FixedValue >> OffsetLabelIntervalBits; 895 if (LabelIndex > 0) { 896 if (LabelIndex <= Section->OffsetSymbols.size()) 897 Reloc.Symb = Section->OffsetSymbols[LabelIndex - 1]; 898 else 899 Reloc.Symb = Section->OffsetSymbols.back(); 900 FixedValue -= Reloc.Symb->Data.Value; 901 } 902 } 903 } else { 904 assert( 905 SymbolMap.contains(&A) && 906 "Symbol must already have been defined in executePostLayoutBinding!"); 907 Reloc.Symb = SymbolMap[&A]; 908 } 909 910 ++Reloc.Symb->Relocations; 911 912 Reloc.Data.VirtualAddress += Fixup.getOffset(); 913 Reloc.Data.Type = OWriter.TargetObjectWriter->getRelocType( 914 Asm.getContext(), Target, Fixup, SymB, Asm.getBackend()); 915 916 // The *_REL32 relocations are relative to the end of the relocation, 917 // not to the start. 918 if ((Header.Machine == COFF::IMAGE_FILE_MACHINE_AMD64 && 919 Reloc.Data.Type == COFF::IMAGE_REL_AMD64_REL32) || 920 (Header.Machine == COFF::IMAGE_FILE_MACHINE_I386 && 921 Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32) || 922 (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT && 923 Reloc.Data.Type == COFF::IMAGE_REL_ARM_REL32) || 924 (COFF::isAnyArm64(Header.Machine) && 925 Reloc.Data.Type == COFF::IMAGE_REL_ARM64_REL32)) 926 FixedValue += 4; 927 928 if (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT) { 929 switch (Reloc.Data.Type) { 930 case COFF::IMAGE_REL_ARM_ABSOLUTE: 931 case COFF::IMAGE_REL_ARM_ADDR32: 932 case COFF::IMAGE_REL_ARM_ADDR32NB: 933 case COFF::IMAGE_REL_ARM_TOKEN: 934 case COFF::IMAGE_REL_ARM_SECTION: 935 case COFF::IMAGE_REL_ARM_SECREL: 936 break; 937 case COFF::IMAGE_REL_ARM_BRANCH11: 938 case COFF::IMAGE_REL_ARM_BLX11: 939 // IMAGE_REL_ARM_BRANCH11 and IMAGE_REL_ARM_BLX11 are only used for 940 // pre-ARMv7, which implicitly rules it out of ARMNT (it would be valid 941 // for Windows CE). 942 case COFF::IMAGE_REL_ARM_BRANCH24: 943 case COFF::IMAGE_REL_ARM_BLX24: 944 case COFF::IMAGE_REL_ARM_MOV32A: 945 // IMAGE_REL_ARM_BRANCH24, IMAGE_REL_ARM_BLX24, IMAGE_REL_ARM_MOV32A are 946 // only used for ARM mode code, which is documented as being unsupported 947 // by Windows on ARM. Empirical proof indicates that masm is able to 948 // generate the relocations however the rest of the MSVC toolchain is 949 // unable to handle it. 950 llvm_unreachable("unsupported relocation"); 951 break; 952 case COFF::IMAGE_REL_ARM_MOV32T: 953 break; 954 case COFF::IMAGE_REL_ARM_BRANCH20T: 955 case COFF::IMAGE_REL_ARM_BRANCH24T: 956 case COFF::IMAGE_REL_ARM_BLX23T: 957 // IMAGE_REL_BRANCH20T, IMAGE_REL_ARM_BRANCH24T, IMAGE_REL_ARM_BLX23T all 958 // perform a 4 byte adjustment to the relocation. Relative branches are 959 // offset by 4 on ARM, however, because there is no RELA relocations, all 960 // branches are offset by 4. 961 FixedValue = FixedValue + 4; 962 break; 963 } 964 } 965 966 // The fixed value never makes sense for section indices, ignore it. 967 if (Fixup.getKind() == FK_SecRel_2) 968 FixedValue = 0; 969 970 if (OWriter.TargetObjectWriter->recordRelocation(Fixup)) 971 Sec->Relocations.push_back(Reloc); 972 } 973 974 static std::time_t getTime() { 975 std::time_t Now = time(nullptr); 976 if (Now < 0 || !isUInt<32>(Now)) 977 return UINT32_MAX; 978 return Now; 979 } 980 981 uint64_t WinCOFFWriter::writeObject(MCAssembler &Asm) { 982 uint64_t StartOffset = W.OS.tell(); 983 984 if (Sections.size() > INT32_MAX) 985 report_fatal_error( 986 "PE COFF object files can't have more than 2147483647 sections"); 987 988 UseBigObj = Sections.size() > COFF::MaxNumberOfSections16; 989 Header.NumberOfSections = Sections.size(); 990 Header.NumberOfSymbols = 0; 991 992 setWeakDefaultNames(); 993 assignSectionNumbers(); 994 if (Mode != DwoOnly) 995 createFileSymbols(Asm); 996 997 for (auto &Symbol : Symbols) { 998 // Update section number & offset for symbols that have them. 999 if (Symbol->Section) 1000 Symbol->Data.SectionNumber = Symbol->Section->Number; 1001 Symbol->setIndex(Header.NumberOfSymbols++); 1002 // Update auxiliary symbol info. 1003 Symbol->Data.NumberOfAuxSymbols = Symbol->Aux.size(); 1004 Header.NumberOfSymbols += Symbol->Data.NumberOfAuxSymbols; 1005 } 1006 1007 // Build string table. 1008 for (const auto &S : Sections) 1009 if (S->Name.size() > COFF::NameSize) 1010 Strings.add(S->Name); 1011 for (const auto &S : Symbols) 1012 if (S->Name.size() > COFF::NameSize) 1013 Strings.add(S->Name); 1014 Strings.finalize(); 1015 1016 // Set names. 1017 for (const auto &S : Sections) 1018 SetSectionName(*S); 1019 for (auto &S : Symbols) 1020 SetSymbolName(*S); 1021 1022 // Fixup weak external references. 1023 for (auto &Symbol : Symbols) { 1024 if (Symbol->Other) { 1025 assert(Symbol->getIndex() != -1); 1026 assert(Symbol->Aux.size() == 1 && "Symbol must contain one aux symbol!"); 1027 assert(Symbol->Aux[0].AuxType == ATWeakExternal && 1028 "Symbol's aux symbol must be a Weak External!"); 1029 Symbol->Aux[0].Aux.WeakExternal.TagIndex = Symbol->Other->getIndex(); 1030 } 1031 } 1032 1033 // Fixup associative COMDAT sections. 1034 for (auto &Section : Sections) { 1035 if (Section->Symbol->Aux[0].Aux.SectionDefinition.Selection != 1036 COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) 1037 continue; 1038 1039 const MCSectionCOFF &MCSec = *Section->MCSection; 1040 const MCSymbol *AssocMCSym = MCSec.getCOMDATSymbol(); 1041 assert(AssocMCSym); 1042 1043 // It's an error to try to associate with an undefined symbol or a symbol 1044 // without a section. 1045 if (!AssocMCSym->isInSection()) { 1046 Asm.getContext().reportError( 1047 SMLoc(), Twine("cannot make section ") + MCSec.getName() + 1048 Twine(" associative with sectionless symbol ") + 1049 AssocMCSym->getName()); 1050 continue; 1051 } 1052 1053 const auto *AssocMCSec = cast<MCSectionCOFF>(&AssocMCSym->getSection()); 1054 assert(SectionMap.count(AssocMCSec)); 1055 COFFSection *AssocSec = SectionMap[AssocMCSec]; 1056 1057 // Skip this section if the associated section is unused. 1058 if (AssocSec->Number == -1) 1059 continue; 1060 1061 Section->Symbol->Aux[0].Aux.SectionDefinition.Number = AssocSec->Number; 1062 } 1063 1064 // Create the contents of the .llvm_addrsig section. 1065 if (Mode != DwoOnly && OWriter.getEmitAddrsigSection()) { 1066 auto *Sec = Asm.getContext().getCOFFSection( 1067 ".llvm_addrsig", COFF::IMAGE_SCN_LNK_REMOVE); 1068 auto *Frag = cast<MCDataFragment>(Sec->curFragList()->Head); 1069 raw_svector_ostream OS(Frag->getContents()); 1070 for (const MCSymbol *S : OWriter.AddrsigSyms) { 1071 if (!S->isRegistered()) 1072 continue; 1073 if (!S->isTemporary()) { 1074 encodeULEB128(S->getIndex(), OS); 1075 continue; 1076 } 1077 1078 MCSection *TargetSection = &S->getSection(); 1079 assert(SectionMap.contains(TargetSection) && 1080 "Section must already have been defined in " 1081 "executePostLayoutBinding!"); 1082 encodeULEB128(SectionMap[TargetSection]->Symbol->getIndex(), OS); 1083 } 1084 } 1085 1086 // Create the contents of the .llvm.call-graph-profile section. 1087 if (Mode != DwoOnly && !OWriter.getCGProfile().empty()) { 1088 auto *Sec = Asm.getContext().getCOFFSection( 1089 ".llvm.call-graph-profile", COFF::IMAGE_SCN_LNK_REMOVE); 1090 auto *Frag = cast<MCDataFragment>(Sec->curFragList()->Head); 1091 raw_svector_ostream OS(Frag->getContents()); 1092 for (const auto &CGPE : OWriter.getCGProfile()) { 1093 uint32_t FromIndex = CGPE.From->getSymbol().getIndex(); 1094 uint32_t ToIndex = CGPE.To->getSymbol().getIndex(); 1095 support::endian::write(OS, FromIndex, W.Endian); 1096 support::endian::write(OS, ToIndex, W.Endian); 1097 support::endian::write(OS, CGPE.Count, W.Endian); 1098 } 1099 } 1100 1101 assignFileOffsets(Asm); 1102 1103 // MS LINK expects to be able to use this timestamp to implement their 1104 // /INCREMENTAL feature. 1105 if (OWriter.IncrementalLinkerCompatible) { 1106 Header.TimeDateStamp = getTime(); 1107 } else { 1108 // Have deterministic output if /INCREMENTAL isn't needed. Also matches GNU. 1109 Header.TimeDateStamp = 0; 1110 } 1111 1112 // Write it all to disk... 1113 WriteFileHeader(Header); 1114 writeSectionHeaders(); 1115 1116 #ifndef NDEBUG 1117 sections::iterator I = Sections.begin(); 1118 sections::iterator IE = Sections.end(); 1119 auto J = Asm.begin(); 1120 auto JE = Asm.end(); 1121 for (; I != IE && J != JE; ++I, ++J) { 1122 while (J != JE && ((Mode == NonDwoOnly && isDwoSection(*J)) || 1123 (Mode == DwoOnly && !isDwoSection(*J)))) 1124 ++J; 1125 assert(J != JE && (**I).MCSection == &*J && "Wrong bound MCSection"); 1126 } 1127 #endif 1128 1129 // Write section contents. 1130 for (std::unique_ptr<COFFSection> &Sec : Sections) 1131 writeSection(Asm, *Sec); 1132 1133 assert(W.OS.tell() == Header.PointerToSymbolTable && 1134 "Header::PointerToSymbolTable is insane!"); 1135 1136 // Write a symbol table. 1137 for (auto &Symbol : Symbols) 1138 if (Symbol->getIndex() != -1) 1139 WriteSymbol(*Symbol); 1140 1141 // Write a string table, which completes the entire COFF file. 1142 Strings.write(W.OS); 1143 1144 return W.OS.tell() - StartOffset; 1145 } 1146 1147 //------------------------------------------------------------------------------ 1148 // WinCOFFObjectWriter class implementation 1149 1150 //////////////////////////////////////////////////////////////////////////////// 1151 // MCObjectWriter interface implementations 1152 1153 void WinCOFFObjectWriter::reset() { 1154 IncrementalLinkerCompatible = false; 1155 ObjWriter->reset(); 1156 if (DwoWriter) 1157 DwoWriter->reset(); 1158 MCObjectWriter::reset(); 1159 } 1160 1161 bool WinCOFFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl( 1162 const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB, 1163 bool InSet, bool IsPCRel) const { 1164 // Don't drop relocations between functions, even if they are in the same text 1165 // section. Multiple Visual C++ linker features depend on having the 1166 // relocations present. The /INCREMENTAL flag will cause these relocations to 1167 // point to thunks, and the /GUARD:CF flag assumes that it can use relocations 1168 // to approximate the set of all address taken functions. LLD's implementation 1169 // of /GUARD:CF also relies on the existance of these relocations. 1170 uint16_t Type = cast<MCSymbolCOFF>(SymA).getType(); 1171 if ((Type >> COFF::SCT_COMPLEX_TYPE_SHIFT) == COFF::IMAGE_SYM_DTYPE_FUNCTION) 1172 return false; 1173 return &SymA.getSection() == FB.getParent(); 1174 } 1175 1176 void WinCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm) { 1177 ObjWriter->executePostLayoutBinding(Asm); 1178 if (DwoWriter) 1179 DwoWriter->executePostLayoutBinding(Asm); 1180 } 1181 1182 void WinCOFFObjectWriter::recordRelocation(MCAssembler &Asm, 1183 const MCFragment *Fragment, 1184 const MCFixup &Fixup, MCValue Target, 1185 uint64_t &FixedValue) { 1186 assert(!isDwoSection(*Fragment->getParent()) && 1187 "No relocation in Dwo sections"); 1188 ObjWriter->recordRelocation(Asm, Fragment, Fixup, Target, FixedValue); 1189 } 1190 1191 uint64_t WinCOFFObjectWriter::writeObject(MCAssembler &Asm) { 1192 uint64_t TotalSize = ObjWriter->writeObject(Asm); 1193 if (DwoWriter) 1194 TotalSize += DwoWriter->writeObject(Asm); 1195 return TotalSize; 1196 } 1197 1198 MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_) 1199 : Machine(Machine_) {} 1200 1201 // Pin the vtable to this file. 1202 void MCWinCOFFObjectTargetWriter::anchor() {} 1203 1204 //------------------------------------------------------------------------------ 1205 // WinCOFFObjectWriter factory function 1206 1207 std::unique_ptr<MCObjectWriter> llvm::createWinCOFFObjectWriter( 1208 std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS) { 1209 return std::make_unique<WinCOFFObjectWriter>(std::move(MOTW), OS); 1210 } 1211 1212 std::unique_ptr<MCObjectWriter> llvm::createWinCOFFDwoObjectWriter( 1213 std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS, 1214 raw_pwrite_stream &DwoOS) { 1215 return std::make_unique<WinCOFFObjectWriter>(std::move(MOTW), OS, DwoOS); 1216 } 1217