| OLD | NEW |
| 1 //===- subzero/src/IceELFObjectWriter.h - ELF object writer -----*- C++ -*-===// | 1 //===- subzero/src/IceELFObjectWriter.h - ELF object writer -----*- C++ -*-===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 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 // Abstraction for a writer that is responsible for writing an ELF file. | 10 // Abstraction for a writer that is responsible for writing an ELF file. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 | 23 |
| 24 namespace Ice { | 24 namespace Ice { |
| 25 | 25 |
| 26 // Higher level ELF object writer. Manages section information and writes | 26 // Higher level ELF object writer. Manages section information and writes |
| 27 // the final ELF object. The object writer will write to file the code | 27 // the final ELF object. The object writer will write to file the code |
| 28 // and data as it is being defined (rather than keep a copy). | 28 // and data as it is being defined (rather than keep a copy). |
| 29 // After all definitions are written out, it will finalize the bookkeeping | 29 // After all definitions are written out, it will finalize the bookkeeping |
| 30 // sections and write them out. Expected usage: | 30 // sections and write them out. Expected usage: |
| 31 // | 31 // |
| 32 // (1) writeInitialELFHeader | 32 // (1) writeInitialELFHeader |
| 33 // (2) writeDataInitializer* | 33 // (2) writeDataSection |
| 34 // (3) writeFunctionCode* | 34 // (3) writeFunctionCode* |
| 35 // (4) writeNonUserSections | 35 // (4) writeNonUserSections |
| 36 class ELFObjectWriter { | 36 class ELFObjectWriter { |
| 37 ELFObjectWriter(const ELFObjectWriter &) = delete; | 37 ELFObjectWriter(const ELFObjectWriter &) = delete; |
| 38 ELFObjectWriter &operator=(const ELFObjectWriter &) = delete; | 38 ELFObjectWriter &operator=(const ELFObjectWriter &) = delete; |
| 39 | 39 |
| 40 public: | 40 public: |
| 41 ELFObjectWriter(GlobalContext &Ctx, ELFStreamer &Out); | 41 ELFObjectWriter(GlobalContext &Ctx, ELFStreamer &Out); |
| 42 | 42 |
| 43 // Write the initial ELF header. This is just to reserve space in the ELF | 43 // Write the initial ELF header. This is just to reserve space in the ELF |
| 44 // file. Reserving space allows the other functions to write text | 44 // file. Reserving space allows the other functions to write text |
| 45 // and data directly to the file and get the right file offsets. | 45 // and data directly to the file and get the right file offsets. |
| 46 void writeInitialELFHeader(); | 46 void writeInitialELFHeader(); |
| 47 | 47 |
| 48 // Copy data of a function's text section to file and note the offset of the | 48 // Copy data of a function's text section to file and note the offset of the |
| 49 // symbol's definition in the symbol table. | 49 // symbol's definition in the symbol table. |
| 50 // Copy the text fixups for use after all functions are written. | 50 // Copy the text fixups for use after all functions are written. |
| 51 void writeFunctionCode(const IceString &FuncName, bool IsInternal, | 51 void writeFunctionCode(const IceString &FuncName, bool IsInternal, |
| 52 const Assembler *Asm); | 52 const Assembler *Asm); |
| 53 | 53 |
| 54 // Copy initializer data for a global to file and note the offset and | 54 // Copy initializer data for globals to file and note the offset and size |
| 55 // size of the global's definition in the symbol table. | 55 // of each global's definition in the symbol table. |
| 56 // TODO(jvoung): This needs to know which section. This also needs the | 56 // Use the given target's RelocationKind for relocations. |
| 57 // relocations to hook them up to the symbol table references. Also | 57 void writeDataSection(const VariableDeclarationList &Vars, |
| 58 // TODO is handling BSS (which just needs to note the size). | 58 FixupKind RelocationKind); |
| 59 void writeDataInitializer(const IceString &VarName, | |
| 60 const llvm::StringRef Data); | |
| 61 | 59 |
| 62 template <typename ConstType> void writeConstantPool(Type Ty); | 60 template <typename ConstType> void writeConstantPool(Type Ty); |
| 63 | 61 |
| 64 // Do final layout and write out the rest of the object file, then | 62 // Do final layout and write out the rest of the object file, then |
| 65 // patch up the initial ELF header with the final info. | 63 // patch up the initial ELF header with the final info. |
| 66 void writeNonUserSections(); | 64 void writeNonUserSections(); |
| 67 | 65 |
| 66 // Which type of ELF section a global variable initializer belongs to. |
| 67 enum SectionType { |
| 68 BaseSectionType = 0, |
| 69 ROData = BaseSectionType, |
| 70 Data, |
| 71 BSS, |
| 72 NumSectionTypes |
| 73 }; |
| 74 |
| 68 private: | 75 private: |
| 69 GlobalContext &Ctx; | 76 GlobalContext &Ctx; |
| 70 ELFStreamer &Str; | 77 ELFStreamer &Str; |
| 71 bool SectionNumbersAssigned; | 78 bool SectionNumbersAssigned; |
| 72 | 79 |
| 73 // All created sections, separated into different pools. | 80 // All created sections, separated into different pools. |
| 74 typedef std::vector<ELFSection *> SectionList; | 81 typedef std::vector<ELFSection *> SectionList; |
| 75 typedef std::vector<ELFTextSection *> TextSectionList; | 82 typedef std::vector<ELFTextSection *> TextSectionList; |
| 76 typedef std::vector<ELFDataSection *> DataSectionList; | 83 typedef std::vector<ELFDataSection *> DataSectionList; |
| 77 typedef std::vector<ELFRelocationSection *> RelSectionList; | 84 typedef std::vector<ELFRelocationSection *> RelSectionList; |
| 78 TextSectionList TextSections; | 85 TextSectionList TextSections; |
| 79 RelSectionList RelTextSections; | 86 RelSectionList RelTextSections; |
| 80 DataSectionList DataSections; | 87 DataSectionList DataSections; |
| 81 RelSectionList RelDataSections; | 88 RelSectionList RelDataSections; |
| 82 DataSectionList RoDataSections; | 89 DataSectionList RODataSections; |
| 83 RelSectionList RelRoDataSections; | 90 RelSectionList RelRODataSections; |
| 91 DataSectionList BSSSections; |
| 84 | 92 |
| 85 // Handles to special sections that need incremental bookkeeping. | 93 // Handles to special sections that need incremental bookkeeping. |
| 86 ELFSection *NullSection; | 94 ELFSection *NullSection; |
| 87 ELFStringTableSection *ShStrTab; | 95 ELFStringTableSection *ShStrTab; |
| 88 ELFSymbolTableSection *SymTab; | 96 ELFSymbolTableSection *SymTab; |
| 89 ELFStringTableSection *StrTab; | 97 ELFStringTableSection *StrTab; |
| 90 | 98 |
| 91 template <typename T> | 99 template <typename T> |
| 92 T *createSection(const IceString &Name, Elf64_Word ShType, | 100 T *createSection(const IceString &Name, Elf64_Word ShType, |
| 93 Elf64_Xword ShFlags, Elf64_Xword ShAddralign, | 101 Elf64_Xword ShFlags, Elf64_Xword ShAddralign, |
| 94 Elf64_Xword ShEntsize); | 102 Elf64_Xword ShEntsize); |
| 95 | 103 |
| 104 // Create a relocation section, given the related section |
| 105 // (e.g., .text, .data., .rodata). |
| 106 ELFRelocationSection * |
| 107 createRelocationSection(bool IsELF64, const ELFSection *RelatedSection); |
| 108 |
| 96 // Align the file position before writing out a section's data, | 109 // Align the file position before writing out a section's data, |
| 97 // and return the position of the file. | 110 // and return the position of the file. |
| 98 Elf64_Off alignFileOffset(Elf64_Xword Align); | 111 Elf64_Off alignFileOffset(Elf64_Xword Align); |
| 99 | 112 |
| 100 // Assign an ordering / section numbers to each section. | 113 // Assign an ordering / section numbers to each section. |
| 101 // Fill in other information that is only known near the end | 114 // Fill in other information that is only known near the end |
| 102 // (such as the size, if it wasn't already incrementally updated). | 115 // (such as the size, if it wasn't already incrementally updated). |
| 103 // This then collects all sections in the decided order, into one vector, | 116 // This then collects all sections in the decided order, into one vector, |
| 104 // for conveniently writing out all of the section headers. | 117 // for conveniently writing out all of the section headers. |
| 105 void assignSectionNumbersInfo(SectionList &AllSections); | 118 void assignSectionNumbersInfo(SectionList &AllSections); |
| 106 | 119 |
| 107 // This function assigns .foo and .rel.foo consecutive section numbers. | 120 // This function assigns .foo and .rel.foo consecutive section numbers. |
| 108 // It also sets the relocation section's sh_info field to the related | 121 // It also sets the relocation section's sh_info field to the related |
| 109 // section's number. | 122 // section's number. |
| 110 template <typename UserSectionList> | 123 template <typename UserSectionList> |
| 111 void assignRelSectionNumInPairs(SizeT &CurSectionNumber, | 124 void assignRelSectionNumInPairs(SizeT &CurSectionNumber, |
| 112 UserSectionList &UserSections, | 125 UserSectionList &UserSections, |
| 113 RelSectionList &RelSections, | 126 RelSectionList &RelSections, |
| 114 SectionList &AllSections); | 127 SectionList &AllSections); |
| 115 | 128 |
| 116 // Link the relocation sections to the symbol table. | 129 // Link the relocation sections to the symbol table. |
| 117 void assignRelLinkNum(SizeT SymTabNumber, RelSectionList &RelSections); | 130 void assignRelLinkNum(SizeT SymTabNumber, RelSectionList &RelSections); |
| 118 | 131 |
| 132 // Helper function for writeDataSection. Writes a data section of type |
| 133 // SectionType, given the global variables Vars belonging to that SectionType. |
| 134 void writeDataOfType(SectionType SectionType, |
| 135 const VariableDeclarationList &Vars, |
| 136 FixupKind RelocationKind, bool IsELF64); |
| 137 |
| 119 // Write the final relocation sections given the final symbol table. | 138 // Write the final relocation sections given the final symbol table. |
| 120 // May also be able to seek around the file and resolve function calls | 139 // May also be able to seek around the file and resolve function calls |
| 121 // that are for functions within the same section. | 140 // that are for functions within the same section. |
| 122 void writeAllRelocationSections(bool IsELF64); | 141 void writeAllRelocationSections(bool IsELF64); |
| 123 void writeRelocationSections(bool IsELF64, RelSectionList &RelSections); | 142 void writeRelocationSections(bool IsELF64, RelSectionList &RelSections); |
| 124 | 143 |
| 125 // Write the ELF file header with the given information about sections. | 144 // Write the ELF file header with the given information about sections. |
| 126 template <bool IsELF64> | 145 template <bool IsELF64> |
| 127 void writeELFHeaderInternal(Elf64_Off SectionHeaderOffset, | 146 void writeELFHeaderInternal(Elf64_Off SectionHeaderOffset, |
| 128 SizeT SectHeaderStrIndex, SizeT NumSections); | 147 SizeT SectHeaderStrIndex, SizeT NumSections); |
| 129 }; | 148 }; |
| 130 | 149 |
| 131 } // end of namespace Ice | 150 } // end of namespace Ice |
| 132 | 151 |
| 133 #endif // SUBZERO_SRC_ICEELFOBJECTWRITER_H | 152 #endif // SUBZERO_SRC_ICEELFOBJECTWRITER_H |
| OLD | NEW |