MCObjectWriter.h 6.0 KB

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