1 //===-- ELFWriter.h - Target-independent ELF writer support -----*- 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 the ELFWriter class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef ELFWRITER_H 15 #define ELFWRITER_H 16 17 #include "llvm/ADT/SetVector.h" 18 #include "llvm/CodeGen/MachineFunctionPass.h" 19 #include <map> 20 21 namespace llvm { 22 class BinaryObject; 23 class Constant; 24 class ConstantInt; 25 class ConstantStruct; 26 class ELFCodeEmitter; 27 class ELFRelocation; 28 class ELFSection; 29 struct ELFSym; 30 class GlobalVariable; 31 class JITDebugRegisterer; 32 class Mangler; 33 class MachineCodeEmitter; 34 class MachineConstantPoolEntry; 35 class ObjectCodeEmitter; 36 class MCAsmInfo; 37 class TargetELFWriterInfo; 38 class TargetLoweringObjectFile; 39 class raw_ostream; 40 class SectionKind; 41 class MCContext; 42 class TargetMachine; 43 44 typedef std::vector<ELFSym*>::iterator ELFSymIter; 45 typedef std::vector<ELFSection*>::iterator ELFSectionIter; 46 typedef SetVector<const GlobalValue*>::const_iterator PendingGblsIter; 47 typedef SetVector<const char *>::const_iterator PendingExtsIter; 48 typedef std::pair<const Constant *, int64_t> CstExprResTy; 49 50 /// ELFWriter - This class implements the common target-independent code for 51 /// writing ELF files. Targets should derive a class from this to 52 /// parameterize the output format. 53 /// 54 class ELFWriter : public MachineFunctionPass { 55 friend class ELFCodeEmitter; 56 friend class JITDebugRegisterer; 57 public: 58 static char ID; 59 60 /// Return the ELFCodeEmitter as an instance of ObjectCodeEmitter 61 ObjectCodeEmitter *getObjectCodeEmitter() { 62 return reinterpret_cast<ObjectCodeEmitter*>(ElfCE); 63 } 64 65 ELFWriter(raw_ostream &O, TargetMachine &TM); 66 ~ELFWriter(); 67 68 protected: 69 /// Output stream to send the resultant object file to. 70 raw_ostream &O; 71 72 /// Target machine description. 73 TargetMachine &TM; 74 75 /// Context object for machine code objects. 76 MCContext &OutContext; 77 78 /// Target Elf Writer description. 79 const TargetELFWriterInfo *TEW; 80 81 /// Mang - The object used to perform name mangling for this module. 82 Mangler *Mang; 83 84 /// MCE - The MachineCodeEmitter object that we are exposing to emit machine 85 /// code for functions to the .o file. 86 ELFCodeEmitter *ElfCE; 87 88 /// TLOF - Target Lowering Object File, provide section names for globals 89 /// and other object file specific stuff 90 const TargetLoweringObjectFile &TLOF; 91 92 /// MAI - Target Asm Info, provide information about section names for 93 /// globals and other target specific stuff. 94 const MCAsmInfo *MAI; 95 96 //===------------------------------------------------------------------===// 97 // Properties inferred automatically from the target machine. 98 //===------------------------------------------------------------------===// 99 100 /// is64Bit/isLittleEndian - This information is inferred from the target 101 /// machine directly, indicating whether to emit a 32- or 64-bit ELF file. 102 bool is64Bit, isLittleEndian; 103 104 /// doInitialization - Emit the file header and all of the global variables 105 /// for the module to the ELF file. 106 bool doInitialization(Module &M); 107 bool runOnMachineFunction(MachineFunction &MF); 108 109 /// doFinalization - Now that the module has been completely processed, emit 110 /// the ELF file to 'O'. 111 bool doFinalization(Module &M); 112 113 private: 114 /// Blob containing the Elf header 115 BinaryObject ElfHdr; 116 117 /// SectionList - This is the list of sections that we have emitted to the 118 /// file. Once the file has been completely built, the section header table 119 /// is constructed from this info. 120 std::vector<ELFSection*> SectionList; 121 unsigned NumSections; // Always = SectionList.size() 122 123 /// SectionLookup - This is a mapping from section name to section number in 124 /// the SectionList. Used to quickly gather the Section Index from MAI names 125 std::map<std::string, ELFSection*> SectionLookup; 126 127 /// PendingGlobals - Globals not processed as symbols yet. 128 SetVector<const GlobalValue*> PendingGlobals; 129 130 /// GblSymLookup - This is a mapping from global value to a symbol index 131 /// in the symbol table or private symbols list. This is useful since reloc 132 /// symbol references must be quickly mapped to their indices on the lists. 133 std::map<const GlobalValue*, uint32_t> GblSymLookup; 134 135 /// PendingExternals - Externals not processed as symbols yet. 136 SetVector<const char *> PendingExternals; 137 138 /// ExtSymLookup - This is a mapping from externals to a symbol index 139 /// in the symbol table list. This is useful since reloc symbol references 140 /// must be quickly mapped to their symbol table indices. 141 std::map<const char *, uint32_t> ExtSymLookup; 142 143 /// SymbolList - This is the list of symbols emitted to the symbol table. 144 /// When the SymbolList is finally built, local symbols must be placed in 145 /// the beginning while non-locals at the end. 146 std::vector<ELFSym*> SymbolList; 147 148 /// PrivateSyms - Record private symbols, every symbol here must never be 149 /// present in the SymbolList. 150 std::vector<ELFSym*> PrivateSyms; 151 152 /// getSection - Return the section with the specified name, creating a new 153 /// section if one does not already exist. 154 ELFSection &getSection(const std::string &Name, unsigned Type, 155 unsigned Flags = 0, unsigned Align = 0) { 156 ELFSection *&SN = SectionLookup[Name]; 157 if (SN) return *SN; 158 159 SectionList.push_back(new ELFSection(Name, isLittleEndian, is64Bit)); 160 SN = SectionList.back(); 161 SN->SectionIdx = NumSections++; 162 SN->Type = Type; 163 SN->Flags = Flags; 164 SN->Link = ELF::SHN_UNDEF; 165 SN->Align = Align; 166 return *SN; 167 } 168 169 ELFSection &getNonExecStackSection() { 170 return getSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0, 1); 171 } 172 173 ELFSection &getSymbolTableSection() { 174 return getSection(".symtab", ELF::SHT_SYMTAB, 0); 175 } 176 177 ELFSection &getStringTableSection() { 178 return getSection(".strtab", ELF::SHT_STRTAB, 0, 1); 179 } 180 181 ELFSection &getSectionHeaderStringTableSection() { 182 return getSection(".shstrtab", ELF::SHT_STRTAB, 0, 1); 183 } 184 185 ELFSection &getNullSection() { 186 return getSection("", ELF::SHT_NULL, 0); 187 } 188 189 ELFSection &getDataSection(); 190 ELFSection &getBSSSection(); 191 ELFSection &getCtorSection(); 192 ELFSection &getDtorSection(); 193 ELFSection &getJumpTableSection(); 194 ELFSection &getConstantPoolSection(MachineConstantPoolEntry &CPE); 195 ELFSection &getTextSection(const Function *F); 196 ELFSection &getRelocSection(ELFSection &S); 197 198 // Helpers for obtaining ELF specific info. 199 unsigned getGlobalELFBinding(const GlobalValue *GV); 200 unsigned getGlobalELFType(const GlobalValue *GV); 201 unsigned getGlobalELFVisibility(const GlobalValue *GV); 202 203 // AddPendingGlobalSymbol - Add a global to be processed and to 204 // the global symbol lookup, use a zero index because the table 205 // index will be determined later. 206 void AddPendingGlobalSymbol(const GlobalValue *GV, 207 bool AddToLookup = false); 208 209 // AddPendingExternalSymbol - Add the external to be processed 210 // and to the external symbol lookup, use a zero index because 211 // the symbol table index will be determined later. 212 void AddPendingExternalSymbol(const char *External); 213 214 // AddToSymbolList - Update the symbol lookup and If the symbol is 215 // private add it to PrivateSyms list, otherwise to SymbolList. 216 void AddToSymbolList(ELFSym *GblSym); 217 218 // As we complete the ELF file, we need to update fields in the ELF header 219 // (e.g. the location of the section table). These members keep track of 220 // the offset in ELFHeader of these various pieces to update and other 221 // locations in the file. 222 unsigned ELFHdr_e_shoff_Offset; // e_shoff in ELF header. 223 unsigned ELFHdr_e_shstrndx_Offset; // e_shstrndx in ELF header. 224 unsigned ELFHdr_e_shnum_Offset; // e_shnum in ELF header. 225 226 private: 227 void EmitGlobal(const GlobalValue *GV); 228 void EmitGlobalConstant(const Constant *C, ELFSection &GblS); 229 void EmitGlobalConstantStruct(const ConstantStruct *CVS, 230 ELFSection &GblS); 231 void EmitGlobalConstantLargeInt(const ConstantInt *CI, ELFSection &S); 232 void EmitGlobalDataRelocation(const GlobalValue *GV, unsigned Size, 233 ELFSection &GblS, int64_t Offset = 0); 234 bool EmitSpecialLLVMGlobal(const GlobalVariable *GV); 235 void EmitXXStructorList(const Constant *List, ELFSection &Xtor); 236 void EmitRelocations(); 237 void EmitRelocation(BinaryObject &RelSec, ELFRelocation &Rel, bool HasRelA); 238 void EmitSectionHeader(BinaryObject &SHdrTab, const ELFSection &SHdr); 239 void EmitSectionTableStringTable(); 240 void EmitSymbol(BinaryObject &SymbolTable, ELFSym &Sym); 241 void EmitSymbolTable(); 242 void EmitStringTable(const std::string &ModuleName); 243 void OutputSectionsAndSectionTable(); 244 void RelocateField(BinaryObject &BO, uint32_t Offset, int64_t Value, 245 unsigned Size); 246 unsigned SortSymbols(); 247 CstExprResTy ResolveConstantExpr(const Constant *CV); 248 }; 249 } 250 251 #endif 252