WinCOFFObjectWriter.cpp revision eb6e77f8cccd14cdba995ff8231f2c9faea9bfcc
1b162290e39afd49d4c7d342333b331bc96232720Chris Lattner//===-- llvm/MC/WinCOFFObjectWriter.cpp -------------------------*- C++ -*-===// 2b162290e39afd49d4c7d342333b331bc96232720Chris Lattner// 3b162290e39afd49d4c7d342333b331bc96232720Chris Lattner// The LLVM Compiler Infrastructure 4b162290e39afd49d4c7d342333b331bc96232720Chris Lattner// 5b162290e39afd49d4c7d342333b331bc96232720Chris Lattner// This file is distributed under the University of Illinois Open Source 6b162290e39afd49d4c7d342333b331bc96232720Chris Lattner// License. See LICENSE.TXT for details. 7b162290e39afd49d4c7d342333b331bc96232720Chris Lattner// 8b162290e39afd49d4c7d342333b331bc96232720Chris Lattner//===----------------------------------------------------------------------===// 9b162290e39afd49d4c7d342333b331bc96232720Chris Lattner// 10b162290e39afd49d4c7d342333b331bc96232720Chris Lattner// This file contains an implementation of a Win32 COFF object file writer. 11b162290e39afd49d4c7d342333b331bc96232720Chris Lattner// 12b162290e39afd49d4c7d342333b331bc96232720Chris Lattner//===----------------------------------------------------------------------===// 13b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 14b162290e39afd49d4c7d342333b331bc96232720Chris Lattner#define DEBUG_TYPE "WinCOFFObjectWriter" 15801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 16b162290e39afd49d4c7d342333b331bc96232720Chris Lattner#include "llvm/MC/MCObjectWriter.h" 17801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer#include "llvm/MC/MCSection.h" 18801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer#include "llvm/MC/MCContext.h" 19801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer#include "llvm/MC/MCSymbol.h" 20801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer#include "llvm/MC/MCExpr.h" 21b162290e39afd49d4c7d342333b331bc96232720Chris Lattner#include "llvm/MC/MCValue.h" 22b162290e39afd49d4c7d342333b331bc96232720Chris Lattner#include "llvm/MC/MCAssembler.h" 23b162290e39afd49d4c7d342333b331bc96232720Chris Lattner#include "llvm/MC/MCAsmLayout.h" 24801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer#include "llvm/MC/MCSectionCOFF.h" 25801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 26801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer#include "llvm/ADT/DenseMap.h" 27801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer#include "llvm/ADT/StringMap.h" 28801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer#include "llvm/ADT/StringRef.h" 29801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 30801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer#include "llvm/Support/COFF.h" 31801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer#include "llvm/Support/Debug.h" 32801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer#include "llvm/Support/ErrorHandling.h" 33801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 34ab3de49c48bd3282421ce24323fb6b868a3da6ccMichael J. Spencer#include "llvm/System/TimeValue.h" 35ab3de49c48bd3282421ce24323fb6b868a3da6ccMichael J. Spencer 36da0bfcdaf95d95a66e306ef6d45f638939272d34Michael J. Spencer#include "../Target/X86/X86FixupKinds.h" 37da0bfcdaf95d95a66e306ef6d45f638939272d34Michael J. Spencer 38801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer#include <cstdio> 39801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 40b162290e39afd49d4c7d342333b331bc96232720Chris Lattnerusing namespace llvm; 41b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 42b162290e39afd49d4c7d342333b331bc96232720Chris Lattnernamespace { 43801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencertypedef llvm::SmallString<COFF::NameSize> name; 44801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 45801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerenum AuxiliaryType { 46801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer ATFunctionDefinition, 47801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer ATbfAndefSymbol, 48801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer ATWeakExternal, 49801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer ATFile, 50801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer ATSectionDefinition 51801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer}; 52801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 53801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerstruct AuxSymbol { 54801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer AuxiliaryType AuxType; 55801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFF::Auxiliary Aux; 56801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer}; 57801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 58a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencerclass COFFSymbol; 59a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencerclass COFFSection; 60a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 61801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerclass COFFSymbol { 62801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerpublic: 63801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFF::symbol Data; 64801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 65801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer typedef llvm::SmallVector<AuxSymbol, 1> AuxiliarySymbols; 66801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 67801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer name Name; 689cf23a9ab466a900bc0f937bc930d398d6097766Michael J. Spencer int Index; 69801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer AuxiliarySymbols Aux; 70801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSymbol *Other; 71a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer COFFSection *Section; 72a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer int Relocations; 73801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 74801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCSymbolData const *MCData; 75801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 76a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer COFFSymbol(llvm::StringRef name); 77801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer size_t size() const; 78801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void set_name_offset(uint32_t Offset); 79a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 80a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer bool should_keep() const; 81801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer}; 82801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 83801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// This class contains staging data for a COFF relocation entry. 84801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerstruct COFFRelocation { 85801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFF::relocation Data; 86801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSymbol *Symb; 87801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 88801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFRelocation() : Symb(NULL) {} 89801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer static size_t size() { return COFF::RelocationSize; } 90801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer}; 91801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 92801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencertypedef std::vector<COFFRelocation> relocations; 93801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 94801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerclass COFFSection { 95801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerpublic: 96801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFF::section Header; 97801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 98801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer std::string Name; 999cf23a9ab466a900bc0f937bc930d398d6097766Michael J. Spencer int Number; 100801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCSectionData const *MCData; 101a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer COFFSymbol *Symbol; 102801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer relocations Relocations; 103801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 104a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer COFFSection(llvm::StringRef name); 105801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer static size_t size(); 106801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer}; 107801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 108801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// This class holds the COFF string table. 109801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerclass StringTable { 110801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer typedef llvm::StringMap<size_t> map; 111801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer map Map; 112801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 113801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void update_length(); 114801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerpublic: 115801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer std::vector<char> Data; 116801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 117801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer StringTable(); 118801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer size_t size() const; 119801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer size_t insert(llvm::StringRef String); 120801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer}; 121801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 122801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerclass WinCOFFObjectWriter : public MCObjectWriter { 123801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerpublic: 124801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 125801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer typedef std::vector<COFFSymbol*> symbols; 126801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer typedef std::vector<COFFSection*> sections; 127b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 128801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer typedef StringMap<COFFSymbol *> name_symbol_map; 129801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer typedef StringMap<COFFSection *> name_section_map; 130b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 131801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer typedef DenseMap<MCSymbolData const *, COFFSymbol *> symbol_map; 132801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer typedef DenseMap<MCSectionData const *, COFFSection *> section_map; 133b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 134801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Root level file contents. 13582c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer bool Is64Bit; 136801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFF::header Header; 137801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer sections Sections; 138801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer symbols Symbols; 139801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer StringTable Strings; 140b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 141801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Maps used during object file creation. 142801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer section_map SectionMap; 143801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer symbol_map SymbolMap; 144801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 145da0bfcdaf95d95a66e306ef6d45f638939272d34Michael J. Spencer WinCOFFObjectWriter(raw_ostream &OS, bool is64Bit); 146808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin Kramer ~WinCOFFObjectWriter(); 147801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 148801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSymbol *createSymbol(llvm::StringRef Name); 149801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSection *createSection(llvm::StringRef Name); 150801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 151801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer template <typename object_t, typename list_t> 152801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer object_t *createCOFFEntity(llvm::StringRef Name, list_t &List); 153801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 154801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void DefineSection(MCSectionData const &SectionData); 155801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void DefineSymbol(MCSymbolData const &SymbolData, MCAssembler &Assembler); 156801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 157a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer void MakeSymbolReal(COFFSymbol &S, size_t Index); 158a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer void MakeSectionReal(COFFSection &S, size_t Number); 159a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 160a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer bool ExportSection(COFFSection const *S); 161801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer bool ExportSymbol(MCSymbolData const &SymbolData, MCAssembler &Asm); 162801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 163a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer bool IsPhysicalSection(COFFSection *S); 164a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 165801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Entity writing methods. 166801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 167801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void WriteFileHeader(const COFF::header &Header); 168801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void WriteSymbol(const COFFSymbol *S); 169801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols &S); 170801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void WriteSectionHeader(const COFF::section &S); 171801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void WriteRelocation(const COFF::relocation &R); 172801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 173801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // MCObjectWriter interface implementation. 174801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 175801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void ExecutePostLayoutBinding(MCAssembler &Asm); 176801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 177801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void RecordRelocation(const MCAssembler &Asm, 178801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer const MCAsmLayout &Layout, 179801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer const MCFragment *Fragment, 180801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer const MCFixup &Fixup, 181801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCValue Target, 182801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer uint64_t &FixedValue); 183801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 1847070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola virtual bool IsFixupFullyResolved(const MCAssembler &Asm, 1857070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola const MCValue Target, 1867070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola bool IsPCRel, 1877070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola const MCFragment *DF) const; 1887070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola 1898f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout); 190801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer}; 191801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 192801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 193801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerstatic inline void write_uint32_le(void *Data, uint32_t const &Value) { 194801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer uint8_t *Ptr = reinterpret_cast<uint8_t *>(Data); 195801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Ptr[0] = (Value & 0x000000FF) >> 0; 196801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Ptr[1] = (Value & 0x0000FF00) >> 8; 197801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Ptr[2] = (Value & 0x00FF0000) >> 16; 198801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Ptr[3] = (Value & 0xFF000000) >> 24; 199801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 200801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 201801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerstatic inline void write_uint16_le(void *Data, uint16_t const &Value) { 202801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer uint8_t *Ptr = reinterpret_cast<uint8_t *>(Data); 203801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Ptr[0] = (Value & 0x00FF) >> 0; 204801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Ptr[1] = (Value & 0xFF00) >> 8; 205801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 206801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 207801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerstatic inline void write_uint8_le(void *Data, uint8_t const &Value) { 208801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer uint8_t *Ptr = reinterpret_cast<uint8_t *>(Data); 209801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Ptr[0] = (Value & 0xFF) >> 0; 210801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 211801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 212801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer//------------------------------------------------------------------------------ 213801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// Symbol class implementation 214801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 215a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. SpencerCOFFSymbol::COFFSymbol(llvm::StringRef name) 216a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer : Name(name.begin(), name.end()) 217a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer , Other(NULL) 218a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer , Section(NULL) 219a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer , Relocations(0) 220a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer , MCData(NULL) { 221801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer memset(&Data, 0, sizeof(Data)); 222801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 223b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 224801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencersize_t COFFSymbol::size() const { 225801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return COFF::SymbolSize + (Data.NumberOfAuxSymbols * COFF::SymbolSize); 226b162290e39afd49d4c7d342333b331bc96232720Chris Lattner} 227b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 228801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// In the case that the name does not fit within 8 bytes, the offset 229801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// into the string table is stored in the last 4 bytes instead, leaving 230801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// the first 4 bytes as 0. 231801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid COFFSymbol::set_name_offset(uint32_t Offset) { 232801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer write_uint32_le(Data.Name + 0, 0); 233801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer write_uint32_le(Data.Name + 4, Offset); 234801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 235801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 236a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer/// logic to decide if the symbol should be reported in the symbol table 237a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencerbool COFFSymbol::should_keep() const { 238a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // no section means its external, keep it 239a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (Section == NULL) 240a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer return true; 241a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 242a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // if it has relocations pointing at it, keep it 243a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (Relocations > 0) { 244a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer assert(Section->Number != -1 && "Sections with relocations must be real!"); 245a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer return true; 246a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer } 247a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 248a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // if the section its in is being droped, drop it 249a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (Section->Number == -1) 250a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer return false; 251a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 252a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // if it is the section symbol, keep it 253a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (Section->Symbol == this) 254a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer return true; 255a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 256a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // if its temporary, drop it 257a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (MCData && MCData->getSymbol().isTemporary()) 258a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer return false; 259a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 260a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // otherwise, keep it 261a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer return true; 262a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer} 263a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 264801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer//------------------------------------------------------------------------------ 265801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// Section class implementation 266801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 267a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. SpencerCOFFSection::COFFSection(llvm::StringRef name) 268a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer : Name(name) 269a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer , MCData(NULL) 270a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer , Symbol(NULL) { 271801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer memset(&Header, 0, sizeof(Header)); 272801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 273801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 274801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencersize_t COFFSection::size() { 275801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return COFF::SectionSize; 276801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 277801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 278801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer//------------------------------------------------------------------------------ 279801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// StringTable class implementation 280801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 281801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// Write the length of the string table into Data. 282801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// The length of the string table includes uint32 length header. 283801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid StringTable::update_length() { 284801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer write_uint32_le(&Data.front(), Data.size()); 285801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 286801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 287801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. SpencerStringTable::StringTable() { 288801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // The string table data begins with the length of the entire string table 289801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // including the length header. Allocate space for this header. 290801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Data.resize(4); 291801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 292801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 293801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencersize_t StringTable::size() const { 294801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return Data.size(); 295801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 296801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 297801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// Add String to the table iff it is not already there. 298801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// @returns the index into the string table where the string is now located. 299801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencersize_t StringTable::insert(llvm::StringRef String) { 300801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer map::iterator i = Map.find(String); 301801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 302801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if (i != Map.end()) 303801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return i->second; 304801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 305801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer size_t Offset = Data.size(); 306801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 307801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Insert string data into string table. 308801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Data.insert(Data.end(), String.begin(), String.end()); 309801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Data.push_back('\0'); 310801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 311801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Put a reference to it in the map. 312801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Map[String] = Offset; 313801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 314801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Update the internal length field. 315801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer update_length(); 316801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 317801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return Offset; 318801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 319801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 320801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer//------------------------------------------------------------------------------ 321801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// WinCOFFObjectWriter class implementation 322801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 323da0bfcdaf95d95a66e306ef6d45f638939272d34Michael J. SpencerWinCOFFObjectWriter::WinCOFFObjectWriter(raw_ostream &OS, bool is64Bit) 32482c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer : MCObjectWriter(OS, true) 32582c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer , Is64Bit(is64Bit) { 326801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer memset(&Header, 0, sizeof(Header)); 327da0bfcdaf95d95a66e306ef6d45f638939272d34Michael J. Spencer 32882c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer Is64Bit ? Header.Machine = COFF::IMAGE_FILE_MACHINE_AMD64 329da0bfcdaf95d95a66e306ef6d45f638939272d34Michael J. Spencer : Header.Machine = COFF::IMAGE_FILE_MACHINE_I386; 330801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 331801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 332808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin KramerWinCOFFObjectWriter::~WinCOFFObjectWriter() { 333808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin Kramer for (symbols::iterator I = Symbols.begin(), E = Symbols.end(); I != E; ++I) 334808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin Kramer delete *I; 335808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin Kramer for (sections::iterator I = Sections.begin(), E = Sections.end(); I != E; ++I) 336808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin Kramer delete *I; 337808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin Kramer} 338808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin Kramer 339801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. SpencerCOFFSymbol *WinCOFFObjectWriter::createSymbol(llvm::StringRef Name) { 340801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return createCOFFEntity<COFFSymbol>(Name, Symbols); 341801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 342801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 343801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. SpencerCOFFSection *WinCOFFObjectWriter::createSection(llvm::StringRef Name) { 344801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return createCOFFEntity<COFFSection>(Name, Sections); 345801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 346801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 347801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// A template used to lookup or create a symbol/section, and initialize it if 348801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// needed. 349801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencertemplate <typename object_t, typename list_t> 350801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerobject_t *WinCOFFObjectWriter::createCOFFEntity(llvm::StringRef Name, 351801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer list_t &List) { 352a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer object_t *Object = new object_t(Name); 353801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 354801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer List.push_back(Object); 355801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 356801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return Object; 357801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 358801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 359801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// This function takes a section data object from the assembler 360801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// and creates the associated COFF section staging object. 361801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) { 362801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // FIXME: Not sure how to verify this (at least in a debug build). 363801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCSectionCOFF const &Sec = 364801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer static_cast<MCSectionCOFF const &>(SectionData.getSection()); 365801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 366801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSection *coff_section = createSection(Sec.getSectionName()); 367801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSymbol *coff_symbol = createSymbol(Sec.getSectionName()); 368801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 369a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer coff_section->Symbol = coff_symbol; 370a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer coff_symbol->Section = coff_section; 371801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_STATIC; 372801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 373801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // In this case the auxiliary symbol is a Section Definition. 374801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux.resize(1); 375801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0])); 376801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux[0].AuxType = ATSectionDefinition; 377801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux[0].Aux.SectionDefinition.Selection = Sec.getSelection(); 378801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 379801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_section->Header.Characteristics = Sec.getCharacteristics(); 380801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 381801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer uint32_t &Characteristics = coff_section->Header.Characteristics; 382801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer switch (SectionData.getAlignment()) { 383801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 1: Characteristics |= COFF::IMAGE_SCN_ALIGN_1BYTES; break; 384801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 2: Characteristics |= COFF::IMAGE_SCN_ALIGN_2BYTES; break; 385801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 4: Characteristics |= COFF::IMAGE_SCN_ALIGN_4BYTES; break; 386801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 8: Characteristics |= COFF::IMAGE_SCN_ALIGN_8BYTES; break; 387801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 16: Characteristics |= COFF::IMAGE_SCN_ALIGN_16BYTES; break; 388801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 32: Characteristics |= COFF::IMAGE_SCN_ALIGN_32BYTES; break; 389801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 64: Characteristics |= COFF::IMAGE_SCN_ALIGN_64BYTES; break; 390801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 128: Characteristics |= COFF::IMAGE_SCN_ALIGN_128BYTES; break; 391801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 256: Characteristics |= COFF::IMAGE_SCN_ALIGN_256BYTES; break; 392801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 512: Characteristics |= COFF::IMAGE_SCN_ALIGN_512BYTES; break; 393801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 1024: Characteristics |= COFF::IMAGE_SCN_ALIGN_1024BYTES; break; 394801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 2048: Characteristics |= COFF::IMAGE_SCN_ALIGN_2048BYTES; break; 395801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 4096: Characteristics |= COFF::IMAGE_SCN_ALIGN_4096BYTES; break; 396801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 8192: Characteristics |= COFF::IMAGE_SCN_ALIGN_8192BYTES; break; 397801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer default: 398801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer llvm_unreachable("unsupported section alignment"); 399801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 400801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 401801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Bind internal COFF section to MC section. 402801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_section->MCData = &SectionData; 403801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer SectionMap[&SectionData] = coff_section; 404801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 405801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 406801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// This function takes a section data object from the assembler 407801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// and creates the associated COFF symbol staging object. 408801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData, 409a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer MCAssembler &Assembler) { 410a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer assert(!SymbolData.getSymbol().isVariable() 411a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer && "Cannot define a symbol that is a variable!"); 412801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSymbol *coff_symbol = createSymbol(SymbolData.getSymbol().getName()); 413801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 414801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Data.Type = (SymbolData.getFlags() & 0x0000FFFF) >> 0; 415801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Data.StorageClass = (SymbolData.getFlags() & 0x00FF0000) >> 16; 416801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 417801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // If no storage class was specified in the streamer, define it here. 418801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if (coff_symbol->Data.StorageClass == 0) { 419801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer bool external = SymbolData.isExternal() || (SymbolData.Fragment == NULL); 420801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 421801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Data.StorageClass = 42281100d0608efb1f4a4c87b9659b944ec0dfd86c8Michael J. Spencer external ? COFF::IMAGE_SYM_CLASS_EXTERNAL : COFF::IMAGE_SYM_CLASS_STATIC; 423801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 424801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 425801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if (SymbolData.getFlags() & COFF::SF_WeakReference) { 426801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL; 427801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 428801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer const MCExpr *Value = SymbolData.getSymbol().getVariableValue(); 429801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 430801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // FIXME: This assert message isn't very good. 431801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(Value->getKind() == MCExpr::SymbolRef && 432801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Value must be a SymbolRef!"); 433801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 434801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer const MCSymbolRefExpr *SymbolRef = 435801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer static_cast<const MCSymbolRefExpr *>(Value); 436801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 437801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer const MCSymbolData &OtherSymbolData = 438801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Assembler.getSymbolData(SymbolRef->getSymbol()); 439801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 440801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // FIXME: This assert message isn't very good. 441801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(SymbolMap.find(&OtherSymbolData) != SymbolMap.end() && 442801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "OtherSymbolData must be in the symbol map!"); 443801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 444801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Other = SymbolMap[&OtherSymbolData]; 445801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 446801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Setup the Weak External auxiliary symbol. 447801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux.resize(1); 448801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0])); 449801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux[0].AuxType = ATWeakExternal; 450801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = 0; 451801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux[0].Aux.WeakExternal.Characteristics = 452801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY; 453801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 454801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 455a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (SymbolData.Fragment != NULL) 456a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer coff_symbol->Section = SectionMap[SymbolData.Fragment->getParent()]; 457a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 458801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Bind internal COFF symbol to MC symbol. 459801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->MCData = &SymbolData; 460801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer SymbolMap[&SymbolData] = coff_symbol; 461801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 462801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 463a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer/// making a section real involves assigned it a number and putting 464a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer/// name into the string table if needed 465a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencervoid WinCOFFObjectWriter::MakeSectionReal(COFFSection &S, size_t Number) { 466a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (S.Name.size() > COFF::NameSize) { 467a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer size_t StringTableEntry = Strings.insert(S.Name.c_str()); 468a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 469a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // FIXME: Why is this number 999999? This number is never mentioned in the 470a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // spec. I'm assuming this is due to the printed value needing to fit into 471a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // the S.Header.Name field. In which case why not 9999999 (7 9's instead of 472a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // 6)? The spec does not state if this entry should be null terminated in 473a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // this case, and thus this seems to be the best way to do it. I think I 474a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // just solved my own FIXME... 475a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (StringTableEntry > 999999) 476a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer report_fatal_error("COFF string table is greater than 999999 bytes."); 477a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 478a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer std::sprintf(S.Header.Name, "/%d", unsigned(StringTableEntry)); 479a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer } else 480a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size()); 481a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 482a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer S.Number = Number; 483a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer S.Symbol->Data.SectionNumber = S.Number; 484a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer S.Symbol->Aux[0].Aux.SectionDefinition.Number = S.Number; 485a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer} 486a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 487a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencervoid WinCOFFObjectWriter::MakeSymbolReal(COFFSymbol &S, size_t Index) { 488a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (S.Name.size() > COFF::NameSize) { 489a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer size_t StringTableEntry = Strings.insert(S.Name.c_str()); 490a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 491a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer S.set_name_offset(StringTableEntry); 492a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer } else 493a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size()); 494a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer S.Index = Index; 495a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer} 496a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 497a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencerbool WinCOFFObjectWriter::ExportSection(COFFSection const *S) { 498a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer return !S->MCData->getFragmentList().empty(); 499801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 500801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 501801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerbool WinCOFFObjectWriter::ExportSymbol(MCSymbolData const &SymbolData, 502801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCAssembler &Asm) { 503801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // This doesn't seem to be right. Strings referred to from the .data section 504801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // need symbols so they can be linked to code in the .text section right? 505801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 506801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // return Asm.isSymbolLinkerVisible (&SymbolData); 507801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 508a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // For now, all non-variable symbols are exported, 509a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // the linker will sort the rest out for us. 510a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer return !SymbolData.getSymbol().isVariable(); 511a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer} 512a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 513a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencerbool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) { 514a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer return (S->Header.Characteristics 515a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0; 516801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 517801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 518801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer//------------------------------------------------------------------------------ 519801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// entity writing methods 520801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 521801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::WriteFileHeader(const COFF::header &Header) { 522801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(Header.Machine); 523801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(Header.NumberOfSections); 524801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(Header.TimeDateStamp); 525801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(Header.PointerToSymbolTable); 526801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(Header.NumberOfSymbols); 527801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(Header.SizeOfOptionalHeader); 528801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(Header.Characteristics); 529801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 530801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 531801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::WriteSymbol(const COFFSymbol *S) { 532801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteBytes(StringRef(S->Data.Name, COFF::NameSize)); 533801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S->Data.Value); 534801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(S->Data.SectionNumber); 535801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(S->Data.Type); 536801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Write8(S->Data.StorageClass); 537801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Write8(S->Data.NumberOfAuxSymbols); 538801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteAuxiliarySymbols(S->Aux); 539801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 540801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 541801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::WriteAuxiliarySymbols( 542801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer const COFFSymbol::AuxiliarySymbols &S) { 543801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for(COFFSymbol::AuxiliarySymbols::const_iterator i = S.begin(), e = S.end(); 544801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer i != e; ++i) { 545801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer switch(i->AuxType) { 546801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case ATFunctionDefinition: 547801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.FunctionDefinition.TagIndex); 548801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.FunctionDefinition.TotalSize); 549801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.FunctionDefinition.PointerToLinenumber); 550801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.FunctionDefinition.PointerToNextFunction); 551801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteZeros(sizeof(i->Aux.FunctionDefinition.unused)); 552801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer break; 553801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case ATbfAndefSymbol: 554801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused1)); 555801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(i->Aux.bfAndefSymbol.Linenumber); 556801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused2)); 557801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.bfAndefSymbol.PointerToNextFunction); 558801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused3)); 559801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer break; 560801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case ATWeakExternal: 561801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.WeakExternal.TagIndex); 562801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.WeakExternal.Characteristics); 563801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteZeros(sizeof(i->Aux.WeakExternal.unused)); 564801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer break; 565801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case ATFile: 566801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteBytes(StringRef(reinterpret_cast<const char *>(i->Aux.File.FileName), 567801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer sizeof(i->Aux.File.FileName))); 568801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer break; 569801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case ATSectionDefinition: 570801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.SectionDefinition.Length); 571801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(i->Aux.SectionDefinition.NumberOfRelocations); 572801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(i->Aux.SectionDefinition.NumberOfLinenumbers); 573801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.SectionDefinition.CheckSum); 574801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(i->Aux.SectionDefinition.Number); 575801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Write8(i->Aux.SectionDefinition.Selection); 576801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteZeros(sizeof(i->Aux.SectionDefinition.unused)); 577801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer break; 578801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 579801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 580801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 581801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 582801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::WriteSectionHeader(const COFF::section &S) { 583801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteBytes(StringRef(S.Name, COFF::NameSize)); 584801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 585801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S.VirtualSize); 586801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S.VirtualAddress); 587801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S.SizeOfRawData); 588801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S.PointerToRawData); 589801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S.PointerToRelocations); 590801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S.PointerToLineNumbers); 591801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(S.NumberOfRelocations); 592801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(S.NumberOfLineNumbers); 593801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S.Characteristics); 594801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 595801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 596801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::WriteRelocation(const COFF::relocation &R) { 597801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(R.VirtualAddress); 598801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(R.SymbolTableIndex); 599801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(R.Type); 600b162290e39afd49d4c7d342333b331bc96232720Chris Lattner} 601b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 602b162290e39afd49d4c7d342333b331bc96232720Chris Lattner//////////////////////////////////////////////////////////////////////////////// 603b162290e39afd49d4c7d342333b331bc96232720Chris Lattner// MCObjectWriter interface implementations 604b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 605b162290e39afd49d4c7d342333b331bc96232720Chris Lattnervoid WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm) { 606801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // "Define" each section & symbol. This creates section & symbol 607a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // entries in the staging area. 608801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 609801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e; i++) 610801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer DefineSection(*i); 611801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 612801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (MCAssembler::const_symbol_iterator i = Asm.symbol_begin(), 613801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer e = Asm.symbol_end(); i != e; i++) { 614801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if (ExportSymbol(*i, Asm)) 615801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer DefineSymbol(*i, Asm); 616801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 617b162290e39afd49d4c7d342333b331bc96232720Chris Lattner} 618b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 619b162290e39afd49d4c7d342333b331bc96232720Chris Lattnervoid WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, 620b162290e39afd49d4c7d342333b331bc96232720Chris Lattner const MCAsmLayout &Layout, 621b162290e39afd49d4c7d342333b331bc96232720Chris Lattner const MCFragment *Fragment, 622b162290e39afd49d4c7d342333b331bc96232720Chris Lattner const MCFixup &Fixup, 623b162290e39afd49d4c7d342333b331bc96232720Chris Lattner MCValue Target, 624b162290e39afd49d4c7d342333b331bc96232720Chris Lattner uint64_t &FixedValue) { 625801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(Target.getSymA() != NULL && "Relocation must reference a symbol!"); 62682c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer 62782c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer const MCSymbol *A = &Target.getSymA()->getSymbol(); 62882c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer MCSymbolData &A_SD = Asm.getSymbolData(*A); 629801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 630801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCSectionData const *SectionData = Fragment->getParent(); 631801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 63282c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer // Mark this symbol as requiring an entry in the symbol table. 633801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(SectionMap.find(SectionData) != SectionMap.end() && 634801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Section must already have been defined in ExecutePostLayoutBinding!"); 63582c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer assert(SymbolMap.find(&A_SD) != SymbolMap.end() && 636801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Symbol must already have been defined in ExecutePostLayoutBinding!"); 637801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 638801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSection *coff_section = SectionMap[SectionData]; 63982c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer COFFSymbol *coff_symbol = SymbolMap[&A_SD]; 64082c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer 64182c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer if (Target.getSymB()) { 64282c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer const MCSymbol *B = &Target.getSymB()->getSymbol(); 64382c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer MCSymbolData &B_SD = Asm.getSymbolData(*B); 644801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 64582c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer FixedValue = Layout.getSymbolAddress(&A_SD) - Layout.getSymbolAddress(&B_SD); 64682c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer 64782c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer // In the case where we have SymbA and SymB, we just need to store the delta 64882c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer // between the two symbols. Update FixedValue to account for the delta, and 64982c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer // skip recording the relocation. 65082c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer return; 65182c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer } else { 65282c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer FixedValue = Target.getConstant(); 65382c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer } 654801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 655801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFRelocation Reloc; 656801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 657425f634917542d7f09c189e2eb130752c6a12d2cDaniel Dunbar Reloc.Data.SymbolTableIndex = 0; 658801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment); 659a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 660a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // turn relocations for temporary symbols into section relocations 661a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (coff_symbol->MCData->getSymbol().isTemporary()) { 662a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer Reloc.Symb = coff_symbol->Section->Symbol; 663eb6e77f8cccd14cdba995ff8231f2c9faea9bfccMichael J. Spencer FixedValue += Layout.getFragmentOffset(coff_symbol->MCData->Fragment) 664eb6e77f8cccd14cdba995ff8231f2c9faea9bfccMichael J. Spencer + coff_symbol->MCData->getOffset(); 665a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer } else 666a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer Reloc.Symb = coff_symbol; 667a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 668a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer ++Reloc.Symb->Relocations; 669801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 670801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Reloc.Data.VirtualAddress += Fixup.getOffset(); 671801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 67282c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer switch (Fixup.getKind()) { 67382c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer case X86::reloc_pcrel_4byte: 67482c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer case X86::reloc_riprel_4byte: 67582c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer case X86::reloc_riprel_4byte_movq_load: 67682c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer Reloc.Data.Type = Is64Bit ? COFF::IMAGE_REL_AMD64_REL32 67782c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer : COFF::IMAGE_REL_I386_REL32; 67882c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer // FIXME: Can anyone explain what this does other than adjust for the size 67982c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer // of the offset? 68082c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer FixedValue += 4; 68182c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer break; 68282c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer case FK_Data_4: 683a8c02c3bdd68e65d14fb6b0d56989663754059b0Rafael Espindola case X86::reloc_signed_4byte: 68482c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer Reloc.Data.Type = Is64Bit ? COFF::IMAGE_REL_AMD64_ADDR32 68582c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer : COFF::IMAGE_REL_I386_DIR32; 68682c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer break; 68782c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer case FK_Data_8: 68882c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer if (Is64Bit) 68982c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer Reloc.Data.Type = COFF::IMAGE_REL_AMD64_ADDR64; 69082c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer else 691da0bfcdaf95d95a66e306ef6d45f638939272d34Michael J. Spencer llvm_unreachable("unsupported relocation type"); 69282c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer break; 69382c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer default: 69482c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer llvm_unreachable("unsupported relocation type"); 69582c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer } 696801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 697801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_section->Relocations.push_back(Reloc); 698b162290e39afd49d4c7d342333b331bc96232720Chris Lattner} 699b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 7007070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindolabool WinCOFFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm, 7017070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola const MCValue Target, 7027070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola bool IsPCRel, 7037070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola const MCFragment *DF) const { 7047070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola return false; 7057070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola} 7067070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola 7078f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindolavoid WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, 708b162290e39afd49d4c7d342333b331bc96232720Chris Lattner const MCAsmLayout &Layout) { 709801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Assign symbol and section indexes and offsets. 710a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer Header.NumberOfSections = 0; 711a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 712a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer for (sections::iterator i = Sections.begin(), 713a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer e = Sections.end(); i != e; i++) { 714a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (Layout.getSectionSize((*i)->MCData) > 0) { 715a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer MakeSectionReal(**i, ++Header.NumberOfSections); 716a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer } else { 717a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer (*i)->Number = -1; 718a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer } 719a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer } 720801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 721801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Header.NumberOfSymbols = 0; 722801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 723801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) { 724801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSymbol *coff_symbol = *i; 725801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCSymbolData const *SymbolData = coff_symbol->MCData; 726801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 727801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Update section number & offset for symbols that have them. 728801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if ((SymbolData != NULL) && (SymbolData->Fragment != NULL)) { 729a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer assert(coff_symbol->Section != NULL); 730801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 731a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer coff_symbol->Data.SectionNumber = coff_symbol->Section->Number; 732237f8fe5df628065874b8590b364d04dfc2686fdMichael J. Spencer coff_symbol->Data.Value = Layout.getFragmentOffset(SymbolData->Fragment) 733237f8fe5df628065874b8590b364d04dfc2686fdMichael J. Spencer + SymbolData->Offset; 734801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 735801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 736a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (coff_symbol->should_keep()) { 737a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer MakeSymbolReal(*coff_symbol, Header.NumberOfSymbols++); 738a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 739a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // Update auxiliary symbol info. 740a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer coff_symbol->Data.NumberOfAuxSymbols = coff_symbol->Aux.size(); 741a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer Header.NumberOfSymbols += coff_symbol->Data.NumberOfAuxSymbols; 742a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer } else 743a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer coff_symbol->Index = -1; 744801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 745801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 746801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Fixup weak external references. 747801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) { 748a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer COFFSymbol *coff_symbol = *i; 749a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (coff_symbol->Other != NULL) { 750a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer assert(coff_symbol->Index != -1); 751a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer assert(coff_symbol->Aux.size() == 1 && 752801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Symbol must contain one aux symbol!"); 753a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer assert(coff_symbol->Aux[0].AuxType == ATWeakExternal && 754801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Symbol's aux symbol must be a Weak External!"); 755a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = coff_symbol->Other->Index; 756801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 757801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 758801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 759801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Assign file offsets to COFF object file structures. 760801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 761801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer unsigned offset = 0; 762801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 763801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer offset += COFF::HeaderSize; 764a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer offset += COFF::SectionSize * Header.NumberOfSections; 765801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 766801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (MCAssembler::const_iterator i = Asm.begin(), 767801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer e = Asm.end(); 768801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer i != e; i++) { 769801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSection *Sec = SectionMap[i]; 770801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 771a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (Sec->Number == -1) 772a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer continue; 773a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 774801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Sec->Header.SizeOfRawData = Layout.getSectionFileSize(i); 775801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 776a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (IsPhysicalSection(Sec)) { 777801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Sec->Header.PointerToRawData = offset; 778801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 779801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer offset += Sec->Header.SizeOfRawData; 780801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 781801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 782801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if (Sec->Relocations.size() > 0) { 783801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Sec->Header.NumberOfRelocations = Sec->Relocations.size(); 784801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Sec->Header.PointerToRelocations = offset; 785801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 786801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer offset += COFF::RelocationSize * Sec->Relocations.size(); 787801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 788801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (relocations::iterator cr = Sec->Relocations.begin(), 789801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer er = Sec->Relocations.end(); 790a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer cr != er; ++cr) { 791a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer assert((*cr).Symb->Index != -1); 792801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer (*cr).Data.SymbolTableIndex = (*cr).Symb->Index; 793801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 794801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 795801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 796a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer assert(Sec->Symbol->Aux.size() == 1 797a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer && "Section's symbol must have one aux!"); 798a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer AuxSymbol &Aux = Sec->Symbol->Aux[0]; 799801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(Aux.AuxType == ATSectionDefinition && 800801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Section's symbol's aux symbol must be a Section Definition!"); 801801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData; 802801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Aux.Aux.SectionDefinition.NumberOfRelocations = 803801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Sec->Header.NumberOfRelocations; 804801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Aux.Aux.SectionDefinition.NumberOfLinenumbers = 805801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Sec->Header.NumberOfLineNumbers; 806801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 807801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 808801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Header.PointerToSymbolTable = offset; 809801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 810ab3de49c48bd3282421ce24323fb6b868a3da6ccMichael J. Spencer Header.TimeDateStamp = sys::TimeValue::now().toEpochTime(); 811ab3de49c48bd3282421ce24323fb6b868a3da6ccMichael J. Spencer 812801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Write it all to disk... 813801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteFileHeader(Header); 814801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 815801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer { 816801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer sections::iterator i, ie; 817801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCAssembler::const_iterator j, je; 818801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 819801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (i = Sections.begin(), ie = Sections.end(); i != ie; i++) 820a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if ((*i)->Number != -1) 821a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer WriteSectionHeader((*i)->Header); 822801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 823801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (i = Sections.begin(), ie = Sections.end(), 824801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer j = Asm.begin(), je = Asm.end(); 825a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer (i != ie) && (j != je); ++i, ++j) { 826a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 827a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if ((*i)->Number == -1) 828a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer continue; 829a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 830801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if ((*i)->Header.PointerToRawData != 0) { 831801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(OS.tell() == (*i)->Header.PointerToRawData && 832801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Section::PointerToRawData is insane!"); 833801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 834801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Asm.WriteSectionData(j, Layout, this); 835801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 836801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 837801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if ((*i)->Relocations.size() > 0) { 838801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(OS.tell() == (*i)->Header.PointerToRelocations && 839801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Section::PointerToRelocations is insane!"); 840801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 841801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (relocations::const_iterator k = (*i)->Relocations.begin(), 842801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer ke = (*i)->Relocations.end(); 843801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer k != ke; k++) { 844801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteRelocation(k->Data); 845801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 846801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } else 847801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert((*i)->Header.PointerToRelocations == 0 && 848801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Section::PointerToRelocations is insane!"); 849801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 850801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 851801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 852801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(OS.tell() == Header.PointerToSymbolTable && 853801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Header::PointerToSymbolTable is insane!"); 854801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 855801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) 856a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if ((*i)->Index != -1) 857a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer WriteSymbol(*i); 858801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 859801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer OS.write((char const *)&Strings.Data.front(), Strings.Data.size()); 860b162290e39afd49d4c7d342333b331bc96232720Chris Lattner} 861b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 862b162290e39afd49d4c7d342333b331bc96232720Chris Lattner//------------------------------------------------------------------------------ 863b162290e39afd49d4c7d342333b331bc96232720Chris Lattner// WinCOFFObjectWriter factory function 864b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 865b162290e39afd49d4c7d342333b331bc96232720Chris Lattnernamespace llvm { 866da0bfcdaf95d95a66e306ef6d45f638939272d34Michael J. Spencer MCObjectWriter *createWinCOFFObjectWriter(raw_ostream &OS, bool is64Bit) { 867da0bfcdaf95d95a66e306ef6d45f638939272d34Michael J. Spencer return new WinCOFFObjectWriter(OS, is64Bit); 868b162290e39afd49d4c7d342333b331bc96232720Chris Lattner } 869933304ef0c3ec18c23d0b385c2117a6eae790430Michael J. Spencer} 870