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