1 //===-- llvm/MC/WinCOFFObjectWriter.cpp -------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains an implementation of a Win32 COFF object file writer. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/MC/MCWinCOFFObjectWriter.h" 15 #include "llvm/ADT/DenseMap.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/ADT/StringMap.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/ADT/Twine.h" 20 #include "llvm/MC/MCAsmLayout.h" 21 #include "llvm/MC/MCAssembler.h" 22 #include "llvm/MC/MCContext.h" 23 #include "llvm/MC/MCExpr.h" 24 #include "llvm/MC/MCObjectFileInfo.h" 25 #include "llvm/MC/MCObjectWriter.h" 26 #include "llvm/MC/MCSection.h" 27 #include "llvm/MC/MCSectionCOFF.h" 28 #include "llvm/MC/MCSymbolCOFF.h" 29 #include "llvm/MC/MCValue.h" 30 #include "llvm/MC/StringTableBuilder.h" 31 #include "llvm/Support/COFF.h" 32 #include "llvm/Support/Debug.h" 33 #include "llvm/Support/Endian.h" 34 #include "llvm/Support/ErrorHandling.h" 35 #include "llvm/Support/JamCRC.h" 36 #include "llvm/Support/TimeValue.h" 37 #include <cstdio> 38 #include <ctime> 39 40 using namespace llvm; 41 42 #define DEBUG_TYPE "WinCOFFObjectWriter" 43 44 namespace { 45 typedef SmallString<COFF::NameSize> name; 46 47 enum AuxiliaryType { 48 ATFunctionDefinition, 49 ATbfAndefSymbol, 50 ATWeakExternal, 51 ATFile, 52 ATSectionDefinition 53 }; 54 55 struct AuxSymbol { 56 AuxiliaryType AuxType; 57 COFF::Auxiliary Aux; 58 }; 59 60 class COFFSymbol; 61 class COFFSection; 62 63 class COFFSymbol { 64 public: 65 COFF::symbol Data; 66 67 typedef SmallVector<AuxSymbol, 1> AuxiliarySymbols; 68 69 name Name; 70 int Index; 71 AuxiliarySymbols Aux; 72 COFFSymbol *Other; 73 COFFSection *Section; 74 int Relocations; 75 76 const MCSymbol *MC; 77 78 COFFSymbol(StringRef name); 79 void set_name_offset(uint32_t Offset); 80 81 bool should_keep() const; 82 83 int64_t getIndex() const { return Index; } 84 void setIndex(int Value) { 85 Index = Value; 86 if (MC) 87 MC->setIndex(static_cast<uint32_t>(Value)); 88 } 89 }; 90 91 // This class contains staging data for a COFF relocation entry. 92 struct COFFRelocation { 93 COFF::relocation Data; 94 COFFSymbol *Symb; 95 96 COFFRelocation() : Symb(nullptr) {} 97 static size_t size() { return COFF::RelocationSize; } 98 }; 99 100 typedef std::vector<COFFRelocation> relocations; 101 102 class COFFSection { 103 public: 104 COFF::section Header; 105 106 std::string Name; 107 int Number; 108 MCSectionCOFF const *MCSection; 109 COFFSymbol *Symbol; 110 relocations Relocations; 111 112 COFFSection(StringRef name); 113 static size_t size(); 114 }; 115 116 class WinCOFFObjectWriter : public MCObjectWriter { 117 public: 118 typedef std::vector<std::unique_ptr<COFFSymbol>> symbols; 119 typedef std::vector<std::unique_ptr<COFFSection>> sections; 120 121 typedef DenseMap<MCSymbol const *, COFFSymbol *> symbol_map; 122 typedef DenseMap<MCSection const *, COFFSection *> section_map; 123 124 std::unique_ptr<MCWinCOFFObjectTargetWriter> TargetObjectWriter; 125 126 // Root level file contents. 127 COFF::header Header; 128 sections Sections; 129 symbols Symbols; 130 StringTableBuilder Strings; 131 132 // Maps used during object file creation. 133 section_map SectionMap; 134 symbol_map SymbolMap; 135 136 bool UseBigObj; 137 138 WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, raw_pwrite_stream &OS); 139 140 void reset() override { 141 memset(&Header, 0, sizeof(Header)); 142 Header.Machine = TargetObjectWriter->getMachine(); 143 Sections.clear(); 144 Symbols.clear(); 145 Strings.clear(); 146 SectionMap.clear(); 147 SymbolMap.clear(); 148 MCObjectWriter::reset(); 149 } 150 151 COFFSymbol *createSymbol(StringRef Name); 152 COFFSymbol *GetOrCreateCOFFSymbol(const MCSymbol *Symbol); 153 COFFSection *createSection(StringRef Name); 154 155 template <typename object_t, typename list_t> 156 object_t *createCOFFEntity(StringRef Name, list_t &List); 157 158 void defineSection(MCSectionCOFF const &Sec); 159 void DefineSymbol(const MCSymbol &Symbol, MCAssembler &Assembler, 160 const MCAsmLayout &Layout); 161 162 void SetSymbolName(COFFSymbol &S); 163 void SetSectionName(COFFSection &S); 164 165 bool ExportSymbol(const MCSymbol &Symbol, MCAssembler &Asm); 166 167 bool IsPhysicalSection(COFFSection *S); 168 169 // Entity writing methods. 170 171 void WriteFileHeader(const COFF::header &Header); 172 void WriteSymbol(const COFFSymbol &S); 173 void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols &S); 174 void writeSectionHeader(const COFF::section &S); 175 void WriteRelocation(const COFF::relocation &R); 176 177 // MCObjectWriter interface implementation. 178 179 void executePostLayoutBinding(MCAssembler &Asm, 180 const MCAsmLayout &Layout) override; 181 182 bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, 183 const MCSymbol &SymA, 184 const MCFragment &FB, bool InSet, 185 bool IsPCRel) const override; 186 187 bool isWeak(const MCSymbol &Sym) const override; 188 189 void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, 190 const MCFragment *Fragment, const MCFixup &Fixup, 191 MCValue Target, bool &IsPCRel, 192 uint64_t &FixedValue) override; 193 194 void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; 195 }; 196 } 197 198 static inline void write_uint32_le(void *Data, uint32_t Value) { 199 support::endian::write<uint32_t, support::little, support::unaligned>(Data, 200 Value); 201 } 202 203 //------------------------------------------------------------------------------ 204 // Symbol class implementation 205 206 COFFSymbol::COFFSymbol(StringRef name) 207 : Name(name.begin(), name.end()), Other(nullptr), Section(nullptr), 208 Relocations(0), MC(nullptr) { 209 memset(&Data, 0, sizeof(Data)); 210 } 211 212 // In the case that the name does not fit within 8 bytes, the offset 213 // into the string table is stored in the last 4 bytes instead, leaving 214 // the first 4 bytes as 0. 215 void COFFSymbol::set_name_offset(uint32_t Offset) { 216 write_uint32_le(Data.Name + 0, 0); 217 write_uint32_le(Data.Name + 4, Offset); 218 } 219 220 /// logic to decide if the symbol should be reported in the symbol table 221 bool COFFSymbol::should_keep() const { 222 // no section means its external, keep it 223 if (!Section) 224 return true; 225 226 // if it has relocations pointing at it, keep it 227 if (Relocations > 0) { 228 assert(Section->Number != -1 && "Sections with relocations must be real!"); 229 return true; 230 } 231 232 // if this is a safeseh handler, keep it 233 if (MC && (cast<MCSymbolCOFF>(MC)->isSafeSEH())) 234 return true; 235 236 // if the section its in is being droped, drop it 237 if (Section->Number == -1) 238 return false; 239 240 // if it is the section symbol, keep it 241 if (Section->Symbol == this) 242 return true; 243 244 // if its temporary, drop it 245 if (MC && MC->isTemporary()) 246 return false; 247 248 // otherwise, keep it 249 return true; 250 } 251 252 //------------------------------------------------------------------------------ 253 // Section class implementation 254 255 COFFSection::COFFSection(StringRef name) 256 : Name(name), MCSection(nullptr), Symbol(nullptr) { 257 memset(&Header, 0, sizeof(Header)); 258 } 259 260 size_t COFFSection::size() { return COFF::SectionSize; } 261 262 //------------------------------------------------------------------------------ 263 // WinCOFFObjectWriter class implementation 264 265 WinCOFFObjectWriter::WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, 266 raw_pwrite_stream &OS) 267 : MCObjectWriter(OS, true), TargetObjectWriter(MOTW) { 268 memset(&Header, 0, sizeof(Header)); 269 270 Header.Machine = TargetObjectWriter->getMachine(); 271 } 272 273 COFFSymbol *WinCOFFObjectWriter::createSymbol(StringRef Name) { 274 return createCOFFEntity<COFFSymbol>(Name, Symbols); 275 } 276 277 COFFSymbol *WinCOFFObjectWriter::GetOrCreateCOFFSymbol(const MCSymbol *Symbol) { 278 symbol_map::iterator i = SymbolMap.find(Symbol); 279 if (i != SymbolMap.end()) 280 return i->second; 281 COFFSymbol *RetSymbol = 282 createCOFFEntity<COFFSymbol>(Symbol->getName(), Symbols); 283 SymbolMap[Symbol] = RetSymbol; 284 return RetSymbol; 285 } 286 287 COFFSection *WinCOFFObjectWriter::createSection(StringRef Name) { 288 return createCOFFEntity<COFFSection>(Name, Sections); 289 } 290 291 /// A template used to lookup or create a symbol/section, and initialize it if 292 /// needed. 293 template <typename object_t, typename list_t> 294 object_t *WinCOFFObjectWriter::createCOFFEntity(StringRef Name, list_t &List) { 295 List.push_back(make_unique<object_t>(Name)); 296 297 return List.back().get(); 298 } 299 300 /// This function takes a section data object from the assembler 301 /// and creates the associated COFF section staging object. 302 void WinCOFFObjectWriter::defineSection(MCSectionCOFF const &Sec) { 303 COFFSection *coff_section = createSection(Sec.getSectionName()); 304 COFFSymbol *coff_symbol = createSymbol(Sec.getSectionName()); 305 if (Sec.getSelection() != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) { 306 if (const MCSymbol *S = Sec.getCOMDATSymbol()) { 307 COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(S); 308 if (COMDATSymbol->Section) 309 report_fatal_error("two sections have the same comdat"); 310 COMDATSymbol->Section = coff_section; 311 } 312 } 313 314 coff_section->Symbol = coff_symbol; 315 coff_symbol->Section = coff_section; 316 coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_STATIC; 317 318 // In this case the auxiliary symbol is a Section Definition. 319 coff_symbol->Aux.resize(1); 320 memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0])); 321 coff_symbol->Aux[0].AuxType = ATSectionDefinition; 322 coff_symbol->Aux[0].Aux.SectionDefinition.Selection = Sec.getSelection(); 323 324 coff_section->Header.Characteristics = Sec.getCharacteristics(); 325 326 uint32_t &Characteristics = coff_section->Header.Characteristics; 327 switch (Sec.getAlignment()) { 328 case 1: 329 Characteristics |= COFF::IMAGE_SCN_ALIGN_1BYTES; 330 break; 331 case 2: 332 Characteristics |= COFF::IMAGE_SCN_ALIGN_2BYTES; 333 break; 334 case 4: 335 Characteristics |= COFF::IMAGE_SCN_ALIGN_4BYTES; 336 break; 337 case 8: 338 Characteristics |= COFF::IMAGE_SCN_ALIGN_8BYTES; 339 break; 340 case 16: 341 Characteristics |= COFF::IMAGE_SCN_ALIGN_16BYTES; 342 break; 343 case 32: 344 Characteristics |= COFF::IMAGE_SCN_ALIGN_32BYTES; 345 break; 346 case 64: 347 Characteristics |= COFF::IMAGE_SCN_ALIGN_64BYTES; 348 break; 349 case 128: 350 Characteristics |= COFF::IMAGE_SCN_ALIGN_128BYTES; 351 break; 352 case 256: 353 Characteristics |= COFF::IMAGE_SCN_ALIGN_256BYTES; 354 break; 355 case 512: 356 Characteristics |= COFF::IMAGE_SCN_ALIGN_512BYTES; 357 break; 358 case 1024: 359 Characteristics |= COFF::IMAGE_SCN_ALIGN_1024BYTES; 360 break; 361 case 2048: 362 Characteristics |= COFF::IMAGE_SCN_ALIGN_2048BYTES; 363 break; 364 case 4096: 365 Characteristics |= COFF::IMAGE_SCN_ALIGN_4096BYTES; 366 break; 367 case 8192: 368 Characteristics |= COFF::IMAGE_SCN_ALIGN_8192BYTES; 369 break; 370 default: 371 llvm_unreachable("unsupported section alignment"); 372 } 373 374 // Bind internal COFF section to MC section. 375 coff_section->MCSection = &Sec; 376 SectionMap[&Sec] = coff_section; 377 } 378 379 static uint64_t getSymbolValue(const MCSymbol &Symbol, 380 const MCAsmLayout &Layout) { 381 if (Symbol.isCommon() && Symbol.isExternal()) 382 return Symbol.getCommonSize(); 383 384 uint64_t Res; 385 if (!Layout.getSymbolOffset(Symbol, Res)) 386 return 0; 387 388 return Res; 389 } 390 391 /// This function takes a symbol data object from the assembler 392 /// and creates the associated COFF symbol staging object. 393 void WinCOFFObjectWriter::DefineSymbol(const MCSymbol &Symbol, 394 MCAssembler &Assembler, 395 const MCAsmLayout &Layout) { 396 COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&Symbol); 397 SymbolMap[&Symbol] = coff_symbol; 398 399 if (cast<MCSymbolCOFF>(Symbol).isWeakExternal()) { 400 coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL; 401 402 if (Symbol.isVariable()) { 403 const MCSymbolRefExpr *SymRef = 404 dyn_cast<MCSymbolRefExpr>(Symbol.getVariableValue()); 405 406 if (!SymRef) 407 report_fatal_error("Weak externals may only alias symbols"); 408 409 coff_symbol->Other = GetOrCreateCOFFSymbol(&SymRef->getSymbol()); 410 } else { 411 std::string WeakName = (".weak." + Symbol.getName() + ".default").str(); 412 COFFSymbol *WeakDefault = createSymbol(WeakName); 413 WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE; 414 WeakDefault->Data.StorageClass = COFF::IMAGE_SYM_CLASS_EXTERNAL; 415 WeakDefault->Data.Type = 0; 416 WeakDefault->Data.Value = 0; 417 coff_symbol->Other = WeakDefault; 418 } 419 420 // Setup the Weak External auxiliary symbol. 421 coff_symbol->Aux.resize(1); 422 memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0])); 423 coff_symbol->Aux[0].AuxType = ATWeakExternal; 424 coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = 0; 425 coff_symbol->Aux[0].Aux.WeakExternal.Characteristics = 426 COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY; 427 428 coff_symbol->MC = &Symbol; 429 } else { 430 const MCSymbol *Base = Layout.getBaseSymbol(Symbol); 431 coff_symbol->Data.Value = getSymbolValue(Symbol, Layout); 432 433 const MCSymbolCOFF &SymbolCOFF = cast<MCSymbolCOFF>(Symbol); 434 coff_symbol->Data.Type = SymbolCOFF.getType(); 435 coff_symbol->Data.StorageClass = SymbolCOFF.getClass(); 436 437 // If no storage class was specified in the streamer, define it here. 438 if (coff_symbol->Data.StorageClass == COFF::IMAGE_SYM_CLASS_NULL) { 439 bool IsExternal = Symbol.isExternal() || 440 (!Symbol.getFragment() && !Symbol.isVariable()); 441 442 coff_symbol->Data.StorageClass = IsExternal 443 ? COFF::IMAGE_SYM_CLASS_EXTERNAL 444 : COFF::IMAGE_SYM_CLASS_STATIC; 445 } 446 447 if (!Base) { 448 coff_symbol->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE; 449 } else { 450 if (Base->getFragment()) { 451 COFFSection *Sec = SectionMap[Base->getFragment()->getParent()]; 452 453 if (coff_symbol->Section && coff_symbol->Section != Sec) 454 report_fatal_error("conflicting sections for symbol"); 455 456 coff_symbol->Section = Sec; 457 } 458 } 459 460 coff_symbol->MC = &Symbol; 461 } 462 } 463 464 // Maximum offsets for different string table entry encodings. 465 static const unsigned Max6DecimalOffset = 999999; 466 static const unsigned Max7DecimalOffset = 9999999; 467 static const uint64_t MaxBase64Offset = 0xFFFFFFFFFULL; // 64^6, including 0 468 469 // Encode a string table entry offset in base 64, padded to 6 chars, and 470 // prefixed with a double slash: '//AAAAAA', '//AAAAAB', ... 471 // Buffer must be at least 8 bytes large. No terminating null appended. 472 static void encodeBase64StringEntry(char *Buffer, uint64_t Value) { 473 assert(Value > Max7DecimalOffset && Value <= MaxBase64Offset && 474 "Illegal section name encoding for value"); 475 476 static const char Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 477 "abcdefghijklmnopqrstuvwxyz" 478 "0123456789+/"; 479 480 Buffer[0] = '/'; 481 Buffer[1] = '/'; 482 483 char *Ptr = Buffer + 7; 484 for (unsigned i = 0; i < 6; ++i) { 485 unsigned Rem = Value % 64; 486 Value /= 64; 487 *(Ptr--) = Alphabet[Rem]; 488 } 489 } 490 491 void WinCOFFObjectWriter::SetSectionName(COFFSection &S) { 492 if (S.Name.size() > COFF::NameSize) { 493 uint64_t StringTableEntry = Strings.getOffset(S.Name); 494 495 if (StringTableEntry <= Max6DecimalOffset) { 496 std::sprintf(S.Header.Name, "/%d", unsigned(StringTableEntry)); 497 } else if (StringTableEntry <= Max7DecimalOffset) { 498 // With seven digits, we have to skip the terminating null. Because 499 // sprintf always appends it, we use a larger temporary buffer. 500 char buffer[9] = {}; 501 std::sprintf(buffer, "/%d", unsigned(StringTableEntry)); 502 std::memcpy(S.Header.Name, buffer, 8); 503 } else if (StringTableEntry <= MaxBase64Offset) { 504 // Starting with 10,000,000, offsets are encoded as base64. 505 encodeBase64StringEntry(S.Header.Name, StringTableEntry); 506 } else { 507 report_fatal_error("COFF string table is greater than 64 GB."); 508 } 509 } else 510 std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size()); 511 } 512 513 void WinCOFFObjectWriter::SetSymbolName(COFFSymbol &S) { 514 if (S.Name.size() > COFF::NameSize) 515 S.set_name_offset(Strings.getOffset(S.Name)); 516 else 517 std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size()); 518 } 519 520 bool WinCOFFObjectWriter::ExportSymbol(const MCSymbol &Symbol, 521 MCAssembler &Asm) { 522 // This doesn't seem to be right. Strings referred to from the .data section 523 // need symbols so they can be linked to code in the .text section right? 524 525 // return Asm.isSymbolLinkerVisible(Symbol); 526 527 // Non-temporary labels should always be visible to the linker. 528 if (!Symbol.isTemporary()) 529 return true; 530 531 // Temporary variable symbols are invisible. 532 if (Symbol.isVariable()) 533 return false; 534 535 // Absolute temporary labels are never visible. 536 return !Symbol.isAbsolute(); 537 } 538 539 bool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) { 540 return (S->Header.Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 541 0; 542 } 543 544 //------------------------------------------------------------------------------ 545 // entity writing methods 546 547 void WinCOFFObjectWriter::WriteFileHeader(const COFF::header &Header) { 548 if (UseBigObj) { 549 writeLE16(COFF::IMAGE_FILE_MACHINE_UNKNOWN); 550 writeLE16(0xFFFF); 551 writeLE16(COFF::BigObjHeader::MinBigObjectVersion); 552 writeLE16(Header.Machine); 553 writeLE32(Header.TimeDateStamp); 554 writeBytes(StringRef(COFF::BigObjMagic, sizeof(COFF::BigObjMagic))); 555 writeLE32(0); 556 writeLE32(0); 557 writeLE32(0); 558 writeLE32(0); 559 writeLE32(Header.NumberOfSections); 560 writeLE32(Header.PointerToSymbolTable); 561 writeLE32(Header.NumberOfSymbols); 562 } else { 563 writeLE16(Header.Machine); 564 writeLE16(static_cast<int16_t>(Header.NumberOfSections)); 565 writeLE32(Header.TimeDateStamp); 566 writeLE32(Header.PointerToSymbolTable); 567 writeLE32(Header.NumberOfSymbols); 568 writeLE16(Header.SizeOfOptionalHeader); 569 writeLE16(Header.Characteristics); 570 } 571 } 572 573 void WinCOFFObjectWriter::WriteSymbol(const COFFSymbol &S) { 574 writeBytes(StringRef(S.Data.Name, COFF::NameSize)); 575 writeLE32(S.Data.Value); 576 if (UseBigObj) 577 writeLE32(S.Data.SectionNumber); 578 else 579 writeLE16(static_cast<int16_t>(S.Data.SectionNumber)); 580 writeLE16(S.Data.Type); 581 write8(S.Data.StorageClass); 582 write8(S.Data.NumberOfAuxSymbols); 583 WriteAuxiliarySymbols(S.Aux); 584 } 585 586 void WinCOFFObjectWriter::WriteAuxiliarySymbols( 587 const COFFSymbol::AuxiliarySymbols &S) { 588 for (COFFSymbol::AuxiliarySymbols::const_iterator i = S.begin(), e = S.end(); 589 i != e; ++i) { 590 switch (i->AuxType) { 591 case ATFunctionDefinition: 592 writeLE32(i->Aux.FunctionDefinition.TagIndex); 593 writeLE32(i->Aux.FunctionDefinition.TotalSize); 594 writeLE32(i->Aux.FunctionDefinition.PointerToLinenumber); 595 writeLE32(i->Aux.FunctionDefinition.PointerToNextFunction); 596 WriteZeros(sizeof(i->Aux.FunctionDefinition.unused)); 597 if (UseBigObj) 598 WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size); 599 break; 600 case ATbfAndefSymbol: 601 WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused1)); 602 writeLE16(i->Aux.bfAndefSymbol.Linenumber); 603 WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused2)); 604 writeLE32(i->Aux.bfAndefSymbol.PointerToNextFunction); 605 WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused3)); 606 if (UseBigObj) 607 WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size); 608 break; 609 case ATWeakExternal: 610 writeLE32(i->Aux.WeakExternal.TagIndex); 611 writeLE32(i->Aux.WeakExternal.Characteristics); 612 WriteZeros(sizeof(i->Aux.WeakExternal.unused)); 613 if (UseBigObj) 614 WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size); 615 break; 616 case ATFile: 617 writeBytes( 618 StringRef(reinterpret_cast<const char *>(&i->Aux), 619 UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size)); 620 break; 621 case ATSectionDefinition: 622 writeLE32(i->Aux.SectionDefinition.Length); 623 writeLE16(i->Aux.SectionDefinition.NumberOfRelocations); 624 writeLE16(i->Aux.SectionDefinition.NumberOfLinenumbers); 625 writeLE32(i->Aux.SectionDefinition.CheckSum); 626 writeLE16(static_cast<int16_t>(i->Aux.SectionDefinition.Number)); 627 write8(i->Aux.SectionDefinition.Selection); 628 WriteZeros(sizeof(i->Aux.SectionDefinition.unused)); 629 writeLE16(static_cast<int16_t>(i->Aux.SectionDefinition.Number >> 16)); 630 if (UseBigObj) 631 WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size); 632 break; 633 } 634 } 635 } 636 637 void WinCOFFObjectWriter::writeSectionHeader(const COFF::section &S) { 638 writeBytes(StringRef(S.Name, COFF::NameSize)); 639 640 writeLE32(S.VirtualSize); 641 writeLE32(S.VirtualAddress); 642 writeLE32(S.SizeOfRawData); 643 writeLE32(S.PointerToRawData); 644 writeLE32(S.PointerToRelocations); 645 writeLE32(S.PointerToLineNumbers); 646 writeLE16(S.NumberOfRelocations); 647 writeLE16(S.NumberOfLineNumbers); 648 writeLE32(S.Characteristics); 649 } 650 651 void WinCOFFObjectWriter::WriteRelocation(const COFF::relocation &R) { 652 writeLE32(R.VirtualAddress); 653 writeLE32(R.SymbolTableIndex); 654 writeLE16(R.Type); 655 } 656 657 //////////////////////////////////////////////////////////////////////////////// 658 // MCObjectWriter interface implementations 659 660 void WinCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm, 661 const MCAsmLayout &Layout) { 662 // "Define" each section & symbol. This creates section & symbol 663 // entries in the staging area. 664 for (const auto &Section : Asm) 665 defineSection(static_cast<const MCSectionCOFF &>(Section)); 666 667 for (const MCSymbol &Symbol : Asm.symbols()) 668 if (ExportSymbol(Symbol, Asm)) 669 DefineSymbol(Symbol, Asm, Layout); 670 } 671 672 bool WinCOFFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl( 673 const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB, 674 bool InSet, bool IsPCRel) const { 675 // MS LINK expects to be able to replace all references to a function with a 676 // thunk to implement their /INCREMENTAL feature. Make sure we don't optimize 677 // away any relocations to functions. 678 uint16_t Type = cast<MCSymbolCOFF>(SymA).getType(); 679 if ((Type >> COFF::SCT_COMPLEX_TYPE_SHIFT) == COFF::IMAGE_SYM_DTYPE_FUNCTION) 680 return false; 681 return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB, 682 InSet, IsPCRel); 683 } 684 685 bool WinCOFFObjectWriter::isWeak(const MCSymbol &Sym) const { 686 if (!Sym.isExternal()) 687 return false; 688 689 if (!Sym.isInSection()) 690 return false; 691 692 const auto &Sec = cast<MCSectionCOFF>(Sym.getSection()); 693 if (!Sec.getCOMDATSymbol()) 694 return false; 695 696 // It looks like for COFF it is invalid to replace a reference to a global 697 // in a comdat with a reference to a local. 698 // FIXME: Add a specification reference if available. 699 return true; 700 } 701 702 void WinCOFFObjectWriter::recordRelocation( 703 MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, 704 const MCFixup &Fixup, MCValue Target, bool &IsPCRel, uint64_t &FixedValue) { 705 assert(Target.getSymA() && "Relocation must reference a symbol!"); 706 707 const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 708 const MCSymbol &A = Symbol; 709 if (!A.isRegistered()) 710 Asm.getContext().reportFatalError(Fixup.getLoc(), 711 Twine("symbol '") + A.getName() + 712 "' can not be undefined"); 713 if (A.isTemporary() && A.isUndefined()) { 714 Asm.getContext().reportFatalError(Fixup.getLoc(), 715 Twine("assembler label '") + A.getName() + 716 "' can not be undefined"); 717 } 718 719 MCSection *Section = Fragment->getParent(); 720 721 // Mark this symbol as requiring an entry in the symbol table. 722 assert(SectionMap.find(Section) != SectionMap.end() && 723 "Section must already have been defined in executePostLayoutBinding!"); 724 assert(SymbolMap.find(&A) != SymbolMap.end() && 725 "Symbol must already have been defined in executePostLayoutBinding!"); 726 727 COFFSection *coff_section = SectionMap[Section]; 728 COFFSymbol *coff_symbol = SymbolMap[&A]; 729 const MCSymbolRefExpr *SymB = Target.getSymB(); 730 bool CrossSection = false; 731 732 if (SymB) { 733 const MCSymbol *B = &SymB->getSymbol(); 734 if (!B->getFragment()) 735 Asm.getContext().reportFatalError( 736 Fixup.getLoc(), 737 Twine("symbol '") + B->getName() + 738 "' can not be undefined in a subtraction expression"); 739 740 if (!A.getFragment()) 741 Asm.getContext().reportFatalError( 742 Fixup.getLoc(), 743 Twine("symbol '") + Symbol.getName() + 744 "' can not be undefined in a subtraction expression"); 745 746 CrossSection = &Symbol.getSection() != &B->getSection(); 747 748 // Offset of the symbol in the section 749 int64_t OffsetOfB = Layout.getSymbolOffset(*B); 750 751 // In the case where we have SymbA and SymB, we just need to store the delta 752 // between the two symbols. Update FixedValue to account for the delta, and 753 // skip recording the relocation. 754 if (!CrossSection) { 755 int64_t OffsetOfA = Layout.getSymbolOffset(A); 756 FixedValue = (OffsetOfA - OffsetOfB) + Target.getConstant(); 757 return; 758 } 759 760 // Offset of the relocation in the section 761 int64_t OffsetOfRelocation = 762 Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); 763 764 FixedValue = (OffsetOfRelocation - OffsetOfB) + Target.getConstant(); 765 } else { 766 FixedValue = Target.getConstant(); 767 } 768 769 COFFRelocation Reloc; 770 771 Reloc.Data.SymbolTableIndex = 0; 772 Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment); 773 774 // Turn relocations for temporary symbols into section relocations. 775 if (coff_symbol->MC->isTemporary() || CrossSection) { 776 Reloc.Symb = coff_symbol->Section->Symbol; 777 FixedValue += Layout.getFragmentOffset(coff_symbol->MC->getFragment()) + 778 coff_symbol->MC->getOffset(); 779 } else 780 Reloc.Symb = coff_symbol; 781 782 ++Reloc.Symb->Relocations; 783 784 Reloc.Data.VirtualAddress += Fixup.getOffset(); 785 Reloc.Data.Type = TargetObjectWriter->getRelocType( 786 Target, Fixup, CrossSection, Asm.getBackend()); 787 788 // FIXME: Can anyone explain what this does other than adjust for the size 789 // of the offset? 790 if ((Header.Machine == COFF::IMAGE_FILE_MACHINE_AMD64 && 791 Reloc.Data.Type == COFF::IMAGE_REL_AMD64_REL32) || 792 (Header.Machine == COFF::IMAGE_FILE_MACHINE_I386 && 793 Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32)) 794 FixedValue += 4; 795 796 if (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT) { 797 switch (Reloc.Data.Type) { 798 case COFF::IMAGE_REL_ARM_ABSOLUTE: 799 case COFF::IMAGE_REL_ARM_ADDR32: 800 case COFF::IMAGE_REL_ARM_ADDR32NB: 801 case COFF::IMAGE_REL_ARM_TOKEN: 802 case COFF::IMAGE_REL_ARM_SECTION: 803 case COFF::IMAGE_REL_ARM_SECREL: 804 break; 805 case COFF::IMAGE_REL_ARM_BRANCH11: 806 case COFF::IMAGE_REL_ARM_BLX11: 807 // IMAGE_REL_ARM_BRANCH11 and IMAGE_REL_ARM_BLX11 are only used for 808 // pre-ARMv7, which implicitly rules it out of ARMNT (it would be valid 809 // for Windows CE). 810 case COFF::IMAGE_REL_ARM_BRANCH24: 811 case COFF::IMAGE_REL_ARM_BLX24: 812 case COFF::IMAGE_REL_ARM_MOV32A: 813 // IMAGE_REL_ARM_BRANCH24, IMAGE_REL_ARM_BLX24, IMAGE_REL_ARM_MOV32A are 814 // only used for ARM mode code, which is documented as being unsupported 815 // by Windows on ARM. Empirical proof indicates that masm is able to 816 // generate the relocations however the rest of the MSVC toolchain is 817 // unable to handle it. 818 llvm_unreachable("unsupported relocation"); 819 break; 820 case COFF::IMAGE_REL_ARM_MOV32T: 821 break; 822 case COFF::IMAGE_REL_ARM_BRANCH20T: 823 case COFF::IMAGE_REL_ARM_BRANCH24T: 824 case COFF::IMAGE_REL_ARM_BLX23T: 825 // IMAGE_REL_BRANCH20T, IMAGE_REL_ARM_BRANCH24T, IMAGE_REL_ARM_BLX23T all 826 // perform a 4 byte adjustment to the relocation. Relative branches are 827 // offset by 4 on ARM, however, because there is no RELA relocations, all 828 // branches are offset by 4. 829 FixedValue = FixedValue + 4; 830 break; 831 } 832 } 833 834 if (TargetObjectWriter->recordRelocation(Fixup)) 835 coff_section->Relocations.push_back(Reloc); 836 } 837 838 void WinCOFFObjectWriter::writeObject(MCAssembler &Asm, 839 const MCAsmLayout &Layout) { 840 size_t SectionsSize = Sections.size(); 841 if (SectionsSize > static_cast<size_t>(INT32_MAX)) 842 report_fatal_error( 843 "PE COFF object files can't have more than 2147483647 sections"); 844 845 // Assign symbol and section indexes and offsets. 846 int32_t NumberOfSections = static_cast<int32_t>(SectionsSize); 847 848 UseBigObj = NumberOfSections > COFF::MaxNumberOfSections16; 849 850 // Assign section numbers. 851 size_t Number = 1; 852 for (const auto &Section : Sections) { 853 Section->Number = Number; 854 Section->Symbol->Data.SectionNumber = Number; 855 Section->Symbol->Aux[0].Aux.SectionDefinition.Number = Number; 856 ++Number; 857 } 858 859 Header.NumberOfSections = NumberOfSections; 860 Header.NumberOfSymbols = 0; 861 862 for (const std::string &Name : Asm.getFileNames()) { 863 // round up to calculate the number of auxiliary symbols required 864 unsigned SymbolSize = UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size; 865 unsigned Count = (Name.size() + SymbolSize - 1) / SymbolSize; 866 867 COFFSymbol *file = createSymbol(".file"); 868 file->Data.SectionNumber = COFF::IMAGE_SYM_DEBUG; 869 file->Data.StorageClass = COFF::IMAGE_SYM_CLASS_FILE; 870 file->Aux.resize(Count); 871 872 unsigned Offset = 0; 873 unsigned Length = Name.size(); 874 for (auto &Aux : file->Aux) { 875 Aux.AuxType = ATFile; 876 877 if (Length > SymbolSize) { 878 memcpy(&Aux.Aux, Name.c_str() + Offset, SymbolSize); 879 Length = Length - SymbolSize; 880 } else { 881 memcpy(&Aux.Aux, Name.c_str() + Offset, Length); 882 memset((char *)&Aux.Aux + Length, 0, SymbolSize - Length); 883 break; 884 } 885 886 Offset += SymbolSize; 887 } 888 } 889 890 for (auto &Symbol : Symbols) { 891 // Update section number & offset for symbols that have them. 892 if (Symbol->Section) 893 Symbol->Data.SectionNumber = Symbol->Section->Number; 894 if (Symbol->should_keep()) { 895 Symbol->setIndex(Header.NumberOfSymbols++); 896 // Update auxiliary symbol info. 897 Symbol->Data.NumberOfAuxSymbols = Symbol->Aux.size(); 898 Header.NumberOfSymbols += Symbol->Data.NumberOfAuxSymbols; 899 } else { 900 Symbol->setIndex(-1); 901 } 902 } 903 904 // Build string table. 905 for (const auto &S : Sections) 906 if (S->Name.size() > COFF::NameSize) 907 Strings.add(S->Name); 908 for (const auto &S : Symbols) 909 if (S->should_keep() && S->Name.size() > COFF::NameSize) 910 Strings.add(S->Name); 911 Strings.finalize(StringTableBuilder::WinCOFF); 912 913 // Set names. 914 for (const auto &S : Sections) 915 SetSectionName(*S); 916 for (auto &S : Symbols) 917 if (S->should_keep()) 918 SetSymbolName(*S); 919 920 // Fixup weak external references. 921 for (auto &Symbol : Symbols) { 922 if (Symbol->Other) { 923 assert(Symbol->getIndex() != -1); 924 assert(Symbol->Aux.size() == 1 && "Symbol must contain one aux symbol!"); 925 assert(Symbol->Aux[0].AuxType == ATWeakExternal && 926 "Symbol's aux symbol must be a Weak External!"); 927 Symbol->Aux[0].Aux.WeakExternal.TagIndex = Symbol->Other->getIndex(); 928 } 929 } 930 931 // Fixup associative COMDAT sections. 932 for (auto &Section : Sections) { 933 if (Section->Symbol->Aux[0].Aux.SectionDefinition.Selection != 934 COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) 935 continue; 936 937 const MCSectionCOFF &MCSec = *Section->MCSection; 938 939 const MCSymbol *COMDAT = MCSec.getCOMDATSymbol(); 940 assert(COMDAT); 941 COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(COMDAT); 942 assert(COMDATSymbol); 943 COFFSection *Assoc = COMDATSymbol->Section; 944 if (!Assoc) 945 report_fatal_error( 946 Twine("Missing associated COMDAT section for section ") + 947 MCSec.getSectionName()); 948 949 // Skip this section if the associated section is unused. 950 if (Assoc->Number == -1) 951 continue; 952 953 Section->Symbol->Aux[0].Aux.SectionDefinition.Number = Assoc->Number; 954 } 955 956 // Assign file offsets to COFF object file structures. 957 958 unsigned offset = 0; 959 960 if (UseBigObj) 961 offset += COFF::Header32Size; 962 else 963 offset += COFF::Header16Size; 964 offset += COFF::SectionSize * Header.NumberOfSections; 965 966 for (const auto &Section : Asm) { 967 COFFSection *Sec = SectionMap[&Section]; 968 969 if (Sec->Number == -1) 970 continue; 971 972 Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(&Section); 973 974 if (IsPhysicalSection(Sec)) { 975 // Align the section data to a four byte boundary. 976 offset = RoundUpToAlignment(offset, 4); 977 Sec->Header.PointerToRawData = offset; 978 979 offset += Sec->Header.SizeOfRawData; 980 } 981 982 if (Sec->Relocations.size() > 0) { 983 bool RelocationsOverflow = Sec->Relocations.size() >= 0xffff; 984 985 if (RelocationsOverflow) { 986 // Signal overflow by setting NumberOfRelocations to max value. Actual 987 // size is found in reloc #0. Microsoft tools understand this. 988 Sec->Header.NumberOfRelocations = 0xffff; 989 } else { 990 Sec->Header.NumberOfRelocations = Sec->Relocations.size(); 991 } 992 Sec->Header.PointerToRelocations = offset; 993 994 if (RelocationsOverflow) { 995 // Reloc #0 will contain actual count, so make room for it. 996 offset += COFF::RelocationSize; 997 } 998 999 offset += COFF::RelocationSize * Sec->Relocations.size(); 1000 1001 for (auto &Relocation : Sec->Relocations) { 1002 assert(Relocation.Symb->getIndex() != -1); 1003 Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex(); 1004 } 1005 } 1006 1007 assert(Sec->Symbol->Aux.size() == 1 && 1008 "Section's symbol must have one aux!"); 1009 AuxSymbol &Aux = Sec->Symbol->Aux[0]; 1010 assert(Aux.AuxType == ATSectionDefinition && 1011 "Section's symbol's aux symbol must be a Section Definition!"); 1012 Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData; 1013 Aux.Aux.SectionDefinition.NumberOfRelocations = 1014 Sec->Header.NumberOfRelocations; 1015 Aux.Aux.SectionDefinition.NumberOfLinenumbers = 1016 Sec->Header.NumberOfLineNumbers; 1017 } 1018 1019 Header.PointerToSymbolTable = offset; 1020 1021 #if (ENABLE_TIMESTAMPS == 1) 1022 // MS LINK expects to be able to use this timestamp to implement their 1023 // /INCREMENTAL feature. 1024 std::time_t Now = time(nullptr); 1025 if (Now < 0 || !isUInt<32>(Now)) 1026 Now = UINT32_MAX; 1027 Header.TimeDateStamp = Now; 1028 #else 1029 // We want a deterministic output. It looks like GNU as also writes 0 in here. 1030 Header.TimeDateStamp = 0; 1031 #endif 1032 1033 // Write it all to disk... 1034 WriteFileHeader(Header); 1035 1036 { 1037 sections::iterator i, ie; 1038 MCAssembler::iterator j, je; 1039 1040 for (auto &Section : Sections) { 1041 if (Section->Number != -1) { 1042 if (Section->Relocations.size() >= 0xffff) 1043 Section->Header.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL; 1044 writeSectionHeader(Section->Header); 1045 } 1046 } 1047 1048 SmallVector<char, 128> SectionContents; 1049 for (i = Sections.begin(), ie = Sections.end(), j = Asm.begin(), 1050 je = Asm.end(); 1051 (i != ie) && (j != je); ++i, ++j) { 1052 1053 if ((*i)->Number == -1) 1054 continue; 1055 1056 if ((*i)->Header.PointerToRawData != 0) { 1057 assert(getStream().tell() <= (*i)->Header.PointerToRawData && 1058 "Section::PointerToRawData is insane!"); 1059 1060 unsigned SectionDataPadding = 1061 (*i)->Header.PointerToRawData - getStream().tell(); 1062 assert(SectionDataPadding < 4 && 1063 "Should only need at most three bytes of padding!"); 1064 1065 WriteZeros(SectionDataPadding); 1066 1067 // Save the contents of the section to a temporary buffer, we need this 1068 // to CRC the data before we dump it into the object file. 1069 SectionContents.clear(); 1070 raw_svector_ostream VecOS(SectionContents); 1071 raw_pwrite_stream &OldStream = getStream(); 1072 // Redirect the output stream to our buffer. 1073 setStream(VecOS); 1074 // Fill our buffer with the section data. 1075 Asm.writeSectionData(&*j, Layout); 1076 // Reset the stream back to what it was before. 1077 setStream(OldStream); 1078 1079 // Calculate our CRC with an initial value of '0', this is not how 1080 // JamCRC is specified but it aligns with the expected output. 1081 JamCRC JC(/*Init=*/0x00000000U); 1082 JC.update(SectionContents); 1083 1084 // Write the section contents to the object file. 1085 getStream() << SectionContents; 1086 1087 // Update the section definition auxiliary symbol to record the CRC. 1088 COFFSection *Sec = SectionMap[&*j]; 1089 COFFSymbol::AuxiliarySymbols &AuxSyms = Sec->Symbol->Aux; 1090 assert(AuxSyms.size() == 1 && 1091 AuxSyms[0].AuxType == ATSectionDefinition); 1092 AuxSymbol &SecDef = AuxSyms[0]; 1093 SecDef.Aux.SectionDefinition.CheckSum = JC.getCRC(); 1094 } 1095 1096 if ((*i)->Relocations.size() > 0) { 1097 assert(getStream().tell() == (*i)->Header.PointerToRelocations && 1098 "Section::PointerToRelocations is insane!"); 1099 1100 if ((*i)->Relocations.size() >= 0xffff) { 1101 // In case of overflow, write actual relocation count as first 1102 // relocation. Including the synthetic reloc itself (+ 1). 1103 COFF::relocation r; 1104 r.VirtualAddress = (*i)->Relocations.size() + 1; 1105 r.SymbolTableIndex = 0; 1106 r.Type = 0; 1107 WriteRelocation(r); 1108 } 1109 1110 for (const auto &Relocation : (*i)->Relocations) 1111 WriteRelocation(Relocation.Data); 1112 } else 1113 assert((*i)->Header.PointerToRelocations == 0 && 1114 "Section::PointerToRelocations is insane!"); 1115 } 1116 } 1117 1118 assert(getStream().tell() == Header.PointerToSymbolTable && 1119 "Header::PointerToSymbolTable is insane!"); 1120 1121 for (auto &Symbol : Symbols) 1122 if (Symbol->getIndex() != -1) 1123 WriteSymbol(*Symbol); 1124 1125 getStream().write(Strings.data().data(), Strings.data().size()); 1126 } 1127 1128 MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_) 1129 : Machine(Machine_) {} 1130 1131 // Pin the vtable to this file. 1132 void MCWinCOFFObjectTargetWriter::anchor() {} 1133 1134 //------------------------------------------------------------------------------ 1135 // WinCOFFObjectWriter factory function 1136 1137 MCObjectWriter * 1138 llvm::createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, 1139 raw_pwrite_stream &OS) { 1140 return new WinCOFFObjectWriter(MOTW, OS); 1141 } 1142