1*9880d681SAndroid Build Coastguard Worker //===-- llvm/MC/MCObjectWriter.h - Object File Writer Interface -*- C++ -*-===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_MC_MCOBJECTWRITER_H 11*9880d681SAndroid Build Coastguard Worker #define LLVM_MC_MCOBJECTWRITER_H 12*9880d681SAndroid Build Coastguard Worker 13*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h" 14*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Compiler.h" 15*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/DataTypes.h" 16*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/EndianStream.h" 17*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h" 18*9880d681SAndroid Build Coastguard Worker #include <cassert> 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Worker namespace llvm { 21*9880d681SAndroid Build Coastguard Worker class MCAsmLayout; 22*9880d681SAndroid Build Coastguard Worker class MCAssembler; 23*9880d681SAndroid Build Coastguard Worker class MCFixup; 24*9880d681SAndroid Build Coastguard Worker class MCFragment; 25*9880d681SAndroid Build Coastguard Worker class MCSymbol; 26*9880d681SAndroid Build Coastguard Worker class MCSymbolRefExpr; 27*9880d681SAndroid Build Coastguard Worker class MCValue; 28*9880d681SAndroid Build Coastguard Worker 29*9880d681SAndroid Build Coastguard Worker /// Defines the object file and target independent interfaces used by the 30*9880d681SAndroid Build Coastguard Worker /// assembler backend to write native file format object files. 31*9880d681SAndroid Build Coastguard Worker /// 32*9880d681SAndroid Build Coastguard Worker /// The object writer contains a few callbacks used by the assembler to allow 33*9880d681SAndroid Build Coastguard Worker /// the object writer to modify the assembler data structures at appropriate 34*9880d681SAndroid Build Coastguard Worker /// points. Once assembly is complete, the object writer is given the 35*9880d681SAndroid Build Coastguard Worker /// MCAssembler instance, which contains all the symbol and section data which 36*9880d681SAndroid Build Coastguard Worker /// should be emitted as part of writeObject(). 37*9880d681SAndroid Build Coastguard Worker /// 38*9880d681SAndroid Build Coastguard Worker /// The object writer also contains a number of helper methods for writing 39*9880d681SAndroid Build Coastguard Worker /// binary data to the output stream. 40*9880d681SAndroid Build Coastguard Worker class MCObjectWriter { 41*9880d681SAndroid Build Coastguard Worker MCObjectWriter(const MCObjectWriter &) = delete; 42*9880d681SAndroid Build Coastguard Worker void operator=(const MCObjectWriter &) = delete; 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard Worker raw_pwrite_stream *OS; 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Worker protected: 47*9880d681SAndroid Build Coastguard Worker unsigned IsLittleEndian : 1; 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Worker protected: // Can only create subclasses. MCObjectWriter(raw_pwrite_stream & OS,bool IsLittleEndian)50*9880d681SAndroid Build Coastguard Worker MCObjectWriter(raw_pwrite_stream &OS, bool IsLittleEndian) 51*9880d681SAndroid Build Coastguard Worker : OS(&OS), IsLittleEndian(IsLittleEndian) {} 52*9880d681SAndroid Build Coastguard Worker getInitialOffset()53*9880d681SAndroid Build Coastguard Worker unsigned getInitialOffset() { 54*9880d681SAndroid Build Coastguard Worker return OS->tell(); 55*9880d681SAndroid Build Coastguard Worker } 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Worker public: 58*9880d681SAndroid Build Coastguard Worker virtual ~MCObjectWriter(); 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Worker /// lifetime management reset()61*9880d681SAndroid Build Coastguard Worker virtual void reset() {} 62*9880d681SAndroid Build Coastguard Worker isLittleEndian()63*9880d681SAndroid Build Coastguard Worker bool isLittleEndian() const { return IsLittleEndian; } 64*9880d681SAndroid Build Coastguard Worker getStream()65*9880d681SAndroid Build Coastguard Worker raw_pwrite_stream &getStream() { return *OS; } setStream(raw_pwrite_stream & NewOS)66*9880d681SAndroid Build Coastguard Worker void setStream(raw_pwrite_stream &NewOS) { OS = &NewOS; } 67*9880d681SAndroid Build Coastguard Worker 68*9880d681SAndroid Build Coastguard Worker /// \name High-Level API 69*9880d681SAndroid Build Coastguard Worker /// @{ 70*9880d681SAndroid Build Coastguard Worker 71*9880d681SAndroid Build Coastguard Worker /// Perform any late binding of symbols (for example, to assign symbol 72*9880d681SAndroid Build Coastguard Worker /// indices for use when generating relocations). 73*9880d681SAndroid Build Coastguard Worker /// 74*9880d681SAndroid Build Coastguard Worker /// This routine is called by the assembler after layout and relaxation is 75*9880d681SAndroid Build Coastguard Worker /// complete. 76*9880d681SAndroid Build Coastguard Worker virtual void executePostLayoutBinding(MCAssembler &Asm, 77*9880d681SAndroid Build Coastguard Worker const MCAsmLayout &Layout) = 0; 78*9880d681SAndroid Build Coastguard Worker 79*9880d681SAndroid Build Coastguard Worker /// Record a relocation entry. 80*9880d681SAndroid Build Coastguard Worker /// 81*9880d681SAndroid Build Coastguard Worker /// This routine is called by the assembler after layout and relaxation, and 82*9880d681SAndroid Build Coastguard Worker /// post layout binding. The implementation is responsible for storing 83*9880d681SAndroid Build Coastguard Worker /// information about the relocation so that it can be emitted during 84*9880d681SAndroid Build Coastguard Worker /// writeObject(). 85*9880d681SAndroid Build Coastguard Worker virtual void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, 86*9880d681SAndroid Build Coastguard Worker const MCFragment *Fragment, 87*9880d681SAndroid Build Coastguard Worker const MCFixup &Fixup, MCValue Target, 88*9880d681SAndroid Build Coastguard Worker bool &IsPCRel, uint64_t &FixedValue) = 0; 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Worker /// Check whether the difference (A - B) between two symbol references is 91*9880d681SAndroid Build Coastguard Worker /// fully resolved. 92*9880d681SAndroid Build Coastguard Worker /// 93*9880d681SAndroid Build Coastguard Worker /// Clients are not required to answer precisely and may conservatively return 94*9880d681SAndroid Build Coastguard Worker /// false, even when a difference is fully resolved. 95*9880d681SAndroid Build Coastguard Worker bool isSymbolRefDifferenceFullyResolved(const MCAssembler &Asm, 96*9880d681SAndroid Build Coastguard Worker const MCSymbolRefExpr *A, 97*9880d681SAndroid Build Coastguard Worker const MCSymbolRefExpr *B, 98*9880d681SAndroid Build Coastguard Worker bool InSet) const; 99*9880d681SAndroid Build Coastguard Worker 100*9880d681SAndroid Build Coastguard Worker virtual bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, 101*9880d681SAndroid Build Coastguard Worker const MCSymbol &A, 102*9880d681SAndroid Build Coastguard Worker const MCSymbol &B, 103*9880d681SAndroid Build Coastguard Worker bool InSet) const; 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Worker virtual bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, 106*9880d681SAndroid Build Coastguard Worker const MCSymbol &SymA, 107*9880d681SAndroid Build Coastguard Worker const MCFragment &FB, 108*9880d681SAndroid Build Coastguard Worker bool InSet, 109*9880d681SAndroid Build Coastguard Worker bool IsPCRel) const; 110*9880d681SAndroid Build Coastguard Worker 111*9880d681SAndroid Build Coastguard Worker /// True if this symbol (which is a variable) is weak. This is not 112*9880d681SAndroid Build Coastguard Worker /// just STB_WEAK, but more generally whether or not we can evaluate 113*9880d681SAndroid Build Coastguard Worker /// past it. 114*9880d681SAndroid Build Coastguard Worker virtual bool isWeak(const MCSymbol &Sym) const; 115*9880d681SAndroid Build Coastguard Worker 116*9880d681SAndroid Build Coastguard Worker /// Write the object file. 117*9880d681SAndroid Build Coastguard Worker /// 118*9880d681SAndroid Build Coastguard Worker /// This routine is called by the assembler after layout and relaxation is 119*9880d681SAndroid Build Coastguard Worker /// complete, fixups have been evaluated and applied, and relocations 120*9880d681SAndroid Build Coastguard Worker /// generated. 121*9880d681SAndroid Build Coastguard Worker virtual void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) = 0; 122*9880d681SAndroid Build Coastguard Worker 123*9880d681SAndroid Build Coastguard Worker /// @} 124*9880d681SAndroid Build Coastguard Worker /// \name Binary Output 125*9880d681SAndroid Build Coastguard Worker /// @{ 126*9880d681SAndroid Build Coastguard Worker write8(uint8_t Value)127*9880d681SAndroid Build Coastguard Worker void write8(uint8_t Value) { *OS << char(Value); } 128*9880d681SAndroid Build Coastguard Worker writeLE16(uint16_t Value)129*9880d681SAndroid Build Coastguard Worker void writeLE16(uint16_t Value) { 130*9880d681SAndroid Build Coastguard Worker support::endian::Writer<support::little>(*OS).write(Value); 131*9880d681SAndroid Build Coastguard Worker } 132*9880d681SAndroid Build Coastguard Worker writeLE32(uint32_t Value)133*9880d681SAndroid Build Coastguard Worker void writeLE32(uint32_t Value) { 134*9880d681SAndroid Build Coastguard Worker support::endian::Writer<support::little>(*OS).write(Value); 135*9880d681SAndroid Build Coastguard Worker } 136*9880d681SAndroid Build Coastguard Worker writeLE64(uint64_t Value)137*9880d681SAndroid Build Coastguard Worker void writeLE64(uint64_t Value) { 138*9880d681SAndroid Build Coastguard Worker support::endian::Writer<support::little>(*OS).write(Value); 139*9880d681SAndroid Build Coastguard Worker } 140*9880d681SAndroid Build Coastguard Worker writeBE16(uint16_t Value)141*9880d681SAndroid Build Coastguard Worker void writeBE16(uint16_t Value) { 142*9880d681SAndroid Build Coastguard Worker support::endian::Writer<support::big>(*OS).write(Value); 143*9880d681SAndroid Build Coastguard Worker } 144*9880d681SAndroid Build Coastguard Worker writeBE32(uint32_t Value)145*9880d681SAndroid Build Coastguard Worker void writeBE32(uint32_t Value) { 146*9880d681SAndroid Build Coastguard Worker support::endian::Writer<support::big>(*OS).write(Value); 147*9880d681SAndroid Build Coastguard Worker } 148*9880d681SAndroid Build Coastguard Worker writeBE64(uint64_t Value)149*9880d681SAndroid Build Coastguard Worker void writeBE64(uint64_t Value) { 150*9880d681SAndroid Build Coastguard Worker support::endian::Writer<support::big>(*OS).write(Value); 151*9880d681SAndroid Build Coastguard Worker } 152*9880d681SAndroid Build Coastguard Worker write16(uint16_t Value)153*9880d681SAndroid Build Coastguard Worker void write16(uint16_t Value) { 154*9880d681SAndroid Build Coastguard Worker if (IsLittleEndian) 155*9880d681SAndroid Build Coastguard Worker writeLE16(Value); 156*9880d681SAndroid Build Coastguard Worker else 157*9880d681SAndroid Build Coastguard Worker writeBE16(Value); 158*9880d681SAndroid Build Coastguard Worker } 159*9880d681SAndroid Build Coastguard Worker write32(uint32_t Value)160*9880d681SAndroid Build Coastguard Worker void write32(uint32_t Value) { 161*9880d681SAndroid Build Coastguard Worker if (IsLittleEndian) 162*9880d681SAndroid Build Coastguard Worker writeLE32(Value); 163*9880d681SAndroid Build Coastguard Worker else 164*9880d681SAndroid Build Coastguard Worker writeBE32(Value); 165*9880d681SAndroid Build Coastguard Worker } 166*9880d681SAndroid Build Coastguard Worker write64(uint64_t Value)167*9880d681SAndroid Build Coastguard Worker void write64(uint64_t Value) { 168*9880d681SAndroid Build Coastguard Worker if (IsLittleEndian) 169*9880d681SAndroid Build Coastguard Worker writeLE64(Value); 170*9880d681SAndroid Build Coastguard Worker else 171*9880d681SAndroid Build Coastguard Worker writeBE64(Value); 172*9880d681SAndroid Build Coastguard Worker } 173*9880d681SAndroid Build Coastguard Worker WriteZeros(unsigned N)174*9880d681SAndroid Build Coastguard Worker void WriteZeros(unsigned N) { 175*9880d681SAndroid Build Coastguard Worker const char Zeros[16] = {0}; 176*9880d681SAndroid Build Coastguard Worker 177*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = N / 16; i != e; ++i) 178*9880d681SAndroid Build Coastguard Worker *OS << StringRef(Zeros, 16); 179*9880d681SAndroid Build Coastguard Worker 180*9880d681SAndroid Build Coastguard Worker *OS << StringRef(Zeros, N % 16); 181*9880d681SAndroid Build Coastguard Worker } 182*9880d681SAndroid Build Coastguard Worker 183*9880d681SAndroid Build Coastguard Worker void writeBytes(const SmallVectorImpl<char> &ByteVec, 184*9880d681SAndroid Build Coastguard Worker unsigned ZeroFillSize = 0) { 185*9880d681SAndroid Build Coastguard Worker writeBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize); 186*9880d681SAndroid Build Coastguard Worker } 187*9880d681SAndroid Build Coastguard Worker 188*9880d681SAndroid Build Coastguard Worker void writeBytes(StringRef Str, unsigned ZeroFillSize = 0) { 189*9880d681SAndroid Build Coastguard Worker // TODO: this version may need to go away once all fragment contents are 190*9880d681SAndroid Build Coastguard Worker // converted to SmallVector<char, N> 191*9880d681SAndroid Build Coastguard Worker assert( 192*9880d681SAndroid Build Coastguard Worker (ZeroFillSize == 0 || Str.size() <= ZeroFillSize) && 193*9880d681SAndroid Build Coastguard Worker "data size greater than fill size, unexpected large write will occur"); 194*9880d681SAndroid Build Coastguard Worker *OS << Str; 195*9880d681SAndroid Build Coastguard Worker if (ZeroFillSize) 196*9880d681SAndroid Build Coastguard Worker WriteZeros(ZeroFillSize - Str.size()); 197*9880d681SAndroid Build Coastguard Worker } 198*9880d681SAndroid Build Coastguard Worker 199*9880d681SAndroid Build Coastguard Worker /// @} 200*9880d681SAndroid Build Coastguard Worker }; 201*9880d681SAndroid Build Coastguard Worker 202*9880d681SAndroid Build Coastguard Worker } // End llvm namespace 203*9880d681SAndroid Build Coastguard Worker 204*9880d681SAndroid Build Coastguard Worker #endif 205