//===-- ELFWriter.h - Target-independent ELF writer support -----*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file defines the ELFWriter class. // //===----------------------------------------------------------------------===// #ifndef ELFWRITER_H #define ELFWRITER_H #include "llvm/ADT/SetVector.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include <map> namespace llvm { class BinaryObject; class Constant; class ConstantInt; class ConstantStruct; class ELFCodeEmitter; class ELFRelocation; class ELFSection; struct ELFSym; class GlobalVariable; class JITDebugRegisterer; class Mangler; class MachineCodeEmitter; class MachineConstantPoolEntry; class ObjectCodeEmitter; class MCAsmInfo; class TargetELFWriterInfo; class TargetLoweringObjectFile; class raw_ostream; class SectionKind; class MCContext; class TargetMachine; typedef std::vector<ELFSym*>::iterator ELFSymIter; typedef std::vector<ELFSection*>::iterator ELFSectionIter; typedef SetVector<const GlobalValue*>::const_iterator PendingGblsIter; typedef SetVector<const char *>::const_iterator PendingExtsIter; typedef std::pair<const Constant *, int64_t> CstExprResTy; /// ELFWriter - This class implements the common target-independent code for /// writing ELF files. Targets should derive a class from this to /// parameterize the output format. /// class ELFWriter : public MachineFunctionPass { friend class ELFCodeEmitter; friend class JITDebugRegisterer; public: static char ID; /// Return the ELFCodeEmitter as an instance of ObjectCodeEmitter ObjectCodeEmitter *getObjectCodeEmitter() { return reinterpret_cast<ObjectCodeEmitter*>(ElfCE); } ELFWriter(raw_ostream &O, TargetMachine &TM); ~ELFWriter(); protected: /// Output stream to send the resultant object file to. raw_ostream &O; /// Target machine description. TargetMachine &TM; /// Context object for machine code objects. MCContext &OutContext; /// Target Elf Writer description. const TargetELFWriterInfo *TEW; /// Mang - The object used to perform name mangling for this module. Mangler *Mang; /// MCE - The MachineCodeEmitter object that we are exposing to emit machine /// code for functions to the .o file. ELFCodeEmitter *ElfCE; /// TLOF - Target Lowering Object File, provide section names for globals /// and other object file specific stuff const TargetLoweringObjectFile &TLOF; /// MAI - Target Asm Info, provide information about section names for /// globals and other target specific stuff. const MCAsmInfo *MAI; //===------------------------------------------------------------------===// // Properties inferred automatically from the target machine. //===------------------------------------------------------------------===// /// is64Bit/isLittleEndian - This information is inferred from the target /// machine directly, indicating whether to emit a 32- or 64-bit ELF file. bool is64Bit, isLittleEndian; /// doInitialization - Emit the file header and all of the global variables /// for the module to the ELF file. bool doInitialization(Module &M); bool runOnMachineFunction(MachineFunction &MF); /// doFinalization - Now that the module has been completely processed, emit /// the ELF file to 'O'. bool doFinalization(Module &M); private: /// Blob containing the Elf header BinaryObject ElfHdr; /// SectionList - This is the list of sections that we have emitted to the /// file. Once the file has been completely built, the section header table /// is constructed from this info. std::vector<ELFSection*> SectionList; unsigned NumSections; // Always = SectionList.size() /// SectionLookup - This is a mapping from section name to section number in /// the SectionList. Used to quickly gather the Section Index from MAI names std::map<std::string, ELFSection*> SectionLookup; /// PendingGlobals - Globals not processed as symbols yet. SetVector<const GlobalValue*> PendingGlobals; /// GblSymLookup - This is a mapping from global value to a symbol index /// in the symbol table or private symbols list. This is useful since reloc /// symbol references must be quickly mapped to their indices on the lists. std::map<const GlobalValue*, uint32_t> GblSymLookup; /// PendingExternals - Externals not processed as symbols yet. SetVector<const char *> PendingExternals; /// ExtSymLookup - This is a mapping from externals to a symbol index /// in the symbol table list. This is useful since reloc symbol references /// must be quickly mapped to their symbol table indices. std::map<const char *, uint32_t> ExtSymLookup; /// SymbolList - This is the list of symbols emitted to the symbol table. /// When the SymbolList is finally built, local symbols must be placed in /// the beginning while non-locals at the end. std::vector<ELFSym*> SymbolList; /// PrivateSyms - Record private symbols, every symbol here must never be /// present in the SymbolList. std::vector<ELFSym*> PrivateSyms; /// getSection - Return the section with the specified name, creating a new /// section if one does not already exist. ELFSection &getSection(const std::string &Name, unsigned Type, unsigned Flags = 0, unsigned Align = 0) { ELFSection *&SN = SectionLookup[Name]; if (SN) return *SN; SectionList.push_back(new ELFSection(Name, isLittleEndian, is64Bit)); SN = SectionList.back(); SN->SectionIdx = NumSections++; SN->Type = Type; SN->Flags = Flags; SN->Link = ELF::SHN_UNDEF; SN->Align = Align; return *SN; } ELFSection &getNonExecStackSection() { return getSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0, 1); } ELFSection &getSymbolTableSection() { return getSection(".symtab", ELF::SHT_SYMTAB, 0); } ELFSection &getStringTableSection() { return getSection(".strtab", ELF::SHT_STRTAB, 0, 1); } ELFSection &getSectionHeaderStringTableSection() { return getSection(".shstrtab", ELF::SHT_STRTAB, 0, 1); } ELFSection &getNullSection() { return getSection("", ELF::SHT_NULL, 0); } ELFSection &getDataSection(); ELFSection &getBSSSection(); ELFSection &getCtorSection(); ELFSection &getDtorSection(); ELFSection &getJumpTableSection(); ELFSection &getConstantPoolSection(MachineConstantPoolEntry &CPE); ELFSection &getTextSection(const Function *F); ELFSection &getRelocSection(ELFSection &S); // Helpers for obtaining ELF specific info. unsigned getGlobalELFBinding(const GlobalValue *GV); unsigned getGlobalELFType(const GlobalValue *GV); unsigned getGlobalELFVisibility(const GlobalValue *GV); // AddPendingGlobalSymbol - Add a global to be processed and to // the global symbol lookup, use a zero index because the table // index will be determined later. void AddPendingGlobalSymbol(const GlobalValue *GV, bool AddToLookup = false); // AddPendingExternalSymbol - Add the external to be processed // and to the external symbol lookup, use a zero index because // the symbol table index will be determined later. void AddPendingExternalSymbol(const char *External); // AddToSymbolList - Update the symbol lookup and If the symbol is // private add it to PrivateSyms list, otherwise to SymbolList. void AddToSymbolList(ELFSym *GblSym); // As we complete the ELF file, we need to update fields in the ELF header // (e.g. the location of the section table). These members keep track of // the offset in ELFHeader of these various pieces to update and other // locations in the file. unsigned ELFHdr_e_shoff_Offset; // e_shoff in ELF header. unsigned ELFHdr_e_shstrndx_Offset; // e_shstrndx in ELF header. unsigned ELFHdr_e_shnum_Offset; // e_shnum in ELF header. private: void EmitGlobal(const GlobalValue *GV); void EmitGlobalConstant(const Constant *C, ELFSection &GblS); void EmitGlobalConstantStruct(const ConstantStruct *CVS, ELFSection &GblS); void EmitGlobalConstantLargeInt(const ConstantInt *CI, ELFSection &S); void EmitGlobalDataRelocation(const GlobalValue *GV, unsigned Size, ELFSection &GblS, int64_t Offset = 0); bool EmitSpecialLLVMGlobal(const GlobalVariable *GV); void EmitXXStructorList(const Constant *List, ELFSection &Xtor); void EmitRelocations(); void EmitRelocation(BinaryObject &RelSec, ELFRelocation &Rel, bool HasRelA); void EmitSectionHeader(BinaryObject &SHdrTab, const ELFSection &SHdr); void EmitSectionTableStringTable(); void EmitSymbol(BinaryObject &SymbolTable, ELFSym &Sym); void EmitSymbolTable(); void EmitStringTable(const std::string &ModuleName); void OutputSectionsAndSectionTable(); void RelocateField(BinaryObject &BO, uint32_t Offset, int64_t Value, unsigned Size); unsigned SortSymbols(); CstExprResTy ResolveConstantExpr(const Constant *CV); }; } #endif