1 //===-- ELFWriter.h - Target-independent ELF writer support -----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the ELFWriter class.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CODEGEN_ELFWRITER_H
15 #define LLVM_CODEGEN_ELFWRITER_H
17 #include "llvm/CodeGen/MachineFunctionPass.h"
23 class MachineCodeEmitter;
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.
30 class ELFWriter : public MachineFunctionPass {
31 friend class ELFCodeEmitter;
33 MachineCodeEmitter &getMachineCodeEmitter() const {
34 return *(MachineCodeEmitter*)MCE;
39 typedef std::vector<unsigned char> DataBuffer;
42 ELFWriter(std::ostream &O, TargetMachine &TM);
44 /// Output stream to send the resultant object file to.
48 /// Target machine description.
52 /// Mang - The object used to perform name mangling for this module.
56 /// MCE - The MachineCodeEmitter object that we are exposing to emit machine
57 /// code for functions to the .o file.
60 //===------------------------------------------------------------------===//
61 // Properties to be set by the derived class ctor, used to configure the
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;
68 // e_flags - The machine flags for the target. This defaults to zero.
71 //===------------------------------------------------------------------===//
72 // Properties inferred automatically from the target machine.
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;
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);
83 bool runOnMachineFunction(MachineFunction &MF);
86 /// doFinalization - Now that the module has been completely processed, emit
87 /// the ELF file to 'O'.
88 bool doFinalization(Module &M);
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
94 DataBuffer FileHeader;
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.
100 std::string Name; // Name of the section.
101 unsigned NameIdx; // Index in .shstrtab of name, once emitted.
112 /// SectionIdx - The number of the section in the Section Table.
114 unsigned short SectionIdx;
116 /// SectionData - The actual data for this section which we are building
117 /// up for emission to the file.
118 DataBuffer SectionData;
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
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) {
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()
149 /// SectionLookup - This is a mapping from section name to section number in
151 std::map<std::string, ELFSection*> SectionLookup;
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];
160 SectionList.push_back(Name);
161 SN = &SectionList.back();
162 SN->SectionIdx = NumSections++;
168 /// ELFSym - This struct contains information about each symbol that is
169 /// added to logical symbol table for the module. This is eventually
170 /// turned into a real symbol table in the file.
172 const GlobalValue *GV; // The global value this corresponds to.
173 unsigned NameIdx; // Index in .strtab of name, once emitted.
178 unsigned short SectionIdx;
180 enum { STB_LOCAL = 0, STB_GLOBAL = 1, STB_WEAK = 2 };
181 enum { STT_NOTYPE = 0, STT_OBJECT = 1, STT_FUNC = 2, STT_SECTION = 3,
183 ELFSym(const GlobalValue *gv) : GV(gv), Value(0), Size(0), Info(0),
184 Other(0), SectionIdx(0) {}
186 void SetBind(unsigned X) {
187 assert(X == (X & 0xF) && "Bind value out of range!");
188 Info = (Info & 0x0F) | (X << 4);
190 void SetType(unsigned X) {
191 assert(X == (X & 0xF) && "Type value out of range!");
192 Info = (Info & 0xF0) | X;
196 /// SymbolTable - This is the list of symbols we have emitted to the file.
197 /// This actually gets rearranged before emission to the file (to put the
198 /// local symbols first in the list).
199 std::vector<ELFSym> SymbolTable;
201 // As we complete the ELF file, we need to update fields in the ELF header
202 // (e.g. the location of the section table). These members keep track of
203 // the offset in ELFHeader of these various pieces to update and other
204 // locations in the file.
205 unsigned ELFHeader_e_shoff_Offset; // e_shoff in ELF header.
206 unsigned ELFHeader_e_shstrndx_Offset; // e_shstrndx in ELF header.
207 unsigned ELFHeader_e_shnum_Offset; // e_shnum in ELF header.
210 // align - Emit padding into the file until the current output position is
211 // aligned to the specified power of two boundary.
212 static void align(DataBuffer &Output, unsigned Boundary) {
213 assert(Boundary && (Boundary & (Boundary-1)) == 0 &&
214 "Must align to 2^k boundary");
215 size_t Size = Output.size();
216 if (Size & (Boundary-1)) {
217 // Add padding to get alignment to the correct place.
218 size_t Pad = Boundary-(Size & (Boundary-1));
219 Output.resize(Size+Pad);
223 static void outbyte(DataBuffer &Output, unsigned char X) {
226 void outhalf(DataBuffer &Output, unsigned short X) {
227 if (isLittleEndian) {
228 Output.push_back(X&255);
229 Output.push_back(X >> 8);
231 Output.push_back(X >> 8);
232 Output.push_back(X&255);
235 void outword(DataBuffer &Output, unsigned X) {
236 if (isLittleEndian) {
237 Output.push_back((X >> 0) & 255);
238 Output.push_back((X >> 8) & 255);
239 Output.push_back((X >> 16) & 255);
240 Output.push_back((X >> 24) & 255);
242 Output.push_back((X >> 24) & 255);
243 Output.push_back((X >> 16) & 255);
244 Output.push_back((X >> 8) & 255);
245 Output.push_back((X >> 0) & 255);
248 void outxword(DataBuffer &Output, uint64_t X) {
249 if (isLittleEndian) {
250 Output.push_back((X >> 0) & 255);
251 Output.push_back((X >> 8) & 255);
252 Output.push_back((X >> 16) & 255);
253 Output.push_back((X >> 24) & 255);
254 Output.push_back((X >> 32) & 255);
255 Output.push_back((X >> 40) & 255);
256 Output.push_back((X >> 48) & 255);
257 Output.push_back((X >> 56) & 255);
259 Output.push_back((X >> 56) & 255);
260 Output.push_back((X >> 48) & 255);
261 Output.push_back((X >> 40) & 255);
262 Output.push_back((X >> 32) & 255);
263 Output.push_back((X >> 24) & 255);
264 Output.push_back((X >> 16) & 255);
265 Output.push_back((X >> 8) & 255);
266 Output.push_back((X >> 0) & 255);
269 void outaddr32(DataBuffer &Output, unsigned X) {
272 void outaddr64(DataBuffer &Output, uint64_t X) {
275 void outaddr(DataBuffer &Output, uint64_t X) {
277 outword(Output, (unsigned)X);
282 // fix functions - Replace an existing entry at an offset.
283 void fixhalf(DataBuffer &Output, unsigned short X, unsigned Offset) {
284 unsigned char *P = &Output[Offset];
285 P[0] = (X >> (isLittleEndian ? 0 : 8)) & 255;
286 P[1] = (X >> (isLittleEndian ? 8 : 0)) & 255;
289 void fixword(DataBuffer &Output, unsigned X, unsigned Offset) {
290 unsigned char *P = &Output[Offset];
291 P[0] = (X >> (isLittleEndian ? 0 : 24)) & 255;
292 P[1] = (X >> (isLittleEndian ? 8 : 16)) & 255;
293 P[2] = (X >> (isLittleEndian ? 16 : 8)) & 255;
294 P[3] = (X >> (isLittleEndian ? 24 : 0)) & 255;
297 void fixaddr(DataBuffer &Output, uint64_t X, unsigned Offset) {
299 fixword(Output, (unsigned)X, Offset);
301 assert(0 && "Emission of 64-bit data not implemented yet!");
305 void EmitGlobal(GlobalVariable *GV, ELFSection &DataSection,
306 ELFSection &BSSSection);
308 void EmitSymbolTable();
310 void EmitSectionTableStringTable();
311 void OutputSectionsAndSectionTable();