Home | History | Annotate | Download | only in CodeGen
      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