Introduce new BinaryObject (blob) class, ELF Writer modified to use it. BinaryObject...
[oota-llvm.git] / include / llvm / CodeGen / BinaryObject.h
1 //===-- llvm/CodeGen/BinaryObject.h - Binary Object. -----------*- 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 // This file defines a Binary Object Aka. "blob" for holding data from code
11 // generators, ready for data to the object module code writters.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_CODEGEN_BINARYOBJECT_H
16 #define LLVM_CODEGEN_BINARYOBJECT_H
17
18 #include <string>
19 #include <vector>
20
21 namespace llvm {
22
23 class MachineRelocation;
24 typedef std::vector<uint8_t> BinaryData;
25
26 class BinaryObject {
27 protected:
28   std::string Name;
29   bool IsLittleEndian;
30   bool Is64Bit;
31   BinaryData Data;
32   std::vector<MachineRelocation> Relocations;
33
34 public:
35   /// Constructors and destructor
36   BinaryObject() {}
37
38   BinaryObject(bool isLittleEndian, bool is64Bit)
39     : IsLittleEndian(isLittleEndian), Is64Bit(is64Bit) {}
40
41   BinaryObject(const std::string &name, bool isLittleEndian, bool is64Bit)
42     : Name(name), IsLittleEndian(isLittleEndian), Is64Bit(is64Bit) {}
43
44   ~BinaryObject() {}
45
46   /// getName - get name of BinaryObject
47   inline std::string getName() const { return Name; }
48
49   /// get size of binary data
50   size_t size() const {
51     return Data.size();
52   }
53
54   /// get binary data
55   BinaryData& getData() {
56     return Data;
57   }
58
59   /// get machine relocations
60   const std::vector<MachineRelocation>& getRelocations() const {
61     return Relocations;
62   }
63
64   /// emitByte - This callback is invoked when a byte needs to be
65   /// written to the data stream.
66   inline void emitByte(uint8_t B) {
67     Data.push_back(B);
68   }
69
70   /// emitWord16 - This callback is invoked when a 16-bit word needs to be
71   /// written to the data stream in correct endian format and correct size.
72   inline void emitWord16(uint16_t W) {
73     if (IsLittleEndian)
74       emitWord16LE(W);
75     else
76       emitWord16BE(W);
77   }
78
79   /// emitWord16LE - This callback is invoked when a 16-bit word needs to be
80   /// written to the data stream in correct endian format and correct size.
81   inline void emitWord16LE(uint16_t W) {
82     Data.push_back((W >> 0) & 255);
83     Data.push_back((W >> 8) & 255);
84   }
85
86   /// emitWord16BE - This callback is invoked when a 16-bit word needs to be
87   /// written to the data stream in correct endian format and correct size.
88   inline void emitWord16BE(uint16_t W) {
89     Data.push_back((W >> 8) & 255);
90     Data.push_back((W >> 0) & 255);
91   }
92
93   /// emitWord - This callback is invoked when a word needs to be
94   /// written to the data stream in correct endian format and correct size.
95   inline void emitWord(uint64_t W) {
96     if (!Is64Bit)
97       emitWord32(W);
98     else
99       emitWord64(W);
100   }
101
102   /// emitWord32 - This callback is invoked when a 32-bit word needs to be
103   /// written to the data stream in correct endian format.
104   inline void emitWord32(uint32_t W) {
105     if (IsLittleEndian)
106       emitWordLE(W);
107     else
108       emitWordBE(W);
109   }
110
111   /// emitWord64 - This callback is invoked when a 32-bit word needs to be
112   /// written to the data stream in correct endian format.
113   inline void emitWord64(uint64_t W) {
114     if (IsLittleEndian)
115       emitDWordLE(W);
116     else
117       emitDWordBE(W);
118   }
119
120   /// emitWordLE - This callback is invoked when a 32-bit word needs to be
121   /// written to the data stream in little-endian format.
122   inline void emitWordLE(uint32_t W) {
123     Data.push_back((W >>  0) & 255);
124     Data.push_back((W >>  8) & 255);
125     Data.push_back((W >> 16) & 255);
126     Data.push_back((W >> 24) & 255);
127   }
128
129   /// emitWordBE - This callback is invoked when a 32-bit word needs to be
130   /// written to the data stream in big-endian format.
131   ///
132   inline void emitWordBE(uint32_t W) {
133     Data.push_back((W >> 24) & 255);
134     Data.push_back((W >> 16) & 255);
135     Data.push_back((W >>  8) & 255);
136     Data.push_back((W >>  0) & 255);
137   }
138
139   /// emitDWordLE - This callback is invoked when a 64-bit word needs to be
140   /// written to the data stream in little-endian format.
141   inline void emitDWordLE(uint64_t W) {
142     Data.push_back(unsigned(W >>  0) & 255);
143     Data.push_back(unsigned(W >>  8) & 255);
144     Data.push_back(unsigned(W >> 16) & 255);
145     Data.push_back(unsigned(W >> 24) & 255);
146     Data.push_back(unsigned(W >> 32) & 255);
147     Data.push_back(unsigned(W >> 40) & 255);
148     Data.push_back(unsigned(W >> 48) & 255);
149     Data.push_back(unsigned(W >> 56) & 255);
150   }
151
152   /// emitDWordBE - This callback is invoked when a 64-bit word needs to be
153   /// written to the data stream in big-endian format.
154   inline void emitDWordBE(uint64_t W) {
155     Data.push_back(unsigned(W >> 56) & 255);
156     Data.push_back(unsigned(W >> 48) & 255);
157     Data.push_back(unsigned(W >> 40) & 255);
158     Data.push_back(unsigned(W >> 32) & 255);
159     Data.push_back(unsigned(W >> 24) & 255);
160     Data.push_back(unsigned(W >> 16) & 255);
161     Data.push_back(unsigned(W >>  8) & 255);
162     Data.push_back(unsigned(W >>  0) & 255);
163   }
164
165   /// fixByte - This callback is invoked when a byte needs to be
166   /// fixup the buffer.
167   inline void fixByte(uint8_t B, uint32_t offset) {
168     Data[offset] = B;
169   }
170
171   /// fixWord16 - This callback is invoked when a 16-bit word needs to
172   /// fixup the data stream in correct endian format.
173   inline void fixWord16(uint16_t W, uint32_t offset) {
174     if (IsLittleEndian)
175       fixWord16LE(W, offset);
176     else
177       fixWord16BE(W, offset);
178   }
179
180   /// emitWord16LE - This callback is invoked when a 16-bit word needs to
181   /// fixup the data stream in little endian format.
182   inline void fixWord16LE(uint16_t W, uint32_t offset) {
183     Data[offset++] = W & 255;
184     Data[offset] = (W >> 8) & 255;
185   }
186
187   /// fixWord16BE - This callback is invoked when a 16-bit word needs to
188   /// fixup data stream in big endian format.
189   inline void fixWord16BE(uint16_t W, uint32_t offset) {
190     Data[offset++] = (W >> 8) & 255;
191     Data[offset] = W & 255;
192   }
193
194   /// emitWord - This callback is invoked when a word needs to
195   /// fixup the data in correct endian format and correct size.
196   inline void fixWord(uint64_t W, uint32_t offset) {
197     if (!Is64Bit)
198       fixWord32(W, offset);
199     else
200       fixWord64(W, offset);
201   }
202
203   /// fixWord32 - This callback is invoked when a 32-bit word needs to
204   /// fixup the data in correct endian format.
205   inline void fixWord32(uint32_t W, uint32_t offset) {
206     if (IsLittleEndian)
207       fixWord32LE(W, offset);
208     else
209       fixWord32BE(W, offset);
210   }
211
212   /// fixWord32LE - This callback is invoked when a 32-bit word needs to
213   /// fixup the data in little endian format.
214   inline void fixWord32LE(uint32_t W, uint32_t offset) {
215     Data[offset++] = W & 255;
216     Data[offset++] = (W >> 8) & 255;
217     Data[offset++] = (W >> 16) & 255;
218     Data[offset] = (W >> 24) & 255;
219   }
220
221   /// fixWord32BE - This callback is invoked when a 32-bit word needs to
222   /// fixup the data in big endian format.
223   inline void fixWord32BE(uint32_t W, uint32_t offset) {
224     Data[offset++] = (W >> 24) & 255;
225     Data[offset++] = (W >> 16) & 255;
226     Data[offset++] = (W >> 8) & 255;
227     Data[offset] = W & 255;
228   }
229
230   /// fixWord64 - This callback is invoked when a 64-bit word needs to
231   /// fixup the data in correct endian format.
232   inline void fixWord64(uint64_t W, uint32_t offset) {
233     if (IsLittleEndian)
234       fixWord64LE(W, offset);
235     else
236       fixWord64BE(W, offset);
237   }
238
239   /// fixWord64BE - This callback is invoked when a 64-bit word needs to
240   /// fixup the data in little endian format.
241   inline void fixWord64LE(uint64_t W, uint32_t offset) {
242     Data[offset++] = W & 255;
243     Data[offset++] = (W >> 8) & 255;
244     Data[offset++] = (W >> 16) & 255;
245     Data[offset++] = (W >> 24) & 255;
246     Data[offset++] = (W >> 32) & 255;
247     Data[offset++] = (W >> 40) & 255;
248     Data[offset++] = (W >> 48) & 255;
249     Data[offset] = (W >> 56) & 255;
250   }
251
252   /// fixWord64BE - This callback is invoked when a 64-bit word needs to
253   /// fixup the data in big endian format.
254   inline void fixWord64BE(uint64_t W, uint32_t offset) {
255     Data[offset++] = (W >> 56) & 255;
256     Data[offset++] = (W >> 48) & 255;
257     Data[offset++] = (W >> 40) & 255;
258     Data[offset++] = (W >> 32) & 255;
259     Data[offset++] = (W >> 24) & 255;
260     Data[offset++] = (W >> 16) & 255;
261     Data[offset++] = (W >> 8) & 255;
262     Data[offset] = W & 255;
263   }
264
265   /// emitAlignment - Pad the data to the specified alignment.
266   void emitAlignment(unsigned Alignment) {
267     if (Alignment <= 1) return;
268     unsigned PadSize = -Data.size() & (Alignment-1);
269     for (unsigned i = 0; i<PadSize; ++i)
270       Data.push_back(0);
271   }
272
273   /// emitULEB128Bytes - This callback is invoked when a ULEB128 needs to be
274   /// written to the data stream.
275   void emitULEB128Bytes(uint64_t Value) {
276     do {
277       unsigned char Byte = Value & 0x7f;
278       Value >>= 7;
279       if (Value) Byte |= 0x80;
280       emitByte(Byte);
281     } while (Value);
282   }
283
284   /// emitSLEB128Bytes - This callback is invoked when a SLEB128 needs to be
285   /// written to the data stream.
286   void emitSLEB128Bytes(int64_t Value) {
287     int Sign = Value >> (8 * sizeof(Value) - 1);
288     bool IsMore;
289
290     do {
291       unsigned char Byte = Value & 0x7f;
292       Value >>= 7;
293       IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
294       if (IsMore) Byte |= 0x80;
295       emitByte(Byte);
296     } while (IsMore);
297   }
298
299   /// emitString - This callback is invoked when a String needs to be
300   /// written to the data stream.
301   void emitString(const std::string &String) {
302     for (unsigned i = 0, N = static_cast<unsigned>(String.size()); i<N; ++i) {
303       unsigned char C = String[i];
304       emitByte(C);
305     }
306     emitByte(0);
307   }
308
309   /// getCurrentPCOffset - Return the offset from the start of the emitted
310   /// buffer that we are currently writing to.
311   uintptr_t getCurrentPCOffset() const {
312     return Data.size();
313   }
314
315   /// addRelocation - Whenever a relocatable address is needed, it should be
316   /// noted with this interface.
317   void addRelocation(const MachineRelocation& relocation) {
318     Relocations.push_back(relocation);
319   }
320 };
321
322 } // end namespace llvm
323
324 #endif
325