1*03ce13f7SAndroid Build Coastguard Worker //===- subzero/src/IceELFObjectWriter.h - ELF object writer -----*- C++ -*-===// 2*03ce13f7SAndroid Build Coastguard Worker // 3*03ce13f7SAndroid Build Coastguard Worker // The Subzero Code Generator 4*03ce13f7SAndroid Build Coastguard Worker // 5*03ce13f7SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*03ce13f7SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*03ce13f7SAndroid Build Coastguard Worker // 8*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*03ce13f7SAndroid Build Coastguard Worker /// 10*03ce13f7SAndroid Build Coastguard Worker /// \file 11*03ce13f7SAndroid Build Coastguard Worker /// \brief Abstraction for a writer that is responsible for writing an ELF file. 12*03ce13f7SAndroid Build Coastguard Worker /// 13*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 14*03ce13f7SAndroid Build Coastguard Worker 15*03ce13f7SAndroid Build Coastguard Worker #ifndef SUBZERO_SRC_ICEELFOBJECTWRITER_H 16*03ce13f7SAndroid Build Coastguard Worker #define SUBZERO_SRC_ICEELFOBJECTWRITER_H 17*03ce13f7SAndroid Build Coastguard Worker 18*03ce13f7SAndroid Build Coastguard Worker #include "IceDefs.h" 19*03ce13f7SAndroid Build Coastguard Worker #include "IceELFSection.h" 20*03ce13f7SAndroid Build Coastguard Worker #include "IceELFStreamer.h" 21*03ce13f7SAndroid Build Coastguard Worker #include "IceTypes.h" 22*03ce13f7SAndroid Build Coastguard Worker 23*03ce13f7SAndroid Build Coastguard Worker using namespace llvm::ELF; 24*03ce13f7SAndroid Build Coastguard Worker 25*03ce13f7SAndroid Build Coastguard Worker namespace Ice { 26*03ce13f7SAndroid Build Coastguard Worker 27*03ce13f7SAndroid Build Coastguard Worker using VariableDeclarationPartition = std::vector<VariableDeclaration *>; 28*03ce13f7SAndroid Build Coastguard Worker 29*03ce13f7SAndroid Build Coastguard Worker /// Higher level ELF object writer. Manages section information and writes the 30*03ce13f7SAndroid Build Coastguard Worker /// final ELF object. The object writer will write to file the code and data as 31*03ce13f7SAndroid Build Coastguard Worker /// it is being defined (rather than keep a copy). After all definitions are 32*03ce13f7SAndroid Build Coastguard Worker /// written out, it will finalize the bookkeeping sections and write them out. 33*03ce13f7SAndroid Build Coastguard Worker /// Expected usage: 34*03ce13f7SAndroid Build Coastguard Worker /// 35*03ce13f7SAndroid Build Coastguard Worker /// (1) writeInitialELFHeader (invoke once) 36*03ce13f7SAndroid Build Coastguard Worker /// (2) writeDataSection (may be invoked multiple times, as long as 37*03ce13f7SAndroid Build Coastguard Worker /// SectionSuffix is unique) 38*03ce13f7SAndroid Build Coastguard Worker /// (3) writeFunctionCode (must invoke once per function) 39*03ce13f7SAndroid Build Coastguard Worker /// (4) writeConstantPool (must invoke once per pooled primitive type) 40*03ce13f7SAndroid Build Coastguard Worker /// (5) setUndefinedSyms (invoke once) 41*03ce13f7SAndroid Build Coastguard Worker /// (6) writeNonUserSections (invoke once) 42*03ce13f7SAndroid Build Coastguard Worker /// 43*03ce13f7SAndroid Build Coastguard Worker /// The requirement for writeDataSection to be invoked only once can be relaxed 44*03ce13f7SAndroid Build Coastguard Worker /// if using -fdata-sections. The requirement to invoke only once without 45*03ce13f7SAndroid Build Coastguard Worker /// -fdata-sections is so that variables that belong to each possible 46*03ce13f7SAndroid Build Coastguard Worker /// SectionType are contiguous in the file. With -fdata-sections, each global 47*03ce13f7SAndroid Build Coastguard Worker /// variable is in a separate section and therefore the sections will be 48*03ce13f7SAndroid Build Coastguard Worker /// trivially contiguous. 49*03ce13f7SAndroid Build Coastguard Worker class ELFObjectWriter { 50*03ce13f7SAndroid Build Coastguard Worker ELFObjectWriter() = delete; 51*03ce13f7SAndroid Build Coastguard Worker ELFObjectWriter(const ELFObjectWriter &) = delete; 52*03ce13f7SAndroid Build Coastguard Worker ELFObjectWriter &operator=(const ELFObjectWriter &) = delete; 53*03ce13f7SAndroid Build Coastguard Worker 54*03ce13f7SAndroid Build Coastguard Worker public: 55*03ce13f7SAndroid Build Coastguard Worker ELFObjectWriter(GlobalContext &Ctx, ELFStreamer &Out); 56*03ce13f7SAndroid Build Coastguard Worker 57*03ce13f7SAndroid Build Coastguard Worker /// Write the initial ELF header. This is just to reserve space in the ELF 58*03ce13f7SAndroid Build Coastguard Worker /// file. Reserving space allows the other functions to write text and data 59*03ce13f7SAndroid Build Coastguard Worker /// directly to the file and get the right file offsets. 60*03ce13f7SAndroid Build Coastguard Worker void writeInitialELFHeader(); 61*03ce13f7SAndroid Build Coastguard Worker 62*03ce13f7SAndroid Build Coastguard Worker /// Copy initializer data for globals to file and note the offset and size of 63*03ce13f7SAndroid Build Coastguard Worker /// each global's definition in the symbol table. Use the given target's 64*03ce13f7SAndroid Build Coastguard Worker /// RelocationKind for any relocations. 65*03ce13f7SAndroid Build Coastguard Worker void writeDataSection(const VariableDeclarationList &Vars, 66*03ce13f7SAndroid Build Coastguard Worker FixupKind RelocationKind, 67*03ce13f7SAndroid Build Coastguard Worker const std::string &SectionSuffix, bool IsPIC); 68*03ce13f7SAndroid Build Coastguard Worker 69*03ce13f7SAndroid Build Coastguard Worker /// Copy data of a function's text section to file and note the offset of the 70*03ce13f7SAndroid Build Coastguard Worker /// symbol's definition in the symbol table. Copy the text fixups for use 71*03ce13f7SAndroid Build Coastguard Worker /// after all functions are written. The text buffer and fixups are extracted 72*03ce13f7SAndroid Build Coastguard Worker /// from the Assembler object. 73*03ce13f7SAndroid Build Coastguard Worker void writeFunctionCode(GlobalString FuncName, bool IsInternal, 74*03ce13f7SAndroid Build Coastguard Worker Assembler *Asm); 75*03ce13f7SAndroid Build Coastguard Worker 76*03ce13f7SAndroid Build Coastguard Worker /// Queries the GlobalContext for constant pools of the given type and writes 77*03ce13f7SAndroid Build Coastguard Worker /// out read-only data sections for those constants. This also fills the 78*03ce13f7SAndroid Build Coastguard Worker /// symbol table with labels for each constant pool entry. 79*03ce13f7SAndroid Build Coastguard Worker template <typename ConstType> void writeConstantPool(Type Ty); 80*03ce13f7SAndroid Build Coastguard Worker 81*03ce13f7SAndroid Build Coastguard Worker /// Write a jump table and register fixups for the target addresses. 82*03ce13f7SAndroid Build Coastguard Worker void writeJumpTable(const JumpTableData &JT, FixupKind RelocationKind, 83*03ce13f7SAndroid Build Coastguard Worker bool IsPIC); 84*03ce13f7SAndroid Build Coastguard Worker 85*03ce13f7SAndroid Build Coastguard Worker /// Populate the symbol table with a list of external/undefined symbols. 86*03ce13f7SAndroid Build Coastguard Worker void setUndefinedSyms(const ConstantList &UndefSyms); 87*03ce13f7SAndroid Build Coastguard Worker 88*03ce13f7SAndroid Build Coastguard Worker /// Do final layout and write out the rest of the object file. Finally, patch 89*03ce13f7SAndroid Build Coastguard Worker /// up the initial ELF header with the final info. 90*03ce13f7SAndroid Build Coastguard Worker void writeNonUserSections(); 91*03ce13f7SAndroid Build Coastguard Worker 92*03ce13f7SAndroid Build Coastguard Worker /// Which type of ELF section a global variable initializer belongs to. This 93*03ce13f7SAndroid Build Coastguard Worker /// is used as an array index so should start at 0 and be contiguous. 94*03ce13f7SAndroid Build Coastguard Worker enum SectionType { ROData = 0, Data, BSS, NumSectionTypes }; 95*03ce13f7SAndroid Build Coastguard Worker 96*03ce13f7SAndroid Build Coastguard Worker /// Create target specific section with the given information about section. 97*03ce13f7SAndroid Build Coastguard Worker void writeTargetRODataSection(const std::string &Name, Elf64_Word ShType, 98*03ce13f7SAndroid Build Coastguard Worker Elf64_Xword ShFlags, Elf64_Xword ShAddralign, 99*03ce13f7SAndroid Build Coastguard Worker Elf64_Xword ShEntsize, 100*03ce13f7SAndroid Build Coastguard Worker const llvm::StringRef &SecData); 101*03ce13f7SAndroid Build Coastguard Worker 102*03ce13f7SAndroid Build Coastguard Worker private: 103*03ce13f7SAndroid Build Coastguard Worker GlobalContext &Ctx; 104*03ce13f7SAndroid Build Coastguard Worker ELFStreamer &Str; 105*03ce13f7SAndroid Build Coastguard Worker bool SectionNumbersAssigned = false; 106*03ce13f7SAndroid Build Coastguard Worker bool ELF64; 107*03ce13f7SAndroid Build Coastguard Worker 108*03ce13f7SAndroid Build Coastguard Worker // All created sections, separated into different pools. 109*03ce13f7SAndroid Build Coastguard Worker using SectionList = std::vector<ELFSection *>; 110*03ce13f7SAndroid Build Coastguard Worker using TextSectionList = std::vector<ELFTextSection *>; 111*03ce13f7SAndroid Build Coastguard Worker using DataSectionList = std::vector<ELFDataSection *>; 112*03ce13f7SAndroid Build Coastguard Worker using RelSectionList = std::vector<ELFRelocationSection *>; 113*03ce13f7SAndroid Build Coastguard Worker TextSectionList TextSections; 114*03ce13f7SAndroid Build Coastguard Worker RelSectionList RelTextSections; 115*03ce13f7SAndroid Build Coastguard Worker DataSectionList DataSections; 116*03ce13f7SAndroid Build Coastguard Worker RelSectionList RelDataSections; 117*03ce13f7SAndroid Build Coastguard Worker DataSectionList RODataSections; 118*03ce13f7SAndroid Build Coastguard Worker RelSectionList RelRODataSections; 119*03ce13f7SAndroid Build Coastguard Worker DataSectionList BSSSections; 120*03ce13f7SAndroid Build Coastguard Worker 121*03ce13f7SAndroid Build Coastguard Worker // Handles to special sections that need incremental bookkeeping. 122*03ce13f7SAndroid Build Coastguard Worker ELFSection *NullSection; 123*03ce13f7SAndroid Build Coastguard Worker ELFStringTableSection *ShStrTab; 124*03ce13f7SAndroid Build Coastguard Worker ELFSymbolTableSection *SymTab; 125*03ce13f7SAndroid Build Coastguard Worker ELFStringTableSection *StrTab; 126*03ce13f7SAndroid Build Coastguard Worker 127*03ce13f7SAndroid Build Coastguard Worker template <typename T> 128*03ce13f7SAndroid Build Coastguard Worker T *createSection(const std::string &Name, Elf64_Word ShType, 129*03ce13f7SAndroid Build Coastguard Worker Elf64_Xword ShFlags, Elf64_Xword ShAddralign, 130*03ce13f7SAndroid Build Coastguard Worker Elf64_Xword ShEntsize); 131*03ce13f7SAndroid Build Coastguard Worker 132*03ce13f7SAndroid Build Coastguard Worker /// Create a relocation section, given the related section (e.g., .text, 133*03ce13f7SAndroid Build Coastguard Worker /// .data., .rodata). 134*03ce13f7SAndroid Build Coastguard Worker ELFRelocationSection * 135*03ce13f7SAndroid Build Coastguard Worker createRelocationSection(const ELFSection *RelatedSection); 136*03ce13f7SAndroid Build Coastguard Worker 137*03ce13f7SAndroid Build Coastguard Worker /// Align the file position before writing out a section's data, and return 138*03ce13f7SAndroid Build Coastguard Worker /// the position of the file. 139*03ce13f7SAndroid Build Coastguard Worker Elf64_Off alignFileOffset(Elf64_Xword Align); 140*03ce13f7SAndroid Build Coastguard Worker 141*03ce13f7SAndroid Build Coastguard Worker /// Assign an ordering / section numbers to each section. Fill in other 142*03ce13f7SAndroid Build Coastguard Worker /// information that is only known near the end (such as the size, if it 143*03ce13f7SAndroid Build Coastguard Worker /// wasn't already incrementally updated). This then collects all sections in 144*03ce13f7SAndroid Build Coastguard Worker /// the decided order, into one vector, for conveniently writing out all of 145*03ce13f7SAndroid Build Coastguard Worker /// the section headers. 146*03ce13f7SAndroid Build Coastguard Worker void assignSectionNumbersInfo(SectionList &AllSections); 147*03ce13f7SAndroid Build Coastguard Worker 148*03ce13f7SAndroid Build Coastguard Worker /// This function assigns .foo and .rel.foo consecutive section numbers. It 149*03ce13f7SAndroid Build Coastguard Worker /// also sets the relocation section's sh_info field to the related section's 150*03ce13f7SAndroid Build Coastguard Worker /// number. 151*03ce13f7SAndroid Build Coastguard Worker template <typename UserSectionList> 152*03ce13f7SAndroid Build Coastguard Worker void assignRelSectionNumInPairs(SizeT &CurSectionNumber, 153*03ce13f7SAndroid Build Coastguard Worker UserSectionList &UserSections, 154*03ce13f7SAndroid Build Coastguard Worker RelSectionList &RelSections, 155*03ce13f7SAndroid Build Coastguard Worker SectionList &AllSections); 156*03ce13f7SAndroid Build Coastguard Worker 157*03ce13f7SAndroid Build Coastguard Worker /// Link the relocation sections to the symbol table. 158*03ce13f7SAndroid Build Coastguard Worker void assignRelLinkNum(SizeT SymTabNumber, RelSectionList &RelSections); 159*03ce13f7SAndroid Build Coastguard Worker 160*03ce13f7SAndroid Build Coastguard Worker /// Helper function for writeDataSection. Writes a data section of type 161*03ce13f7SAndroid Build Coastguard Worker /// SectionType, given the global variables Vars belonging to that 162*03ce13f7SAndroid Build Coastguard Worker /// SectionType. 163*03ce13f7SAndroid Build Coastguard Worker void writeDataOfType(SectionType SectionType, 164*03ce13f7SAndroid Build Coastguard Worker const VariableDeclarationPartition &Vars, 165*03ce13f7SAndroid Build Coastguard Worker FixupKind RelocationKind, 166*03ce13f7SAndroid Build Coastguard Worker const std::string &SectionSuffix, bool IsPIC); 167*03ce13f7SAndroid Build Coastguard Worker 168*03ce13f7SAndroid Build Coastguard Worker /// Write the final relocation sections given the final symbol table. May also 169*03ce13f7SAndroid Build Coastguard Worker /// be able to seek around the file and resolve function calls that are for 170*03ce13f7SAndroid Build Coastguard Worker /// functions within the same section. 171*03ce13f7SAndroid Build Coastguard Worker void writeAllRelocationSections(); 172*03ce13f7SAndroid Build Coastguard Worker void writeRelocationSections(RelSectionList &RelSections); 173*03ce13f7SAndroid Build Coastguard Worker 174*03ce13f7SAndroid Build Coastguard Worker /// Write the ELF file header with the given information about sections. 175*03ce13f7SAndroid Build Coastguard Worker template <bool IsELF64> 176*03ce13f7SAndroid Build Coastguard Worker void writeELFHeaderInternal(Elf64_Off SectionHeaderOffset, 177*03ce13f7SAndroid Build Coastguard Worker SizeT SectHeaderStrIndex, SizeT NumSections); 178*03ce13f7SAndroid Build Coastguard Worker }; 179*03ce13f7SAndroid Build Coastguard Worker 180*03ce13f7SAndroid Build Coastguard Worker } // end of namespace Ice 181*03ce13f7SAndroid Build Coastguard Worker 182*03ce13f7SAndroid Build Coastguard Worker #endif // SUBZERO_SRC_ICEELFOBJECTWRITER_H 183