1210006Srdivacky//===-- llvm/MC/WinCOFFObjectWriter.cpp -------------------------*- C++ -*-===// 2210006Srdivacky// 3210006Srdivacky// The LLVM Compiler Infrastructure 4210006Srdivacky// 5210006Srdivacky// This file is distributed under the University of Illinois Open Source 6210006Srdivacky// License. See LICENSE.TXT for details. 7210006Srdivacky// 8210006Srdivacky//===----------------------------------------------------------------------===// 9210006Srdivacky// 10210006Srdivacky// This file contains an implementation of a Win32 COFF object file writer. 11210006Srdivacky// 12210006Srdivacky//===----------------------------------------------------------------------===// 13210006Srdivacky 14210006Srdivacky#define DEBUG_TYPE "WinCOFFObjectWriter" 15212904Sdim 16234353Sdim#include "llvm/MC/MCWinCOFFObjectWriter.h" 17212904Sdim#include "llvm/ADT/DenseMap.h" 18234353Sdim#include "llvm/ADT/OwningPtr.h" 19212904Sdim#include "llvm/ADT/StringMap.h" 20212904Sdim#include "llvm/ADT/StringRef.h" 21263508Sdim#include "llvm/ADT/Twine.h" 22249423Sdim#include "llvm/MC/MCAsmLayout.h" 23249423Sdim#include "llvm/MC/MCAssembler.h" 24249423Sdim#include "llvm/MC/MCContext.h" 25249423Sdim#include "llvm/MC/MCExpr.h" 26249423Sdim#include "llvm/MC/MCObjectWriter.h" 27249423Sdim#include "llvm/MC/MCSection.h" 28249423Sdim#include "llvm/MC/MCSectionCOFF.h" 29249423Sdim#include "llvm/MC/MCSymbol.h" 30249423Sdim#include "llvm/MC/MCValue.h" 31212904Sdim#include "llvm/Support/COFF.h" 32212904Sdim#include "llvm/Support/Debug.h" 33212904Sdim#include "llvm/Support/ErrorHandling.h" 34218893Sdim#include "llvm/Support/TimeValue.h" 35212904Sdim#include <cstdio> 36212904Sdim 37210006Srdivackyusing namespace llvm; 38210006Srdivacky 39210006Srdivackynamespace { 40249423Sdimtypedef SmallString<COFF::NameSize> name; 41210006Srdivacky 42212904Sdimenum AuxiliaryType { 43212904Sdim ATFunctionDefinition, 44212904Sdim ATbfAndefSymbol, 45212904Sdim ATWeakExternal, 46212904Sdim ATFile, 47212904Sdim ATSectionDefinition 48212904Sdim}; 49210006Srdivacky 50212904Sdimstruct AuxSymbol { 51212904Sdim AuxiliaryType AuxType; 52212904Sdim COFF::Auxiliary Aux; 53212904Sdim}; 54210006Srdivacky 55218893Sdimclass COFFSymbol; 56218893Sdimclass COFFSection; 57218893Sdim 58212904Sdimclass COFFSymbol { 59212904Sdimpublic: 60212904Sdim COFF::symbol Data; 61210006Srdivacky 62249423Sdim typedef SmallVector<AuxSymbol, 1> AuxiliarySymbols; 63210006Srdivacky 64212904Sdim name Name; 65218893Sdim int Index; 66212904Sdim AuxiliarySymbols Aux; 67212904Sdim COFFSymbol *Other; 68218893Sdim COFFSection *Section; 69218893Sdim int Relocations; 70212904Sdim 71212904Sdim MCSymbolData const *MCData; 72212904Sdim 73249423Sdim COFFSymbol(StringRef name); 74212904Sdim size_t size() const; 75212904Sdim void set_name_offset(uint32_t Offset); 76218893Sdim 77218893Sdim bool should_keep() const; 78212904Sdim}; 79212904Sdim 80212904Sdim// This class contains staging data for a COFF relocation entry. 81212904Sdimstruct COFFRelocation { 82212904Sdim COFF::relocation Data; 83212904Sdim COFFSymbol *Symb; 84212904Sdim 85212904Sdim COFFRelocation() : Symb(NULL) {} 86212904Sdim static size_t size() { return COFF::RelocationSize; } 87212904Sdim}; 88212904Sdim 89212904Sdimtypedef std::vector<COFFRelocation> relocations; 90212904Sdim 91212904Sdimclass COFFSection { 92212904Sdimpublic: 93212904Sdim COFF::section Header; 94212904Sdim 95212904Sdim std::string Name; 96218893Sdim int Number; 97212904Sdim MCSectionData const *MCData; 98218893Sdim COFFSymbol *Symbol; 99212904Sdim relocations Relocations; 100212904Sdim 101249423Sdim COFFSection(StringRef name); 102212904Sdim static size_t size(); 103212904Sdim}; 104212904Sdim 105212904Sdim// This class holds the COFF string table. 106212904Sdimclass StringTable { 107249423Sdim typedef StringMap<size_t> map; 108212904Sdim map Map; 109212904Sdim 110212904Sdim void update_length(); 111212904Sdimpublic: 112212904Sdim std::vector<char> Data; 113212904Sdim 114212904Sdim StringTable(); 115212904Sdim size_t size() const; 116249423Sdim size_t insert(StringRef String); 117212904Sdim}; 118212904Sdim 119212904Sdimclass WinCOFFObjectWriter : public MCObjectWriter { 120212904Sdimpublic: 121212904Sdim 122212904Sdim typedef std::vector<COFFSymbol*> symbols; 123212904Sdim typedef std::vector<COFFSection*> sections; 124212904Sdim 125218893Sdim typedef DenseMap<MCSymbol const *, COFFSymbol *> symbol_map; 126218893Sdim typedef DenseMap<MCSection const *, COFFSection *> section_map; 127212904Sdim 128234353Sdim llvm::OwningPtr<MCWinCOFFObjectTargetWriter> TargetObjectWriter; 129234353Sdim 130212904Sdim // Root level file contents. 131212904Sdim COFF::header Header; 132212904Sdim sections Sections; 133212904Sdim symbols Symbols; 134212904Sdim StringTable Strings; 135212904Sdim 136212904Sdim // Maps used during object file creation. 137212904Sdim section_map SectionMap; 138212904Sdim symbol_map SymbolMap; 139212904Sdim 140234353Sdim WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, raw_ostream &OS); 141263508Sdim virtual ~WinCOFFObjectWriter(); 142212904Sdim 143218893Sdim COFFSymbol *createSymbol(StringRef Name); 144218893Sdim COFFSymbol *GetOrCreateCOFFSymbol(const MCSymbol * Symbol); 145218893Sdim COFFSection *createSection(StringRef Name); 146212904Sdim 147212904Sdim template <typename object_t, typename list_t> 148249423Sdim object_t *createCOFFEntity(StringRef Name, list_t &List); 149212904Sdim 150212904Sdim void DefineSection(MCSectionData const &SectionData); 151263508Sdim void DefineSymbol(MCSymbolData const &SymbolData, MCAssembler &Assembler, 152263508Sdim const MCAsmLayout &Layout); 153212904Sdim 154218893Sdim void MakeSymbolReal(COFFSymbol &S, size_t Index); 155218893Sdim void MakeSectionReal(COFFSection &S, size_t Number); 156218893Sdim 157212904Sdim bool ExportSymbol(MCSymbolData const &SymbolData, MCAssembler &Asm); 158212904Sdim 159218893Sdim bool IsPhysicalSection(COFFSection *S); 160218893Sdim 161212904Sdim // Entity writing methods. 162212904Sdim 163212904Sdim void WriteFileHeader(const COFF::header &Header); 164212904Sdim void WriteSymbol(const COFFSymbol *S); 165212904Sdim void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols &S); 166212904Sdim void WriteSectionHeader(const COFF::section &S); 167212904Sdim void WriteRelocation(const COFF::relocation &R); 168212904Sdim 169212904Sdim // MCObjectWriter interface implementation. 170212904Sdim 171218893Sdim void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout); 172212904Sdim 173212904Sdim void RecordRelocation(const MCAssembler &Asm, 174212904Sdim const MCAsmLayout &Layout, 175212904Sdim const MCFragment *Fragment, 176212904Sdim const MCFixup &Fixup, 177212904Sdim MCValue Target, 178212904Sdim uint64_t &FixedValue); 179212904Sdim 180218893Sdim void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout); 181212904Sdim}; 182210006Srdivacky} 183210006Srdivacky 184212904Sdimstatic inline void write_uint32_le(void *Data, uint32_t const &Value) { 185212904Sdim uint8_t *Ptr = reinterpret_cast<uint8_t *>(Data); 186212904Sdim Ptr[0] = (Value & 0x000000FF) >> 0; 187212904Sdim Ptr[1] = (Value & 0x0000FF00) >> 8; 188212904Sdim Ptr[2] = (Value & 0x00FF0000) >> 16; 189212904Sdim Ptr[3] = (Value & 0xFF000000) >> 24; 190210006Srdivacky} 191210006Srdivacky 192212904Sdim//------------------------------------------------------------------------------ 193212904Sdim// Symbol class implementation 194212904Sdim 195249423SdimCOFFSymbol::COFFSymbol(StringRef name) 196218893Sdim : Name(name.begin(), name.end()) 197218893Sdim , Other(NULL) 198218893Sdim , Section(NULL) 199218893Sdim , Relocations(0) 200218893Sdim , MCData(NULL) { 201212904Sdim memset(&Data, 0, sizeof(Data)); 202212904Sdim} 203212904Sdim 204212904Sdimsize_t COFFSymbol::size() const { 205212904Sdim return COFF::SymbolSize + (Data.NumberOfAuxSymbols * COFF::SymbolSize); 206212904Sdim} 207212904Sdim 208212904Sdim// In the case that the name does not fit within 8 bytes, the offset 209212904Sdim// into the string table is stored in the last 4 bytes instead, leaving 210212904Sdim// the first 4 bytes as 0. 211212904Sdimvoid COFFSymbol::set_name_offset(uint32_t Offset) { 212212904Sdim write_uint32_le(Data.Name + 0, 0); 213212904Sdim write_uint32_le(Data.Name + 4, Offset); 214212904Sdim} 215212904Sdim 216218893Sdim/// logic to decide if the symbol should be reported in the symbol table 217218893Sdimbool COFFSymbol::should_keep() const { 218218893Sdim // no section means its external, keep it 219218893Sdim if (Section == NULL) 220218893Sdim return true; 221218893Sdim 222218893Sdim // if it has relocations pointing at it, keep it 223218893Sdim if (Relocations > 0) { 224218893Sdim assert(Section->Number != -1 && "Sections with relocations must be real!"); 225218893Sdim return true; 226218893Sdim } 227218893Sdim 228218893Sdim // if the section its in is being droped, drop it 229218893Sdim if (Section->Number == -1) 230218893Sdim return false; 231218893Sdim 232218893Sdim // if it is the section symbol, keep it 233218893Sdim if (Section->Symbol == this) 234218893Sdim return true; 235218893Sdim 236218893Sdim // if its temporary, drop it 237218893Sdim if (MCData && MCData->getSymbol().isTemporary()) 238218893Sdim return false; 239218893Sdim 240218893Sdim // otherwise, keep it 241218893Sdim return true; 242218893Sdim} 243218893Sdim 244212904Sdim//------------------------------------------------------------------------------ 245212904Sdim// Section class implementation 246212904Sdim 247249423SdimCOFFSection::COFFSection(StringRef name) 248218893Sdim : Name(name) 249218893Sdim , MCData(NULL) 250218893Sdim , Symbol(NULL) { 251212904Sdim memset(&Header, 0, sizeof(Header)); 252212904Sdim} 253212904Sdim 254212904Sdimsize_t COFFSection::size() { 255212904Sdim return COFF::SectionSize; 256212904Sdim} 257212904Sdim 258212904Sdim//------------------------------------------------------------------------------ 259212904Sdim// StringTable class implementation 260212904Sdim 261212904Sdim/// Write the length of the string table into Data. 262212904Sdim/// The length of the string table includes uint32 length header. 263212904Sdimvoid StringTable::update_length() { 264212904Sdim write_uint32_le(&Data.front(), Data.size()); 265212904Sdim} 266212904Sdim 267212904SdimStringTable::StringTable() { 268212904Sdim // The string table data begins with the length of the entire string table 269212904Sdim // including the length header. Allocate space for this header. 270212904Sdim Data.resize(4); 271234353Sdim update_length(); 272212904Sdim} 273212904Sdim 274212904Sdimsize_t StringTable::size() const { 275212904Sdim return Data.size(); 276212904Sdim} 277212904Sdim 278212904Sdim/// Add String to the table iff it is not already there. 279212904Sdim/// @returns the index into the string table where the string is now located. 280249423Sdimsize_t StringTable::insert(StringRef String) { 281212904Sdim map::iterator i = Map.find(String); 282212904Sdim 283212904Sdim if (i != Map.end()) 284212904Sdim return i->second; 285212904Sdim 286212904Sdim size_t Offset = Data.size(); 287212904Sdim 288212904Sdim // Insert string data into string table. 289212904Sdim Data.insert(Data.end(), String.begin(), String.end()); 290212904Sdim Data.push_back('\0'); 291212904Sdim 292212904Sdim // Put a reference to it in the map. 293212904Sdim Map[String] = Offset; 294212904Sdim 295212904Sdim // Update the internal length field. 296212904Sdim update_length(); 297212904Sdim 298212904Sdim return Offset; 299212904Sdim} 300212904Sdim 301212904Sdim//------------------------------------------------------------------------------ 302212904Sdim// WinCOFFObjectWriter class implementation 303212904Sdim 304234353SdimWinCOFFObjectWriter::WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, 305234353Sdim raw_ostream &OS) 306212904Sdim : MCObjectWriter(OS, true) 307234353Sdim , TargetObjectWriter(MOTW) { 308212904Sdim memset(&Header, 0, sizeof(Header)); 309212904Sdim 310234353Sdim Header.Machine = TargetObjectWriter->getMachine(); 311212904Sdim} 312212904Sdim 313212904SdimWinCOFFObjectWriter::~WinCOFFObjectWriter() { 314212904Sdim for (symbols::iterator I = Symbols.begin(), E = Symbols.end(); I != E; ++I) 315212904Sdim delete *I; 316212904Sdim for (sections::iterator I = Sections.begin(), E = Sections.end(); I != E; ++I) 317212904Sdim delete *I; 318212904Sdim} 319212904Sdim 320218893SdimCOFFSymbol *WinCOFFObjectWriter::createSymbol(StringRef Name) { 321212904Sdim return createCOFFEntity<COFFSymbol>(Name, Symbols); 322212904Sdim} 323212904Sdim 324218893SdimCOFFSymbol *WinCOFFObjectWriter::GetOrCreateCOFFSymbol(const MCSymbol * Symbol){ 325218893Sdim symbol_map::iterator i = SymbolMap.find(Symbol); 326218893Sdim if (i != SymbolMap.end()) 327218893Sdim return i->second; 328218893Sdim COFFSymbol *RetSymbol 329218893Sdim = createCOFFEntity<COFFSymbol>(Symbol->getName(), Symbols); 330218893Sdim SymbolMap[Symbol] = RetSymbol; 331218893Sdim return RetSymbol; 332218893Sdim} 333218893Sdim 334249423SdimCOFFSection *WinCOFFObjectWriter::createSection(StringRef Name) { 335212904Sdim return createCOFFEntity<COFFSection>(Name, Sections); 336212904Sdim} 337212904Sdim 338212904Sdim/// A template used to lookup or create a symbol/section, and initialize it if 339212904Sdim/// needed. 340212904Sdimtemplate <typename object_t, typename list_t> 341249423Sdimobject_t *WinCOFFObjectWriter::createCOFFEntity(StringRef Name, 342212904Sdim list_t &List) { 343218893Sdim object_t *Object = new object_t(Name); 344212904Sdim 345212904Sdim List.push_back(Object); 346212904Sdim 347212904Sdim return Object; 348212904Sdim} 349212904Sdim 350212904Sdim/// This function takes a section data object from the assembler 351212904Sdim/// and creates the associated COFF section staging object. 352212904Sdimvoid WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) { 353218893Sdim assert(SectionData.getSection().getVariant() == MCSection::SV_COFF 354218893Sdim && "Got non COFF section in the COFF backend!"); 355212904Sdim // FIXME: Not sure how to verify this (at least in a debug build). 356212904Sdim MCSectionCOFF const &Sec = 357212904Sdim static_cast<MCSectionCOFF const &>(SectionData.getSection()); 358212904Sdim 359212904Sdim COFFSection *coff_section = createSection(Sec.getSectionName()); 360212904Sdim COFFSymbol *coff_symbol = createSymbol(Sec.getSectionName()); 361212904Sdim 362218893Sdim coff_section->Symbol = coff_symbol; 363218893Sdim coff_symbol->Section = coff_section; 364212904Sdim coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_STATIC; 365212904Sdim 366212904Sdim // In this case the auxiliary symbol is a Section Definition. 367212904Sdim coff_symbol->Aux.resize(1); 368212904Sdim memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0])); 369212904Sdim coff_symbol->Aux[0].AuxType = ATSectionDefinition; 370212904Sdim coff_symbol->Aux[0].Aux.SectionDefinition.Selection = Sec.getSelection(); 371212904Sdim 372212904Sdim coff_section->Header.Characteristics = Sec.getCharacteristics(); 373212904Sdim 374212904Sdim uint32_t &Characteristics = coff_section->Header.Characteristics; 375212904Sdim switch (SectionData.getAlignment()) { 376212904Sdim case 1: Characteristics |= COFF::IMAGE_SCN_ALIGN_1BYTES; break; 377212904Sdim case 2: Characteristics |= COFF::IMAGE_SCN_ALIGN_2BYTES; break; 378212904Sdim case 4: Characteristics |= COFF::IMAGE_SCN_ALIGN_4BYTES; break; 379212904Sdim case 8: Characteristics |= COFF::IMAGE_SCN_ALIGN_8BYTES; break; 380212904Sdim case 16: Characteristics |= COFF::IMAGE_SCN_ALIGN_16BYTES; break; 381212904Sdim case 32: Characteristics |= COFF::IMAGE_SCN_ALIGN_32BYTES; break; 382212904Sdim case 64: Characteristics |= COFF::IMAGE_SCN_ALIGN_64BYTES; break; 383212904Sdim case 128: Characteristics |= COFF::IMAGE_SCN_ALIGN_128BYTES; break; 384212904Sdim case 256: Characteristics |= COFF::IMAGE_SCN_ALIGN_256BYTES; break; 385212904Sdim case 512: Characteristics |= COFF::IMAGE_SCN_ALIGN_512BYTES; break; 386212904Sdim case 1024: Characteristics |= COFF::IMAGE_SCN_ALIGN_1024BYTES; break; 387212904Sdim case 2048: Characteristics |= COFF::IMAGE_SCN_ALIGN_2048BYTES; break; 388212904Sdim case 4096: Characteristics |= COFF::IMAGE_SCN_ALIGN_4096BYTES; break; 389212904Sdim case 8192: Characteristics |= COFF::IMAGE_SCN_ALIGN_8192BYTES; break; 390212904Sdim default: 391212904Sdim llvm_unreachable("unsupported section alignment"); 392212904Sdim } 393212904Sdim 394212904Sdim // Bind internal COFF section to MC section. 395212904Sdim coff_section->MCData = &SectionData; 396218893Sdim SectionMap[&SectionData.getSection()] = coff_section; 397212904Sdim} 398212904Sdim 399212904Sdim/// This function takes a section data object from the assembler 400212904Sdim/// and creates the associated COFF symbol staging object. 401251662Sdimvoid WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData, 402263508Sdim MCAssembler &Assembler, 403263508Sdim const MCAsmLayout &Layout) { 404251662Sdim MCSymbol const &Symbol = SymbolData.getSymbol(); 405249423Sdim COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&Symbol); 406251662Sdim SymbolMap[&Symbol] = coff_symbol; 407212904Sdim 408218893Sdim if (SymbolData.getFlags() & COFF::SF_WeakExternal) { 409212904Sdim coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL; 410212904Sdim 411249423Sdim if (Symbol.isVariable()) { 412251662Sdim const MCSymbolRefExpr *SymRef = 413251662Sdim dyn_cast<MCSymbolRefExpr>(Symbol.getVariableValue()); 414212904Sdim 415251662Sdim if (!SymRef) 416251662Sdim report_fatal_error("Weak externals may only alias symbols"); 417212904Sdim 418251662Sdim coff_symbol->Other = GetOrCreateCOFFSymbol(&SymRef->getSymbol()); 419218893Sdim } else { 420218893Sdim std::string WeakName = std::string(".weak.") 421249423Sdim + Symbol.getName().str() 422218893Sdim + ".default"; 423218893Sdim COFFSymbol *WeakDefault = createSymbol(WeakName); 424218893Sdim WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE; 425218893Sdim WeakDefault->Data.StorageClass = COFF::IMAGE_SYM_CLASS_EXTERNAL; 426218893Sdim WeakDefault->Data.Type = 0; 427218893Sdim WeakDefault->Data.Value = 0; 428218893Sdim coff_symbol->Other = WeakDefault; 429218893Sdim } 430212904Sdim 431212904Sdim // Setup the Weak External auxiliary symbol. 432212904Sdim coff_symbol->Aux.resize(1); 433212904Sdim memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0])); 434212904Sdim coff_symbol->Aux[0].AuxType = ATWeakExternal; 435212904Sdim coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = 0; 436212904Sdim coff_symbol->Aux[0].Aux.WeakExternal.Characteristics = 437218893Sdim COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY; 438212904Sdim 439251662Sdim coff_symbol->MCData = &SymbolData; 440251662Sdim } else { 441251662Sdim const MCSymbolData &ResSymData = 442251662Sdim Assembler.getSymbolData(Symbol.AliasedSymbol()); 443218893Sdim 444263508Sdim if (Symbol.isVariable()) { 445263508Sdim int64_t Addr; 446263508Sdim if (Symbol.getVariableValue()->EvaluateAsAbsolute(Addr, Layout)) 447263508Sdim coff_symbol->Data.Value = Addr; 448263508Sdim } 449263508Sdim 450251662Sdim coff_symbol->Data.Type = (ResSymData.getFlags() & 0x0000FFFF) >> 0; 451251662Sdim coff_symbol->Data.StorageClass = (ResSymData.getFlags() & 0x00FF0000) >> 16; 452218893Sdim 453251662Sdim // If no storage class was specified in the streamer, define it here. 454251662Sdim if (coff_symbol->Data.StorageClass == 0) { 455251662Sdim bool external = ResSymData.isExternal() || (ResSymData.Fragment == NULL); 456218893Sdim 457251662Sdim coff_symbol->Data.StorageClass = 458251662Sdim external ? COFF::IMAGE_SYM_CLASS_EXTERNAL : COFF::IMAGE_SYM_CLASS_STATIC; 459251662Sdim } 460251662Sdim 461263508Sdim if (Symbol.isAbsolute() || Symbol.AliasedSymbol().isVariable()) 462263508Sdim coff_symbol->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE; 463263508Sdim else if (ResSymData.Fragment != NULL) 464251662Sdim coff_symbol->Section = 465251662Sdim SectionMap[&ResSymData.Fragment->getParent()->getSection()]; 466251662Sdim 467251662Sdim coff_symbol->MCData = &ResSymData; 468251662Sdim } 469212904Sdim} 470212904Sdim 471218893Sdim/// making a section real involves assigned it a number and putting 472218893Sdim/// name into the string table if needed 473218893Sdimvoid WinCOFFObjectWriter::MakeSectionReal(COFFSection &S, size_t Number) { 474218893Sdim if (S.Name.size() > COFF::NameSize) { 475263508Sdim const unsigned Max6DecimalSize = 999999; 476263508Sdim const unsigned Max7DecimalSize = 9999999; 477263508Sdim uint64_t StringTableEntry = Strings.insert(S.Name.c_str()); 478218893Sdim 479263508Sdim if (StringTableEntry <= Max6DecimalSize) { 480263508Sdim std::sprintf(S.Header.Name, "/%d", unsigned(StringTableEntry)); 481263508Sdim } else if (StringTableEntry <= Max7DecimalSize) { 482263508Sdim // With seven digits, we have to skip the terminating null. Because 483263508Sdim // sprintf always appends it, we use a larger temporary buffer. 484263508Sdim char buffer[9] = { }; 485263508Sdim std::sprintf(buffer, "/%d", unsigned(StringTableEntry)); 486263508Sdim std::memcpy(S.Header.Name, buffer, 8); 487263508Sdim } else { 488263508Sdim report_fatal_error("COFF string table is greater than 9,999,999 bytes."); 489263508Sdim } 490218893Sdim } else 491218893Sdim std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size()); 492218893Sdim 493218893Sdim S.Number = Number; 494218893Sdim S.Symbol->Data.SectionNumber = S.Number; 495218893Sdim S.Symbol->Aux[0].Aux.SectionDefinition.Number = S.Number; 496212904Sdim} 497212904Sdim 498218893Sdimvoid WinCOFFObjectWriter::MakeSymbolReal(COFFSymbol &S, size_t Index) { 499218893Sdim if (S.Name.size() > COFF::NameSize) { 500218893Sdim size_t StringTableEntry = Strings.insert(S.Name.c_str()); 501218893Sdim 502218893Sdim S.set_name_offset(StringTableEntry); 503218893Sdim } else 504218893Sdim std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size()); 505218893Sdim S.Index = Index; 506218893Sdim} 507218893Sdim 508212904Sdimbool WinCOFFObjectWriter::ExportSymbol(MCSymbolData const &SymbolData, 509212904Sdim MCAssembler &Asm) { 510212904Sdim // This doesn't seem to be right. Strings referred to from the .data section 511212904Sdim // need symbols so they can be linked to code in the .text section right? 512212904Sdim 513212904Sdim // return Asm.isSymbolLinkerVisible (&SymbolData); 514212904Sdim 515218893Sdim // For now, all non-variable symbols are exported, 516218893Sdim // the linker will sort the rest out for us. 517218893Sdim return SymbolData.isExternal() || !SymbolData.getSymbol().isVariable(); 518212904Sdim} 519212904Sdim 520218893Sdimbool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) { 521218893Sdim return (S->Header.Characteristics 522218893Sdim & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0; 523218893Sdim} 524218893Sdim 525212904Sdim//------------------------------------------------------------------------------ 526212904Sdim// entity writing methods 527212904Sdim 528212904Sdimvoid WinCOFFObjectWriter::WriteFileHeader(const COFF::header &Header) { 529212904Sdim WriteLE16(Header.Machine); 530212904Sdim WriteLE16(Header.NumberOfSections); 531212904Sdim WriteLE32(Header.TimeDateStamp); 532212904Sdim WriteLE32(Header.PointerToSymbolTable); 533212904Sdim WriteLE32(Header.NumberOfSymbols); 534212904Sdim WriteLE16(Header.SizeOfOptionalHeader); 535212904Sdim WriteLE16(Header.Characteristics); 536212904Sdim} 537212904Sdim 538212904Sdimvoid WinCOFFObjectWriter::WriteSymbol(const COFFSymbol *S) { 539212904Sdim WriteBytes(StringRef(S->Data.Name, COFF::NameSize)); 540212904Sdim WriteLE32(S->Data.Value); 541212904Sdim WriteLE16(S->Data.SectionNumber); 542212904Sdim WriteLE16(S->Data.Type); 543212904Sdim Write8(S->Data.StorageClass); 544212904Sdim Write8(S->Data.NumberOfAuxSymbols); 545212904Sdim WriteAuxiliarySymbols(S->Aux); 546212904Sdim} 547212904Sdim 548212904Sdimvoid WinCOFFObjectWriter::WriteAuxiliarySymbols( 549212904Sdim const COFFSymbol::AuxiliarySymbols &S) { 550212904Sdim for(COFFSymbol::AuxiliarySymbols::const_iterator i = S.begin(), e = S.end(); 551212904Sdim i != e; ++i) { 552212904Sdim switch(i->AuxType) { 553212904Sdim case ATFunctionDefinition: 554212904Sdim WriteLE32(i->Aux.FunctionDefinition.TagIndex); 555212904Sdim WriteLE32(i->Aux.FunctionDefinition.TotalSize); 556212904Sdim WriteLE32(i->Aux.FunctionDefinition.PointerToLinenumber); 557212904Sdim WriteLE32(i->Aux.FunctionDefinition.PointerToNextFunction); 558212904Sdim WriteZeros(sizeof(i->Aux.FunctionDefinition.unused)); 559212904Sdim break; 560212904Sdim case ATbfAndefSymbol: 561212904Sdim WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused1)); 562212904Sdim WriteLE16(i->Aux.bfAndefSymbol.Linenumber); 563212904Sdim WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused2)); 564212904Sdim WriteLE32(i->Aux.bfAndefSymbol.PointerToNextFunction); 565212904Sdim WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused3)); 566212904Sdim break; 567212904Sdim case ATWeakExternal: 568212904Sdim WriteLE32(i->Aux.WeakExternal.TagIndex); 569212904Sdim WriteLE32(i->Aux.WeakExternal.Characteristics); 570212904Sdim WriteZeros(sizeof(i->Aux.WeakExternal.unused)); 571212904Sdim break; 572212904Sdim case ATFile: 573212904Sdim WriteBytes(StringRef(reinterpret_cast<const char *>(i->Aux.File.FileName), 574212904Sdim sizeof(i->Aux.File.FileName))); 575212904Sdim break; 576212904Sdim case ATSectionDefinition: 577212904Sdim WriteLE32(i->Aux.SectionDefinition.Length); 578212904Sdim WriteLE16(i->Aux.SectionDefinition.NumberOfRelocations); 579212904Sdim WriteLE16(i->Aux.SectionDefinition.NumberOfLinenumbers); 580212904Sdim WriteLE32(i->Aux.SectionDefinition.CheckSum); 581212904Sdim WriteLE16(i->Aux.SectionDefinition.Number); 582212904Sdim Write8(i->Aux.SectionDefinition.Selection); 583212904Sdim WriteZeros(sizeof(i->Aux.SectionDefinition.unused)); 584212904Sdim break; 585212904Sdim } 586212904Sdim } 587212904Sdim} 588212904Sdim 589212904Sdimvoid WinCOFFObjectWriter::WriteSectionHeader(const COFF::section &S) { 590212904Sdim WriteBytes(StringRef(S.Name, COFF::NameSize)); 591212904Sdim 592212904Sdim WriteLE32(S.VirtualSize); 593212904Sdim WriteLE32(S.VirtualAddress); 594212904Sdim WriteLE32(S.SizeOfRawData); 595212904Sdim WriteLE32(S.PointerToRawData); 596212904Sdim WriteLE32(S.PointerToRelocations); 597212904Sdim WriteLE32(S.PointerToLineNumbers); 598212904Sdim WriteLE16(S.NumberOfRelocations); 599212904Sdim WriteLE16(S.NumberOfLineNumbers); 600212904Sdim WriteLE32(S.Characteristics); 601212904Sdim} 602212904Sdim 603212904Sdimvoid WinCOFFObjectWriter::WriteRelocation(const COFF::relocation &R) { 604212904Sdim WriteLE32(R.VirtualAddress); 605212904Sdim WriteLE32(R.SymbolTableIndex); 606212904Sdim WriteLE16(R.Type); 607212904Sdim} 608212904Sdim 609210006Srdivacky//////////////////////////////////////////////////////////////////////////////// 610210006Srdivacky// MCObjectWriter interface implementations 611210006Srdivacky 612218893Sdimvoid WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, 613218893Sdim const MCAsmLayout &Layout) { 614212904Sdim // "Define" each section & symbol. This creates section & symbol 615218893Sdim // entries in the staging area. 616212904Sdim 617212904Sdim for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e; i++) 618212904Sdim DefineSection(*i); 619212904Sdim 620212904Sdim for (MCAssembler::const_symbol_iterator i = Asm.symbol_begin(), 621263508Sdim e = Asm.symbol_end(); 622263508Sdim i != e; i++) { 623249423Sdim if (ExportSymbol(*i, Asm)) { 624263508Sdim DefineSymbol(*i, Asm, Layout); 625249423Sdim } 626212904Sdim } 627210006Srdivacky} 628210006Srdivacky 629210006Srdivackyvoid WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, 630210006Srdivacky const MCAsmLayout &Layout, 631210006Srdivacky const MCFragment *Fragment, 632210006Srdivacky const MCFixup &Fixup, 633210006Srdivacky MCValue Target, 634210006Srdivacky uint64_t &FixedValue) { 635212904Sdim assert(Target.getSymA() != NULL && "Relocation must reference a symbol!"); 636212904Sdim 637263508Sdim const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 638263508Sdim const MCSymbol &A = Symbol.AliasedSymbol(); 639263508Sdim MCSymbolData &A_SD = Asm.getSymbolData(A); 640212904Sdim 641212904Sdim MCSectionData const *SectionData = Fragment->getParent(); 642212904Sdim 643212904Sdim // Mark this symbol as requiring an entry in the symbol table. 644218893Sdim assert(SectionMap.find(&SectionData->getSection()) != SectionMap.end() && 645212904Sdim "Section must already have been defined in ExecutePostLayoutBinding!"); 646218893Sdim assert(SymbolMap.find(&A_SD.getSymbol()) != SymbolMap.end() && 647212904Sdim "Symbol must already have been defined in ExecutePostLayoutBinding!"); 648212904Sdim 649218893Sdim COFFSection *coff_section = SectionMap[&SectionData->getSection()]; 650218893Sdim COFFSymbol *coff_symbol = SymbolMap[&A_SD.getSymbol()]; 651221345Sdim const MCSymbolRefExpr *SymA = Target.getSymA(); 652221345Sdim const MCSymbolRefExpr *SymB = Target.getSymB(); 653221345Sdim const bool CrossSection = SymB && 654221345Sdim &SymA->getSymbol().getSection() != &SymB->getSymbol().getSection(); 655212904Sdim 656212904Sdim if (Target.getSymB()) { 657212904Sdim const MCSymbol *B = &Target.getSymB()->getSymbol(); 658212904Sdim MCSymbolData &B_SD = Asm.getSymbolData(*B); 659212904Sdim 660221345Sdim // Offset of the symbol in the section 661221345Sdim int64_t a = Layout.getSymbolOffset(&B_SD); 662212904Sdim 663221345Sdim // Ofeset of the relocation in the section 664221345Sdim int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); 665221345Sdim 666221345Sdim FixedValue = b - a; 667212904Sdim // In the case where we have SymbA and SymB, we just need to store the delta 668212904Sdim // between the two symbols. Update FixedValue to account for the delta, and 669212904Sdim // skip recording the relocation. 670221345Sdim if (!CrossSection) 671221345Sdim return; 672212904Sdim } else { 673212904Sdim FixedValue = Target.getConstant(); 674212904Sdim } 675212904Sdim 676212904Sdim COFFRelocation Reloc; 677212904Sdim 678212904Sdim Reloc.Data.SymbolTableIndex = 0; 679212904Sdim Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment); 680212904Sdim 681218893Sdim // Turn relocations for temporary symbols into section relocations. 682221345Sdim if (coff_symbol->MCData->getSymbol().isTemporary() || CrossSection) { 683218893Sdim Reloc.Symb = coff_symbol->Section->Symbol; 684218893Sdim FixedValue += Layout.getFragmentOffset(coff_symbol->MCData->Fragment) 685218893Sdim + coff_symbol->MCData->getOffset(); 686218893Sdim } else 687218893Sdim Reloc.Symb = coff_symbol; 688218893Sdim 689218893Sdim ++Reloc.Symb->Relocations; 690218893Sdim 691212904Sdim Reloc.Data.VirtualAddress += Fixup.getOffset(); 692251662Sdim Reloc.Data.Type = TargetObjectWriter->getRelocType(Target, Fixup, 693251662Sdim CrossSection); 694212904Sdim 695234353Sdim // FIXME: Can anyone explain what this does other than adjust for the size 696234353Sdim // of the offset? 697234353Sdim if (Reloc.Data.Type == COFF::IMAGE_REL_AMD64_REL32 || 698234353Sdim Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32) 699212904Sdim FixedValue += 4; 700212904Sdim 701212904Sdim coff_section->Relocations.push_back(Reloc); 702210006Srdivacky} 703210006Srdivacky 704218893Sdimvoid WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, 705210006Srdivacky const MCAsmLayout &Layout) { 706212904Sdim // Assign symbol and section indexes and offsets. 707218893Sdim Header.NumberOfSections = 0; 708212904Sdim 709263508Sdim DenseMap<COFFSection *, uint16_t> SectionIndices; 710218893Sdim for (sections::iterator i = Sections.begin(), 711218893Sdim e = Sections.end(); i != e; i++) { 712218893Sdim if (Layout.getSectionAddressSize((*i)->MCData) > 0) { 713263508Sdim size_t Number = ++Header.NumberOfSections; 714263508Sdim SectionIndices[*i] = Number; 715263508Sdim MakeSectionReal(**i, Number); 716218893Sdim } else { 717218893Sdim (*i)->Number = -1; 718218893Sdim } 719218893Sdim } 720218893Sdim 721212904Sdim Header.NumberOfSymbols = 0; 722212904Sdim 723212904Sdim for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) { 724212904Sdim COFFSymbol *coff_symbol = *i; 725212904Sdim MCSymbolData const *SymbolData = coff_symbol->MCData; 726212904Sdim 727212904Sdim // Update section number & offset for symbols that have them. 728212904Sdim if ((SymbolData != NULL) && (SymbolData->Fragment != NULL)) { 729218893Sdim assert(coff_symbol->Section != NULL); 730212904Sdim 731218893Sdim coff_symbol->Data.SectionNumber = coff_symbol->Section->Number; 732212904Sdim coff_symbol->Data.Value = Layout.getFragmentOffset(SymbolData->Fragment) 733212904Sdim + SymbolData->Offset; 734212904Sdim } 735212904Sdim 736218893Sdim if (coff_symbol->should_keep()) { 737218893Sdim MakeSymbolReal(*coff_symbol, Header.NumberOfSymbols++); 738218893Sdim 739218893Sdim // Update auxiliary symbol info. 740218893Sdim coff_symbol->Data.NumberOfAuxSymbols = coff_symbol->Aux.size(); 741218893Sdim Header.NumberOfSymbols += coff_symbol->Data.NumberOfAuxSymbols; 742218893Sdim } else 743218893Sdim coff_symbol->Index = -1; 744212904Sdim } 745212904Sdim 746212904Sdim // Fixup weak external references. 747212904Sdim for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) { 748218893Sdim COFFSymbol *coff_symbol = *i; 749218893Sdim if (coff_symbol->Other != NULL) { 750218893Sdim assert(coff_symbol->Index != -1); 751218893Sdim assert(coff_symbol->Aux.size() == 1 && 752212904Sdim "Symbol must contain one aux symbol!"); 753218893Sdim assert(coff_symbol->Aux[0].AuxType == ATWeakExternal && 754212904Sdim "Symbol's aux symbol must be a Weak External!"); 755218893Sdim coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = coff_symbol->Other->Index; 756212904Sdim } 757212904Sdim } 758212904Sdim 759263508Sdim // Fixup associative COMDAT sections. 760263508Sdim for (sections::iterator i = Sections.begin(), 761263508Sdim e = Sections.end(); i != e; i++) { 762263508Sdim if ((*i)->Symbol->Aux[0].Aux.SectionDefinition.Selection != 763263508Sdim COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) 764263508Sdim continue; 765263508Sdim 766263508Sdim const MCSectionCOFF &MCSec = static_cast<const MCSectionCOFF &>( 767263508Sdim (*i)->MCData->getSection()); 768263508Sdim 769263508Sdim COFFSection *Assoc = SectionMap.lookup(MCSec.getAssocSection()); 770263508Sdim if (!Assoc) { 771263508Sdim report_fatal_error(Twine("Missing associated COMDAT section ") + 772263508Sdim MCSec.getAssocSection()->getSectionName() + 773263508Sdim " for section " + MCSec.getSectionName()); 774263508Sdim } 775263508Sdim 776263508Sdim // Skip this section if the associated section is unused. 777263508Sdim if (Assoc->Number == -1) 778263508Sdim continue; 779263508Sdim 780263508Sdim (*i)->Symbol->Aux[0].Aux.SectionDefinition.Number = SectionIndices[Assoc]; 781263508Sdim } 782263508Sdim 783263508Sdim 784212904Sdim // Assign file offsets to COFF object file structures. 785212904Sdim 786212904Sdim unsigned offset = 0; 787212904Sdim 788212904Sdim offset += COFF::HeaderSize; 789218893Sdim offset += COFF::SectionSize * Header.NumberOfSections; 790212904Sdim 791212904Sdim for (MCAssembler::const_iterator i = Asm.begin(), 792212904Sdim e = Asm.end(); 793212904Sdim i != e; i++) { 794218893Sdim COFFSection *Sec = SectionMap[&i->getSection()]; 795212904Sdim 796218893Sdim if (Sec->Number == -1) 797218893Sdim continue; 798212904Sdim 799218893Sdim Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(i); 800218893Sdim 801218893Sdim if (IsPhysicalSection(Sec)) { 802212904Sdim Sec->Header.PointerToRawData = offset; 803212904Sdim 804212904Sdim offset += Sec->Header.SizeOfRawData; 805212904Sdim } 806212904Sdim 807212904Sdim if (Sec->Relocations.size() > 0) { 808234353Sdim bool RelocationsOverflow = Sec->Relocations.size() >= 0xffff; 809234353Sdim 810234353Sdim if (RelocationsOverflow) { 811234353Sdim // Signal overflow by setting NumberOfSections to max value. Actual 812234353Sdim // size is found in reloc #0. Microsoft tools understand this. 813234353Sdim Sec->Header.NumberOfRelocations = 0xffff; 814234353Sdim } else { 815234353Sdim Sec->Header.NumberOfRelocations = Sec->Relocations.size(); 816234353Sdim } 817212904Sdim Sec->Header.PointerToRelocations = offset; 818212904Sdim 819234353Sdim if (RelocationsOverflow) { 820234353Sdim // Reloc #0 will contain actual count, so make room for it. 821234353Sdim offset += COFF::RelocationSize; 822234353Sdim } 823234353Sdim 824212904Sdim offset += COFF::RelocationSize * Sec->Relocations.size(); 825212904Sdim 826212904Sdim for (relocations::iterator cr = Sec->Relocations.begin(), 827212904Sdim er = Sec->Relocations.end(); 828218893Sdim cr != er; ++cr) { 829218893Sdim assert((*cr).Symb->Index != -1); 830212904Sdim (*cr).Data.SymbolTableIndex = (*cr).Symb->Index; 831212904Sdim } 832212904Sdim } 833212904Sdim 834218893Sdim assert(Sec->Symbol->Aux.size() == 1 835218893Sdim && "Section's symbol must have one aux!"); 836218893Sdim AuxSymbol &Aux = Sec->Symbol->Aux[0]; 837212904Sdim assert(Aux.AuxType == ATSectionDefinition && 838212904Sdim "Section's symbol's aux symbol must be a Section Definition!"); 839212904Sdim Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData; 840212904Sdim Aux.Aux.SectionDefinition.NumberOfRelocations = 841212904Sdim Sec->Header.NumberOfRelocations; 842212904Sdim Aux.Aux.SectionDefinition.NumberOfLinenumbers = 843212904Sdim Sec->Header.NumberOfLineNumbers; 844212904Sdim } 845212904Sdim 846212904Sdim Header.PointerToSymbolTable = offset; 847212904Sdim 848212904Sdim Header.TimeDateStamp = sys::TimeValue::now().toEpochTime(); 849212904Sdim 850212904Sdim // Write it all to disk... 851212904Sdim WriteFileHeader(Header); 852212904Sdim 853212904Sdim { 854212904Sdim sections::iterator i, ie; 855212904Sdim MCAssembler::const_iterator j, je; 856212904Sdim 857212904Sdim for (i = Sections.begin(), ie = Sections.end(); i != ie; i++) 858234353Sdim if ((*i)->Number != -1) { 859234353Sdim if ((*i)->Relocations.size() >= 0xffff) { 860234353Sdim (*i)->Header.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL; 861234353Sdim } 862218893Sdim WriteSectionHeader((*i)->Header); 863234353Sdim } 864212904Sdim 865212904Sdim for (i = Sections.begin(), ie = Sections.end(), 866212904Sdim j = Asm.begin(), je = Asm.end(); 867218893Sdim (i != ie) && (j != je); ++i, ++j) { 868218893Sdim 869218893Sdim if ((*i)->Number == -1) 870218893Sdim continue; 871218893Sdim 872212904Sdim if ((*i)->Header.PointerToRawData != 0) { 873212904Sdim assert(OS.tell() == (*i)->Header.PointerToRawData && 874212904Sdim "Section::PointerToRawData is insane!"); 875212904Sdim 876234353Sdim Asm.writeSectionData(j, Layout); 877212904Sdim } 878212904Sdim 879212904Sdim if ((*i)->Relocations.size() > 0) { 880212904Sdim assert(OS.tell() == (*i)->Header.PointerToRelocations && 881212904Sdim "Section::PointerToRelocations is insane!"); 882212904Sdim 883234353Sdim if ((*i)->Relocations.size() >= 0xffff) { 884234353Sdim // In case of overflow, write actual relocation count as first 885234353Sdim // relocation. Including the synthetic reloc itself (+ 1). 886234353Sdim COFF::relocation r; 887234353Sdim r.VirtualAddress = (*i)->Relocations.size() + 1; 888234353Sdim r.SymbolTableIndex = 0; 889234353Sdim r.Type = 0; 890234353Sdim WriteRelocation(r); 891234353Sdim } 892234353Sdim 893212904Sdim for (relocations::const_iterator k = (*i)->Relocations.begin(), 894212904Sdim ke = (*i)->Relocations.end(); 895212904Sdim k != ke; k++) { 896212904Sdim WriteRelocation(k->Data); 897212904Sdim } 898212904Sdim } else 899212904Sdim assert((*i)->Header.PointerToRelocations == 0 && 900212904Sdim "Section::PointerToRelocations is insane!"); 901212904Sdim } 902212904Sdim } 903212904Sdim 904212904Sdim assert(OS.tell() == Header.PointerToSymbolTable && 905212904Sdim "Header::PointerToSymbolTable is insane!"); 906212904Sdim 907212904Sdim for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) 908218893Sdim if ((*i)->Index != -1) 909218893Sdim WriteSymbol(*i); 910212904Sdim 911212904Sdim OS.write((char const *)&Strings.Data.front(), Strings.Data.size()); 912210006Srdivacky} 913210006Srdivacky 914234353SdimMCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_) : 915234353Sdim Machine(Machine_) { 916234353Sdim} 917234353Sdim 918263508Sdim// Pin the vtable to this file. 919263508Sdimvoid MCWinCOFFObjectTargetWriter::anchor() {} 920263508Sdim 921210006Srdivacky//------------------------------------------------------------------------------ 922210006Srdivacky// WinCOFFObjectWriter factory function 923210006Srdivacky 924210006Srdivackynamespace llvm { 925234353Sdim MCObjectWriter *createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, 926234353Sdim raw_ostream &OS) { 927234353Sdim return new WinCOFFObjectWriter(MOTW, OS); 928210006Srdivacky } 929210006Srdivacky} 930