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