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