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