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