Remove some of the obvious v9-specific cruft
[oota-llvm.git] / include / llvm / CodeGen / ELFWriter.h
1 //===-- ELFWriter.h - Target-independent ELF writer support -----*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Chris Lattner and is distributed under the
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the ELFWriter class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_CODEGEN_ELFWRITER_H
15 #define LLVM_CODEGEN_ELFWRITER_H
16
17 #include "llvm/CodeGen/MachineFunctionPass.h"
18 #include <list>
19
20 namespace llvm {
21   class GlobalVariable;
22   class Mangler;
23   class MachineCodeEmitter;
24   class ELFCodeEmitter;
25
26   /// ELFWriter - This class implements the common target-independent code for
27   /// writing ELF files.  Targets should derive a class from this to
28   /// parameterize the output format.
29   ///
30   class ELFWriter : public MachineFunctionPass {
31     friend class ELFCodeEmitter;
32   public:
33     MachineCodeEmitter &getMachineCodeEmitter() const {
34       return *(MachineCodeEmitter*)MCE;
35     }
36
37     ~ELFWriter();
38
39     typedef std::vector<unsigned char> DataBuffer;
40
41   protected:
42     ELFWriter(std::ostream &O, TargetMachine &TM);
43
44     /// Output stream to send the resultant object file to.
45     ///
46     std::ostream &O;
47
48     /// Target machine description.
49     ///
50     TargetMachine &TM;
51
52     /// Mang - The object used to perform name mangling for this module.
53     ///
54     Mangler *Mang;
55
56     /// MCE - The MachineCodeEmitter object that we are exposing to emit machine
57     /// code for functions to the .o file.
58     ELFCodeEmitter *MCE;
59
60     //===------------------------------------------------------------------===//
61     // Properties to be set by the derived class ctor, used to configure the
62     // ELFWriter.
63
64     // e_machine - This field is the target specific value to emit as the
65     // e_machine member of the ELF header.
66     unsigned short e_machine;
67
68     // e_flags - The machine flags for the target.  This defaults to zero.
69     unsigned e_flags;
70
71     //===------------------------------------------------------------------===//
72     // Properties inferred automatically from the target machine.
73     //
74
75     /// is64Bit/isLittleEndian - This information is inferred from the target
76     /// machine directly, indicating whether to emit a 32- or 64-bit ELF file.
77     bool is64Bit, isLittleEndian;
78
79     /// doInitialization - Emit the file header and all of the global variables
80     /// for the module to the ELF file.
81     bool doInitialization(Module &M);
82
83     bool runOnMachineFunction(MachineFunction &MF);
84
85
86     /// doFinalization - Now that the module has been completely processed, emit
87     /// the ELF file to 'O'.
88     bool doFinalization(Module &M);
89
90   private:
91     // The buffer we accumulate the file header into.  Note that this should be
92     // changed into something much more efficient later (and the bytecode writer
93     // as well!).
94     DataBuffer FileHeader;
95
96     /// ELFSection - This struct contains information about each section that is
97     /// emitted to the file.  This is eventually turned into the section header
98     /// table at the end of the file.
99     struct ELFSection {
100       std::string Name;       // Name of the section.
101       unsigned NameIdx;       // Index in .shstrtab of name, once emitted.
102       unsigned Type;
103       unsigned Flags;
104       uint64_t Addr;
105       unsigned Offset;
106       unsigned Size;
107       unsigned Link;
108       unsigned Info;
109       unsigned Align;
110       unsigned EntSize;
111
112       /// SectionIdx - The number of the section in the Section Table.
113       ///
114       unsigned short SectionIdx;
115
116       /// SectionData - The actual data for this section which we are building
117       /// up for emission to the file.
118       DataBuffer SectionData;
119
120       enum { SHT_NULL = 0, SHT_PROGBITS = 1, SHT_SYMTAB = 2, SHT_STRTAB = 3,
121              SHT_RELA = 4, SHT_HASH = 5, SHT_DYNAMIC = 6, SHT_NOTE = 7,
122              SHT_NOBITS = 8, SHT_REL = 9, SHT_SHLIB = 10, SHT_DYNSYM = 11 };
123       enum { SHN_UNDEF = 0, SHN_ABS = 0xFFF1, SHN_COMMON = 0xFFF2 };
124       enum {   // SHF - ELF Section Header Flags
125         SHF_WRITE            = 1 << 0, // Writable
126         SHF_ALLOC            = 1 << 1, // Mapped into the process addr space
127         SHF_EXECINSTR        = 1 << 2, // Executable
128         SHF_MERGE            = 1 << 4, // Might be merged if equal
129         SHF_STRINGS          = 1 << 5, // Contains null-terminated strings
130         SHF_INFO_LINK        = 1 << 6, // 'sh_info' contains SHT index
131         SHF_LINK_ORDER       = 1 << 7, // Preserve order after combining
132         SHF_OS_NONCONFORMING = 1 << 8, // nonstandard OS support required
133         SHF_GROUP            = 1 << 9, // Section is a member of a group
134         SHF_TLS              = 1 << 10 // Section holds thread-local data
135       };
136
137       ELFSection(const std::string &name)
138         : Name(name), Type(0), Flags(0), Addr(0), Offset(0), Size(0),
139           Link(0), Info(0), Align(0), EntSize(0) {
140       }
141     };
142
143     /// SectionList - This is the list of sections that we have emitted to the
144     /// file.  Once the file has been completely built, the section header table
145     /// is constructed from this info.
146     std::list<ELFSection> SectionList;
147     unsigned NumSections;   // Always = SectionList.size()
148
149     /// SectionLookup - This is a mapping from section name to section number in
150     /// the SectionList.
151     std::map<std::string, ELFSection*> SectionLookup;
152
153     /// getSection - Return the section with the specified name, creating a new
154     /// section if one does not already exist.
155     ELFSection &getSection(const std::string &Name,
156                            unsigned Type, unsigned Flags = 0) {
157       ELFSection *&SN = SectionLookup[Name];
158       if (SN) return *SN;
159
160       SectionList.push_back(Name);
161       SN = &SectionList.back();
162       SN->SectionIdx = NumSections++;
163       SN->Type = Type;
164       SN->Flags = Flags;
165       return *SN;
166     }
167
168     ELFSection &getDataSection() {
169       return getSection(".data", ELFSection::SHT_PROGBITS,
170                         ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC);
171     }
172     ELFSection &getBSSSection() {
173       return getSection(".bss", ELFSection::SHT_NOBITS,
174                         ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC);
175     }
176
177     /// ELFSym - This struct contains information about each symbol that is
178     /// added to logical symbol table for the module.  This is eventually
179     /// turned into a real symbol table in the file.
180     struct ELFSym {
181       const GlobalValue *GV;    // The global value this corresponds to.
182       unsigned NameIdx;         // Index in .strtab of name, once emitted.
183       uint64_t Value;
184       unsigned Size;
185       unsigned char Info;
186       unsigned char Other;
187       unsigned short SectionIdx;
188
189       enum { STB_LOCAL = 0, STB_GLOBAL = 1, STB_WEAK = 2 };
190       enum { STT_NOTYPE = 0, STT_OBJECT = 1, STT_FUNC = 2, STT_SECTION = 3,
191              STT_FILE = 4 };
192       ELFSym(const GlobalValue *gv) : GV(gv), Value(0), Size(0), Info(0),
193                                       Other(0), SectionIdx(0) {}
194
195       void SetBind(unsigned X) {
196         assert(X == (X & 0xF) && "Bind value out of range!");
197         Info = (Info & 0x0F) | (X << 4);
198       }
199       void SetType(unsigned X) {
200         assert(X == (X & 0xF) && "Type value out of range!");
201         Info = (Info & 0xF0) | X;
202       }
203     };
204
205     /// SymbolTable - This is the list of symbols we have emitted to the file.
206     /// This actually gets rearranged before emission to the file (to put the
207     /// local symbols first in the list).
208     std::vector<ELFSym> SymbolTable;
209
210     // As we complete the ELF file, we need to update fields in the ELF header
211     // (e.g. the location of the section table).  These members keep track of
212     // the offset in ELFHeader of these various pieces to update and other
213     // locations in the file.
214     unsigned ELFHeader_e_shoff_Offset;     // e_shoff    in ELF header.
215     unsigned ELFHeader_e_shstrndx_Offset;  // e_shstrndx in ELF header.
216     unsigned ELFHeader_e_shnum_Offset;     // e_shnum    in ELF header.
217
218
219     // align - Emit padding into the file until the current output position is
220     // aligned to the specified power of two boundary.
221     static void align(DataBuffer &Output, unsigned Boundary) {
222       assert(Boundary && (Boundary & (Boundary-1)) == 0 &&
223              "Must align to 2^k boundary");
224       size_t Size = Output.size();
225       if (Size & (Boundary-1)) {
226         // Add padding to get alignment to the correct place.
227         size_t Pad = Boundary-(Size & (Boundary-1));
228         Output.resize(Size+Pad);
229       }
230     }
231
232     static void outbyte(DataBuffer &Output, unsigned char X) {
233       Output.push_back(X);
234     }
235     void outhalf(DataBuffer &Output, unsigned short X) {
236       if (isLittleEndian) {
237         Output.push_back(X&255);
238         Output.push_back(X >> 8);
239       } else {
240         Output.push_back(X >> 8);
241         Output.push_back(X&255);
242       }
243     }
244     void outword(DataBuffer &Output, unsigned X) {
245       if (isLittleEndian) {
246         Output.push_back((X >>  0) & 255);
247         Output.push_back((X >>  8) & 255);
248         Output.push_back((X >> 16) & 255);
249         Output.push_back((X >> 24) & 255);
250       } else {
251         Output.push_back((X >> 24) & 255);
252         Output.push_back((X >> 16) & 255);
253         Output.push_back((X >>  8) & 255);
254         Output.push_back((X >>  0) & 255);
255       }
256     }
257     void outxword(DataBuffer &Output, uint64_t X) {
258       if (isLittleEndian) {
259         Output.push_back(unsigned(X >>  0) & 255);
260         Output.push_back(unsigned(X >>  8) & 255);
261         Output.push_back(unsigned(X >> 16) & 255);
262         Output.push_back(unsigned(X >> 24) & 255);
263         Output.push_back(unsigned(X >> 32) & 255);
264         Output.push_back(unsigned(X >> 40) & 255);
265         Output.push_back(unsigned(X >> 48) & 255);
266         Output.push_back(unsigned(X >> 56) & 255);
267       } else {
268         Output.push_back(unsigned(X >> 56) & 255);
269         Output.push_back(unsigned(X >> 48) & 255);
270         Output.push_back(unsigned(X >> 40) & 255);
271         Output.push_back(unsigned(X >> 32) & 255);
272         Output.push_back(unsigned(X >> 24) & 255);
273         Output.push_back(unsigned(X >> 16) & 255);
274         Output.push_back(unsigned(X >>  8) & 255);
275         Output.push_back(unsigned(X >>  0) & 255);
276       }
277     }
278     void outaddr32(DataBuffer &Output, unsigned X) {
279       outword(Output, X);
280     }
281     void outaddr64(DataBuffer &Output, uint64_t X) {
282       outxword(Output, X);
283     }
284     void outaddr(DataBuffer &Output, uint64_t X) {
285       if (!is64Bit)
286         outword(Output, (unsigned)X);
287       else
288         outxword(Output, X);
289     }
290
291     // fix functions - Replace an existing entry at an offset.
292     void fixhalf(DataBuffer &Output, unsigned short X, unsigned Offset) {
293       unsigned char *P = &Output[Offset];
294       P[0] = (X >> (isLittleEndian ?  0 : 8)) & 255;
295       P[1] = (X >> (isLittleEndian ?  8 : 0)) & 255;
296     }
297
298     void fixword(DataBuffer &Output, unsigned X, unsigned Offset) {
299       unsigned char *P = &Output[Offset];
300       P[0] = (X >> (isLittleEndian ?  0 : 24)) & 255;
301       P[1] = (X >> (isLittleEndian ?  8 : 16)) & 255;
302       P[2] = (X >> (isLittleEndian ? 16 :  8)) & 255;
303       P[3] = (X >> (isLittleEndian ? 24 :  0)) & 255;
304     }
305
306     void fixaddr(DataBuffer &Output, uint64_t X, unsigned Offset) {
307       if (!is64Bit)
308         fixword(Output, (unsigned)X, Offset);
309       else
310         assert(0 && "Emission of 64-bit data not implemented yet!");
311     }
312
313   private:
314     void EmitGlobal(GlobalVariable *GV);
315
316     void EmitSymbolTable();
317
318     void EmitSectionTableStringTable();
319     void OutputSectionsAndSectionTable();
320   };
321 }
322
323 #endif