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