| 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 "llvm/Support/Debug.h" | |
| 20 #include "llvm/Target/TargetAsmInfo.h" | |
| 21 #include "llvm/Target/TargetELFWriterInfo.h" | |
| 22 #include "ELF.h" | |
| 23 #include <list> | |
| 24 #include <map> | 19 #include <map> |
| 25 | 20 |
| 26 namespace llvm { | 21 namespace llvm { |
| 27 class BinaryObject; | 22 class BinaryObject; |
| 23 class Constant; | |
| 24 class ConstantInt; | |
| 28 class ConstantStruct; | 25 class ConstantStruct; |
| 29 class ELFCodeEmitter; | 26 class ELFCodeEmitter; |
| 27 class ELFRelocation; | |
| 28 class ELFSection; | |
| 29 struct ELFSym; | |
| 30 class GlobalVariable; | 30 class GlobalVariable; |
| 31 class JITDebugRegisterer; | |
| 31 class Mangler; | 32 class Mangler; |
| 32 class MachineCodeEmitter; | 33 class MachineCodeEmitter; |
| 33 class JITDebugRegisterer; | 34 class MachineConstantPoolEntry; |
| 35 class ObjectCodeEmitter; | |
| 36 class MCAsmInfo; | |
| 37 class TargetELFWriterInfo; | |
| 38 class TargetLoweringObjectFile; | |
| 34 class raw_ostream; | 39 class raw_ostream; |
| 40 class SectionKind; | |
| 41 class MCContext; | |
| 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; | |
| 35 | 48 |
| 36 /// ELFWriter - This class implements the common target-independent code for | 49 /// ELFWriter - This class implements the common target-independent code for |
| 37 /// writing ELF files. Targets should derive a class from this to | 50 /// writing ELF files. Targets should derive a class from this to |
| 38 /// parameterize the output format. | 51 /// parameterize the output format. |
| 39 /// | 52 /// |
| 40 class ELFWriter : public MachineFunctionPass { | 53 class ELFWriter : public MachineFunctionPass { |
| 41 friend class ELFCodeEmitter; | 54 friend class ELFCodeEmitter; |
| 42 friend class JITDebugRegisterer; | 55 friend class JITDebugRegisterer; |
|
nlewycky
2009/07/04 01:27:07
Did you know that there are 116 words in the Engli
| |
| 43 public: | 56 public: |
| 44 static char ID; | 57 static char ID; |
| 45 | 58 |
| 46 MachineCodeEmitter &getMachineCodeEmitter() const { | 59 /// Return the ELFCodeEmitter as an instance of ObjectCodeEmitter |
| 47 return *(MachineCodeEmitter*)MCE; | 60 ObjectCodeEmitter *getObjectCodeEmitter() { |
| 61 return reinterpret_cast<ObjectCodeEmitter*>(ElfCE); | |
| 48 } | 62 } |
| 49 | 63 |
| 50 ELFWriter(raw_ostream &O, TargetMachine &TM); | 64 ELFWriter(raw_ostream &O, TargetMachine &TM); |
| 51 ~ELFWriter(); | 65 ~ELFWriter(); |
| 52 | |
| 53 typedef std::vector<unsigned char> DataBuffer; | |
| 54 | 66 |
| 55 protected: | 67 protected: |
| 56 /// Output stream to send the resultant object file to. | 68 /// Output stream to send the resultant object file to. |
| 57 raw_ostream &O; | 69 raw_ostream &O; |
| 58 | 70 |
| 59 /// Target machine description. | 71 /// Target machine description. |
| 60 TargetMachine &TM; | 72 TargetMachine &TM; |
| 61 | 73 |
| 74 /// Context object for machine code objects. | |
| 75 MCContext &OutContext; | |
| 76 | |
| 62 /// Target Elf Writer description. | 77 /// Target Elf Writer description. |
| 63 const TargetELFWriterInfo *TEW; | 78 const TargetELFWriterInfo *TEW; |
| 64 | 79 |
| 65 /// Mang - The object used to perform name mangling for this module. | 80 /// Mang - The object used to perform name mangling for this module. |
| 66 Mangler *Mang; | 81 Mangler *Mang; |
| 67 | 82 |
| 68 /// MCE - The MachineCodeEmitter object that we are exposing to emit machine | 83 /// MCE - The MachineCodeEmitter object that we are exposing to emit machine |
| 69 /// code for functions to the .o file. | 84 /// code for functions to the .o file. |
| 70 ELFCodeEmitter *MCE; | 85 ELFCodeEmitter *ElfCE; |
| 71 | 86 |
| 72 /// 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 | |
| 73 /// globals and other target specific stuff. | 92 /// globals and other target specific stuff. |
| 74 const TargetAsmInfo *TAI; | 93 const MCAsmInfo *MAI; |
| 75 | 94 |
| 76 //===------------------------------------------------------------------===// | 95 //===------------------------------------------------------------------===// |
| 77 // Properties inferred automatically from the target machine. | 96 // Properties inferred automatically from the target machine. |
| 78 //===------------------------------------------------------------------===// | 97 //===------------------------------------------------------------------===// |
| 79 | 98 |
| 80 /// is64Bit/isLittleEndian - This information is inferred from the target | 99 /// is64Bit/isLittleEndian - This information is inferred from the target |
| 81 /// 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. |
| 82 bool is64Bit, isLittleEndian; | 101 bool is64Bit, isLittleEndian; |
| 83 | 102 |
| 84 /// doInitialization - Emit the file header and all of the global variables | 103 /// doInitialization - Emit the file header and all of the global variables |
| 85 /// for the module to the ELF file. | 104 /// for the module to the ELF file. |
| 86 bool doInitialization(Module &M); | 105 bool doInitialization(Module &M); |
| 87 bool runOnMachineFunction(MachineFunction &MF); | 106 bool runOnMachineFunction(MachineFunction &MF); |
| 88 | 107 |
| 89 /// doFinalization - Now that the module has been completely processed, emit | 108 /// doFinalization - Now that the module has been completely processed, emit |
| 90 /// the ELF file to 'O'. | 109 /// the ELF file to 'O'. |
| 91 bool doFinalization(Module &M); | 110 bool doFinalization(Module &M); |
| 92 | 111 |
| 93 private: | 112 private: |
| 94 /// Blob containing the Elf header | 113 /// Blob containing the Elf header |
| 95 BinaryObject ElfHdr; | 114 BinaryObject ElfHdr; |
| 96 | 115 |
| 97 /// 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 |
| 98 /// 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 |
| 99 /// is constructed from this info. | 118 /// is constructed from this info. |
| 100 std::list<ELFSection> SectionList; | 119 std::vector<ELFSection*> SectionList; |
| 101 unsigned NumSections; // Always = SectionList.size() | 120 unsigned NumSections; // Always = SectionList.size() |
| 102 | 121 |
| 103 /// 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 |
| 104 /// the SectionList. | 123 /// the SectionList. Used to quickly gather the Section Index from MAI names |
| 105 std::map<std::string, ELFSection*> SectionLookup; | 124 std::map<std::string, ELFSection*> SectionLookup; |
| 106 | 125 |
| 126 /// PendingGlobals - Globals not processed as symbols yet. | |
| 127 SetVector<const GlobalValue*> PendingGlobals; | |
| 128 | |
| 107 /// 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 |
| 108 /// 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 |
| 109 /// must be quickly mapped to a symbol table index | 131 /// symbol references must be quickly mapped to their indices on the lists. |
| 110 std::map<const GlobalValue*, uint32_t> GblSymLookup; | 132 std::map<const GlobalValue*, uint32_t> GblSymLookup; |
| 111 | 133 |
| 112 /// SymbolList - This is the list of symbols emitted to the symbol table | 134 /// PendingExternals - Externals not processed as symbols yet. |
| 113 /// Local symbols go to the front and Globals to the back. | 135 SetVector<const char *> PendingExternals; |
| 114 std::list<ELFSym> SymbolList; | 136 |
| 115 | 137 /// ExtSymLookup - This is a mapping from externals to a symbol index |
| 116 /// PendingGlobals - List of externally defined symbols that we have been | 138 /// in the symbol table list. This is useful since reloc symbol references |
| 117 /// asked to emit, but have not seen a reference to. When a reference | 139 /// must be quickly mapped to their symbol table indices. |
| 118 /// is seen, the symbol will move from this list to the SymbolList. | 140 std::map<const char *, uint32_t> ExtSymLookup; |
| 119 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; | |
| 120 | 150 |
| 121 /// getSection - Return the section with the specified name, creating a new | 151 /// getSection - Return the section with the specified name, creating a new |
| 122 /// section if one does not already exist. | 152 /// section if one does not already exist. |
| 123 ELFSection &getSection(const std::string &Name, unsigned Type, | 153 ELFSection &getSection(const std::string &Name, unsigned Type, |
| 124 unsigned Flags = 0, unsigned Align = 0) { | 154 unsigned Flags = 0, unsigned Align = 0) { |
| 125 ELFSection *&SN = SectionLookup[Name]; | 155 ELFSection *&SN = SectionLookup[Name]; |
| 126 if (SN) return *SN; | 156 if (SN) return *SN; |
| 127 | 157 |
| 128 // Remove tab from section name prefix. This is necessary becase TAI | 158 SectionList.push_back(new ELFSection(Name, isLittleEndian, is64Bit)); |
| 129 // sometimes return a section name prefixed with a "\t" char. | 159 SN = SectionList.back(); |
| 130 std::string SectionName(Name); | |
| 131 size_t Pos = SectionName.find("\t"); | |
| 132 if (Pos != std::string::npos) | |
| 133 SectionName.erase(Pos, 1); | |
| 134 | |
| 135 SectionList.push_back(ELFSection(SectionName, isLittleEndian, is64Bit)); | |
| 136 SN = &SectionList.back(); | |
| 137 SN->SectionIdx = NumSections++; | 160 SN->SectionIdx = NumSections++; |
| 138 SN->Type = Type; | 161 SN->Type = Type; |
| 139 SN->Flags = Flags; | 162 SN->Flags = Flags; |
| 140 SN->Link = ELFSection::SHN_UNDEF; | 163 SN->Link = ELFSection::SHN_UNDEF; |
| 141 SN->Align = Align; | 164 SN->Align = Align; |
| 142 return *SN; | 165 return *SN; |
| 143 } | 166 } |
| 144 | 167 |
| 145 /// TODO: support mangled names here to emit the right .text section | |
| 146 /// for c++ object files. | |
| 147 ELFSection &getTextSection() { | |
| 148 return getSection(".text", ELFSection::SHT_PROGBITS, | |
| 149 ELFSection::SHF_EXECINSTR | ELFSection::SHF_ALLOC); | |
| 150 } | |
| 151 | |
| 152 /// Get a constant pool section based on the section name returned by TAI | |
| 153 ELFSection &getConstantPoolSection(std::string SName, unsigned Align) { | |
| 154 return getSection(SName, ELFSection::SHT_PROGBITS, | |
| 155 ELFSection::SHF_MERGE | ELFSection::SHF_ALLOC, Align); | |
| 156 } | |
| 157 | |
| 158 /// Return the relocation section of section 'S'. 'RelA' is true | |
| 159 /// if the relocation section contains entries with addends. | |
| 160 ELFSection &getRelocSection(std::string SName, bool RelA) { | |
| 161 std::string RelSName(".rel"); | |
| 162 unsigned SHdrTy = RelA ? ELFSection::SHT_RELA : ELFSection::SHT_REL; | |
| 163 | |
| 164 if (RelA) RelSName.append("a"); | |
| 165 RelSName.append(SName); | |
| 166 | |
| 167 return getSection(RelSName, SHdrTy, 0, TEW->getPrefELFAlignment()); | |
| 168 } | |
| 169 | |
| 170 ELFSection &getNonExecStackSection() { | 168 ELFSection &getNonExecStackSection() { |
| 171 return getSection(".note.GNU-stack", ELFSection::SHT_PROGBITS, 0, 1); | 169 return getSection(".note.GNU-stack", ELFSection::SHT_PROGBITS, 0, 1); |
| 172 } | 170 } |
| 173 | 171 |
| 174 ELFSection &getSymbolTableSection() { | 172 ELFSection &getSymbolTableSection() { |
| 175 return getSection(".symtab", ELFSection::SHT_SYMTAB, 0); | 173 return getSection(".symtab", ELFSection::SHT_SYMTAB, 0); |
| 176 } | 174 } |
| 177 | 175 |
| 178 ELFSection &getStringTableSection() { | 176 ELFSection &getStringTableSection() { |
| 179 return getSection(".strtab", ELFSection::SHT_STRTAB, 0, 1); | 177 return getSection(".strtab", ELFSection::SHT_STRTAB, 0, 1); |
| 180 } | 178 } |
| 181 | 179 |
| 182 ELFSection &getSectionHeaderStringTableSection() { | 180 ELFSection &getSectionHeaderStringTableSection() { |
| 183 return getSection(".shstrtab", ELFSection::SHT_STRTAB, 0, 1); | 181 return getSection(".shstrtab", ELFSection::SHT_STRTAB, 0, 1); |
| 184 } | 182 } |
| 185 | 183 |
| 186 ELFSection &getDataSection() { | |
| 187 return getSection(".data", ELFSection::SHT_PROGBITS, | |
| 188 ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC, 4); | |
| 189 } | |
| 190 | |
| 191 ELFSection &getBSSSection() { | |
| 192 return getSection(".bss", ELFSection::SHT_NOBITS, | |
| 193 ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC, 4); | |
| 194 } | |
| 195 | |
| 196 ELFSection &getNullSection() { | 184 ELFSection &getNullSection() { |
| 197 return getSection("", ELFSection::SHT_NULL, 0); | 185 return getSection("", ELFSection::SHT_NULL, 0); |
| 198 } | 186 } |
| 187 | |
| 188 ELFSection &getDataSection(); | |
| 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); | |
| 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); | |
| 199 | 216 |
| 200 // 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 |
| 201 // (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 |
| 202 // 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 |
| 203 // locations in the file. | 220 // locations in the file. |
| 204 unsigned ELFHdr_e_shoff_Offset; // e_shoff in ELF header. | 221 unsigned ELFHdr_e_shoff_Offset; // e_shoff in ELF header. |
| 205 unsigned ELFHdr_e_shstrndx_Offset; // e_shstrndx in ELF header. | 222 unsigned ELFHdr_e_shstrndx_Offset; // e_shstrndx in ELF header. |
| 206 unsigned ELFHdr_e_shnum_Offset; // e_shnum in ELF header. | 223 unsigned ELFHdr_e_shnum_Offset; // e_shnum in ELF header. |
| 207 | 224 |
| 208 private: | 225 private: |
| 209 void EmitFunctionDeclaration(const Function *F); | 226 void EmitGlobal(const GlobalValue *GV); |
| 210 void EmitGlobalVar(const GlobalVariable *GV); | |
| 211 void EmitGlobalConstant(const Constant *C, ELFSection &GblS); | 227 void EmitGlobalConstant(const Constant *C, ELFSection &GblS); |
| 212 void EmitGlobalConstantStruct(const ConstantStruct *CVS, | 228 void EmitGlobalConstantStruct(const ConstantStruct *CVS, |
| 213 ELFSection &GblS); | 229 ELFSection &GblS); |
| 214 unsigned getGlobalELFLinkage(const GlobalVariable *GV); | 230 void EmitGlobalConstantLargeInt(const ConstantInt *CI, ELFSection &S); |
| 215 ELFSection &getGlobalSymELFSection(const GlobalVariable *GV, ELFSym &Sym); | 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); | |
| 216 void EmitRelocations(); | 235 void EmitRelocations(); |
| 217 void EmitRelocation(BinaryObject &RelSec, ELFRelocation &Rel, bool HasRelA); | 236 void EmitRelocation(BinaryObject &RelSec, ELFRelocation &Rel, bool HasRelA); |
| 218 void EmitSectionHeader(BinaryObject &SHdrTab, const ELFSection &SHdr); | 237 void EmitSectionHeader(BinaryObject &SHdrTab, const ELFSection &SHdr); |
| 219 void EmitSectionTableStringTable(); | 238 void EmitSectionTableStringTable(); |
| 220 void EmitSymbol(BinaryObject &SymbolTable, ELFSym &Sym); | 239 void EmitSymbol(BinaryObject &SymbolTable, ELFSym &Sym); |
| 221 void EmitSymbolTable(); | 240 void EmitSymbolTable(); |
| 222 void EmitStringTable(); | 241 void EmitStringTable(const std::string &ModuleName); |
| 223 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); | |
| 224 }; | 247 }; |
| 225 } | 248 } |
| 226 | 249 |
| 227 #endif | 250 #endif |
| LEFT | RIGHT |