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