MCObjectWriter.h revision 285b3e5b61af15f11e59a7700375aefa2a326bd8
1//===-- llvm/MC/MCObjectWriter.h - Object File Writer Interface -*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef LLVM_MC_MCOBJECTWRITER_H 11#define LLVM_MC_MCOBJECTWRITER_H 12 13#include "llvm/ADT/Triple.h" 14#include "llvm/Support/raw_ostream.h" 15#include "llvm/Support/DataTypes.h" 16#include <cassert> 17 18namespace llvm { 19class MCAsmLayout; 20class MCAssembler; 21class MCFixup; 22class MCFragment; 23class MCSymbolRefExpr; 24class MCValue; 25class raw_ostream; 26 27/// MCObjectWriter - Defines the object file and target independent interfaces 28/// used by the assembler backend to write native file format object files. 29/// 30/// The object writer contains a few callbacks used by the assembler to allow 31/// the object writer to modify the assembler data structures at appropriate 32/// points. Once assembly is complete, the object writer is given the 33/// MCAssembler instance, which contains all the symbol and section data which 34/// should be emitted as part of WriteObject(). 35/// 36/// The object writer also contains a number of helper methods for writing 37/// binary data to the output stream. 38class MCObjectWriter { 39 MCObjectWriter(const MCObjectWriter &); // DO NOT IMPLEMENT 40 void operator=(const MCObjectWriter &); // DO NOT IMPLEMENT 41 42protected: 43 raw_ostream &OS; 44 45 unsigned IsLittleEndian : 1; 46 47protected: // Can only create subclasses. 48 MCObjectWriter(raw_ostream &_OS, bool _IsLittleEndian) 49 : OS(_OS), IsLittleEndian(_IsLittleEndian) {} 50 51public: 52 virtual ~MCObjectWriter(); 53 54 bool isLittleEndian() const { return IsLittleEndian; } 55 56 raw_ostream &getStream() { return OS; } 57 58 /// @name High-Level API 59 /// @{ 60 61 /// Perform any late binding of symbols (for example, to assign symbol indices 62 /// for use when generating relocations). 63 /// 64 /// This routine is called by the assembler after layout and relaxation is 65 /// complete. 66 virtual void ExecutePostLayoutBinding(MCAssembler &Asm, 67 const MCAsmLayout &Layout) = 0; 68 69 /// Record a relocation entry. 70 /// 71 /// This routine is called by the assembler after layout and relaxation, and 72 /// post layout binding. The implementation is responsible for storing 73 /// information about the relocation so that it can be emitted during 74 /// WriteObject(). 75 virtual void RecordRelocation(const MCAssembler &Asm, 76 const MCAsmLayout &Layout, 77 const MCFragment *Fragment, 78 const MCFixup &Fixup, MCValue Target, 79 uint64_t &FixedValue) = 0; 80 81 /// \brief Check whether the difference (A - B) between two symbol 82 /// references is fully resolved. 83 /// 84 /// Clients are not required to answer precisely and may conservatively return 85 /// false, even when a difference is fully resolved. 86 virtual bool 87 IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm, 88 const MCSymbolRefExpr *A, 89 const MCSymbolRefExpr *B) const = 0; 90 91 /// Check if a fixup is fully resolved. 92 /// 93 /// This routine is used by the assembler to let the file format decide 94 /// if a fixup is not fully resolved. For example, one that crosses 95 /// two sections on ELF. 96 virtual bool IsFixupFullyResolved(const MCAssembler &Asm, 97 const MCValue Target, 98 bool IsPCRel, 99 const MCFragment *DF) const = 0; 100 101 /// Write the object file. 102 /// 103 /// This routine is called by the assembler after layout and relaxation is 104 /// complete, fixups have been evaluated and applied, and relocations 105 /// generated. 106 virtual void WriteObject(MCAssembler &Asm, 107 const MCAsmLayout &Layout) = 0; 108 109 /// @} 110 /// @name Binary Output 111 /// @{ 112 113 void Write8(uint8_t Value) { 114 OS << char(Value); 115 } 116 117 void WriteLE16(uint16_t Value) { 118 Write8(uint8_t(Value >> 0)); 119 Write8(uint8_t(Value >> 8)); 120 } 121 122 void WriteLE32(uint32_t Value) { 123 WriteLE16(uint16_t(Value >> 0)); 124 WriteLE16(uint16_t(Value >> 16)); 125 } 126 127 void WriteLE64(uint64_t Value) { 128 WriteLE32(uint32_t(Value >> 0)); 129 WriteLE32(uint32_t(Value >> 32)); 130 } 131 132 void WriteBE16(uint16_t Value) { 133 Write8(uint8_t(Value >> 8)); 134 Write8(uint8_t(Value >> 0)); 135 } 136 137 void WriteBE32(uint32_t Value) { 138 WriteBE16(uint16_t(Value >> 16)); 139 WriteBE16(uint16_t(Value >> 0)); 140 } 141 142 void WriteBE64(uint64_t Value) { 143 WriteBE32(uint32_t(Value >> 32)); 144 WriteBE32(uint32_t(Value >> 0)); 145 } 146 147 void Write16(uint16_t Value) { 148 if (IsLittleEndian) 149 WriteLE16(Value); 150 else 151 WriteBE16(Value); 152 } 153 154 void Write32(uint32_t Value) { 155 if (IsLittleEndian) 156 WriteLE32(Value); 157 else 158 WriteBE32(Value); 159 } 160 161 void Write64(uint64_t Value) { 162 if (IsLittleEndian) 163 WriteLE64(Value); 164 else 165 WriteBE64(Value); 166 } 167 168 void WriteZeros(unsigned N) { 169 const char Zeros[16] = { 0 }; 170 171 for (unsigned i = 0, e = N / 16; i != e; ++i) 172 OS << StringRef(Zeros, 16); 173 174 OS << StringRef(Zeros, N % 16); 175 } 176 177 void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) { 178 assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) && 179 "data size greater than fill size, unexpected large write will occur"); 180 OS << Str; 181 if (ZeroFillSize) 182 WriteZeros(ZeroFillSize - Str.size()); 183 } 184 185 /// @} 186 187 /// Utility function to encode a SLEB128 value. 188 static void EncodeSLEB128(int64_t Value, raw_ostream &OS); 189 /// Utility function to encode a ULEB128 value. 190 static void EncodeULEB128(uint64_t Value, raw_ostream &OS); 191}; 192 193MCObjectWriter *createWinCOFFObjectWriter(raw_ostream &OS, bool is64Bit); 194 195} // End llvm namespace 196 197#endif 198