WinCOFFObjectWriter.cpp revision 28860823ad34d41d4f58561dc14a982fb0843fdd
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 16df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola#include "llvm/MC/MCWinCOFFObjectWriter.h" 17801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer#include "llvm/ADT/DenseMap.h" 18df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola#include "llvm/ADT/OwningPtr.h" 19801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer#include "llvm/ADT/StringMap.h" 20801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer#include "llvm/ADT/StringRef.h" 2180646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck#include "llvm/ADT/Twine.h" 22d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCAsmLayout.h" 23d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCAssembler.h" 24d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCContext.h" 25d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCExpr.h" 26d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCObjectWriter.h" 27d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCSection.h" 28d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCSectionCOFF.h" 29d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCSymbol.h" 30d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCValue.h" 31801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer#include "llvm/Support/COFF.h" 32801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer#include "llvm/Support/Debug.h" 33801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer#include "llvm/Support/ErrorHandling.h" 341f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/TimeValue.h" 35801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer#include <cstdio> 36801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 37b162290e39afd49d4c7d342333b331bc96232720Chris Lattnerusing namespace llvm; 38b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 39b162290e39afd49d4c7d342333b331bc96232720Chris Lattnernamespace { 4096f498bd9f140a98321c478f517877c4767b94faDmitri Gribenkotypedef SmallString<COFF::NameSize> name; 41801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 42801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerenum AuxiliaryType { 43801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer ATFunctionDefinition, 44801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer ATbfAndefSymbol, 45801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer ATWeakExternal, 46801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer ATFile, 47801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer ATSectionDefinition 48801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer}; 49801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 50801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerstruct AuxSymbol { 51801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer AuxiliaryType AuxType; 52801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFF::Auxiliary Aux; 53801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer}; 54801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 55a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencerclass COFFSymbol; 56a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencerclass COFFSection; 57a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 58801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerclass COFFSymbol { 59801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerpublic: 60801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFF::symbol Data; 61801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 6296f498bd9f140a98321c478f517877c4767b94faDmitri Gribenko typedef SmallVector<AuxSymbol, 1> AuxiliarySymbols; 63801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 64801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer name Name; 659cf23a9ab466a900bc0f937bc930d398d6097766Michael J. Spencer int Index; 66801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer AuxiliarySymbols Aux; 67801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSymbol *Other; 68a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer COFFSection *Section; 69a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer int Relocations; 70801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 71801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCSymbolData const *MCData; 72801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 7396f498bd9f140a98321c478f517877c4767b94faDmitri Gribenko COFFSymbol(StringRef name); 74801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer size_t size() const; 75801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void set_name_offset(uint32_t Offset); 76a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 77a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer bool should_keep() const; 78801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer}; 79801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 80801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// This class contains staging data for a COFF relocation entry. 81801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerstruct COFFRelocation { 82801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFF::relocation Data; 83801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSymbol *Symb; 84801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 85801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFRelocation() : Symb(NULL) {} 86801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer static size_t size() { return COFF::RelocationSize; } 87801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer}; 88801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 89801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencertypedef std::vector<COFFRelocation> relocations; 90801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 91801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerclass COFFSection { 92801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerpublic: 93801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFF::section Header; 94801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 95801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer std::string Name; 969cf23a9ab466a900bc0f937bc930d398d6097766Michael J. Spencer int Number; 97801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCSectionData const *MCData; 98a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer COFFSymbol *Symbol; 99801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer relocations Relocations; 100801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 10196f498bd9f140a98321c478f517877c4767b94faDmitri Gribenko COFFSection(StringRef name); 102801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer static size_t size(); 103801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer}; 104801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 105801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// This class holds the COFF string table. 106801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerclass StringTable { 10796f498bd9f140a98321c478f517877c4767b94faDmitri Gribenko typedef StringMap<size_t> map; 108801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer map Map; 109801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 110801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void update_length(); 111801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerpublic: 112801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer std::vector<char> Data; 113801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 114801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer StringTable(); 115801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer size_t size() const; 11696f498bd9f140a98321c478f517877c4767b94faDmitri Gribenko size_t insert(StringRef String); 117801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer}; 118801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 119801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerclass WinCOFFObjectWriter : public MCObjectWriter { 120801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerpublic: 121801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 122801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer typedef std::vector<COFFSymbol*> symbols; 123801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer typedef std::vector<COFFSection*> sections; 124b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 1254cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer typedef DenseMap<MCSymbol const *, COFFSymbol *> symbol_map; 1264cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer typedef DenseMap<MCSection const *, COFFSection *> section_map; 127b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 128df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola llvm::OwningPtr<MCWinCOFFObjectTargetWriter> TargetObjectWriter; 129df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola 130801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Root level file contents. 131801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFF::header Header; 132801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer sections Sections; 133801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer symbols Symbols; 134801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer StringTable Strings; 135b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 136801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Maps used during object file creation. 137801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer section_map SectionMap; 138801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer symbol_map SymbolMap; 139801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 140df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, raw_ostream &OS); 141808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin Kramer ~WinCOFFObjectWriter(); 142801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 1434cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer COFFSymbol *createSymbol(StringRef Name); 1444cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer COFFSymbol *GetOrCreateCOFFSymbol(const MCSymbol * Symbol); 1454cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer COFFSection *createSection(StringRef Name); 146801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 147801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer template <typename object_t, typename list_t> 14896f498bd9f140a98321c478f517877c4767b94faDmitri Gribenko object_t *createCOFFEntity(StringRef Name, list_t &List); 149801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 150801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void DefineSection(MCSectionData const &SectionData); 15128860823ad34d41d4f58561dc14a982fb0843fddReid Kleckner void DefineSymbol(MCSymbolData const &SymbolData, MCAssembler &Assembler, 15228860823ad34d41d4f58561dc14a982fb0843fddReid Kleckner const MCAsmLayout &Layout); 153801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 154a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer void MakeSymbolReal(COFFSymbol &S, size_t Index); 155a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer void MakeSectionReal(COFFSection &S, size_t Number); 156a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 157a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer bool IsPhysicalSection(COFFSection *S); 158a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 159801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Entity writing methods. 160801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 161801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void WriteFileHeader(const COFF::header &Header); 162801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void WriteSymbol(const COFFSymbol *S); 163801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols &S); 164801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void WriteSectionHeader(const COFF::section &S); 165801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void WriteRelocation(const COFF::relocation &R); 166801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 167801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // MCObjectWriter interface implementation. 168801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 16985f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout); 170801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 171801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer void RecordRelocation(const MCAssembler &Asm, 172801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer const MCAsmLayout &Layout, 173801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer const MCFragment *Fragment, 174801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer const MCFixup &Fixup, 175801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCValue Target, 176801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer uint64_t &FixedValue); 177801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 1788f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout); 179801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer}; 180801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 181801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 182801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencerstatic inline void write_uint32_le(void *Data, uint32_t const &Value) { 183801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer uint8_t *Ptr = reinterpret_cast<uint8_t *>(Data); 184801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Ptr[0] = (Value & 0x000000FF) >> 0; 185801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Ptr[1] = (Value & 0x0000FF00) >> 8; 186801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Ptr[2] = (Value & 0x00FF0000) >> 16; 187801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Ptr[3] = (Value & 0xFF000000) >> 24; 188801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 189801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 190801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer//------------------------------------------------------------------------------ 191801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// Symbol class implementation 192801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 19396f498bd9f140a98321c478f517877c4767b94faDmitri GribenkoCOFFSymbol::COFFSymbol(StringRef name) 194a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer : Name(name.begin(), name.end()) 195a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer , Other(NULL) 196a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer , Section(NULL) 197a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer , Relocations(0) 198a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer , MCData(NULL) { 199801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer memset(&Data, 0, sizeof(Data)); 200801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 201b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 202801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencersize_t COFFSymbol::size() const { 203801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return COFF::SymbolSize + (Data.NumberOfAuxSymbols * COFF::SymbolSize); 204b162290e39afd49d4c7d342333b331bc96232720Chris Lattner} 205b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 206801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// In the case that the name does not fit within 8 bytes, the offset 207801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// into the string table is stored in the last 4 bytes instead, leaving 208801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// the first 4 bytes as 0. 209801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid COFFSymbol::set_name_offset(uint32_t Offset) { 210801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer write_uint32_le(Data.Name + 0, 0); 211801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer write_uint32_le(Data.Name + 4, Offset); 212801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 213801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 214a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer/// logic to decide if the symbol should be reported in the symbol table 215a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencerbool COFFSymbol::should_keep() const { 216a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // no section means its external, keep it 217a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (Section == NULL) 218a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer return true; 219a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 220a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // if it has relocations pointing at it, keep it 221a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (Relocations > 0) { 222a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer assert(Section->Number != -1 && "Sections with relocations must be real!"); 223a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer return true; 224a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer } 225a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 226a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // if the section its in is being droped, drop it 227a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (Section->Number == -1) 228a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer return false; 229a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 230a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // if it is the section symbol, keep it 231a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (Section->Symbol == this) 232a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer return true; 233a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 234a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // if its temporary, drop it 235a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (MCData && MCData->getSymbol().isTemporary()) 236a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer return false; 237a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 238a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // otherwise, keep it 239a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer return true; 240a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer} 241a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 242801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer//------------------------------------------------------------------------------ 243801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// Section class implementation 244801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 24596f498bd9f140a98321c478f517877c4767b94faDmitri GribenkoCOFFSection::COFFSection(StringRef name) 246a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer : Name(name) 247a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer , MCData(NULL) 248a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer , Symbol(NULL) { 249801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer memset(&Header, 0, sizeof(Header)); 250801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 251801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 252801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencersize_t COFFSection::size() { 253801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return COFF::SectionSize; 254801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 255801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 256801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer//------------------------------------------------------------------------------ 257801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// StringTable class implementation 258801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 259801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// Write the length of the string table into Data. 260801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// The length of the string table includes uint32 length header. 261801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid StringTable::update_length() { 262801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer write_uint32_le(&Data.front(), Data.size()); 263801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 264801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 265801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. SpencerStringTable::StringTable() { 266801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // The string table data begins with the length of the entire string table 267801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // including the length header. Allocate space for this header. 268801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Data.resize(4); 2690d64632c9e8a2632b8804bcc3fbc3523588862a7Michael J. Spencer update_length(); 270801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 271801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 272801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencersize_t StringTable::size() const { 273801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return Data.size(); 274801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 275801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 27694c22716d60ff5edf6a98a3c67e0faa001be1142Sylvestre Ledru/// Add String to the table iff it is not already there. 277801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// @returns the index into the string table where the string is now located. 27896f498bd9f140a98321c478f517877c4767b94faDmitri Gribenkosize_t StringTable::insert(StringRef String) { 279801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer map::iterator i = Map.find(String); 280801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 281801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if (i != Map.end()) 282801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return i->second; 283801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 284801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer size_t Offset = Data.size(); 285801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 286801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Insert string data into string table. 287801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Data.insert(Data.end(), String.begin(), String.end()); 288801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Data.push_back('\0'); 289801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 290801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Put a reference to it in the map. 291801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Map[String] = Offset; 292801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 293801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Update the internal length field. 294801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer update_length(); 295801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 296801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return Offset; 297801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 298801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 299801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer//------------------------------------------------------------------------------ 300801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// WinCOFFObjectWriter class implementation 301801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 302df09270ae897e7fa64a7c162de163c32ee181a03Rafael EspindolaWinCOFFObjectWriter::WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, 303df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola raw_ostream &OS) 30482c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer : MCObjectWriter(OS, true) 305df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola , TargetObjectWriter(MOTW) { 306801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer memset(&Header, 0, sizeof(Header)); 307da0bfcdaf95d95a66e306ef6d45f638939272d34Michael J. Spencer 308df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola Header.Machine = TargetObjectWriter->getMachine(); 309801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 310801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 311808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin KramerWinCOFFObjectWriter::~WinCOFFObjectWriter() { 312808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin Kramer for (symbols::iterator I = Symbols.begin(), E = Symbols.end(); I != E; ++I) 313808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin Kramer delete *I; 314808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin Kramer for (sections::iterator I = Sections.begin(), E = Sections.end(); I != E; ++I) 315808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin Kramer delete *I; 316808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin Kramer} 317808ecfce6a312625bee5c0f4f9831a0d0ed01b16Benjamin Kramer 3184cee2890a66974af506f2125243114cc14bd5556Michael J. SpencerCOFFSymbol *WinCOFFObjectWriter::createSymbol(StringRef Name) { 319801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return createCOFFEntity<COFFSymbol>(Name, Symbols); 320801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 321801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 3224cee2890a66974af506f2125243114cc14bd5556Michael J. SpencerCOFFSymbol *WinCOFFObjectWriter::GetOrCreateCOFFSymbol(const MCSymbol * Symbol){ 3234cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer symbol_map::iterator i = SymbolMap.find(Symbol); 3244cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer if (i != SymbolMap.end()) 3254cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer return i->second; 3264cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer COFFSymbol *RetSymbol 3274cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer = createCOFFEntity<COFFSymbol>(Symbol->getName(), Symbols); 3284cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer SymbolMap[Symbol] = RetSymbol; 3294cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer return RetSymbol; 3304cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer} 3314cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer 33296f498bd9f140a98321c478f517877c4767b94faDmitri GribenkoCOFFSection *WinCOFFObjectWriter::createSection(StringRef Name) { 333801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return createCOFFEntity<COFFSection>(Name, Sections); 334801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 335801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 336801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// A template used to lookup or create a symbol/section, and initialize it if 337801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// needed. 338801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencertemplate <typename object_t, typename list_t> 33996f498bd9f140a98321c478f517877c4767b94faDmitri Gribenkoobject_t *WinCOFFObjectWriter::createCOFFEntity(StringRef Name, 340801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer list_t &List) { 341a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer object_t *Object = new object_t(Name); 342801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 343801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer List.push_back(Object); 344801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 345801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer return Object; 346801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 347801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 348801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// This function takes a section data object from the assembler 349801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// and creates the associated COFF section staging object. 350801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) { 351d47f4a9c982d264e46a6a2fe0f357288768bb5b9Michael J. Spencer assert(SectionData.getSection().getVariant() == MCSection::SV_COFF 352d47f4a9c982d264e46a6a2fe0f357288768bb5b9Michael J. Spencer && "Got non COFF section in the COFF backend!"); 353801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // FIXME: Not sure how to verify this (at least in a debug build). 354801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCSectionCOFF const &Sec = 355801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer static_cast<MCSectionCOFF const &>(SectionData.getSection()); 356801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 357801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSection *coff_section = createSection(Sec.getSectionName()); 358801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSymbol *coff_symbol = createSymbol(Sec.getSectionName()); 359801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 360a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer coff_section->Symbol = coff_symbol; 361a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer coff_symbol->Section = coff_section; 362801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_STATIC; 363801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 364801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // In this case the auxiliary symbol is a Section Definition. 365801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux.resize(1); 366801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0])); 367801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux[0].AuxType = ATSectionDefinition; 368801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux[0].Aux.SectionDefinition.Selection = Sec.getSelection(); 369801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 370801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_section->Header.Characteristics = Sec.getCharacteristics(); 371801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 372801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer uint32_t &Characteristics = coff_section->Header.Characteristics; 373801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer switch (SectionData.getAlignment()) { 374801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 1: Characteristics |= COFF::IMAGE_SCN_ALIGN_1BYTES; break; 375801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 2: Characteristics |= COFF::IMAGE_SCN_ALIGN_2BYTES; break; 376801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 4: Characteristics |= COFF::IMAGE_SCN_ALIGN_4BYTES; break; 377801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 8: Characteristics |= COFF::IMAGE_SCN_ALIGN_8BYTES; break; 378801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 16: Characteristics |= COFF::IMAGE_SCN_ALIGN_16BYTES; break; 379801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 32: Characteristics |= COFF::IMAGE_SCN_ALIGN_32BYTES; break; 380801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 64: Characteristics |= COFF::IMAGE_SCN_ALIGN_64BYTES; break; 381801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 128: Characteristics |= COFF::IMAGE_SCN_ALIGN_128BYTES; break; 382801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 256: Characteristics |= COFF::IMAGE_SCN_ALIGN_256BYTES; break; 383801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 512: Characteristics |= COFF::IMAGE_SCN_ALIGN_512BYTES; break; 384801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 1024: Characteristics |= COFF::IMAGE_SCN_ALIGN_1024BYTES; break; 385801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 2048: Characteristics |= COFF::IMAGE_SCN_ALIGN_2048BYTES; break; 386801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 4096: Characteristics |= COFF::IMAGE_SCN_ALIGN_4096BYTES; break; 387801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case 8192: Characteristics |= COFF::IMAGE_SCN_ALIGN_8192BYTES; break; 388801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer default: 389801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer llvm_unreachable("unsupported section alignment"); 390801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 391801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 392801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Bind internal COFF section to MC section. 393801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_section->MCData = &SectionData; 3944cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer SectionMap[&SectionData.getSection()] = coff_section; 395801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 396801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 397801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// This function takes a section data object from the assembler 398801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer/// and creates the associated COFF symbol staging object. 3994974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbournevoid WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData, 40028860823ad34d41d4f58561dc14a982fb0843fddReid Kleckner MCAssembler &Assembler, 40128860823ad34d41d4f58561dc14a982fb0843fddReid Kleckner const MCAsmLayout &Layout) { 4024974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne MCSymbol const &Symbol = SymbolData.getSymbol(); 4030933134a304b47d3767aad202df9f0e09743da6dMichael J. Spencer COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&Symbol); 4044974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne SymbolMap[&Symbol] = coff_symbol; 405801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 4064cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer if (SymbolData.getFlags() & COFF::SF_WeakExternal) { 407801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL; 408801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 4090933134a304b47d3767aad202df9f0e09743da6dMichael J. Spencer if (Symbol.isVariable()) { 4104974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne const MCSymbolRefExpr *SymRef = 4114974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne dyn_cast<MCSymbolRefExpr>(Symbol.getVariableValue()); 412801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 4134974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne if (!SymRef) 4144974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne report_fatal_error("Weak externals may only alias symbols"); 415801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 4164974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne coff_symbol->Other = GetOrCreateCOFFSymbol(&SymRef->getSymbol()); 4174cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer } else { 4184cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer std::string WeakName = std::string(".weak.") 4190933134a304b47d3767aad202df9f0e09743da6dMichael J. Spencer + Symbol.getName().str() 4204cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer + ".default"; 4214cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer COFFSymbol *WeakDefault = createSymbol(WeakName); 4224cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE; 4234cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer WeakDefault->Data.StorageClass = COFF::IMAGE_SYM_CLASS_EXTERNAL; 4244cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer WeakDefault->Data.Type = 0; 4254cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer WeakDefault->Data.Value = 0; 4264cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer coff_symbol->Other = WeakDefault; 4274cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer } 428801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 429801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Setup the Weak External auxiliary symbol. 430801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux.resize(1); 431801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0])); 432801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux[0].AuxType = ATWeakExternal; 433801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = 0; 434801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_symbol->Aux[0].Aux.WeakExternal.Characteristics = 4354cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY; 4364cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer 4374974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne coff_symbol->MCData = &SymbolData; 4384974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne } else { 4394974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne const MCSymbolData &ResSymData = 4404974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne Assembler.getSymbolData(Symbol.AliasedSymbol()); 4414cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer 44228860823ad34d41d4f58561dc14a982fb0843fddReid Kleckner if (Symbol.isVariable()) { 44328860823ad34d41d4f58561dc14a982fb0843fddReid Kleckner int64_t Addr; 44428860823ad34d41d4f58561dc14a982fb0843fddReid Kleckner if (Symbol.getVariableValue()->EvaluateAsAbsolute(Addr, Layout)) 44528860823ad34d41d4f58561dc14a982fb0843fddReid Kleckner coff_symbol->Data.Value = Addr; 44628860823ad34d41d4f58561dc14a982fb0843fddReid Kleckner } 44728860823ad34d41d4f58561dc14a982fb0843fddReid Kleckner 4484974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne coff_symbol->Data.Type = (ResSymData.getFlags() & 0x0000FFFF) >> 0; 4494974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne coff_symbol->Data.StorageClass = (ResSymData.getFlags() & 0x00FF0000) >> 16; 450801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 4514974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne // If no storage class was specified in the streamer, define it here. 4524974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne if (coff_symbol->Data.StorageClass == 0) { 4534974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne bool external = ResSymData.isExternal() || (ResSymData.Fragment == NULL); 454a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 4554974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne coff_symbol->Data.StorageClass = 4564974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne external ? COFF::IMAGE_SYM_CLASS_EXTERNAL : COFF::IMAGE_SYM_CLASS_STATIC; 4574974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne } 4584974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne 45928860823ad34d41d4f58561dc14a982fb0843fddReid Kleckner if (Symbol.isAbsolute() || Symbol.AliasedSymbol().isVariable()) 46028860823ad34d41d4f58561dc14a982fb0843fddReid Kleckner coff_symbol->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE; 46128860823ad34d41d4f58561dc14a982fb0843fddReid Kleckner else if (ResSymData.Fragment != NULL) 4624974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne coff_symbol->Section = 4634974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne SectionMap[&ResSymData.Fragment->getParent()->getSection()]; 4644974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne 4654974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne coff_symbol->MCData = &ResSymData; 4664974b972e7dd94fad74ada4df32a12aba09c4de0Peter Collingbourne } 467801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 468801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 469a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer/// making a section real involves assigned it a number and putting 470a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer/// name into the string table if needed 471a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencervoid WinCOFFObjectWriter::MakeSectionReal(COFFSection &S, size_t Number) { 472a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (S.Name.size() > COFF::NameSize) { 473c63dce3c59ac24b2656e06f7017cd4dce4bf733cNico Rieck const unsigned Max6DecimalSize = 999999; 474c63dce3c59ac24b2656e06f7017cd4dce4bf733cNico Rieck const unsigned Max7DecimalSize = 9999999; 475c63dce3c59ac24b2656e06f7017cd4dce4bf733cNico Rieck uint64_t StringTableEntry = Strings.insert(S.Name.c_str()); 476c63dce3c59ac24b2656e06f7017cd4dce4bf733cNico Rieck 477c63dce3c59ac24b2656e06f7017cd4dce4bf733cNico Rieck if (StringTableEntry <= Max6DecimalSize) { 478c63dce3c59ac24b2656e06f7017cd4dce4bf733cNico Rieck std::sprintf(S.Header.Name, "/%d", unsigned(StringTableEntry)); 479c63dce3c59ac24b2656e06f7017cd4dce4bf733cNico Rieck } else if (StringTableEntry <= Max7DecimalSize) { 480c63dce3c59ac24b2656e06f7017cd4dce4bf733cNico Rieck // With seven digits, we have to skip the terminating null. Because 481c63dce3c59ac24b2656e06f7017cd4dce4bf733cNico Rieck // sprintf always appends it, we use a larger temporary buffer. 482c63dce3c59ac24b2656e06f7017cd4dce4bf733cNico Rieck char buffer[9] = { }; 483c63dce3c59ac24b2656e06f7017cd4dce4bf733cNico Rieck std::sprintf(buffer, "/%d", unsigned(StringTableEntry)); 484c63dce3c59ac24b2656e06f7017cd4dce4bf733cNico Rieck std::memcpy(S.Header.Name, buffer, 8); 485c63dce3c59ac24b2656e06f7017cd4dce4bf733cNico Rieck } else { 486c63dce3c59ac24b2656e06f7017cd4dce4bf733cNico Rieck report_fatal_error("COFF string table is greater than 9,999,999 bytes."); 487c63dce3c59ac24b2656e06f7017cd4dce4bf733cNico Rieck } 488a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer } else 489a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size()); 490a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 491a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer S.Number = Number; 492a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer S.Symbol->Data.SectionNumber = S.Number; 493a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer S.Symbol->Aux[0].Aux.SectionDefinition.Number = S.Number; 494a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer} 495a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 496a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencervoid WinCOFFObjectWriter::MakeSymbolReal(COFFSymbol &S, size_t Index) { 497a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (S.Name.size() > COFF::NameSize) { 498a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer size_t StringTableEntry = Strings.insert(S.Name.c_str()); 499a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 500a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer S.set_name_offset(StringTableEntry); 501a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer } else 502a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size()); 503a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer S.Index = Index; 504a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer} 505a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 506a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencerbool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) { 507a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer return (S->Header.Characteristics 508a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0; 509801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 510801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 511801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer//------------------------------------------------------------------------------ 512801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer// entity writing methods 513801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 514801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::WriteFileHeader(const COFF::header &Header) { 515801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(Header.Machine); 516801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(Header.NumberOfSections); 517801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(Header.TimeDateStamp); 518801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(Header.PointerToSymbolTable); 519801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(Header.NumberOfSymbols); 520801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(Header.SizeOfOptionalHeader); 521801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(Header.Characteristics); 522801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 523801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 524801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::WriteSymbol(const COFFSymbol *S) { 525801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteBytes(StringRef(S->Data.Name, COFF::NameSize)); 526801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S->Data.Value); 527801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(S->Data.SectionNumber); 528801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(S->Data.Type); 529801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Write8(S->Data.StorageClass); 530801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Write8(S->Data.NumberOfAuxSymbols); 531801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteAuxiliarySymbols(S->Aux); 532801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 533801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 534801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::WriteAuxiliarySymbols( 535801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer const COFFSymbol::AuxiliarySymbols &S) { 536801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for(COFFSymbol::AuxiliarySymbols::const_iterator i = S.begin(), e = S.end(); 537801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer i != e; ++i) { 538801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer switch(i->AuxType) { 539801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case ATFunctionDefinition: 540801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.FunctionDefinition.TagIndex); 541801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.FunctionDefinition.TotalSize); 542801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.FunctionDefinition.PointerToLinenumber); 543801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.FunctionDefinition.PointerToNextFunction); 544801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteZeros(sizeof(i->Aux.FunctionDefinition.unused)); 545801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer break; 546801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case ATbfAndefSymbol: 547801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused1)); 548801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(i->Aux.bfAndefSymbol.Linenumber); 549801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused2)); 550801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.bfAndefSymbol.PointerToNextFunction); 551801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused3)); 552801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer break; 553801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case ATWeakExternal: 554801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.WeakExternal.TagIndex); 555801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.WeakExternal.Characteristics); 556801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteZeros(sizeof(i->Aux.WeakExternal.unused)); 557801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer break; 558801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case ATFile: 559801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteBytes(StringRef(reinterpret_cast<const char *>(i->Aux.File.FileName), 560801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer sizeof(i->Aux.File.FileName))); 561801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer break; 562801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer case ATSectionDefinition: 563801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.SectionDefinition.Length); 564801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(i->Aux.SectionDefinition.NumberOfRelocations); 565801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(i->Aux.SectionDefinition.NumberOfLinenumbers); 566801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(i->Aux.SectionDefinition.CheckSum); 567801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(i->Aux.SectionDefinition.Number); 568801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Write8(i->Aux.SectionDefinition.Selection); 569801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteZeros(sizeof(i->Aux.SectionDefinition.unused)); 570801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer break; 571801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 572801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 573801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 574801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 575801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::WriteSectionHeader(const COFF::section &S) { 576801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteBytes(StringRef(S.Name, COFF::NameSize)); 577801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 578801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S.VirtualSize); 579801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S.VirtualAddress); 580801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S.SizeOfRawData); 581801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S.PointerToRawData); 582801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S.PointerToRelocations); 583801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S.PointerToLineNumbers); 584801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(S.NumberOfRelocations); 585801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(S.NumberOfLineNumbers); 586801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(S.Characteristics); 587801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer} 588801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 589801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencervoid WinCOFFObjectWriter::WriteRelocation(const COFF::relocation &R) { 590801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(R.VirtualAddress); 591801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE32(R.SymbolTableIndex); 592801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteLE16(R.Type); 593b162290e39afd49d4c7d342333b331bc96232720Chris Lattner} 594b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 595b162290e39afd49d4c7d342333b331bc96232720Chris Lattner//////////////////////////////////////////////////////////////////////////////// 596b162290e39afd49d4c7d342333b331bc96232720Chris Lattner// MCObjectWriter interface implementations 597b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 59885f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindolavoid WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, 59985f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola const MCAsmLayout &Layout) { 600801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // "Define" each section & symbol. This creates section & symbol 601a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // entries in the staging area. 602801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 603801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e; i++) 604801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer DefineSection(*i); 605801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 606801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (MCAssembler::const_symbol_iterator i = Asm.symbol_begin(), 6073168868bb91ac871dbb83c879e763d39a39e607eReid Kleckner e = Asm.symbol_end(); 6083168868bb91ac871dbb83c879e763d39a39e607eReid Kleckner i != e; i++) 60928860823ad34d41d4f58561dc14a982fb0843fddReid Kleckner DefineSymbol(*i, Asm, Layout); 610b162290e39afd49d4c7d342333b331bc96232720Chris Lattner} 611b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 612b162290e39afd49d4c7d342333b331bc96232720Chris Lattnervoid WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, 613b162290e39afd49d4c7d342333b331bc96232720Chris Lattner const MCAsmLayout &Layout, 614b162290e39afd49d4c7d342333b331bc96232720Chris Lattner const MCFragment *Fragment, 615b162290e39afd49d4c7d342333b331bc96232720Chris Lattner const MCFixup &Fixup, 616b162290e39afd49d4c7d342333b331bc96232720Chris Lattner MCValue Target, 617b162290e39afd49d4c7d342333b331bc96232720Chris Lattner uint64_t &FixedValue) { 618801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(Target.getSymA() != NULL && "Relocation must reference a symbol!"); 61982c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer 6206057eb7ab697fcd0feb3cdd55e9a497cfe0aff72Reid Kleckner const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 6216057eb7ab697fcd0feb3cdd55e9a497cfe0aff72Reid Kleckner const MCSymbol &A = Symbol.AliasedSymbol(); 6226057eb7ab697fcd0feb3cdd55e9a497cfe0aff72Reid Kleckner MCSymbolData &A_SD = Asm.getSymbolData(A); 623801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 624801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCSectionData const *SectionData = Fragment->getParent(); 625801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 62682c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer // Mark this symbol as requiring an entry in the symbol table. 6274cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer assert(SectionMap.find(&SectionData->getSection()) != SectionMap.end() && 628801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Section must already have been defined in ExecutePostLayoutBinding!"); 6294cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer assert(SymbolMap.find(&A_SD.getSymbol()) != SymbolMap.end() && 630801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Symbol must already have been defined in ExecutePostLayoutBinding!"); 631801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 6324cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer COFFSection *coff_section = SectionMap[&SectionData->getSection()]; 6334cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer COFFSymbol *coff_symbol = SymbolMap[&A_SD.getSymbol()]; 6343660a847f1820d73847539f3959dc069396f8e44Rafael Espindola const MCSymbolRefExpr *SymA = Target.getSymA(); 6353660a847f1820d73847539f3959dc069396f8e44Rafael Espindola const MCSymbolRefExpr *SymB = Target.getSymB(); 6363660a847f1820d73847539f3959dc069396f8e44Rafael Espindola const bool CrossSection = SymB && 6373660a847f1820d73847539f3959dc069396f8e44Rafael Espindola &SymA->getSymbol().getSection() != &SymB->getSymbol().getSection(); 63882c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer 63982c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer if (Target.getSymB()) { 64082c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer const MCSymbol *B = &Target.getSymB()->getSymbol(); 64182c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer MCSymbolData &B_SD = Asm.getSymbolData(*B); 642801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 6431ac7fe0f4dae8a9266fa6ff31ea4939ec64a3e5eRafael Espindola // Offset of the symbol in the section 6441ac7fe0f4dae8a9266fa6ff31ea4939ec64a3e5eRafael Espindola int64_t a = Layout.getSymbolOffset(&B_SD); 64582c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer 6461ac7fe0f4dae8a9266fa6ff31ea4939ec64a3e5eRafael Espindola // Ofeset of the relocation in the section 6471ac7fe0f4dae8a9266fa6ff31ea4939ec64a3e5eRafael Espindola int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); 6481ac7fe0f4dae8a9266fa6ff31ea4939ec64a3e5eRafael Espindola 6491ac7fe0f4dae8a9266fa6ff31ea4939ec64a3e5eRafael Espindola FixedValue = b - a; 65082c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer // In the case where we have SymbA and SymB, we just need to store the delta 65182c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer // between the two symbols. Update FixedValue to account for the delta, and 65282c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer // skip recording the relocation. 6533660a847f1820d73847539f3959dc069396f8e44Rafael Espindola if (!CrossSection) 6543660a847f1820d73847539f3959dc069396f8e44Rafael Espindola return; 65582c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer } else { 65682c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer FixedValue = Target.getConstant(); 65782c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer } 658801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 659801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFRelocation Reloc; 660801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 661425f634917542d7f09c189e2eb130752c6a12d2cDaniel Dunbar Reloc.Data.SymbolTableIndex = 0; 662801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment); 663a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 664ea1104a4c376634ed8eb693f6c71e0ac51074949Michael J. Spencer // Turn relocations for temporary symbols into section relocations. 6653660a847f1820d73847539f3959dc069396f8e44Rafael Espindola if (coff_symbol->MCData->getSymbol().isTemporary() || CrossSection) { 666a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer Reloc.Symb = coff_symbol->Section->Symbol; 667eb6e77f8cccd14cdba995ff8231f2c9faea9bfccMichael J. Spencer FixedValue += Layout.getFragmentOffset(coff_symbol->MCData->Fragment) 668eb6e77f8cccd14cdba995ff8231f2c9faea9bfccMichael J. Spencer + coff_symbol->MCData->getOffset(); 669a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer } else 670a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer Reloc.Symb = coff_symbol; 671a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 672a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer ++Reloc.Symb->Relocations; 673801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 674801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Reloc.Data.VirtualAddress += Fixup.getOffset(); 67518d49acdab79d6f0966b47182b6c3a2ba3d9f80fNico Rieck Reloc.Data.Type = TargetObjectWriter->getRelocType(Target, Fixup, 67618d49acdab79d6f0966b47182b6c3a2ba3d9f80fNico Rieck CrossSection); 677b156c5d3765637393eda28b04b7fc1e5c55675ebRafael Espindola 678b156c5d3765637393eda28b04b7fc1e5c55675ebRafael Espindola // FIXME: Can anyone explain what this does other than adjust for the size 679b156c5d3765637393eda28b04b7fc1e5c55675ebRafael Espindola // of the offset? 680b156c5d3765637393eda28b04b7fc1e5c55675ebRafael Espindola if (Reloc.Data.Type == COFF::IMAGE_REL_AMD64_REL32 || 681b156c5d3765637393eda28b04b7fc1e5c55675ebRafael Espindola Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32) 68282c84fdd23669d23c02a07498c83b83702979829Michael J. Spencer FixedValue += 4; 683801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 684801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer coff_section->Relocations.push_back(Reloc); 685b162290e39afd49d4c7d342333b331bc96232720Chris Lattner} 686b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 6878f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindolavoid WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, 688b162290e39afd49d4c7d342333b331bc96232720Chris Lattner const MCAsmLayout &Layout) { 689801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Assign symbol and section indexes and offsets. 690a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer Header.NumberOfSections = 0; 691a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 69280646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck DenseMap<COFFSection *, uint16_t> SectionIndices; 693a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer for (sections::iterator i = Sections.begin(), 694a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer e = Sections.end(); i != e; i++) { 69585f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola if (Layout.getSectionAddressSize((*i)->MCData) > 0) { 69680646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck size_t Number = ++Header.NumberOfSections; 69780646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck SectionIndices[*i] = Number; 69880646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck MakeSectionReal(**i, Number); 699a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer } else { 700a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer (*i)->Number = -1; 701a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer } 702a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer } 703801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 704801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Header.NumberOfSymbols = 0; 705801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 706801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) { 707801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer COFFSymbol *coff_symbol = *i; 708801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCSymbolData const *SymbolData = coff_symbol->MCData; 709801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 710801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Update section number & offset for symbols that have them. 711801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if ((SymbolData != NULL) && (SymbolData->Fragment != NULL)) { 712a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer assert(coff_symbol->Section != NULL); 713801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 714a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer coff_symbol->Data.SectionNumber = coff_symbol->Section->Number; 715237f8fe5df628065874b8590b364d04dfc2686fdMichael J. Spencer coff_symbol->Data.Value = Layout.getFragmentOffset(SymbolData->Fragment) 716237f8fe5df628065874b8590b364d04dfc2686fdMichael J. Spencer + SymbolData->Offset; 717801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 718801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 719a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (coff_symbol->should_keep()) { 720a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer MakeSymbolReal(*coff_symbol, Header.NumberOfSymbols++); 721a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 722a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer // Update auxiliary symbol info. 723a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer coff_symbol->Data.NumberOfAuxSymbols = coff_symbol->Aux.size(); 724a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer Header.NumberOfSymbols += coff_symbol->Data.NumberOfAuxSymbols; 725a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer } else 726a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer coff_symbol->Index = -1; 727801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 728801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 729801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Fixup weak external references. 730801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) { 731a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer COFFSymbol *coff_symbol = *i; 732a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (coff_symbol->Other != NULL) { 733a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer assert(coff_symbol->Index != -1); 734a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer assert(coff_symbol->Aux.size() == 1 && 735801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Symbol must contain one aux symbol!"); 736a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer assert(coff_symbol->Aux[0].AuxType == ATWeakExternal && 737801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Symbol's aux symbol must be a Weak External!"); 738a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = coff_symbol->Other->Index; 739801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 740801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 741801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 74280646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck // Fixup associative COMDAT sections. 74380646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck for (sections::iterator i = Sections.begin(), 74480646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck e = Sections.end(); i != e; i++) { 74580646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck if ((*i)->Symbol->Aux[0].Aux.SectionDefinition.Selection != 74680646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) 74780646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck continue; 74880646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck 74980646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck const MCSectionCOFF &MCSec = static_cast<const MCSectionCOFF &>( 75080646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck (*i)->MCData->getSection()); 75180646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck 75280646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck COFFSection *Assoc = SectionMap.lookup(MCSec.getAssocSection()); 75380646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck if (!Assoc) { 75480646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck report_fatal_error(Twine("Missing associated COMDAT section ") + 75580646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck MCSec.getAssocSection()->getSectionName() + 75680646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck " for section " + MCSec.getSectionName()); 75780646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck } 75880646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck 75980646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck // Skip this section if the associated section is unused. 76080646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck if (Assoc->Number == -1) 76180646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck continue; 76280646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck 76380646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck (*i)->Symbol->Aux[0].Aux.SectionDefinition.Number = SectionIndices[Assoc]; 76480646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck } 76580646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck 76680646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck 767801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Assign file offsets to COFF object file structures. 768801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 769801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer unsigned offset = 0; 770801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 771801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer offset += COFF::HeaderSize; 772a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer offset += COFF::SectionSize * Header.NumberOfSections; 773801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 774801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (MCAssembler::const_iterator i = Asm.begin(), 775801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer e = Asm.end(); 776801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer i != e; i++) { 7774cee2890a66974af506f2125243114cc14bd5556Michael J. Spencer COFFSection *Sec = SectionMap[&i->getSection()]; 778801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 779a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (Sec->Number == -1) 780a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer continue; 781a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 78228ca86aa19fe2a5493573164ef0c2c54542ed9daMichael J. Spencer Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(i); 783801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 784a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if (IsPhysicalSection(Sec)) { 785801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Sec->Header.PointerToRawData = offset; 786801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 787801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer offset += Sec->Header.SizeOfRawData; 788801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 789801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 790801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if (Sec->Relocations.size() > 0) { 791d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer bool RelocationsOverflow = Sec->Relocations.size() >= 0xffff; 792d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer 793d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer if (RelocationsOverflow) { 794d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer // Signal overflow by setting NumberOfSections to max value. Actual 795d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer // size is found in reloc #0. Microsoft tools understand this. 796d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer Sec->Header.NumberOfRelocations = 0xffff; 797d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer } else { 798d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer Sec->Header.NumberOfRelocations = Sec->Relocations.size(); 799d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer } 800801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Sec->Header.PointerToRelocations = offset; 801801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 802d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer if (RelocationsOverflow) { 803d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer // Reloc #0 will contain actual count, so make room for it. 804d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer offset += COFF::RelocationSize; 805d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer } 806d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer 807801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer offset += COFF::RelocationSize * Sec->Relocations.size(); 808801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 809801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (relocations::iterator cr = Sec->Relocations.begin(), 810801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer er = Sec->Relocations.end(); 811a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer cr != er; ++cr) { 812a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer assert((*cr).Symb->Index != -1); 813801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer (*cr).Data.SymbolTableIndex = (*cr).Symb->Index; 814801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 815801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 816801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 817a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer assert(Sec->Symbol->Aux.size() == 1 818a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer && "Section's symbol must have one aux!"); 819a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer AuxSymbol &Aux = Sec->Symbol->Aux[0]; 820801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(Aux.AuxType == ATSectionDefinition && 821801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Section's symbol's aux symbol must be a Section Definition!"); 822801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData; 823801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Aux.Aux.SectionDefinition.NumberOfRelocations = 824801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Sec->Header.NumberOfRelocations; 825801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Aux.Aux.SectionDefinition.NumberOfLinenumbers = 826801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Sec->Header.NumberOfLineNumbers; 827801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 828801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 829801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer Header.PointerToSymbolTable = offset; 830801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 831ab3de49c48bd3282421ce24323fb6b868a3da6ccMichael J. Spencer Header.TimeDateStamp = sys::TimeValue::now().toEpochTime(); 832ab3de49c48bd3282421ce24323fb6b868a3da6ccMichael J. Spencer 833801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer // Write it all to disk... 834801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteFileHeader(Header); 835801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 836801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer { 837801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer sections::iterator i, ie; 838801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer MCAssembler::const_iterator j, je; 839801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 840801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (i = Sections.begin(), ie = Sections.end(); i != ie; i++) 841d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer if ((*i)->Number != -1) { 842d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer if ((*i)->Relocations.size() >= 0xffff) { 843d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer (*i)->Header.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL; 844d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer } 845a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer WriteSectionHeader((*i)->Header); 846d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer } 847801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 848801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (i = Sections.begin(), ie = Sections.end(), 849801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer j = Asm.begin(), je = Asm.end(); 850a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer (i != ie) && (j != je); ++i, ++j) { 851a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 852a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if ((*i)->Number == -1) 853a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer continue; 854a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer 855801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if ((*i)->Header.PointerToRawData != 0) { 856801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(OS.tell() == (*i)->Header.PointerToRawData && 857801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Section::PointerToRawData is insane!"); 858801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 859f77d5b14af6b92403b93f7ed249f9023e99028ccJim Grosbach Asm.writeSectionData(j, Layout); 860801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 861801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 862801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer if ((*i)->Relocations.size() > 0) { 863801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(OS.tell() == (*i)->Header.PointerToRelocations && 864801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Section::PointerToRelocations is insane!"); 865801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 866d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer if ((*i)->Relocations.size() >= 0xffff) { 867d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer // In case of overflow, write actual relocation count as first 868d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer // relocation. Including the synthetic reloc itself (+ 1). 869d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer COFF::relocation r; 870d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer r.VirtualAddress = (*i)->Relocations.size() + 1; 871d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer r.SymbolTableIndex = 0; 872d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer r.Type = 0; 873d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer WriteRelocation(r); 874d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer } 875d03a29b69d7285ed2ca523d70a45174e33716727Michael J. Spencer 876801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (relocations::const_iterator k = (*i)->Relocations.begin(), 877801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer ke = (*i)->Relocations.end(); 878801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer k != ke; k++) { 879801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer WriteRelocation(k->Data); 880801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 881801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } else 882801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert((*i)->Header.PointerToRelocations == 0 && 883801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Section::PointerToRelocations is insane!"); 884801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 885801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer } 886801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 887801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer assert(OS.tell() == Header.PointerToSymbolTable && 888801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer "Header::PointerToSymbolTable is insane!"); 889801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 890801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) 891a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer if ((*i)->Index != -1) 892a72d87899bc1bfdb17744aae2545a21b3630d3c1Michael J. Spencer WriteSymbol(*i); 893801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer 894801a3591161789e9716b0ec519f0f950b2d0c2acMichael J. Spencer OS.write((char const *)&Strings.Data.front(), Strings.Data.size()); 895b162290e39afd49d4c7d342333b331bc96232720Chris Lattner} 896b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 897df09270ae897e7fa64a7c162de163c32ee181a03Rafael EspindolaMCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_) : 898df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola Machine(Machine_) { 899df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola} 900df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola 901b162290e39afd49d4c7d342333b331bc96232720Chris Lattner//------------------------------------------------------------------------------ 902b162290e39afd49d4c7d342333b331bc96232720Chris Lattner// WinCOFFObjectWriter factory function 903b162290e39afd49d4c7d342333b331bc96232720Chris Lattner 904b162290e39afd49d4c7d342333b331bc96232720Chris Lattnernamespace llvm { 905df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola MCObjectWriter *createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, 906df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola raw_ostream &OS) { 907df09270ae897e7fa64a7c162de163c32ee181a03Rafael Espindola return new WinCOFFObjectWriter(MOTW, OS); 908b162290e39afd49d4c7d342333b331bc96232720Chris Lattner } 909933304ef0c3ec18c23d0b385c2117a6eae790430Michael J. Spencer} 910