LLVM API Documentation
00001 //===-- ELFWriter.h - Target-independent ELF writer support -----*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by Chris Lattner and is distributed under the 00006 // University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the ELFWriter class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_CODEGEN_ELFWRITER_H 00015 #define LLVM_CODEGEN_ELFWRITER_H 00016 00017 #include "llvm/CodeGen/MachineFunctionPass.h" 00018 #include <list> 00019 00020 namespace llvm { 00021 class GlobalVariable; 00022 class Mangler; 00023 class MachineCodeEmitter; 00024 class ELFCodeEmitter; 00025 00026 /// ELFWriter - This class implements the common target-independent code for 00027 /// writing ELF files. Targets should derive a class from this to 00028 /// parameterize the output format. 00029 /// 00030 class ELFWriter : public MachineFunctionPass { 00031 friend class ELFCodeEmitter; 00032 public: 00033 MachineCodeEmitter &getMachineCodeEmitter() const { 00034 return *(MachineCodeEmitter*)MCE; 00035 } 00036 00037 ~ELFWriter(); 00038 00039 typedef std::vector<unsigned char> DataBuffer; 00040 00041 protected: 00042 ELFWriter(std::ostream &O, TargetMachine &TM); 00043 00044 /// Output stream to send the resultant object file to. 00045 /// 00046 std::ostream &O; 00047 00048 /// Target machine description. 00049 /// 00050 TargetMachine &TM; 00051 00052 /// Mang - The object used to perform name mangling for this module. 00053 /// 00054 Mangler *Mang; 00055 00056 /// MCE - The MachineCodeEmitter object that we are exposing to emit machine 00057 /// code for functions to the .o file. 00058 ELFCodeEmitter *MCE; 00059 00060 //===------------------------------------------------------------------===// 00061 // Properties to be set by the derived class ctor, used to configure the 00062 // ELFWriter. 00063 00064 // e_machine - This field is the target specific value to emit as the 00065 // e_machine member of the ELF header. 00066 unsigned short e_machine; 00067 00068 // e_flags - The machine flags for the target. This defaults to zero. 00069 unsigned e_flags; 00070 00071 //===------------------------------------------------------------------===// 00072 // Properties inferred automatically from the target machine. 00073 // 00074 00075 /// is64Bit/isLittleEndian - This information is inferred from the target 00076 /// machine directly, indicating whether to emit a 32- or 64-bit ELF file. 00077 bool is64Bit, isLittleEndian; 00078 00079 /// doInitialization - Emit the file header and all of the global variables 00080 /// for the module to the ELF file. 00081 bool doInitialization(Module &M); 00082 00083 bool runOnMachineFunction(MachineFunction &MF); 00084 00085 00086 /// doFinalization - Now that the module has been completely processed, emit 00087 /// the ELF file to 'O'. 00088 bool doFinalization(Module &M); 00089 00090 private: 00091 // The buffer we accumulate the file header into. Note that this should be 00092 // changed into something much more efficient later (and the bytecode writer 00093 // as well!). 00094 DataBuffer FileHeader; 00095 00096 /// ELFSection - This struct contains information about each section that is 00097 /// emitted to the file. This is eventually turned into the section header 00098 /// table at the end of the file. 00099 struct ELFSection { 00100 std::string Name; // Name of the section. 00101 unsigned NameIdx; // Index in .shstrtab of name, once emitted. 00102 unsigned Type; 00103 unsigned Flags; 00104 uint64_t Addr; 00105 unsigned Offset; 00106 unsigned Size; 00107 unsigned Link; 00108 unsigned Info; 00109 unsigned Align; 00110 unsigned EntSize; 00111 00112 /// SectionIdx - The number of the section in the Section Table. 00113 /// 00114 unsigned short SectionIdx; 00115 00116 /// SectionData - The actual data for this section which we are building 00117 /// up for emission to the file. 00118 DataBuffer SectionData; 00119 00120 enum { SHT_NULL = 0, SHT_PROGBITS = 1, SHT_SYMTAB = 2, SHT_STRTAB = 3, 00121 SHT_RELA = 4, SHT_HASH = 5, SHT_DYNAMIC = 6, SHT_NOTE = 7, 00122 SHT_NOBITS = 8, SHT_REL = 9, SHT_SHLIB = 10, SHT_DYNSYM = 11 }; 00123 enum { SHN_UNDEF = 0, SHN_ABS = 0xFFF1, SHN_COMMON = 0xFFF2 }; 00124 enum { // SHF - ELF Section Header Flags 00125 SHF_WRITE = 1 << 0, // Writable 00126 SHF_ALLOC = 1 << 1, // Mapped into the process addr space 00127 SHF_EXECINSTR = 1 << 2, // Executable 00128 SHF_MERGE = 1 << 4, // Might be merged if equal 00129 SHF_STRINGS = 1 << 5, // Contains null-terminated strings 00130 SHF_INFO_LINK = 1 << 6, // 'sh_info' contains SHT index 00131 SHF_LINK_ORDER = 1 << 7, // Preserve order after combining 00132 SHF_OS_NONCONFORMING = 1 << 8, // nonstandard OS support required 00133 SHF_GROUP = 1 << 9, // Section is a member of a group 00134 SHF_TLS = 1 << 10 // Section holds thread-local data 00135 }; 00136 00137 ELFSection(const std::string &name) 00138 : Name(name), Type(0), Flags(0), Addr(0), Offset(0), Size(0), 00139 Link(0), Info(0), Align(0), EntSize(0) { 00140 } 00141 }; 00142 00143 /// SectionList - This is the list of sections that we have emitted to the 00144 /// file. Once the file has been completely built, the section header table 00145 /// is constructed from this info. 00146 std::list<ELFSection> SectionList; 00147 unsigned NumSections; // Always = SectionList.size() 00148 00149 /// SectionLookup - This is a mapping from section name to section number in 00150 /// the SectionList. 00151 std::map<std::string, ELFSection*> SectionLookup; 00152 00153 /// getSection - Return the section with the specified name, creating a new 00154 /// section if one does not already exist. 00155 ELFSection &getSection(const std::string &Name, 00156 unsigned Type, unsigned Flags = 0) { 00157 ELFSection *&SN = SectionLookup[Name]; 00158 if (SN) return *SN; 00159 00160 SectionList.push_back(Name); 00161 SN = &SectionList.back(); 00162 SN->SectionIdx = NumSections++; 00163 SN->Type = Type; 00164 SN->Flags = Flags; 00165 return *SN; 00166 } 00167 00168 ELFSection &getDataSection() { 00169 return getSection(".data", ELFSection::SHT_PROGBITS, 00170 ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC); 00171 } 00172 ELFSection &getBSSSection() { 00173 return getSection(".bss", ELFSection::SHT_NOBITS, 00174 ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC); 00175 } 00176 00177 /// ELFSym - This struct contains information about each symbol that is 00178 /// added to logical symbol table for the module. This is eventually 00179 /// turned into a real symbol table in the file. 00180 struct ELFSym { 00181 const GlobalValue *GV; // The global value this corresponds to. 00182 unsigned NameIdx; // Index in .strtab of name, once emitted. 00183 uint64_t Value; 00184 unsigned Size; 00185 unsigned char Info; 00186 unsigned char Other; 00187 unsigned short SectionIdx; 00188 00189 enum { STB_LOCAL = 0, STB_GLOBAL = 1, STB_WEAK = 2 }; 00190 enum { STT_NOTYPE = 0, STT_OBJECT = 1, STT_FUNC = 2, STT_SECTION = 3, 00191 STT_FILE = 4 }; 00192 ELFSym(const GlobalValue *gv) : GV(gv), Value(0), Size(0), Info(0), 00193 Other(0), SectionIdx(0) {} 00194 00195 void SetBind(unsigned X) { 00196 assert(X == (X & 0xF) && "Bind value out of range!"); 00197 Info = (Info & 0x0F) | (X << 4); 00198 } 00199 void SetType(unsigned X) { 00200 assert(X == (X & 0xF) && "Type value out of range!"); 00201 Info = (Info & 0xF0) | X; 00202 } 00203 }; 00204 00205 /// SymbolTable - This is the list of symbols we have emitted to the file. 00206 /// This actually gets rearranged before emission to the file (to put the 00207 /// local symbols first in the list). 00208 std::vector<ELFSym> SymbolTable; 00209 00210 // As we complete the ELF file, we need to update fields in the ELF header 00211 // (e.g. the location of the section table). These members keep track of 00212 // the offset in ELFHeader of these various pieces to update and other 00213 // locations in the file. 00214 unsigned ELFHeader_e_shoff_Offset; // e_shoff in ELF header. 00215 unsigned ELFHeader_e_shstrndx_Offset; // e_shstrndx in ELF header. 00216 unsigned ELFHeader_e_shnum_Offset; // e_shnum in ELF header. 00217 00218 00219 // align - Emit padding into the file until the current output position is 00220 // aligned to the specified power of two boundary. 00221 static void align(DataBuffer &Output, unsigned Boundary) { 00222 assert(Boundary && (Boundary & (Boundary-1)) == 0 && 00223 "Must align to 2^k boundary"); 00224 size_t Size = Output.size(); 00225 if (Size & (Boundary-1)) { 00226 // Add padding to get alignment to the correct place. 00227 size_t Pad = Boundary-(Size & (Boundary-1)); 00228 Output.resize(Size+Pad); 00229 } 00230 } 00231 00232 static void outbyte(DataBuffer &Output, unsigned char X) { 00233 Output.push_back(X); 00234 } 00235 void outhalf(DataBuffer &Output, unsigned short X) { 00236 if (isLittleEndian) { 00237 Output.push_back(X&255); 00238 Output.push_back(X >> 8); 00239 } else { 00240 Output.push_back(X >> 8); 00241 Output.push_back(X&255); 00242 } 00243 } 00244 void outword(DataBuffer &Output, unsigned X) { 00245 if (isLittleEndian) { 00246 Output.push_back((X >> 0) & 255); 00247 Output.push_back((X >> 8) & 255); 00248 Output.push_back((X >> 16) & 255); 00249 Output.push_back((X >> 24) & 255); 00250 } else { 00251 Output.push_back((X >> 24) & 255); 00252 Output.push_back((X >> 16) & 255); 00253 Output.push_back((X >> 8) & 255); 00254 Output.push_back((X >> 0) & 255); 00255 } 00256 } 00257 void outxword(DataBuffer &Output, uint64_t X) { 00258 if (isLittleEndian) { 00259 Output.push_back(unsigned(X >> 0) & 255); 00260 Output.push_back(unsigned(X >> 8) & 255); 00261 Output.push_back(unsigned(X >> 16) & 255); 00262 Output.push_back(unsigned(X >> 24) & 255); 00263 Output.push_back(unsigned(X >> 32) & 255); 00264 Output.push_back(unsigned(X >> 40) & 255); 00265 Output.push_back(unsigned(X >> 48) & 255); 00266 Output.push_back(unsigned(X >> 56) & 255); 00267 } else { 00268 Output.push_back(unsigned(X >> 56) & 255); 00269 Output.push_back(unsigned(X >> 48) & 255); 00270 Output.push_back(unsigned(X >> 40) & 255); 00271 Output.push_back(unsigned(X >> 32) & 255); 00272 Output.push_back(unsigned(X >> 24) & 255); 00273 Output.push_back(unsigned(X >> 16) & 255); 00274 Output.push_back(unsigned(X >> 8) & 255); 00275 Output.push_back(unsigned(X >> 0) & 255); 00276 } 00277 } 00278 void outaddr32(DataBuffer &Output, unsigned X) { 00279 outword(Output, X); 00280 } 00281 void outaddr64(DataBuffer &Output, uint64_t X) { 00282 outxword(Output, X); 00283 } 00284 void outaddr(DataBuffer &Output, uint64_t X) { 00285 if (!is64Bit) 00286 outword(Output, (unsigned)X); 00287 else 00288 outxword(Output, X); 00289 } 00290 00291 // fix functions - Replace an existing entry at an offset. 00292 void fixhalf(DataBuffer &Output, unsigned short X, unsigned Offset) { 00293 unsigned char *P = &Output[Offset]; 00294 P[0] = (X >> (isLittleEndian ? 0 : 8)) & 255; 00295 P[1] = (X >> (isLittleEndian ? 8 : 0)) & 255; 00296 } 00297 00298 void fixword(DataBuffer &Output, unsigned X, unsigned Offset) { 00299 unsigned char *P = &Output[Offset]; 00300 P[0] = (X >> (isLittleEndian ? 0 : 24)) & 255; 00301 P[1] = (X >> (isLittleEndian ? 8 : 16)) & 255; 00302 P[2] = (X >> (isLittleEndian ? 16 : 8)) & 255; 00303 P[3] = (X >> (isLittleEndian ? 24 : 0)) & 255; 00304 } 00305 00306 void fixaddr(DataBuffer &Output, uint64_t X, unsigned Offset) { 00307 if (!is64Bit) 00308 fixword(Output, (unsigned)X, Offset); 00309 else 00310 assert(0 && "Emission of 64-bit data not implemented yet!"); 00311 } 00312 00313 private: 00314 void EmitGlobal(GlobalVariable *GV); 00315 00316 void EmitSymbolTable(); 00317 00318 void EmitSectionTableStringTable(); 00319 void OutputSectionsAndSectionTable(); 00320 }; 00321 } 00322 00323 #endif