MCObjectWriter.h revision 3fa0c8ca96edbd2c77541c937b10149c6fb08cac
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 MCAsmFixup; 19class MCAsmLayout; 20class MCAssembler; 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 MCAsmFixup &Fixup, MCValue Target, 76 uint64_t &FixedValue) = 0; 77 78 /// Write the object file. 79 /// 80 /// This routine is called by the assembler after layout and relaxation is 81 /// complete, fixups have been evaluated and applied, and relocations 82 /// generated. 83 virtual void WriteObject(const MCAssembler &Asm, 84 const MCAsmLayout &Layout) = 0; 85 86 /// @} 87 /// @name Binary Output 88 /// @{ 89 90 void Write8(uint8_t Value) { 91 OS << char(Value); 92 } 93 94 void WriteLE16(uint16_t Value) { 95 Write8(uint8_t(Value >> 0)); 96 Write8(uint8_t(Value >> 8)); 97 } 98 99 void WriteLE32(uint32_t Value) { 100 WriteLE16(uint16_t(Value >> 0)); 101 WriteLE16(uint16_t(Value >> 16)); 102 } 103 104 void WriteLE64(uint64_t Value) { 105 WriteLE32(uint32_t(Value >> 0)); 106 WriteLE32(uint32_t(Value >> 32)); 107 } 108 109 void WriteBE16(uint16_t Value) { 110 Write8(uint8_t(Value >> 8)); 111 Write8(uint8_t(Value >> 0)); 112 } 113 114 void WriteBE32(uint32_t Value) { 115 WriteBE16(uint16_t(Value >> 16)); 116 WriteBE16(uint16_t(Value >> 0)); 117 } 118 119 void WriteBE64(uint64_t Value) { 120 WriteBE32(uint32_t(Value >> 32)); 121 WriteBE32(uint32_t(Value >> 0)); 122 } 123 124 void Write16(uint16_t Value) { 125 if (IsLittleEndian) 126 WriteLE16(Value); 127 else 128 WriteBE16(Value); 129 } 130 131 void Write32(uint32_t Value) { 132 if (IsLittleEndian) 133 WriteLE32(Value); 134 else 135 WriteBE32(Value); 136 } 137 138 void Write64(uint64_t Value) { 139 if (IsLittleEndian) 140 WriteLE64(Value); 141 else 142 WriteBE64(Value); 143 } 144 145 void WriteZeros(unsigned N) { 146 const char Zeros[16] = { 0 }; 147 148 for (unsigned i = 0, e = N / 16; i != e; ++i) 149 OS << StringRef(Zeros, 16); 150 151 OS << StringRef(Zeros, N % 16); 152 } 153 154 void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) { 155 OS << Str; 156 if (ZeroFillSize) 157 WriteZeros(ZeroFillSize - Str.size()); 158 } 159 160 /// @} 161}; 162 163} // End llvm namespace 164 165#endif 166