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