LLVM API Documentation

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