diff options
Diffstat (limited to 'contrib/llvm/lib/CodeGen/ELFWriter.h')
-rw-r--r-- | contrib/llvm/lib/CodeGen/ELFWriter.h | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/contrib/llvm/lib/CodeGen/ELFWriter.h b/contrib/llvm/lib/CodeGen/ELFWriter.h new file mode 100644 index 0000000..b8bac55 --- /dev/null +++ b/contrib/llvm/lib/CodeGen/ELFWriter.h @@ -0,0 +1,251 @@ +//===-- 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(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 |