Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

199 lines
5.8 KiB

  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/raw_ostream.h"
  15. #include <cassert>
  16. namespace llvm {
  17. class MCAsmLayout;
  18. class MCAssembler;
  19. class MCFixup;
  20. class MCFragment;
  21. class MCSymbolData;
  22. class MCSymbolRefExpr;
  23. class MCValue;
  24. /// MCObjectWriter - Defines the object file and target independent interfaces
  25. /// used by the 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 &) LLVM_DELETED_FUNCTION;
  37. void operator=(const MCObjectWriter &) LLVM_DELETED_FUNCTION;
  38. protected:
  39. raw_ostream &OS;
  40. unsigned IsLittleEndian : 1;
  41. protected: // Can only create subclasses.
  42. MCObjectWriter(raw_ostream &_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. /// \brief 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. /// \brief 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(const MCAssembler &Asm,
  66. const MCAsmLayout &Layout,
  67. const MCFragment *Fragment,
  68. const MCFixup &Fixup, MCValue Target,
  69. uint64_t &FixedValue) = 0;
  70. /// \brief Check whether the difference (A - B) between two symbol
  71. /// references is fully resolved.
  72. ///
  73. /// Clients are not required to answer precisely and may conservatively return
  74. /// false, even when a difference is fully resolved.
  75. bool
  76. IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
  77. const MCSymbolRefExpr *A,
  78. const MCSymbolRefExpr *B,
  79. bool InSet) const;
  80. virtual bool
  81. IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
  82. const MCSymbolData &DataA,
  83. const MCFragment &FB,
  84. bool InSet,
  85. bool IsPCRel) const;
  86. /// \brief Write the object file.
  87. ///
  88. /// This routine is called by the assembler after layout and relaxation is
  89. /// complete, fixups have been evaluated and applied, and relocations
  90. /// generated.
  91. virtual void WriteObject(MCAssembler &Asm,
  92. const MCAsmLayout &Layout) = 0;
  93. /// @}
  94. /// @name Binary Output
  95. /// @{
  96. void Write8(uint8_t Value) {
  97. OS << char(Value);
  98. }
  99. void WriteLE16(uint16_t Value) {
  100. Write8(uint8_t(Value >> 0));
  101. Write8(uint8_t(Value >> 8));
  102. }
  103. void WriteLE32(uint32_t Value) {
  104. WriteLE16(uint16_t(Value >> 0));
  105. WriteLE16(uint16_t(Value >> 16));
  106. }
  107. void WriteLE64(uint64_t Value) {
  108. WriteLE32(uint32_t(Value >> 0));
  109. WriteLE32(uint32_t(Value >> 32));
  110. }
  111. void WriteBE16(uint16_t Value) {
  112. Write8(uint8_t(Value >> 8));
  113. Write8(uint8_t(Value >> 0));
  114. }
  115. void WriteBE32(uint32_t Value) {
  116. WriteBE16(uint16_t(Value >> 16));
  117. WriteBE16(uint16_t(Value >> 0));
  118. }
  119. void WriteBE64(uint64_t Value) {
  120. WriteBE32(uint32_t(Value >> 32));
  121. WriteBE32(uint32_t(Value >> 0));
  122. }
  123. void Write16(uint16_t Value) {
  124. if (IsLittleEndian)
  125. WriteLE16(Value);
  126. else
  127. WriteBE16(Value);
  128. }
  129. void Write32(uint32_t Value) {
  130. if (IsLittleEndian)
  131. WriteLE32(Value);
  132. else
  133. WriteBE32(Value);
  134. }
  135. void Write64(uint64_t Value) {
  136. if (IsLittleEndian)
  137. WriteLE64(Value);
  138. else
  139. WriteBE64(Value);
  140. }
  141. void WriteZeros(unsigned N) {
  142. const char Zeros[16] = { 0 };
  143. for (unsigned i = 0, e = N / 16; i != e; ++i)
  144. OS << StringRef(Zeros, 16);
  145. OS << StringRef(Zeros, N % 16);
  146. }
  147. void WriteBytes(const SmallVectorImpl<char> &ByteVec, unsigned ZeroFillSize = 0) {
  148. WriteBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize);
  149. }
  150. void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) {
  151. // TODO: this version may need to go away once all fragment contents are
  152. // converted to SmallVector<char, N>
  153. assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) &&
  154. "data size greater than fill size, unexpected large write will occur");
  155. OS << Str;
  156. if (ZeroFillSize)
  157. WriteZeros(ZeroFillSize - Str.size());
  158. }
  159. /// @}
  160. };
  161. } // End llvm namespace
  162. #endif