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 #define DEBUG_TYPE "WinCOFFObjectWriter" 15 16 #include "llvm/MC/MCWinCOFFObjectWriter.h" 17 #include "llvm/ADT/DenseMap.h" 18 #include "llvm/ADT/OwningPtr.h" 19 #include "llvm/ADT/StringMap.h" 20 #include "llvm/ADT/StringRef.h" 21 #include "llvm/ADT/Twine.h" 22 #include "llvm/MC/MCAsmLayout.h" 23 #include "llvm/MC/MCAssembler.h" 24 #include "llvm/MC/MCContext.h" 25 #include "llvm/MC/MCExpr.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/MCValue.h" 31 #include "llvm/Support/COFF.h" 32 #include "llvm/Support/Debug.h" 33 #include "llvm/Support/ErrorHandling.h" 34 #include "llvm/Support/TimeValue.h" 35 #include <cstdio> 36 37 using namespace llvm; 38 39 namespace { 40 typedef SmallString<COFF::NameSize> name; 41 42 enum AuxiliaryType { 43 ATFunctionDefinition, 44 ATbfAndefSymbol, 45 ATWeakExternal, 46 ATFile, 47 ATSectionDefinition 48 }; 49 50 struct AuxSymbol { 51 AuxiliaryType AuxType; 52 COFF::Auxiliary Aux; 53 }; 54 55 class COFFSymbol; 56 class COFFSection; 57 58 class COFFSymbol { 59 public: 60 COFF::symbol Data; 61 62 typedef SmallVector<AuxSymbol, 1> AuxiliarySymbols; 63 64 name Name; 65 int Index; 66 AuxiliarySymbols Aux; 67 COFFSymbol *Other; 68 COFFSection *Section; 69 int Relocations; 70 71 MCSymbolData const *MCData; 72 73 COFFSymbol(StringRef name); 74 size_t size() const; 75 void set_name_offset(uint32_t Offset); 76 77 bool should_keep() const; 78 }; 79 80 // This class contains staging data for a COFF relocation entry. 81 struct COFFRelocation { 82 COFF::relocation Data; 83 COFFSymbol *Symb; 84 85 COFFRelocation() : Symb(NULL) {} 86 static size_t size() { return COFF::RelocationSize; } 87 }; 88 89 typedef std::vector<COFFRelocation> relocations; 90 91 class COFFSection { 92 public: 93 COFF::section Header; 94 95 std::string Name; 96 int Number; 97 MCSectionData const *MCData; 98 COFFSymbol *Symbol; 99 relocations Relocations; 100 101 COFFSection(StringRef name); 102 static size_t size(); 103 }; 104 105 // This class holds the COFF string table. 106 class StringTable { 107 typedef StringMap<size_t> map; 108 map Map; 109 110 void update_length(); 111 public: 112 std::vector<char> Data; 113 114 StringTable(); 115 size_t size() const; 116 size_t insert(StringRef String); 117 }; 118 119 class WinCOFFObjectWriter : public MCObjectWriter { 120 public: 121 122 typedef std::vector<COFFSymbol*> symbols; 123 typedef std::vector<COFFSection*> sections; 124 125 typedef DenseMap<MCSymbol const *, COFFSymbol *> symbol_map; 126 typedef DenseMap<MCSection const *, COFFSection *> section_map; 127 128 llvm::OwningPtr<MCWinCOFFObjectTargetWriter> TargetObjectWriter; 129 130 // Root level file contents. 131 COFF::header Header; 132 sections Sections; 133 symbols Symbols; 134 StringTable Strings; 135 136 // Maps used during object file creation. 137 section_map SectionMap; 138 symbol_map SymbolMap; 139 140 WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, raw_ostream &OS); 141 ~WinCOFFObjectWriter(); 142 143 COFFSymbol *createSymbol(StringRef Name); 144 COFFSymbol *GetOrCreateCOFFSymbol(const MCSymbol * Symbol); 145 COFFSection *createSection(StringRef Name); 146 147 template <typename object_t, typename list_t> 148 object_t *createCOFFEntity(StringRef Name, list_t &List); 149 150 void DefineSection(MCSectionData const &SectionData); 151 void DefineSymbol(MCSymbolData const &SymbolData, 152 MCAssembler &Assembler); 153 154 void MakeSymbolReal(COFFSymbol &S, size_t Index); 155 void MakeSectionReal(COFFSection &S, size_t Number); 156 157 bool ExportSection(COFFSection const *S); 158 bool ExportSymbol(MCSymbolData const &SymbolData, MCAssembler &Asm); 159 160 bool IsPhysicalSection(COFFSection *S); 161 162 // Entity writing methods. 163 164 void WriteFileHeader(const COFF::header &Header); 165 void WriteSymbol(const COFFSymbol *S); 166 void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols &S); 167 void WriteSectionHeader(const COFF::section &S); 168 void WriteRelocation(const COFF::relocation &R); 169 170 // MCObjectWriter interface implementation. 171 172 void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout); 173 174 void RecordRelocation(const MCAssembler &Asm, 175 const MCAsmLayout &Layout, 176 const MCFragment *Fragment, 177 const MCFixup &Fixup, 178 MCValue Target, 179 uint64_t &FixedValue); 180 181 void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout); 182 }; 183 } 184 185 static inline void write_uint32_le(void *Data, uint32_t const &Value) { 186 uint8_t *Ptr = reinterpret_cast<uint8_t *>(Data); 187 Ptr[0] = (Value & 0x000000FF) >> 0; 188 Ptr[1] = (Value & 0x0000FF00) >> 8; 189 Ptr[2] = (Value & 0x00FF0000) >> 16; 190 Ptr[3] = (Value & 0xFF000000) >> 24; 191 } 192 193 static inline void write_uint16_le(void *Data, uint16_t const &Value) { 194 uint8_t *Ptr = reinterpret_cast<uint8_t *>(Data); 195 Ptr[0] = (Value & 0x00FF) >> 0; 196 Ptr[1] = (Value & 0xFF00) >> 8; 197 } 198 199 static inline void write_uint8_le(void *Data, uint8_t const &Value) { 200 uint8_t *Ptr = reinterpret_cast<uint8_t *>(Data); 201 Ptr[0] = (Value & 0xFF) >> 0; 202 } 203 204 //------------------------------------------------------------------------------ 205 // Symbol class implementation 206 207 COFFSymbol::COFFSymbol(StringRef name) 208 : Name(name.begin(), name.end()) 209 , Other(NULL) 210 , Section(NULL) 211 , Relocations(0) 212 , MCData(NULL) { 213 memset(&Data, 0, sizeof(Data)); 214 } 215 216 size_t COFFSymbol::size() const { 217 return COFF::SymbolSize + (Data.NumberOfAuxSymbols * COFF::SymbolSize); 218 } 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 write_uint32_le(Data.Name + 0, 0); 225 write_uint32_le(Data.Name + 4, Offset); 226 } 227 228 /// logic to decide if the symbol should be reported in the symbol table 229 bool COFFSymbol::should_keep() const { 230 // no section means its external, keep it 231 if (Section == NULL) 232 return true; 233 234 // if it has relocations pointing at it, keep it 235 if (Relocations > 0) { 236 assert(Section->Number != -1 && "Sections with relocations must be real!"); 237 return true; 238 } 239 240 // if the section its in is being droped, drop it 241 if (Section->Number == -1) 242 return false; 243 244 // if it is the section symbol, keep it 245 if (Section->Symbol == this) 246 return true; 247 248 // if its temporary, drop it 249 if (MCData && MCData->getSymbol().isTemporary()) 250 return false; 251 252 // otherwise, keep it 253 return true; 254 } 255 256 //------------------------------------------------------------------------------ 257 // Section class implementation 258 259 COFFSection::COFFSection(StringRef name) 260 : Name(name) 261 , MCData(NULL) 262 , Symbol(NULL) { 263 memset(&Header, 0, sizeof(Header)); 264 } 265 266 size_t COFFSection::size() { 267 return COFF::SectionSize; 268 } 269 270 //------------------------------------------------------------------------------ 271 // StringTable class implementation 272 273 /// Write the length of the string table into Data. 274 /// The length of the string table includes uint32 length header. 275 void StringTable::update_length() { 276 write_uint32_le(&Data.front(), Data.size()); 277 } 278 279 StringTable::StringTable() { 280 // The string table data begins with the length of the entire string table 281 // including the length header. Allocate space for this header. 282 Data.resize(4); 283 update_length(); 284 } 285 286 size_t StringTable::size() const { 287 return Data.size(); 288 } 289 290 /// Add String to the table iff it is not already there. 291 /// @returns the index into the string table where the string is now located. 292 size_t StringTable::insert(StringRef String) { 293 map::iterator i = Map.find(String); 294 295 if (i != Map.end()) 296 return i->second; 297 298 size_t Offset = Data.size(); 299 300 // Insert string data into string table. 301 Data.insert(Data.end(), String.begin(), String.end()); 302 Data.push_back('\0'); 303 304 // Put a reference to it in the map. 305 Map[String] = Offset; 306 307 // Update the internal length field. 308 update_length(); 309 310 return Offset; 311 } 312 313 //------------------------------------------------------------------------------ 314 // WinCOFFObjectWriter class implementation 315 316 WinCOFFObjectWriter::WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, 317 raw_ostream &OS) 318 : MCObjectWriter(OS, true) 319 , TargetObjectWriter(MOTW) { 320 memset(&Header, 0, sizeof(Header)); 321 322 Header.Machine = TargetObjectWriter->getMachine(); 323 } 324 325 WinCOFFObjectWriter::~WinCOFFObjectWriter() { 326 for (symbols::iterator I = Symbols.begin(), E = Symbols.end(); I != E; ++I) 327 delete *I; 328 for (sections::iterator I = Sections.begin(), E = Sections.end(); I != E; ++I) 329 delete *I; 330 } 331 332 COFFSymbol *WinCOFFObjectWriter::createSymbol(StringRef Name) { 333 return createCOFFEntity<COFFSymbol>(Name, Symbols); 334 } 335 336 COFFSymbol *WinCOFFObjectWriter::GetOrCreateCOFFSymbol(const MCSymbol * Symbol){ 337 symbol_map::iterator i = SymbolMap.find(Symbol); 338 if (i != SymbolMap.end()) 339 return i->second; 340 COFFSymbol *RetSymbol 341 = createCOFFEntity<COFFSymbol>(Symbol->getName(), Symbols); 342 SymbolMap[Symbol] = RetSymbol; 343 return RetSymbol; 344 } 345 346 COFFSection *WinCOFFObjectWriter::createSection(StringRef Name) { 347 return createCOFFEntity<COFFSection>(Name, Sections); 348 } 349 350 /// A template used to lookup or create a symbol/section, and initialize it if 351 /// needed. 352 template <typename object_t, typename list_t> 353 object_t *WinCOFFObjectWriter::createCOFFEntity(StringRef Name, 354 list_t &List) { 355 object_t *Object = new object_t(Name); 356 357 List.push_back(Object); 358 359 return Object; 360 } 361 362 /// This function takes a section data object from the assembler 363 /// and creates the associated COFF section staging object. 364 void WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) { 365 assert(SectionData.getSection().getVariant() == MCSection::SV_COFF 366 && "Got non COFF section in the COFF backend!"); 367 // FIXME: Not sure how to verify this (at least in a debug build). 368 MCSectionCOFF const &Sec = 369 static_cast<MCSectionCOFF const &>(SectionData.getSection()); 370 371 COFFSection *coff_section = createSection(Sec.getSectionName()); 372 COFFSymbol *coff_symbol = createSymbol(Sec.getSectionName()); 373 374 coff_section->Symbol = coff_symbol; 375 coff_symbol->Section = coff_section; 376 coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_STATIC; 377 378 // In this case the auxiliary symbol is a Section Definition. 379 coff_symbol->Aux.resize(1); 380 memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0])); 381 coff_symbol->Aux[0].AuxType = ATSectionDefinition; 382 coff_symbol->Aux[0].Aux.SectionDefinition.Selection = Sec.getSelection(); 383 384 coff_section->Header.Characteristics = Sec.getCharacteristics(); 385 386 uint32_t &Characteristics = coff_section->Header.Characteristics; 387 switch (SectionData.getAlignment()) { 388 case 1: Characteristics |= COFF::IMAGE_SCN_ALIGN_1BYTES; break; 389 case 2: Characteristics |= COFF::IMAGE_SCN_ALIGN_2BYTES; break; 390 case 4: Characteristics |= COFF::IMAGE_SCN_ALIGN_4BYTES; break; 391 case 8: Characteristics |= COFF::IMAGE_SCN_ALIGN_8BYTES; break; 392 case 16: Characteristics |= COFF::IMAGE_SCN_ALIGN_16BYTES; break; 393 case 32: Characteristics |= COFF::IMAGE_SCN_ALIGN_32BYTES; break; 394 case 64: Characteristics |= COFF::IMAGE_SCN_ALIGN_64BYTES; break; 395 case 128: Characteristics |= COFF::IMAGE_SCN_ALIGN_128BYTES; break; 396 case 256: Characteristics |= COFF::IMAGE_SCN_ALIGN_256BYTES; break; 397 case 512: Characteristics |= COFF::IMAGE_SCN_ALIGN_512BYTES; break; 398 case 1024: Characteristics |= COFF::IMAGE_SCN_ALIGN_1024BYTES; break; 399 case 2048: Characteristics |= COFF::IMAGE_SCN_ALIGN_2048BYTES; break; 400 case 4096: Characteristics |= COFF::IMAGE_SCN_ALIGN_4096BYTES; break; 401 case 8192: Characteristics |= COFF::IMAGE_SCN_ALIGN_8192BYTES; break; 402 default: 403 llvm_unreachable("unsupported section alignment"); 404 } 405 406 // Bind internal COFF section to MC section. 407 coff_section->MCData = &SectionData; 408 SectionMap[&SectionData.getSection()] = coff_section; 409 } 410 411 /// This function takes a section data object from the assembler 412 /// and creates the associated COFF symbol staging object. 413 void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData, 414 MCAssembler &Assembler) { 415 MCSymbol const &Symbol = SymbolData.getSymbol(); 416 COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&Symbol); 417 SymbolMap[&Symbol] = coff_symbol; 418 419 if (SymbolData.getFlags() & COFF::SF_WeakExternal) { 420 coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL; 421 422 if (Symbol.isVariable()) { 423 const MCSymbolRefExpr *SymRef = 424 dyn_cast<MCSymbolRefExpr>(Symbol.getVariableValue()); 425 426 if (!SymRef) 427 report_fatal_error("Weak externals may only alias symbols"); 428 429 coff_symbol->Other = GetOrCreateCOFFSymbol(&SymRef->getSymbol()); 430 } else { 431 std::string WeakName = std::string(".weak.") 432 + Symbol.getName().str() 433 + ".default"; 434 COFFSymbol *WeakDefault = createSymbol(WeakName); 435 WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE; 436 WeakDefault->Data.StorageClass = COFF::IMAGE_SYM_CLASS_EXTERNAL; 437 WeakDefault->Data.Type = 0; 438 WeakDefault->Data.Value = 0; 439 coff_symbol->Other = WeakDefault; 440 } 441 442 // Setup the Weak External auxiliary symbol. 443 coff_symbol->Aux.resize(1); 444 memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0])); 445 coff_symbol->Aux[0].AuxType = ATWeakExternal; 446 coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = 0; 447 coff_symbol->Aux[0].Aux.WeakExternal.Characteristics = 448 COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY; 449 450 coff_symbol->MCData = &SymbolData; 451 } else { 452 const MCSymbolData &ResSymData = 453 Assembler.getSymbolData(Symbol.AliasedSymbol()); 454 455 coff_symbol->Data.Type = (ResSymData.getFlags() & 0x0000FFFF) >> 0; 456 coff_symbol->Data.StorageClass = (ResSymData.getFlags() & 0x00FF0000) >> 16; 457 458 // If no storage class was specified in the streamer, define it here. 459 if (coff_symbol->Data.StorageClass == 0) { 460 bool external = ResSymData.isExternal() || (ResSymData.Fragment == NULL); 461 462 coff_symbol->Data.StorageClass = 463 external ? COFF::IMAGE_SYM_CLASS_EXTERNAL : COFF::IMAGE_SYM_CLASS_STATIC; 464 } 465 466 if (ResSymData.Fragment != NULL) 467 coff_symbol->Section = 468 SectionMap[&ResSymData.Fragment->getParent()->getSection()]; 469 470 coff_symbol->MCData = &ResSymData; 471 } 472 } 473 474 /// making a section real involves assigned it a number and putting 475 /// name into the string table if needed 476 void WinCOFFObjectWriter::MakeSectionReal(COFFSection &S, size_t Number) { 477 if (S.Name.size() > COFF::NameSize) { 478 const unsigned Max6DecimalSize = 999999; 479 const unsigned Max7DecimalSize = 9999999; 480 uint64_t StringTableEntry = Strings.insert(S.Name.c_str()); 481 482 if (StringTableEntry <= Max6DecimalSize) { 483 std::sprintf(S.Header.Name, "/%d", unsigned(StringTableEntry)); 484 } else if (StringTableEntry <= Max7DecimalSize) { 485 // With seven digits, we have to skip the terminating null. Because 486 // sprintf always appends it, we use a larger temporary buffer. 487 char buffer[9] = { }; 488 std::sprintf(buffer, "/%d", unsigned(StringTableEntry)); 489 std::memcpy(S.Header.Name, buffer, 8); 490 } else { 491 report_fatal_error("COFF string table is greater than 9,999,999 bytes."); 492 } 493 } else 494 std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size()); 495 496 S.Number = Number; 497 S.Symbol->Data.SectionNumber = S.Number; 498 S.Symbol->Aux[0].Aux.SectionDefinition.Number = S.Number; 499 } 500 501 void WinCOFFObjectWriter::MakeSymbolReal(COFFSymbol &S, size_t Index) { 502 if (S.Name.size() > COFF::NameSize) { 503 size_t StringTableEntry = Strings.insert(S.Name.c_str()); 504 505 S.set_name_offset(StringTableEntry); 506 } else 507 std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size()); 508 S.Index = Index; 509 } 510 511 bool WinCOFFObjectWriter::ExportSection(COFFSection const *S) { 512 return !S->MCData->getFragmentList().empty(); 513 } 514 515 bool WinCOFFObjectWriter::ExportSymbol(MCSymbolData const &SymbolData, 516 MCAssembler &Asm) { 517 // This doesn't seem to be right. Strings referred to from the .data section 518 // need symbols so they can be linked to code in the .text section right? 519 520 // return Asm.isSymbolLinkerVisible (&SymbolData); 521 522 // For now, all non-variable symbols are exported, 523 // the linker will sort the rest out for us. 524 return SymbolData.isExternal() || !SymbolData.getSymbol().isVariable(); 525 } 526 527 bool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) { 528 return (S->Header.Characteristics 529 & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0; 530 } 531 532 //------------------------------------------------------------------------------ 533 // entity writing methods 534 535 void WinCOFFObjectWriter::WriteFileHeader(const COFF::header &Header) { 536 WriteLE16(Header.Machine); 537 WriteLE16(Header.NumberOfSections); 538 WriteLE32(Header.TimeDateStamp); 539 WriteLE32(Header.PointerToSymbolTable); 540 WriteLE32(Header.NumberOfSymbols); 541 WriteLE16(Header.SizeOfOptionalHeader); 542 WriteLE16(Header.Characteristics); 543 } 544 545 void WinCOFFObjectWriter::WriteSymbol(const COFFSymbol *S) { 546 WriteBytes(StringRef(S->Data.Name, COFF::NameSize)); 547 WriteLE32(S->Data.Value); 548 WriteLE16(S->Data.SectionNumber); 549 WriteLE16(S->Data.Type); 550 Write8(S->Data.StorageClass); 551 Write8(S->Data.NumberOfAuxSymbols); 552 WriteAuxiliarySymbols(S->Aux); 553 } 554 555 void WinCOFFObjectWriter::WriteAuxiliarySymbols( 556 const COFFSymbol::AuxiliarySymbols &S) { 557 for(COFFSymbol::AuxiliarySymbols::const_iterator i = S.begin(), e = S.end(); 558 i != e; ++i) { 559 switch(i->AuxType) { 560 case ATFunctionDefinition: 561 WriteLE32(i->Aux.FunctionDefinition.TagIndex); 562 WriteLE32(i->Aux.FunctionDefinition.TotalSize); 563 WriteLE32(i->Aux.FunctionDefinition.PointerToLinenumber); 564 WriteLE32(i->Aux.FunctionDefinition.PointerToNextFunction); 565 WriteZeros(sizeof(i->Aux.FunctionDefinition.unused)); 566 break; 567 case ATbfAndefSymbol: 568 WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused1)); 569 WriteLE16(i->Aux.bfAndefSymbol.Linenumber); 570 WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused2)); 571 WriteLE32(i->Aux.bfAndefSymbol.PointerToNextFunction); 572 WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused3)); 573 break; 574 case ATWeakExternal: 575 WriteLE32(i->Aux.WeakExternal.TagIndex); 576 WriteLE32(i->Aux.WeakExternal.Characteristics); 577 WriteZeros(sizeof(i->Aux.WeakExternal.unused)); 578 break; 579 case ATFile: 580 WriteBytes(StringRef(reinterpret_cast<const char *>(i->Aux.File.FileName), 581 sizeof(i->Aux.File.FileName))); 582 break; 583 case ATSectionDefinition: 584 WriteLE32(i->Aux.SectionDefinition.Length); 585 WriteLE16(i->Aux.SectionDefinition.NumberOfRelocations); 586 WriteLE16(i->Aux.SectionDefinition.NumberOfLinenumbers); 587 WriteLE32(i->Aux.SectionDefinition.CheckSum); 588 WriteLE16(i->Aux.SectionDefinition.Number); 589 Write8(i->Aux.SectionDefinition.Selection); 590 WriteZeros(sizeof(i->Aux.SectionDefinition.unused)); 591 break; 592 } 593 } 594 } 595 596 void WinCOFFObjectWriter::WriteSectionHeader(const COFF::section &S) { 597 WriteBytes(StringRef(S.Name, COFF::NameSize)); 598 599 WriteLE32(S.VirtualSize); 600 WriteLE32(S.VirtualAddress); 601 WriteLE32(S.SizeOfRawData); 602 WriteLE32(S.PointerToRawData); 603 WriteLE32(S.PointerToRelocations); 604 WriteLE32(S.PointerToLineNumbers); 605 WriteLE16(S.NumberOfRelocations); 606 WriteLE16(S.NumberOfLineNumbers); 607 WriteLE32(S.Characteristics); 608 } 609 610 void WinCOFFObjectWriter::WriteRelocation(const COFF::relocation &R) { 611 WriteLE32(R.VirtualAddress); 612 WriteLE32(R.SymbolTableIndex); 613 WriteLE16(R.Type); 614 } 615 616 //////////////////////////////////////////////////////////////////////////////// 617 // MCObjectWriter interface implementations 618 619 void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, 620 const MCAsmLayout &Layout) { 621 // "Define" each section & symbol. This creates section & symbol 622 // entries in the staging area. 623 624 for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e; i++) 625 DefineSection(*i); 626 627 for (MCAssembler::const_symbol_iterator i = Asm.symbol_begin(), 628 e = Asm.symbol_end(); i != e; i++) { 629 if (ExportSymbol(*i, Asm)) { 630 DefineSymbol(*i, Asm); 631 } 632 } 633 } 634 635 void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, 636 const MCAsmLayout &Layout, 637 const MCFragment *Fragment, 638 const MCFixup &Fixup, 639 MCValue Target, 640 uint64_t &FixedValue) { 641 assert(Target.getSymA() != NULL && "Relocation must reference a symbol!"); 642 643 const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 644 const MCSymbol &A = Symbol.AliasedSymbol(); 645 MCSymbolData &A_SD = Asm.getSymbolData(A); 646 647 MCSectionData const *SectionData = Fragment->getParent(); 648 649 // Mark this symbol as requiring an entry in the symbol table. 650 assert(SectionMap.find(&SectionData->getSection()) != SectionMap.end() && 651 "Section must already have been defined in ExecutePostLayoutBinding!"); 652 assert(SymbolMap.find(&A_SD.getSymbol()) != SymbolMap.end() && 653 "Symbol must already have been defined in ExecutePostLayoutBinding!"); 654 655 COFFSection *coff_section = SectionMap[&SectionData->getSection()]; 656 COFFSymbol *coff_symbol = SymbolMap[&A_SD.getSymbol()]; 657 const MCSymbolRefExpr *SymA = Target.getSymA(); 658 const MCSymbolRefExpr *SymB = Target.getSymB(); 659 const bool CrossSection = SymB && 660 &SymA->getSymbol().getSection() != &SymB->getSymbol().getSection(); 661 662 if (Target.getSymB()) { 663 const MCSymbol *B = &Target.getSymB()->getSymbol(); 664 MCSymbolData &B_SD = Asm.getSymbolData(*B); 665 666 // Offset of the symbol in the section 667 int64_t a = Layout.getSymbolOffset(&B_SD); 668 669 // Ofeset of the relocation in the section 670 int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); 671 672 FixedValue = b - a; 673 // In the case where we have SymbA and SymB, we just need to store the delta 674 // between the two symbols. Update FixedValue to account for the delta, and 675 // skip recording the relocation. 676 if (!CrossSection) 677 return; 678 } else { 679 FixedValue = Target.getConstant(); 680 } 681 682 COFFRelocation Reloc; 683 684 Reloc.Data.SymbolTableIndex = 0; 685 Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment); 686 687 // Turn relocations for temporary symbols into section relocations. 688 if (coff_symbol->MCData->getSymbol().isTemporary() || CrossSection) { 689 Reloc.Symb = coff_symbol->Section->Symbol; 690 FixedValue += Layout.getFragmentOffset(coff_symbol->MCData->Fragment) 691 + coff_symbol->MCData->getOffset(); 692 } else 693 Reloc.Symb = coff_symbol; 694 695 ++Reloc.Symb->Relocations; 696 697 Reloc.Data.VirtualAddress += Fixup.getOffset(); 698 Reloc.Data.Type = TargetObjectWriter->getRelocType(Target, Fixup, 699 CrossSection); 700 701 // FIXME: Can anyone explain what this does other than adjust for the size 702 // of the offset? 703 if (Reloc.Data.Type == COFF::IMAGE_REL_AMD64_REL32 || 704 Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32) 705 FixedValue += 4; 706 707 coff_section->Relocations.push_back(Reloc); 708 } 709 710 void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, 711 const MCAsmLayout &Layout) { 712 // Assign symbol and section indexes and offsets. 713 Header.NumberOfSections = 0; 714 715 DenseMap<COFFSection *, uint16_t> SectionIndices; 716 for (sections::iterator i = Sections.begin(), 717 e = Sections.end(); i != e; i++) { 718 if (Layout.getSectionAddressSize((*i)->MCData) > 0) { 719 size_t Number = ++Header.NumberOfSections; 720 SectionIndices[*i] = Number; 721 MakeSectionReal(**i, Number); 722 } else { 723 (*i)->Number = -1; 724 } 725 } 726 727 Header.NumberOfSymbols = 0; 728 729 for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) { 730 COFFSymbol *coff_symbol = *i; 731 MCSymbolData const *SymbolData = coff_symbol->MCData; 732 733 // Update section number & offset for symbols that have them. 734 if ((SymbolData != NULL) && (SymbolData->Fragment != NULL)) { 735 assert(coff_symbol->Section != NULL); 736 737 coff_symbol->Data.SectionNumber = coff_symbol->Section->Number; 738 coff_symbol->Data.Value = Layout.getFragmentOffset(SymbolData->Fragment) 739 + SymbolData->Offset; 740 } 741 742 if (coff_symbol->should_keep()) { 743 MakeSymbolReal(*coff_symbol, Header.NumberOfSymbols++); 744 745 // Update auxiliary symbol info. 746 coff_symbol->Data.NumberOfAuxSymbols = coff_symbol->Aux.size(); 747 Header.NumberOfSymbols += coff_symbol->Data.NumberOfAuxSymbols; 748 } else 749 coff_symbol->Index = -1; 750 } 751 752 // Fixup weak external references. 753 for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) { 754 COFFSymbol *coff_symbol = *i; 755 if (coff_symbol->Other != NULL) { 756 assert(coff_symbol->Index != -1); 757 assert(coff_symbol->Aux.size() == 1 && 758 "Symbol must contain one aux symbol!"); 759 assert(coff_symbol->Aux[0].AuxType == ATWeakExternal && 760 "Symbol's aux symbol must be a Weak External!"); 761 coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = coff_symbol->Other->Index; 762 } 763 } 764 765 // Fixup associative COMDAT sections. 766 for (sections::iterator i = Sections.begin(), 767 e = Sections.end(); i != e; i++) { 768 if ((*i)->Symbol->Aux[0].Aux.SectionDefinition.Selection != 769 COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) 770 continue; 771 772 const MCSectionCOFF &MCSec = static_cast<const MCSectionCOFF &>( 773 (*i)->MCData->getSection()); 774 775 COFFSection *Assoc = SectionMap.lookup(MCSec.getAssocSection()); 776 if (!Assoc) { 777 report_fatal_error(Twine("Missing associated COMDAT section ") + 778 MCSec.getAssocSection()->getSectionName() + 779 " for section " + MCSec.getSectionName()); 780 } 781 782 // Skip this section if the associated section is unused. 783 if (Assoc->Number == -1) 784 continue; 785 786 (*i)->Symbol->Aux[0].Aux.SectionDefinition.Number = SectionIndices[Assoc]; 787 } 788 789 790 // Assign file offsets to COFF object file structures. 791 792 unsigned offset = 0; 793 794 offset += COFF::HeaderSize; 795 offset += COFF::SectionSize * Header.NumberOfSections; 796 797 for (MCAssembler::const_iterator i = Asm.begin(), 798 e = Asm.end(); 799 i != e; i++) { 800 COFFSection *Sec = SectionMap[&i->getSection()]; 801 802 if (Sec->Number == -1) 803 continue; 804 805 Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(i); 806 807 if (IsPhysicalSection(Sec)) { 808 Sec->Header.PointerToRawData = offset; 809 810 offset += Sec->Header.SizeOfRawData; 811 } 812 813 if (Sec->Relocations.size() > 0) { 814 bool RelocationsOverflow = Sec->Relocations.size() >= 0xffff; 815 816 if (RelocationsOverflow) { 817 // Signal overflow by setting NumberOfSections to max value. Actual 818 // size is found in reloc #0. Microsoft tools understand this. 819 Sec->Header.NumberOfRelocations = 0xffff; 820 } else { 821 Sec->Header.NumberOfRelocations = Sec->Relocations.size(); 822 } 823 Sec->Header.PointerToRelocations = offset; 824 825 if (RelocationsOverflow) { 826 // Reloc #0 will contain actual count, so make room for it. 827 offset += COFF::RelocationSize; 828 } 829 830 offset += COFF::RelocationSize * Sec->Relocations.size(); 831 832 for (relocations::iterator cr = Sec->Relocations.begin(), 833 er = Sec->Relocations.end(); 834 cr != er; ++cr) { 835 assert((*cr).Symb->Index != -1); 836 (*cr).Data.SymbolTableIndex = (*cr).Symb->Index; 837 } 838 } 839 840 assert(Sec->Symbol->Aux.size() == 1 841 && "Section's symbol must have one aux!"); 842 AuxSymbol &Aux = Sec->Symbol->Aux[0]; 843 assert(Aux.AuxType == ATSectionDefinition && 844 "Section's symbol's aux symbol must be a Section Definition!"); 845 Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData; 846 Aux.Aux.SectionDefinition.NumberOfRelocations = 847 Sec->Header.NumberOfRelocations; 848 Aux.Aux.SectionDefinition.NumberOfLinenumbers = 849 Sec->Header.NumberOfLineNumbers; 850 } 851 852 Header.PointerToSymbolTable = offset; 853 854 Header.TimeDateStamp = sys::TimeValue::now().toEpochTime(); 855 856 // Write it all to disk... 857 WriteFileHeader(Header); 858 859 { 860 sections::iterator i, ie; 861 MCAssembler::const_iterator j, je; 862 863 for (i = Sections.begin(), ie = Sections.end(); i != ie; i++) 864 if ((*i)->Number != -1) { 865 if ((*i)->Relocations.size() >= 0xffff) { 866 (*i)->Header.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL; 867 } 868 WriteSectionHeader((*i)->Header); 869 } 870 871 for (i = Sections.begin(), ie = Sections.end(), 872 j = Asm.begin(), je = Asm.end(); 873 (i != ie) && (j != je); ++i, ++j) { 874 875 if ((*i)->Number == -1) 876 continue; 877 878 if ((*i)->Header.PointerToRawData != 0) { 879 assert(OS.tell() == (*i)->Header.PointerToRawData && 880 "Section::PointerToRawData is insane!"); 881 882 Asm.writeSectionData(j, Layout); 883 } 884 885 if ((*i)->Relocations.size() > 0) { 886 assert(OS.tell() == (*i)->Header.PointerToRelocations && 887 "Section::PointerToRelocations is insane!"); 888 889 if ((*i)->Relocations.size() >= 0xffff) { 890 // In case of overflow, write actual relocation count as first 891 // relocation. Including the synthetic reloc itself (+ 1). 892 COFF::relocation r; 893 r.VirtualAddress = (*i)->Relocations.size() + 1; 894 r.SymbolTableIndex = 0; 895 r.Type = 0; 896 WriteRelocation(r); 897 } 898 899 for (relocations::const_iterator k = (*i)->Relocations.begin(), 900 ke = (*i)->Relocations.end(); 901 k != ke; k++) { 902 WriteRelocation(k->Data); 903 } 904 } else 905 assert((*i)->Header.PointerToRelocations == 0 && 906 "Section::PointerToRelocations is insane!"); 907 } 908 } 909 910 assert(OS.tell() == Header.PointerToSymbolTable && 911 "Header::PointerToSymbolTable is insane!"); 912 913 for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) 914 if ((*i)->Index != -1) 915 WriteSymbol(*i); 916 917 OS.write((char const *)&Strings.Data.front(), Strings.Data.size()); 918 } 919 920 MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_) : 921 Machine(Machine_) { 922 } 923 924 //------------------------------------------------------------------------------ 925 // WinCOFFObjectWriter factory function 926 927 namespace llvm { 928 MCObjectWriter *createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, 929 raw_ostream &OS) { 930 return new WinCOFFObjectWriter(MOTW, OS); 931 } 932 } 933