WinCOFFObjectWriter.cpp revision ab3de49c48bd3282421ce24323fb6b868a3da6cc
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 36801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer#include <cstdio> 37801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 38b162290e39afd49d4c7d342333b331bc96232720Chris Lattnerusing namespace llvm; 39b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 40b162290e39afd49d4c7d342333b331bc96232720Chris Lattnernamespace { 41801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencertypedef llvm::SmallString<COFF::NameSize> name; 42801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 43801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerenum AuxiliaryType { 44801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer ATFunctionDefinition, 45801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer ATbfAndefSymbol, 46801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer ATWeakExternal, 47801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer ATFile, 48801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer ATSectionDefinition 49801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer}; 50801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 51801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerstruct AuxSymbol { 52801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer AuxiliaryType AuxType; 53801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFF::Auxiliary Aux; 54801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer}; 55801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 56801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerclass COFFSymbol { 57801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerpublic: 58801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFF::symbol Data; 59801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 60801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer typedef llvm::SmallVector<AuxSymbol, 1> AuxiliarySymbols; 61801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 62801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer name Name; 63801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer size_t Index; 64801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer AuxiliarySymbols Aux; 65801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSymbol *Other; 66801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 67801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCSymbolData const *MCData; 68801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 69801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSymbol(llvm::StringRef name, size_t index); 70801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer size_t size() const; 71801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void set_name_offset(uint32_t Offset); 72801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer}; 73801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 74801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// This class contains staging data for a COFF relocation entry. 75801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerstruct COFFRelocation { 76801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFF::relocation Data; 77801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSymbol *Symb; 78801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 79801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFRelocation() : Symb(NULL) {} 80801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer static size_t size() { return COFF::RelocationSize; } 81801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer}; 82801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 83801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencertypedef std::vector<COFFRelocation> relocations; 84801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 85801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerclass COFFSection { 86801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerpublic: 87801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFF::section Header; 88801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 89801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer std::string Name; 90801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer size_t Number; 91801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCSectionData const *MCData; 92801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSymbol *Symb; 93801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer relocations Relocations; 94801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 95801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSection(llvm::StringRef name, size_t Index); 96801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer static size_t size(); 97801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer}; 98801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 99801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// This class holds the COFF string table. 100801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerclass StringTable { 101801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer typedef llvm::StringMap<size_t> map; 102801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer map Map; 103801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 104801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void update_length(); 105801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerpublic: 106801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer std::vector<char> Data; 107801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 108801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer StringTable(); 109801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer size_t size() const; 110801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer size_t insert(llvm::StringRef String); 111801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer}; 112801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 113801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerclass WinCOFFObjectWriter : public MCObjectWriter { 114801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerpublic: 115801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 116801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer typedef std::vector<COFFSymbol*> symbols; 117801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer typedef std::vector<COFFSection*> sections; 118b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 119801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer typedef StringMap<COFFSymbol *> name_symbol_map; 120801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer typedef StringMap<COFFSection *> name_section_map; 121b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 122801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer typedef DenseMap<MCSymbolData const *, COFFSymbol *> symbol_map; 123801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer typedef DenseMap<MCSectionData const *, COFFSection *> section_map; 124b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 125801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Root level file contents. 126801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFF::header Header; 127801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer sections Sections; 128801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer symbols Symbols; 129801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer StringTable Strings; 130b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 131801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Maps used during object file creation. 132801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer section_map SectionMap; 133801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer symbol_map SymbolMap; 134801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 135801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WinCOFFObjectWriter(raw_ostream &OS); 136808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin Kramer ~WinCOFFObjectWriter(); 137801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 138801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSymbol *createSymbol(llvm::StringRef Name); 139801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSection *createSection(llvm::StringRef Name); 140801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 141801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void InitCOFFEntity(COFFSymbol &Symbol); 142801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void InitCOFFEntity(COFFSection &Section); 143801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 144801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer template <typename object_t, typename list_t> 145801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer object_t *createCOFFEntity(llvm::StringRef Name, list_t &List); 146801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 147801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void DefineSection(MCSectionData const &SectionData); 148801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void DefineSymbol(MCSymbolData const &SymbolData, MCAssembler &Assembler); 149801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 150801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer bool ExportSection(COFFSection *S); 151801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer bool ExportSymbol(MCSymbolData const &SymbolData, MCAssembler &Asm); 152801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 153801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Entity writing methods. 154801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 155801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void WriteFileHeader(const COFF::header &Header); 156801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void WriteSymbol(const COFFSymbol *S); 157801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols &S); 158801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void WriteSectionHeader(const COFF::section &S); 159801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void WriteRelocation(const COFF::relocation &R); 160801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 161801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // MCObjectWriter interface implementation. 162801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 163801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void ExecutePostLayoutBinding(MCAssembler &Asm); 164801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 165801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void RecordRelocation(const MCAssembler &Asm, 166801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer const MCAsmLayout &Layout, 167801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer const MCFragment *Fragment, 168801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer const MCFixup &Fixup, 169801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCValue Target, 170801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer uint64_t &FixedValue); 171801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 172801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void WriteObject(const MCAssembler &Asm, const MCAsmLayout &Layout); 173801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer}; 174801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 175801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 176801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerstatic inline void write_uint32_le(void *Data, uint32_t const &Value) { 177801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer uint8_t *Ptr = reinterpret_cast<uint8_t *>(Data); 178801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Ptr[0] = (Value & 0x000000FF) >> 0; 179801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Ptr[1] = (Value & 0x0000FF00) >> 8; 180801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Ptr[2] = (Value & 0x00FF0000) >> 16; 181801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Ptr[3] = (Value & 0xFF000000) >> 24; 182801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 183801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 184801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerstatic inline void write_uint16_le(void *Data, uint16_t const &Value) { 185801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer uint8_t *Ptr = reinterpret_cast<uint8_t *>(Data); 186801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Ptr[0] = (Value & 0x00FF) >> 0; 187801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Ptr[1] = (Value & 0xFF00) >> 8; 188801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 189801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 190801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerstatic inline void write_uint8_le(void *Data, uint8_t const &Value) { 191801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer uint8_t *Ptr = reinterpret_cast<uint8_t *>(Data); 192801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Ptr[0] = (Value & 0xFF) >> 0; 193801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 194801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 195801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer//------------------------------------------------------------------------------ 196801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// Symbol class implementation 197801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 198801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. SpencerCOFFSymbol::COFFSymbol(llvm::StringRef name, size_t index) 199801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer : Name(name.begin(), name.end()), Index(-1) 200801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer , Other(NULL), MCData(NULL) { 201801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer memset(&Data, 0, sizeof(Data)); 202801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 203b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 204801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencersize_t COFFSymbol::size() const { 205801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return COFF::SymbolSize + (Data.NumberOfAuxSymbols * COFF::SymbolSize); 206b162290e39afd49d4c7d342333b331bc96232720Chris Lattner} 207b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 208801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// In the case that the name does not fit within 8 bytes, the offset 209801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// into the string table is stored in the last 4 bytes instead, leaving 210801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// the first 4 bytes as 0. 211801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid COFFSymbol::set_name_offset(uint32_t Offset) { 212801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer write_uint32_le(Data.Name + 0, 0); 213801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer write_uint32_le(Data.Name + 4, Offset); 214801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 215801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 216801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer//------------------------------------------------------------------------------ 217801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// Section class implementation 218801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 219801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. SpencerCOFFSection::COFFSection(llvm::StringRef name, size_t Index) 220801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer : Name(name), Number(Index + 1) 221801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer , MCData(NULL), Symb(NULL) { 222801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer memset(&Header, 0, sizeof(Header)); 223801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 224801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 225801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencersize_t COFFSection::size() { 226801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return COFF::SectionSize; 227801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 228801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 229801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer//------------------------------------------------------------------------------ 230801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// StringTable class implementation 231801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 232801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// Write the length of the string table into Data. 233801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// The length of the string table includes uint32 length header. 234801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid StringTable::update_length() { 235801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer write_uint32_le(&Data.front(), Data.size()); 236801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 237801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 238801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. SpencerStringTable::StringTable() { 239801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // The string table data begins with the length of the entire string table 240801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // including the length header. Allocate space for this header. 241801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Data.resize(4); 242801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 243801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 244801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencersize_t StringTable::size() const { 245801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return Data.size(); 246801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 247801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 248801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// Add String to the table iff it is not already there. 249801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// @returns the index into the string table where the string is now located. 250801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencersize_t StringTable::insert(llvm::StringRef String) { 251801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer map::iterator i = Map.find(String); 252801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 253801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if (i != Map.end()) 254801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return i->second; 255801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 256801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer size_t Offset = Data.size(); 257801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 258801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Insert string data into string table. 259801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Data.insert(Data.end(), String.begin(), String.end()); 260801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Data.push_back('\0'); 261801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 262801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Put a reference to it in the map. 263801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Map[String] = Offset; 264801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 265801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Update the internal length field. 266801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer update_length(); 267801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 268801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return Offset; 269801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 270801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 271801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer//------------------------------------------------------------------------------ 272801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// WinCOFFObjectWriter class implementation 273801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 274b162290e39afd49d4c7d342333b331bc96232720Chris LattnerWinCOFFObjectWriter::WinCOFFObjectWriter(raw_ostream &OS) 275b162290e39afd49d4c7d342333b331bc96232720Chris Lattner : MCObjectWriter(OS, true) { 276801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer memset(&Header, 0, sizeof(Header)); 277801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // TODO: Move magic constant out to COFF.h 278801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Header.Machine = 0x14C; // x86 279801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 280801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 281808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin KramerWinCOFFObjectWriter::~WinCOFFObjectWriter() { 282808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin Kramer for (symbols::iterator I = Symbols.begin(), E = Symbols.end(); I != E; ++I) 283808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin Kramer delete *I; 284808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin Kramer for (sections::iterator I = Sections.begin(), E = Sections.end(); I != E; ++I) 285808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin Kramer delete *I; 286808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin Kramer} 287808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin Kramer 288801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. SpencerCOFFSymbol *WinCOFFObjectWriter::createSymbol(llvm::StringRef Name) { 289801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return createCOFFEntity<COFFSymbol>(Name, Symbols); 290801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 291801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 292801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. SpencerCOFFSection *WinCOFFObjectWriter::createSection(llvm::StringRef Name) { 293801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return createCOFFEntity<COFFSection>(Name, Sections); 294801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 295801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 296801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// This function initializes a symbol by entering its name into the string 297801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// table if it is too long to fit in the symbol table header. 298801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::InitCOFFEntity(COFFSymbol &S) { 299801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if (S.Name.size() > COFF::NameSize) { 300801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer size_t StringTableEntry = Strings.insert(S.Name.c_str()); 301801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 302801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer S.set_name_offset(StringTableEntry); 303801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } else 304801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer memcpy(S.Data.Name, S.Name.c_str(), S.Name.size()); 305801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 306801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 307801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// This function initializes a section by entering its name into the string 308801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// table if it is too long to fit in the section table header. 309801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::InitCOFFEntity(COFFSection &S) { 310801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if (S.Name.size() > COFF::NameSize) { 311801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer size_t StringTableEntry = Strings.insert(S.Name.c_str()); 312801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 313801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // FIXME: Why is this number 999999? This number is never mentioned in the 314801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // spec. I'm assuming this is due to the printed value needing to fit into 315801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // the S.Header.Name field. In which case why not 9999999 (7 9's instead of 316801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // 6)? The spec does not state if this entry should be null terminated in 317801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // this case, and thus this seems to be the best way to do it. I think I 318801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // just solved my own FIXME... 319801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if (StringTableEntry > 999999) 320801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer report_fatal_error("COFF string table is greater than 999999 bytes."); 321801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 322fd2878c8d0e876e849f795bb3f5d5e2f82aa59bdDouglas Gregor sprintf(S.Header.Name, "/%d", (unsigned)StringTableEntry); 323801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } else 324801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer memcpy(S.Header.Name, S.Name.c_str(), S.Name.size()); 325801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 326801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 327801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// A template used to lookup or create a symbol/section, and initialize it if 328801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// needed. 329801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencertemplate <typename object_t, typename list_t> 330801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerobject_t *WinCOFFObjectWriter::createCOFFEntity(llvm::StringRef Name, 331801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer list_t &List) { 332801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer object_t *Object = new object_t(Name, List.size()); 333801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 334801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer InitCOFFEntity(*Object); 335801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 336801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer List.push_back(Object); 337801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 338801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return Object; 339801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 340801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 341801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// This function takes a section data object from the assembler 342801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// and creates the associated COFF section staging object. 343801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) { 344801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // FIXME: Not sure how to verify this (at least in a debug build). 345801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCSectionCOFF const &Sec = 346801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer static_cast<MCSectionCOFF const &>(SectionData.getSection()); 347801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 348801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSection *coff_section = createSection(Sec.getSectionName()); 349801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSymbol *coff_symbol = createSymbol(Sec.getSectionName()); 350801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 351801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_section->Symb = coff_symbol; 352801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_STATIC; 353801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Data.SectionNumber = coff_section->Number; 354801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 355801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // In this case the auxiliary symbol is a Section Definition. 356801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux.resize(1); 357801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0])); 358801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux[0].AuxType = ATSectionDefinition; 359801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux[0].Aux.SectionDefinition.Number = coff_section->Number; 360801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux[0].Aux.SectionDefinition.Selection = Sec.getSelection(); 361801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 362801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_section->Header.Characteristics = Sec.getCharacteristics(); 363801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 364801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer uint32_t &Characteristics = coff_section->Header.Characteristics; 365801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer switch (SectionData.getAlignment()) { 366801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 1: Characteristics |= COFF::IMAGE_SCN_ALIGN_1BYTES; break; 367801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 2: Characteristics |= COFF::IMAGE_SCN_ALIGN_2BYTES; break; 368801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 4: Characteristics |= COFF::IMAGE_SCN_ALIGN_4BYTES; break; 369801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 8: Characteristics |= COFF::IMAGE_SCN_ALIGN_8BYTES; break; 370801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 16: Characteristics |= COFF::IMAGE_SCN_ALIGN_16BYTES; break; 371801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 32: Characteristics |= COFF::IMAGE_SCN_ALIGN_32BYTES; break; 372801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 64: Characteristics |= COFF::IMAGE_SCN_ALIGN_64BYTES; break; 373801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 128: Characteristics |= COFF::IMAGE_SCN_ALIGN_128BYTES; break; 374801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 256: Characteristics |= COFF::IMAGE_SCN_ALIGN_256BYTES; break; 375801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 512: Characteristics |= COFF::IMAGE_SCN_ALIGN_512BYTES; break; 376801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 1024: Characteristics |= COFF::IMAGE_SCN_ALIGN_1024BYTES; break; 377801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 2048: Characteristics |= COFF::IMAGE_SCN_ALIGN_2048BYTES; break; 378801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 4096: Characteristics |= COFF::IMAGE_SCN_ALIGN_4096BYTES; break; 379801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 8192: Characteristics |= COFF::IMAGE_SCN_ALIGN_8192BYTES; break; 380801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer default: 381801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer llvm_unreachable("unsupported section alignment"); 382801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 383801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 384801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Bind internal COFF section to MC section. 385801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_section->MCData = &SectionData; 386801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer SectionMap[&SectionData] = coff_section; 387801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 388801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 389801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// This function takes a section data object from the assembler 390801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// and creates the associated COFF symbol staging object. 391801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData, 392801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCAssembler &Assembler) { 393801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSymbol *coff_symbol = createSymbol(SymbolData.getSymbol().getName()); 394801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 395801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Data.Type = (SymbolData.getFlags() & 0x0000FFFF) >> 0; 396801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Data.StorageClass = (SymbolData.getFlags() & 0x00FF0000) >> 16; 397801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 398801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // If no storage class was specified in the streamer, define it here. 399801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if (coff_symbol->Data.StorageClass == 0) { 400801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer bool external = SymbolData.isExternal() || (SymbolData.Fragment == NULL); 401801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 402801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Data.StorageClass = 403801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer external ? COFF::IMAGE_SYM_CLASS_EXTERNAL : COFF::IMAGE_SYM_CLASS_STATIC; 404801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 405801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 406801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if (SymbolData.getFlags() & COFF::SF_WeakReference) { 407801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL; 408801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 409801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer const MCExpr *Value = SymbolData.getSymbol().getVariableValue(); 410801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 411801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // FIXME: This assert message isn't very good. 412801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(Value->getKind() == MCExpr::SymbolRef && 413801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Value must be a SymbolRef!"); 414801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 415801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer const MCSymbolRefExpr *SymbolRef = 416801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer static_cast<const MCSymbolRefExpr *>(Value); 417801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 418801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer const MCSymbolData &OtherSymbolData = 419801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Assembler.getSymbolData(SymbolRef->getSymbol()); 420801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 421801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // FIXME: This assert message isn't very good. 422801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(SymbolMap.find(&OtherSymbolData) != SymbolMap.end() && 423801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "OtherSymbolData must be in the symbol map!"); 424801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 425801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Other = SymbolMap[&OtherSymbolData]; 426801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 427801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Setup the Weak External auxiliary symbol. 428801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux.resize(1); 429801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0])); 430801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux[0].AuxType = ATWeakExternal; 431801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = 0; 432801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux[0].Aux.WeakExternal.Characteristics = 433801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY; 434801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 435801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 436801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Bind internal COFF symbol to MC symbol. 437801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->MCData = &SymbolData; 438801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer SymbolMap[&SymbolData] = coff_symbol; 439801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 440801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 441801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerbool WinCOFFObjectWriter::ExportSection(COFFSection *S) { 442801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return (S->Header.Characteristics 443801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0; 444801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 445801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 446801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerbool WinCOFFObjectWriter::ExportSymbol(MCSymbolData const &SymbolData, 447801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCAssembler &Asm) { 448801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // This doesn't seem to be right. Strings referred to from the .data section 449801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // need symbols so they can be linked to code in the .text section right? 450801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 451801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // return Asm.isSymbolLinkerVisible (&SymbolData); 452801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 453801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // For now, all symbols are exported, the linker will sort it out for us. 454801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return true; 455801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 456801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 457801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer//------------------------------------------------------------------------------ 458801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// entity writing methods 459801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 460801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::WriteFileHeader(const COFF::header &Header) { 461801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(Header.Machine); 462801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(Header.NumberOfSections); 463801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(Header.TimeDateStamp); 464801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(Header.PointerToSymbolTable); 465801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(Header.NumberOfSymbols); 466801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(Header.SizeOfOptionalHeader); 467801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(Header.Characteristics); 468801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 469801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 470801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::WriteSymbol(const COFFSymbol *S) { 471801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteBytes(StringRef(S->Data.Name, COFF::NameSize)); 472801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S->Data.Value); 473801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(S->Data.SectionNumber); 474801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(S->Data.Type); 475801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Write8(S->Data.StorageClass); 476801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Write8(S->Data.NumberOfAuxSymbols); 477801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteAuxiliarySymbols(S->Aux); 478801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 479801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 480801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::WriteAuxiliarySymbols( 481801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer const COFFSymbol::AuxiliarySymbols &S) { 482801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for(COFFSymbol::AuxiliarySymbols::const_iterator i = S.begin(), e = S.end(); 483801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer i != e; ++i) { 484801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer switch(i->AuxType) { 485801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case ATFunctionDefinition: 486801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.FunctionDefinition.TagIndex); 487801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.FunctionDefinition.TotalSize); 488801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.FunctionDefinition.PointerToLinenumber); 489801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.FunctionDefinition.PointerToNextFunction); 490801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteZeros(sizeof(i->Aux.FunctionDefinition.unused)); 491801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer break; 492801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case ATbfAndefSymbol: 493801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused1)); 494801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(i->Aux.bfAndefSymbol.Linenumber); 495801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused2)); 496801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.bfAndefSymbol.PointerToNextFunction); 497801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused3)); 498801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer break; 499801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case ATWeakExternal: 500801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.WeakExternal.TagIndex); 501801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.WeakExternal.Characteristics); 502801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteZeros(sizeof(i->Aux.WeakExternal.unused)); 503801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer break; 504801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case ATFile: 505801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteBytes(StringRef(reinterpret_cast<const char *>(i->Aux.File.FileName), 506801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer sizeof(i->Aux.File.FileName))); 507801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer break; 508801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case ATSectionDefinition: 509801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.SectionDefinition.Length); 510801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(i->Aux.SectionDefinition.NumberOfRelocations); 511801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(i->Aux.SectionDefinition.NumberOfLinenumbers); 512801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.SectionDefinition.CheckSum); 513801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(i->Aux.SectionDefinition.Number); 514801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Write8(i->Aux.SectionDefinition.Selection); 515801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteZeros(sizeof(i->Aux.SectionDefinition.unused)); 516801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer break; 517801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 518801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 519801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 520801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 521801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::WriteSectionHeader(const COFF::section &S) { 522801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteBytes(StringRef(S.Name, COFF::NameSize)); 523801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 524801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S.VirtualSize); 525801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S.VirtualAddress); 526801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S.SizeOfRawData); 527801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S.PointerToRawData); 528801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S.PointerToRelocations); 529801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S.PointerToLineNumbers); 530801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(S.NumberOfRelocations); 531801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(S.NumberOfLineNumbers); 532801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S.Characteristics); 533801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 534801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 535801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::WriteRelocation(const COFF::relocation &R) { 536801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(R.VirtualAddress); 537801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(R.SymbolTableIndex); 538801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(R.Type); 539b162290e39afd49d4c7d342333b331bc96232720Chris Lattner} 540b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 541b162290e39afd49d4c7d342333b331bc96232720Chris Lattner//////////////////////////////////////////////////////////////////////////////// 542b162290e39afd49d4c7d342333b331bc96232720Chris Lattner// MCObjectWriter interface implementations 543b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 544b162290e39afd49d4c7d342333b331bc96232720Chris Lattnervoid WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm) { 545801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // "Define" each section & symbol. This creates section & symbol 546801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // entries in the staging area and gives them their final indexes. 547801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 548801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e; i++) 549801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer DefineSection(*i); 550801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 551801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (MCAssembler::const_symbol_iterator i = Asm.symbol_begin(), 552801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer e = Asm.symbol_end(); i != e; i++) { 553801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if (ExportSymbol(*i, Asm)) 554801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer DefineSymbol(*i, Asm); 555801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 556b162290e39afd49d4c7d342333b331bc96232720Chris Lattner} 557b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 558b162290e39afd49d4c7d342333b331bc96232720Chris Lattnervoid WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, 559b162290e39afd49d4c7d342333b331bc96232720Chris Lattner const MCAsmLayout &Layout, 560b162290e39afd49d4c7d342333b331bc96232720Chris Lattner const MCFragment *Fragment, 561b162290e39afd49d4c7d342333b331bc96232720Chris Lattner const MCFixup &Fixup, 562b162290e39afd49d4c7d342333b331bc96232720Chris Lattner MCValue Target, 563b162290e39afd49d4c7d342333b331bc96232720Chris Lattner uint64_t &FixedValue) { 564801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(Target.getSymA() != NULL && "Relocation must reference a symbol!"); 565801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(Target.getSymB() == NULL && 566801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Relocation must reference only one symbol!"); 567801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 568801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCSectionData const *SectionData = Fragment->getParent(); 569801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCSymbolData const *SymbolData = 570801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer &Asm.getSymbolData(Target.getSymA()->getSymbol()); 571801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 572801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(SectionMap.find(SectionData) != SectionMap.end() && 573801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Section must already have been defined in ExecutePostLayoutBinding!"); 574801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(SymbolMap.find(SymbolData) != SymbolMap.end() && 575801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Symbol must already have been defined in ExecutePostLayoutBinding!"); 576801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 577801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSection *coff_section = SectionMap[SectionData]; 578801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSymbol *coff_symbol = SymbolMap[SymbolData]; 579801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 580801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer FixedValue = Target.getConstant(); 581801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 582801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFRelocation Reloc; 583801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 584425f634917542d7f09c189e2eb130752c6a12d2cDaniel Dunbar Reloc.Data.SymbolTableIndex = 0; 585801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment); 586801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Reloc.Symb = coff_symbol; 587801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 588801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Reloc.Data.VirtualAddress += Fixup.getOffset(); 589801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 590801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer switch (Fixup.getKind()) { 591801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case FirstTargetFixupKind: // reloc_pcrel_4byte 592801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Reloc.Data.Type = COFF::IMAGE_REL_I386_REL32; 593801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer FixedValue += 4; 594801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer break; 595801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case FK_Data_4: 596801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Reloc.Data.Type = COFF::IMAGE_REL_I386_DIR32; 597801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer break; 598801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer default: 599801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer llvm_unreachable("unsupported relocation type"); 600801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 601801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 602801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_section->Relocations.push_back(Reloc); 603b162290e39afd49d4c7d342333b331bc96232720Chris Lattner} 604b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 605b162290e39afd49d4c7d342333b331bc96232720Chris Lattnervoid WinCOFFObjectWriter::WriteObject(const MCAssembler &Asm, 606b162290e39afd49d4c7d342333b331bc96232720Chris Lattner const MCAsmLayout &Layout) { 607801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Assign symbol and section indexes and offsets. 608801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 609801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Header.NumberOfSymbols = 0; 610801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 611801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) { 612801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSymbol *coff_symbol = *i; 613801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCSymbolData const *SymbolData = coff_symbol->MCData; 614801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 615801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Index = Header.NumberOfSymbols++; 616801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 617801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Update section number & offset for symbols that have them. 618801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if ((SymbolData != NULL) && (SymbolData->Fragment != NULL)) { 619801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSection *coff_section = SectionMap[SymbolData->Fragment->getParent()]; 620801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 621801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Data.SectionNumber = coff_section->Number; 622ef1f8c3cc3b509f83b1e887505881e4506602703Michael J. Spencer coff_symbol->Data.Value = Layout.getFragmentOffset(SymbolData->Fragment) 623ef1f8c3cc3b509f83b1e887505881e4506602703Michael J. Spencer + SymbolData->Offset; 624801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 625801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 626801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Update auxiliary symbol info. 627801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Data.NumberOfAuxSymbols = coff_symbol->Aux.size(); 628801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Header.NumberOfSymbols += coff_symbol->Data.NumberOfAuxSymbols; 629801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 630801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 631801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Fixup weak external references. 632801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) { 633801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSymbol *symb = *i; 634801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 635801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if (symb->Other != NULL) { 636801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(symb->Aux.size() == 1 && 637801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Symbol must contain one aux symbol!"); 638801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(symb->Aux[0].AuxType == ATWeakExternal && 639801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Symbol's aux symbol must be a Weak External!"); 640801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer symb->Aux[0].Aux.WeakExternal.TagIndex = symb->Other->Index; 641801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 642801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 643801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 644801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Assign file offsets to COFF object file structures. 645801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 646801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer unsigned offset = 0; 647801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 648801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer offset += COFF::HeaderSize; 649801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer offset += COFF::SectionSize * Asm.size(); 650801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 651801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Header.NumberOfSections = Sections.size(); 652801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 653801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (MCAssembler::const_iterator i = Asm.begin(), 654801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer e = Asm.end(); 655801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer i != e; i++) { 656801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSection *Sec = SectionMap[i]; 657801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 658801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Sec->Header.SizeOfRawData = Layout.getSectionFileSize(i); 659801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 660801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if (ExportSection(Sec)) { 661801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Sec->Header.PointerToRawData = offset; 662801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 663801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer offset += Sec->Header.SizeOfRawData; 664801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 665801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 666801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if (Sec->Relocations.size() > 0) { 667801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Sec->Header.NumberOfRelocations = Sec->Relocations.size(); 668801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Sec->Header.PointerToRelocations = offset; 669801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 670801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer offset += COFF::RelocationSize * Sec->Relocations.size(); 671801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 672801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (relocations::iterator cr = Sec->Relocations.begin(), 673801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer er = Sec->Relocations.end(); 674801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer cr != er; cr++) { 675801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer (*cr).Data.SymbolTableIndex = (*cr).Symb->Index; 676801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 677801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 678801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 679801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(Sec->Symb->Aux.size() == 1 && "Section's symbol must have one aux!"); 680801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer AuxSymbol &Aux = Sec->Symb->Aux[0]; 681801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(Aux.AuxType == ATSectionDefinition && 682801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Section's symbol's aux symbol must be a Section Definition!"); 683801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData; 684801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Aux.Aux.SectionDefinition.NumberOfRelocations = 685801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Sec->Header.NumberOfRelocations; 686801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Aux.Aux.SectionDefinition.NumberOfLinenumbers = 687801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Sec->Header.NumberOfLineNumbers; 688801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 689801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 690801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Header.PointerToSymbolTable = offset; 691801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 692ab3de49c48bd3282421ce24323fb6b868a3da6ccMichael J. Spencer Header.TimeDateStamp = sys::TimeValue::now().toEpochTime(); 693ab3de49c48bd3282421ce24323fb6b868a3da6ccMichael J. Spencer 694801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Write it all to disk... 695801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteFileHeader(Header); 696801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 697801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer { 698801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer sections::iterator i, ie; 699801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCAssembler::const_iterator j, je; 700801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 701801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (i = Sections.begin(), ie = Sections.end(); i != ie; i++) 702801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteSectionHeader((*i)->Header); 703801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 704801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (i = Sections.begin(), ie = Sections.end(), 705801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer j = Asm.begin(), je = Asm.end(); 706801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer (i != ie) && (j != je); i++, j++) { 707801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if ((*i)->Header.PointerToRawData != 0) { 708801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(OS.tell() == (*i)->Header.PointerToRawData && 709801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Section::PointerToRawData is insane!"); 710801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 711801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Asm.WriteSectionData(j, Layout, this); 712801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 713801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 714801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if ((*i)->Relocations.size() > 0) { 715801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(OS.tell() == (*i)->Header.PointerToRelocations && 716801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Section::PointerToRelocations is insane!"); 717801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 718801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (relocations::const_iterator k = (*i)->Relocations.begin(), 719801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer ke = (*i)->Relocations.end(); 720801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer k != ke; k++) { 721801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteRelocation(k->Data); 722801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 723801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } else 724801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert((*i)->Header.PointerToRelocations == 0 && 725801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Section::PointerToRelocations is insane!"); 726801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 727801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 728801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 729801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(OS.tell() == Header.PointerToSymbolTable && 730801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Header::PointerToSymbolTable is insane!"); 731801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 732801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) 733801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteSymbol(*i); 734801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 735801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer OS.write((char const *)&Strings.Data.front(), Strings.Data.size()); 736b162290e39afd49d4c7d342333b331bc96232720Chris Lattner} 737b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 738b162290e39afd49d4c7d342333b331bc96232720Chris Lattner//------------------------------------------------------------------------------ 739b162290e39afd49d4c7d342333b331bc96232720Chris Lattner// WinCOFFObjectWriter factory function 740b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 741b162290e39afd49d4c7d342333b331bc96232720Chris Lattnernamespace llvm { 742b162290e39afd49d4c7d342333b331bc96232720Chris Lattner MCObjectWriter *createWinCOFFObjectWriter(raw_ostream &OS) { 743b162290e39afd49d4c7d342333b331bc96232720Chris Lattner return new WinCOFFObjectWriter(OS); 744b162290e39afd49d4c7d342333b331bc96232720Chris Lattner } 745933304ef0c3ec18c23d0b385c2117a6eae790430Michael J. Spencer} 746