1 //===-- llvm/MC/MCObjectWriter.h - Object File Writer Interface -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_MC_MCOBJECTWRITER_H
11 #define LLVM_MC_MCOBJECTWRITER_H
13 #include "llvm/Support/MathExtras.h"
14 #include "llvm/Support/raw_ostream.h"
15 #include "llvm/System/DataTypes.h"
16 #include "llvm/System/Host.h"
27 /// MCObjectWriter - Defines the object file and target independent interfaces
28 /// used by the assembler backend to write native file format object files.
30 /// The object writer contains a few callbacks used by the assembler to allow
31 /// the object writer to modify the assembler data structures at appropriate
32 /// points. Once assembly is complete, the object writer is given the
33 /// MCAssembler instance, which contains all the symbol and section data which
34 /// should be emitted as part of WriteObject().
36 /// The object writer also contains a number of helper methods for writing
37 /// binary data to the output stream.
38 class MCObjectWriter {
39 MCObjectWriter(const MCObjectWriter &); // DO NOT IMPLEMENT
40 void operator=(const MCObjectWriter &); // DO NOT IMPLEMENT
45 unsigned IsLittleEndian : 1;
47 protected: // Can only create subclasses.
48 MCObjectWriter(raw_ostream &_OS, bool _IsLittleEndian)
49 : OS(_OS), IsLittleEndian(_IsLittleEndian) {}
52 virtual ~MCObjectWriter();
54 bool isLittleEndian() const { return IsLittleEndian; }
56 raw_ostream &getStream() { return OS; }
58 /// @name High-Level API
61 /// Perform any late binding of symbols (for example, to assign symbol indices
62 /// for use when generating relocations).
64 /// This routine is called by the assembler after layout and relaxation is
66 virtual void ExecutePostLayoutBinding(MCAssembler &Asm) = 0;
68 /// Record a relocation entry.
70 /// This routine is called by the assembler after layout and relaxation, and
71 /// post layout binding. The implementation is responsible for storing
72 /// information about the relocation so that it can be emitted during
74 virtual void RecordRelocation(const MCAssembler &Asm,
75 const MCAsmLayout &Layout,
76 const MCFragment *Fragment,
77 const MCFixup &Fixup, MCValue Target,
78 uint64_t &FixedValue) = 0;
80 /// Write the object file.
82 /// This routine is called by the assembler after layout and relaxation is
83 /// complete, fixups have been evaluated and applied, and relocations
85 virtual void WriteObject(const MCAssembler &Asm,
86 const MCAsmLayout &Layout) = 0;
89 /// @name Binary Output
92 void Write8(uint8_t Value) {
96 void WriteLE16(uint16_t Value) {
97 if (sys::isBigEndianHost())
98 Value = ByteSwap_16(Value);
99 OS << StringRef((const char*)&Value, sizeof(Value));
102 void WriteLE32(uint32_t Value) {
103 if (sys::isBigEndianHost())
104 Value = ByteSwap_32(Value);
105 OS << StringRef((const char*)&Value, sizeof(Value));
108 void WriteLE64(uint64_t Value) {
109 if (sys::isBigEndianHost())
110 Value = ByteSwap_64(Value);
111 OS << StringRef((const char*)&Value, sizeof(Value));
114 void WriteBE16(uint16_t Value) {
115 if (sys::isLittleEndianHost())
116 Value = ByteSwap_16(Value);
117 OS << StringRef((const char*)&Value, sizeof(Value));
120 void WriteBE32(uint32_t Value) {
121 if (sys::isLittleEndianHost())
122 Value = ByteSwap_32(Value);
123 OS << StringRef((const char*)&Value, sizeof(Value));
126 void WriteBE64(uint64_t Value) {
127 if (sys::isLittleEndianHost())
128 Value = ByteSwap_64(Value);
129 OS << StringRef((const char*)&Value, sizeof(Value));
132 void Write16(uint16_t Value) {
133 if (IsLittleEndian != sys::isLittleEndianHost())
134 Value = ByteSwap_16(Value);
135 OS << StringRef((const char*)&Value, sizeof(Value));
138 void Write32(uint32_t Value) {
139 if (IsLittleEndian != sys::isLittleEndianHost())
140 Value = ByteSwap_32(Value);
141 OS << StringRef((const char*)&Value, sizeof(Value));
144 void Write64(uint64_t Value) {
145 if (IsLittleEndian != sys::isLittleEndianHost())
146 Value = ByteSwap_64(Value);
147 OS << StringRef((const char*)&Value, sizeof(Value));
150 void WriteZeros(unsigned N) {
151 const char Zeros[16] = { 0 };
153 for (unsigned i = 0, e = N / 16; i != e; ++i)
154 OS << StringRef(Zeros, 16);
156 OS << StringRef(Zeros, N % 16);
159 void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) {
160 assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) &&
161 "data size greater than fill size, unexpected large write will occur");
164 WriteZeros(ZeroFillSize - Str.size());
170 MCObjectWriter *createWinCOFFObjectWriter(raw_ostream &OS);
172 } // End llvm namespace