1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===-- llvm/MC/WinCOFFObjectWriter.cpp -------------------------*- C++ -*-===//
2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//                     The LLVM Compiler Infrastructure
4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source
6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details.
7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file contains an implementation of a Win32 COFF object file writer.
11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#define DEBUG_TYPE "WinCOFFObjectWriter"
15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCObjectWriter.h"
17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCSection.h"
18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCContext.h"
19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCSymbol.h"
20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCExpr.h"
21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCValue.h"
22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCAssembler.h"
23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCAsmLayout.h"
24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCSectionCOFF.h"
25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/DenseMap.h"
27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/StringMap.h"
28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/StringRef.h"
29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/COFF.h"
31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/Debug.h"
32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/ErrorHandling.h"
33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/TimeValue.h"
3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "../Target/X86/MCTargetDesc/X86FixupKinds.h"
37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include <cstdio>
39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm;
41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace {
43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantypedef llvm::SmallString<COFF::NameSize> name;
44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanenum AuxiliaryType {
46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ATFunctionDefinition,
47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ATbfAndefSymbol,
48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ATWeakExternal,
49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ATFile,
50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ATSectionDefinition
51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstruct AuxSymbol {
54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  AuxiliaryType   AuxType;
55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  COFF::Auxiliary Aux;
56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanclass COFFSymbol;
5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanclass COFFSection;
6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass COFFSymbol {
62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  COFF::symbol Data;
64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  typedef llvm::SmallVector<AuxSymbol, 1> AuxiliarySymbols;
66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  name             Name;
6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int              Index;
69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  AuxiliarySymbols Aux;
70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  COFFSymbol      *Other;
7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  COFFSection     *Section;
7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int              Relocations;
73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  MCSymbolData const *MCData;
75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  COFFSymbol(llvm::StringRef name);
77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  size_t size() const;
78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void set_name_offset(uint32_t Offset);
7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool should_keep() const;
81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This class contains staging data for a COFF relocation entry.
84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstruct COFFRelocation {
85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  COFF::relocation Data;
86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  COFFSymbol          *Symb;
87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  COFFRelocation() : Symb(NULL) {}
89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static size_t size() { return COFF::RelocationSize; }
90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantypedef std::vector<COFFRelocation> relocations;
93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass COFFSection {
95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  COFF::section Header;
97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  std::string          Name;
9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int                  Number;
100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  MCSectionData const *MCData;
10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  COFFSymbol          *Symbol;
102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  relocations          Relocations;
103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  COFFSection(llvm::StringRef name);
105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static size_t size();
106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This class holds the COFF string table.
109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass StringTable {
110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  typedef llvm::StringMap<size_t> map;
111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  map Map;
112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void update_length();
114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  std::vector<char> Data;
116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  StringTable();
118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  size_t size() const;
119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  size_t insert(llvm::StringRef String);
120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass WinCOFFObjectWriter : public MCObjectWriter {
123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  typedef std::vector<COFFSymbol*>  symbols;
126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  typedef std::vector<COFFSection*> sections;
127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  typedef DenseMap<MCSymbol  const *, COFFSymbol *>   symbol_map;
12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  typedef DenseMap<MCSection const *, COFFSection *> section_map;
130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Root level file contents.
13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool Is64Bit;
133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  COFF::header Header;
134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  sections     Sections;
135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  symbols      Symbols;
136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  StringTable  Strings;
137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Maps used during object file creation.
139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  section_map SectionMap;
140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  symbol_map  SymbolMap;
141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WinCOFFObjectWriter(raw_ostream &OS, bool is64Bit);
143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ~WinCOFFObjectWriter();
144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  COFFSymbol *createSymbol(StringRef Name);
14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  COFFSymbol *GetOrCreateCOFFSymbol(const MCSymbol * Symbol);
14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  COFFSection *createSection(StringRef Name);
148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  template <typename object_t, typename list_t>
150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  object_t *createCOFFEntity(llvm::StringRef Name, list_t &List);
151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void DefineSection(MCSectionData const &SectionData);
153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void DefineSymbol(MCSymbolData const &SymbolData, MCAssembler &Assembler);
154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  void MakeSymbolReal(COFFSymbol &S, size_t Index);
15619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  void MakeSectionReal(COFFSection &S, size_t Number);
15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
15819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool ExportSection(COFFSection const *S);
159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool ExportSymbol(MCSymbolData const &SymbolData, MCAssembler &Asm);
160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
16119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool IsPhysicalSection(COFFSection *S);
16219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Entity writing methods.
164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void WriteFileHeader(const COFF::header &Header);
166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void WriteSymbol(const COFFSymbol *S);
167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols &S);
168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void WriteSectionHeader(const COFF::section &S);
169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void WriteRelocation(const COFF::relocation &R);
170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // MCObjectWriter interface implementation.
172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout);
174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void RecordRelocation(const MCAssembler &Asm,
176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                        const MCAsmLayout &Layout,
177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                        const MCFragment *Fragment,
178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                        const MCFixup &Fixup,
179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                        MCValue Target,
180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                        uint64_t &FixedValue);
181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
18219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic inline void write_uint32_le(void *Data, uint32_t const &Value) {
187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  uint8_t *Ptr = reinterpret_cast<uint8_t *>(Data);
188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Ptr[0] = (Value & 0x000000FF) >>  0;
189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Ptr[1] = (Value & 0x0000FF00) >>  8;
190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Ptr[2] = (Value & 0x00FF0000) >> 16;
191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Ptr[3] = (Value & 0xFF000000) >> 24;
192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic inline void write_uint16_le(void *Data, uint16_t const &Value) {
195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  uint8_t *Ptr = reinterpret_cast<uint8_t *>(Data);
196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Ptr[0] = (Value & 0x00FF) >> 0;
197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Ptr[1] = (Value & 0xFF00) >> 8;
198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic inline void write_uint8_le(void *Data, uint8_t const &Value) {
201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  uint8_t *Ptr = reinterpret_cast<uint8_t *>(Data);
202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Ptr[0] = (Value & 0xFF) >> 0;
203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//------------------------------------------------------------------------------
206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Symbol class implementation
207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanCOFFSymbol::COFFSymbol(llvm::StringRef name)
20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : Name(name.begin(), name.end())
21019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  , Other(NULL)
21119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  , Section(NULL)
21219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  , Relocations(0)
21319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  , MCData(NULL) {
214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  memset(&Data, 0, sizeof(Data));
215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumansize_t COFFSymbol::size() const {
218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return COFF::SymbolSize + (Data.NumberOfAuxSymbols * COFF::SymbolSize);
219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// In the case that the name does not fit within 8 bytes, the offset
222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// into the string table is stored in the last 4 bytes instead, leaving
223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// the first 4 bytes as 0.
224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid COFFSymbol::set_name_offset(uint32_t Offset) {
225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  write_uint32_le(Data.Name + 0, 0);
226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  write_uint32_le(Data.Name + 4, Offset);
227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
22919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// logic to decide if the symbol should be reported in the symbol table
23019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool COFFSymbol::should_keep() const {
23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // no section means its external, keep it
23219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Section == NULL)
23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
23419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
23519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // if it has relocations pointing at it, keep it
23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Relocations > 0)   {
23719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    assert(Section->Number != -1 && "Sections with relocations must be real!");
23819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
23919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
24019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
24119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // if the section its in is being droped, drop it
24219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Section->Number == -1)
24319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
24419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
24519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // if it is the section symbol, keep it
24619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Section->Symbol == this)
24719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
24819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
24919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // if its temporary, drop it
25019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (MCData && MCData->getSymbol().isTemporary())
25119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
25219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
25319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // otherwise, keep it
25419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
25519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
25619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//------------------------------------------------------------------------------
258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Section class implementation
259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
26019bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanCOFFSection::COFFSection(llvm::StringRef name)
26119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : Name(name)
26219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  , MCData(NULL)
26319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  , Symbol(NULL) {
264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  memset(&Header, 0, sizeof(Header));
265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumansize_t COFFSection::size() {
268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return COFF::SectionSize;
269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//------------------------------------------------------------------------------
272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// StringTable class implementation
273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Write the length of the string table into Data.
275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// The length of the string table includes uint32 length header.
276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid StringTable::update_length() {
277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  write_uint32_le(&Data.front(), Data.size());
278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanStringTable::StringTable() {
281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // The string table data begins with the length of the entire string table
282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // including the length header. Allocate space for this header.
283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Data.resize(4);
284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumansize_t StringTable::size() const {
287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return Data.size();
288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Add String to the table iff it is not already there.
291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// @returns the index into the string table where the string is now located.
292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumansize_t StringTable::insert(llvm::StringRef String) {
293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  map::iterator i = Map.find(String);
294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (i != Map.end())
296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return i->second;
297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  size_t Offset = Data.size();
299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Insert string data into string table.
301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Data.insert(Data.end(), String.begin(), String.end());
302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Data.push_back('\0');
303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Put a reference to it in the map.
305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Map[String] = Offset;
306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Update the internal length field.
308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  update_length();
309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return Offset;
311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//------------------------------------------------------------------------------
314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// WinCOFFObjectWriter class implementation
315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
31619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanWinCOFFObjectWriter::WinCOFFObjectWriter(raw_ostream &OS, bool is64Bit)
31719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  : MCObjectWriter(OS, true)
31819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  , Is64Bit(is64Bit) {
319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  memset(&Header, 0, sizeof(Header));
32019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
32119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Is64Bit ? Header.Machine = COFF::IMAGE_FILE_MACHINE_AMD64
32219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          : Header.Machine = COFF::IMAGE_FILE_MACHINE_I386;
323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanWinCOFFObjectWriter::~WinCOFFObjectWriter() {
326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (symbols::iterator I = Symbols.begin(), E = Symbols.end(); I != E; ++I)
327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    delete *I;
328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (sections::iterator I = Sections.begin(), E = Sections.end(); I != E; ++I)
329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    delete *I;
330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
33219bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanCOFFSymbol *WinCOFFObjectWriter::createSymbol(StringRef Name) {
333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return createCOFFEntity<COFFSymbol>(Name, Symbols);
334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
33619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanCOFFSymbol *WinCOFFObjectWriter::GetOrCreateCOFFSymbol(const MCSymbol * Symbol){
33719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  symbol_map::iterator i = SymbolMap.find(Symbol);
33819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (i != SymbolMap.end())
33919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return i->second;
34019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  COFFSymbol *RetSymbol
34119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    = createCOFFEntity<COFFSymbol>(Symbol->getName(), Symbols);
34219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SymbolMap[Symbol] = RetSymbol;
34319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return RetSymbol;
344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
345894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
34619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanCOFFSection *WinCOFFObjectWriter::createSection(llvm::StringRef Name) {
34719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return createCOFFEntity<COFFSection>(Name, Sections);
348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// A template used to lookup or create a symbol/section, and initialize it if
351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// needed.
352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate <typename object_t, typename list_t>
353894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanobject_t *WinCOFFObjectWriter::createCOFFEntity(llvm::StringRef Name,
354894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                                list_t &List) {
35519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  object_t *Object = new object_t(Name);
356894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
357894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  List.push_back(Object);
358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return Object;
360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// This function takes a section data object from the assembler
363894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// and creates the associated COFF section staging object.
364894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) {
36519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(SectionData.getSection().getVariant() == MCSection::SV_COFF
36619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    && "Got non COFF section in the COFF backend!");
367894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // FIXME: Not sure how to verify this (at least in a debug build).
368894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  MCSectionCOFF const &Sec =
369894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    static_cast<MCSectionCOFF const &>(SectionData.getSection());
370894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  COFFSection *coff_section = createSection(Sec.getSectionName());
372894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  COFFSymbol  *coff_symbol = createSymbol(Sec.getSectionName());
373894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
37419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  coff_section->Symbol = coff_symbol;
37519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  coff_symbol->Section = coff_section;
376894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_STATIC;
377894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // In this case the auxiliary symbol is a Section Definition.
379894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  coff_symbol->Aux.resize(1);
380894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0]));
381894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  coff_symbol->Aux[0].AuxType = ATSectionDefinition;
382894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  coff_symbol->Aux[0].Aux.SectionDefinition.Selection = Sec.getSelection();
383894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
384894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  coff_section->Header.Characteristics = Sec.getCharacteristics();
385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
386894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  uint32_t &Characteristics = coff_section->Header.Characteristics;
387894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  switch (SectionData.getAlignment()) {
388894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case 1:    Characteristics |= COFF::IMAGE_SCN_ALIGN_1BYTES;    break;
389894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case 2:    Characteristics |= COFF::IMAGE_SCN_ALIGN_2BYTES;    break;
390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case 4:    Characteristics |= COFF::IMAGE_SCN_ALIGN_4BYTES;    break;
391894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case 8:    Characteristics |= COFF::IMAGE_SCN_ALIGN_8BYTES;    break;
392894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case 16:   Characteristics |= COFF::IMAGE_SCN_ALIGN_16BYTES;   break;
393894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case 32:   Characteristics |= COFF::IMAGE_SCN_ALIGN_32BYTES;   break;
394894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case 64:   Characteristics |= COFF::IMAGE_SCN_ALIGN_64BYTES;   break;
395894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case 128:  Characteristics |= COFF::IMAGE_SCN_ALIGN_128BYTES;  break;
396894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case 256:  Characteristics |= COFF::IMAGE_SCN_ALIGN_256BYTES;  break;
397894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case 512:  Characteristics |= COFF::IMAGE_SCN_ALIGN_512BYTES;  break;
398894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case 1024: Characteristics |= COFF::IMAGE_SCN_ALIGN_1024BYTES; break;
399894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case 2048: Characteristics |= COFF::IMAGE_SCN_ALIGN_2048BYTES; break;
400894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case 4096: Characteristics |= COFF::IMAGE_SCN_ALIGN_4096BYTES; break;
401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case 8192: Characteristics |= COFF::IMAGE_SCN_ALIGN_8192BYTES; break;
402894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  default:
403894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    llvm_unreachable("unsupported section alignment");
404894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
405894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Bind internal COFF section to MC section.
407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  coff_section->MCData = &SectionData;
40819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SectionMap[&SectionData.getSection()] = coff_section;
409894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
410894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
411894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// This function takes a section data object from the assembler
412894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// and creates the associated COFF symbol staging object.
413894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
41419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       MCAssembler &Assembler) {
41519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&SymbolData.getSymbol());
416894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
417894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  coff_symbol->Data.Type         = (SymbolData.getFlags() & 0x0000FFFF) >>  0;
418894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  coff_symbol->Data.StorageClass = (SymbolData.getFlags() & 0x00FF0000) >> 16;
419894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
42019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (SymbolData.getFlags() & COFF::SF_WeakExternal) {
42119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
42219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
42319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (SymbolData.getSymbol().isVariable()) {
42419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
42519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const MCExpr *Value = SymbolData.getSymbol().getVariableValue();
42619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
42719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // FIXME: This assert message isn't very good.
42819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert(Value->getKind() == MCExpr::SymbolRef &&
42919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              "Value must be a SymbolRef!");
43019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
43119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const MCSymbolRefExpr *SymbolRef =
43219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        static_cast<const MCSymbolRefExpr *>(Value);
43319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      coff_symbol->Other = GetOrCreateCOFFSymbol(&SymbolRef->getSymbol());
43419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else {
43519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      std::string WeakName = std::string(".weak.")
43619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           +  SymbolData.getSymbol().getName().str()
43719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           + ".default";
43819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      COFFSymbol *WeakDefault = createSymbol(WeakName);
43919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
44019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      WeakDefault->Data.StorageClass  = COFF::IMAGE_SYM_CLASS_EXTERNAL;
44119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      WeakDefault->Data.Type          = 0;
44219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      WeakDefault->Data.Value         = 0;
44319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      coff_symbol->Other = WeakDefault;
44419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
44519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
44619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Setup the Weak External auxiliary symbol.
44719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    coff_symbol->Aux.resize(1);
44819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0]));
44919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    coff_symbol->Aux[0].AuxType = ATWeakExternal;
45019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = 0;
45119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    coff_symbol->Aux[0].Aux.WeakExternal.Characteristics =
45219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY;
45319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
45419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
455894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // If no storage class was specified in the streamer, define it here.
456894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (coff_symbol->Data.StorageClass == 0) {
457894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    bool external = SymbolData.isExternal() || (SymbolData.Fragment == NULL);
458894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
459894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    coff_symbol->Data.StorageClass =
460894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      external ? COFF::IMAGE_SYM_CLASS_EXTERNAL : COFF::IMAGE_SYM_CLASS_STATIC;
461894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
462894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
46319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (SymbolData.Fragment != NULL)
46419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    coff_symbol->Section =
46519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      SectionMap[&SymbolData.Fragment->getParent()->getSection()];
466894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
46719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Bind internal COFF symbol to MC symbol.
46819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  coff_symbol->MCData = &SymbolData;
46919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SymbolMap[&SymbolData.getSymbol()] = coff_symbol;
47019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
471894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
47219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// making a section real involves assigned it a number and putting
47319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// name into the string table if needed
47419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid WinCOFFObjectWriter::MakeSectionReal(COFFSection &S, size_t Number) {
47519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (S.Name.size() > COFF::NameSize) {
47619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    size_t StringTableEntry = Strings.insert(S.Name.c_str());
477894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
47819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // FIXME: Why is this number 999999? This number is never mentioned in the
47919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // spec. I'm assuming this is due to the printed value needing to fit into
48019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // the S.Header.Name field. In which case why not 9999999 (7 9's instead of
48119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // 6)? The spec does not state if this entry should be null terminated in
48219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // this case, and thus this seems to be the best way to do it. I think I
48319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // just solved my own FIXME...
48419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (StringTableEntry > 999999)
48519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      report_fatal_error("COFF string table is greater than 999999 bytes.");
486894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
48767a940b4a58b5a3578d7b2e04d559cb31525dfa8Ping-Hao Wu#if defined(__ANDROID__) || defined(ANDROID)
48867a940b4a58b5a3578d7b2e04d559cb31525dfa8Ping-Hao Wu    // bionic defines sprintf as __builtin___sprintf_chk, which is not available
48967a940b4a58b5a3578d7b2e04d559cb31525dfa8Ping-Hao Wu    // in std.
49067a940b4a58b5a3578d7b2e04d559cb31525dfa8Ping-Hao Wu    sprintf(S.Header.Name, "/%d", unsigned(StringTableEntry));
49167a940b4a58b5a3578d7b2e04d559cb31525dfa8Ping-Hao Wu#else
49219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::sprintf(S.Header.Name, "/%d", unsigned(StringTableEntry));
49367a940b4a58b5a3578d7b2e04d559cb31525dfa8Ping-Hao Wu#endif
49419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else
49519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size());
496894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
49719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  S.Number = Number;
49819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  S.Symbol->Data.SectionNumber = S.Number;
49919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  S.Symbol->Aux[0].Aux.SectionDefinition.Number = S.Number;
50019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
501894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
50219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid WinCOFFObjectWriter::MakeSymbolReal(COFFSymbol &S, size_t Index) {
50319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (S.Name.size() > COFF::NameSize) {
50419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    size_t StringTableEntry = Strings.insert(S.Name.c_str());
505894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
50619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    S.set_name_offset(StringTableEntry);
50719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else
50819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size());
50919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  S.Index = Index;
510894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
511894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
51219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool WinCOFFObjectWriter::ExportSection(COFFSection const *S) {
51319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return !S->MCData->getFragmentList().empty();
514894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
515894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
516894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool WinCOFFObjectWriter::ExportSymbol(MCSymbolData const &SymbolData,
517894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                       MCAssembler &Asm) {
518894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // This doesn't seem to be right. Strings referred to from the .data section
519894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // need symbols so they can be linked to code in the .text section right?
520894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // return Asm.isSymbolLinkerVisible (&SymbolData);
522894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
52319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // For now, all non-variable symbols are exported,
52419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // the linker will sort the rest out for us.
52519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return SymbolData.isExternal() || !SymbolData.getSymbol().isVariable();
52619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
52719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
52819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) {
52919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return (S->Header.Characteristics
53019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0;
531894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
532894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
533894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//------------------------------------------------------------------------------
534894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// entity writing methods
535894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
536894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid WinCOFFObjectWriter::WriteFileHeader(const COFF::header &Header) {
537894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE16(Header.Machine);
538894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE16(Header.NumberOfSections);
539894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE32(Header.TimeDateStamp);
540894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE32(Header.PointerToSymbolTable);
541894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE32(Header.NumberOfSymbols);
542894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE16(Header.SizeOfOptionalHeader);
543894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE16(Header.Characteristics);
544894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
545894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
546894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid WinCOFFObjectWriter::WriteSymbol(const COFFSymbol *S) {
547894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteBytes(StringRef(S->Data.Name, COFF::NameSize));
548894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE32(S->Data.Value);
549894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE16(S->Data.SectionNumber);
550894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE16(S->Data.Type);
551894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Write8(S->Data.StorageClass);
552894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Write8(S->Data.NumberOfAuxSymbols);
553894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteAuxiliarySymbols(S->Aux);
554894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
555894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
556894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid WinCOFFObjectWriter::WriteAuxiliarySymbols(
557894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                        const COFFSymbol::AuxiliarySymbols &S) {
558894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for(COFFSymbol::AuxiliarySymbols::const_iterator i = S.begin(), e = S.end();
559894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      i != e; ++i) {
560894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    switch(i->AuxType) {
561894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case ATFunctionDefinition:
562894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      WriteLE32(i->Aux.FunctionDefinition.TagIndex);
563894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      WriteLE32(i->Aux.FunctionDefinition.TotalSize);
564894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      WriteLE32(i->Aux.FunctionDefinition.PointerToLinenumber);
565894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      WriteLE32(i->Aux.FunctionDefinition.PointerToNextFunction);
566894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      WriteZeros(sizeof(i->Aux.FunctionDefinition.unused));
567894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
568894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case ATbfAndefSymbol:
569894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused1));
570894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      WriteLE16(i->Aux.bfAndefSymbol.Linenumber);
571894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused2));
572894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      WriteLE32(i->Aux.bfAndefSymbol.PointerToNextFunction);
573894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused3));
574894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
575894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case ATWeakExternal:
576894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      WriteLE32(i->Aux.WeakExternal.TagIndex);
577894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      WriteLE32(i->Aux.WeakExternal.Characteristics);
578894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      WriteZeros(sizeof(i->Aux.WeakExternal.unused));
579894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
580894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case ATFile:
581894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      WriteBytes(StringRef(reinterpret_cast<const char *>(i->Aux.File.FileName),
582894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                 sizeof(i->Aux.File.FileName)));
583894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
584894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case ATSectionDefinition:
585894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      WriteLE32(i->Aux.SectionDefinition.Length);
586894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      WriteLE16(i->Aux.SectionDefinition.NumberOfRelocations);
587894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      WriteLE16(i->Aux.SectionDefinition.NumberOfLinenumbers);
588894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      WriteLE32(i->Aux.SectionDefinition.CheckSum);
589894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      WriteLE16(i->Aux.SectionDefinition.Number);
590894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Write8(i->Aux.SectionDefinition.Selection);
591894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      WriteZeros(sizeof(i->Aux.SectionDefinition.unused));
592894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
593894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
594894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
595894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
596894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
597894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid WinCOFFObjectWriter::WriteSectionHeader(const COFF::section &S) {
598894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteBytes(StringRef(S.Name, COFF::NameSize));
599894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
600894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE32(S.VirtualSize);
601894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE32(S.VirtualAddress);
602894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE32(S.SizeOfRawData);
603894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE32(S.PointerToRawData);
604894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE32(S.PointerToRelocations);
605894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE32(S.PointerToLineNumbers);
606894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE16(S.NumberOfRelocations);
607894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE16(S.NumberOfLineNumbers);
608894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE32(S.Characteristics);
609894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
610894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
611894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid WinCOFFObjectWriter::WriteRelocation(const COFF::relocation &R) {
612894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE32(R.VirtualAddress);
613894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE32(R.SymbolTableIndex);
614894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteLE16(R.Type);
615894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
616894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
617894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman////////////////////////////////////////////////////////////////////////////////
618894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// MCObjectWriter interface implementations
619894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
62019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
62119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                   const MCAsmLayout &Layout) {
622894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // "Define" each section & symbol. This creates section & symbol
62319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // entries in the staging area.
624894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e; i++)
626894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    DefineSection(*i);
627894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
628894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (MCAssembler::const_symbol_iterator i = Asm.symbol_begin(),
629894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                          e = Asm.symbol_end(); i != e; i++) {
630894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (ExportSymbol(*i, Asm))
631894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      DefineSymbol(*i, Asm);
632894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
633894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
634894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
635894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
636894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                           const MCAsmLayout &Layout,
637894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                           const MCFragment *Fragment,
638894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                           const MCFixup &Fixup,
639894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                           MCValue Target,
640894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                           uint64_t &FixedValue) {
641894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  assert(Target.getSymA() != NULL && "Relocation must reference a symbol!");
64219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
64319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSymbol *A = &Target.getSymA()->getSymbol();
64419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCSymbolData &A_SD = Asm.getSymbolData(*A);
645894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
646894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  MCSectionData const *SectionData = Fragment->getParent();
647894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
64819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Mark this symbol as requiring an entry in the symbol table.
64919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(SectionMap.find(&SectionData->getSection()) != SectionMap.end() &&
650894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman         "Section must already have been defined in ExecutePostLayoutBinding!");
65119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(SymbolMap.find(&A_SD.getSymbol()) != SymbolMap.end() &&
652894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman         "Symbol must already have been defined in ExecutePostLayoutBinding!");
653894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
65419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  COFFSection *coff_section = SectionMap[&SectionData->getSection()];
65519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  COFFSymbol *coff_symbol = SymbolMap[&A_SD.getSymbol()];
65619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSymbolRefExpr *SymA = Target.getSymA();
65719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCSymbolRefExpr *SymB = Target.getSymB();
65819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const bool CrossSection = SymB &&
65919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    &SymA->getSymbol().getSection() != &SymB->getSymbol().getSection();
66019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
66119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Target.getSymB()) {
66219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MCSymbol *B = &Target.getSymB()->getSymbol();
66319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCSymbolData &B_SD = Asm.getSymbolData(*B);
66419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
66519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Offset of the symbol in the section
66619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    int64_t a = Layout.getSymbolOffset(&B_SD);
66719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
66819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Ofeset of the relocation in the section
66919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
67019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
67119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    FixedValue = b - a;
67219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // In the case where we have SymbA and SymB, we just need to store the delta
67319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // between the two symbols.  Update FixedValue to account for the delta, and
67419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // skip recording the relocation.
67519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!CrossSection)
67619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return;
67719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
67819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    FixedValue = Target.getConstant();
67919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
680894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
681894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  COFFRelocation Reloc;
682894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
683894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Reloc.Data.SymbolTableIndex = 0;
684894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment);
68519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
68619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Turn relocations for temporary symbols into section relocations.
68719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (coff_symbol->MCData->getSymbol().isTemporary() || CrossSection) {
68819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Reloc.Symb = coff_symbol->Section->Symbol;
68919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    FixedValue += Layout.getFragmentOffset(coff_symbol->MCData->Fragment)
69019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                + coff_symbol->MCData->getOffset();
69119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else
69219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Reloc.Symb = coff_symbol;
69319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
69419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ++Reloc.Symb->Relocations;
695894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
696894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Reloc.Data.VirtualAddress += Fixup.getOffset();
697894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
69819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned FixupKind = Fixup.getKind();
69919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
70019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (CrossSection)
70119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    FixupKind = FK_PCRel_4;
70219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
70319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (FixupKind) {
70419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case FK_PCRel_4:
70519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case X86::reloc_riprel_4byte:
70619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case X86::reloc_riprel_4byte_movq_load:
70719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Reloc.Data.Type = Is64Bit ? COFF::IMAGE_REL_AMD64_REL32
70819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                              : COFF::IMAGE_REL_I386_REL32;
70919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // FIXME: Can anyone explain what this does other than adjust for the size
71019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // of the offset?
711894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    FixedValue += 4;
712894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    break;
713894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case FK_Data_4:
71419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case X86::reloc_signed_4byte:
71519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Reloc.Data.Type = Is64Bit ? COFF::IMAGE_REL_AMD64_ADDR32
71619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                              : COFF::IMAGE_REL_I386_DIR32;
71719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
71819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case FK_Data_8:
71919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Is64Bit)
72019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Reloc.Data.Type = COFF::IMAGE_REL_AMD64_ADDR64;
72119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else
72219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      llvm_unreachable("unsupported relocation type");
723894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    break;
724894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  default:
725894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    llvm_unreachable("unsupported relocation type");
726894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
727894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
728894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  coff_section->Relocations.push_back(Reloc);
729894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
730894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
73119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
732894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                      const MCAsmLayout &Layout) {
733894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Assign symbol and section indexes and offsets.
73419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Header.NumberOfSections = 0;
73519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
73619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (sections::iterator i = Sections.begin(),
73719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                          e = Sections.end(); i != e; i++) {
73819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Layout.getSectionAddressSize((*i)->MCData) > 0) {
73919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MakeSectionReal(**i, ++Header.NumberOfSections);
74019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else {
74119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      (*i)->Number = -1;
74219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
74319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
744894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
745894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Header.NumberOfSymbols = 0;
746894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
747894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) {
748894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    COFFSymbol *coff_symbol = *i;
749894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MCSymbolData const *SymbolData = coff_symbol->MCData;
750894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
751894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Update section number & offset for symbols that have them.
752894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if ((SymbolData != NULL) && (SymbolData->Fragment != NULL)) {
75319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert(coff_symbol->Section != NULL);
754894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
75519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      coff_symbol->Data.SectionNumber = coff_symbol->Section->Number;
756894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      coff_symbol->Data.Value = Layout.getFragmentOffset(SymbolData->Fragment)
757894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                              + SymbolData->Offset;
758894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
759894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
76019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (coff_symbol->should_keep()) {
76119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MakeSymbolReal(*coff_symbol, Header.NumberOfSymbols++);
76219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
76319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Update auxiliary symbol info.
76419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      coff_symbol->Data.NumberOfAuxSymbols = coff_symbol->Aux.size();
76519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Header.NumberOfSymbols += coff_symbol->Data.NumberOfAuxSymbols;
76619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else
76719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      coff_symbol->Index = -1;
768894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
769894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
770894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Fixup weak external references.
771894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) {
77219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    COFFSymbol *coff_symbol = *i;
77319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (coff_symbol->Other != NULL) {
77419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert(coff_symbol->Index != -1);
77519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert(coff_symbol->Aux.size() == 1 &&
776894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman             "Symbol must contain one aux symbol!");
77719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert(coff_symbol->Aux[0].AuxType == ATWeakExternal &&
778894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman             "Symbol's aux symbol must be a Weak External!");
77919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = coff_symbol->Other->Index;
780894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
781894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
782894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
783894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Assign file offsets to COFF object file structures.
784894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
785894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  unsigned offset = 0;
786894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
787894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  offset += COFF::HeaderSize;
78819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  offset += COFF::SectionSize * Header.NumberOfSections;
789894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
790894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (MCAssembler::const_iterator i = Asm.begin(),
791894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                   e = Asm.end();
792894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                   i != e; i++) {
79319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    COFFSection *Sec = SectionMap[&i->getSection()];
794894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
79519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Sec->Number == -1)
79619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
797894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
79819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(i);
79919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
80019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IsPhysicalSection(Sec)) {
801894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Sec->Header.PointerToRawData = offset;
802894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
803894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      offset += Sec->Header.SizeOfRawData;
804894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
805894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
806894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (Sec->Relocations.size() > 0) {
807894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Sec->Header.NumberOfRelocations = Sec->Relocations.size();
808894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Sec->Header.PointerToRelocations = offset;
809894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
810894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      offset += COFF::RelocationSize * Sec->Relocations.size();
811894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
812894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      for (relocations::iterator cr = Sec->Relocations.begin(),
813894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                 er = Sec->Relocations.end();
81419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                 cr != er; ++cr) {
81519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        assert((*cr).Symb->Index != -1);
816894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        (*cr).Data.SymbolTableIndex = (*cr).Symb->Index;
817894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
818894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
819894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
82019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    assert(Sec->Symbol->Aux.size() == 1
82119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      && "Section's symbol must have one aux!");
82219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AuxSymbol &Aux = Sec->Symbol->Aux[0];
823894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    assert(Aux.AuxType == ATSectionDefinition &&
824894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman           "Section's symbol's aux symbol must be a Section Definition!");
825894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData;
826894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Aux.Aux.SectionDefinition.NumberOfRelocations =
827894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                                Sec->Header.NumberOfRelocations;
828894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Aux.Aux.SectionDefinition.NumberOfLinenumbers =
829894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                                Sec->Header.NumberOfLineNumbers;
830894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
831894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
832894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Header.PointerToSymbolTable = offset;
833894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
834894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Header.TimeDateStamp = sys::TimeValue::now().toEpochTime();
835894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
836894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Write it all to disk...
837894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  WriteFileHeader(Header);
838894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
839894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  {
840894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    sections::iterator i, ie;
841894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    MCAssembler::const_iterator j, je;
842894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
843894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    for (i = Sections.begin(), ie = Sections.end(); i != ie; i++)
84419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if ((*i)->Number != -1)
84519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        WriteSectionHeader((*i)->Header);
846894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
847894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    for (i = Sections.begin(), ie = Sections.end(),
848894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman         j = Asm.begin(), je = Asm.end();
84919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         (i != ie) && (j != je); ++i, ++j) {
85019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
85119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if ((*i)->Number == -1)
85219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        continue;
85319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
854894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if ((*i)->Header.PointerToRawData != 0) {
855894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        assert(OS.tell() == (*i)->Header.PointerToRawData &&
856894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman               "Section::PointerToRawData is insane!");
857894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
85819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Asm.WriteSectionData(j, Layout);
859894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
860894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
861894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if ((*i)->Relocations.size() > 0) {
862894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        assert(OS.tell() == (*i)->Header.PointerToRelocations &&
863894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman               "Section::PointerToRelocations is insane!");
864894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
865894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        for (relocations::const_iterator k = (*i)->Relocations.begin(),
866894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                               ke = (*i)->Relocations.end();
867894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                               k != ke; k++) {
868894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          WriteRelocation(k->Data);
869894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        }
870894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      } else
871894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        assert((*i)->Header.PointerToRelocations == 0 &&
872894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman               "Section::PointerToRelocations is insane!");
873894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
874894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
875894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
876894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  assert(OS.tell() == Header.PointerToSymbolTable &&
877894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman         "Header::PointerToSymbolTable is insane!");
878894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
879894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++)
88019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if ((*i)->Index != -1)
88119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      WriteSymbol(*i);
882894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
883894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  OS.write((char const *)&Strings.Data.front(), Strings.Data.size());
884894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
885894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
886894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//------------------------------------------------------------------------------
887894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// WinCOFFObjectWriter factory function
888894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
889894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace llvm {
89019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCObjectWriter *createWinCOFFObjectWriter(raw_ostream &OS, bool is64Bit) {
89119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return new WinCOFFObjectWriter(OS, is64Bit);
892894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
893894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
894