LLVM API Documentation

ELFWriter.h

Go to the documentation of this file.
00001 //===-- ELFWriter.h - Target-independent ELF writer support -----*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by Chris Lattner and is distributed under the
00006 // University of Illinois Open Source License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines the ELFWriter class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_CODEGEN_ELFWRITER_H
00015 #define LLVM_CODEGEN_ELFWRITER_H
00016 
00017 #include "llvm/CodeGen/MachineFunctionPass.h"
00018 #include <list>
00019 
00020 namespace llvm {
00021   class GlobalVariable;
00022   class Mangler;
00023   class MachineCodeEmitter;
00024   class ELFCodeEmitter;
00025 
00026   /// ELFWriter - This class implements the common target-independent code for
00027   /// writing ELF files.  Targets should derive a class from this to
00028   /// parameterize the output format.
00029   ///
00030   class ELFWriter : public MachineFunctionPass {
00031     friend class ELFCodeEmitter;
00032   public:
00033     MachineCodeEmitter &getMachineCodeEmitter() const {
00034       return *(MachineCodeEmitter*)MCE;
00035     }
00036 
00037     ~ELFWriter();
00038 
00039     typedef std::vector<unsigned char> DataBuffer;
00040 
00041   protected:
00042     ELFWriter(std::ostream &O, TargetMachine &TM);
00043 
00044     /// Output stream to send the resultant object file to.
00045     ///
00046     std::ostream &O;
00047 
00048     /// Target machine description.
00049     ///
00050     TargetMachine &TM;
00051 
00052     /// Mang - The object used to perform name mangling for this module.
00053     ///
00054     Mangler *Mang;
00055 
00056     /// MCE - The MachineCodeEmitter object that we are exposing to emit machine
00057     /// code for functions to the .o file.
00058     ELFCodeEmitter *MCE;
00059 
00060     //===------------------------------------------------------------------===//
00061     // Properties to be set by the derived class ctor, used to configure the
00062     // ELFWriter.
00063 
00064     // e_machine - This field is the target specific value to emit as the
00065     // e_machine member of the ELF header.
00066     unsigned short e_machine;
00067 
00068     // e_flags - The machine flags for the target.  This defaults to zero.
00069     unsigned e_flags;
00070 
00071     //===------------------------------------------------------------------===//
00072     // Properties inferred automatically from the target machine.
00073     //
00074 
00075     /// is64Bit/isLittleEndian - This information is inferred from the target
00076     /// machine directly, indicating whether to emit a 32- or 64-bit ELF file.
00077     bool is64Bit, isLittleEndian;
00078 
00079     /// doInitialization - Emit the file header and all of the global variables
00080     /// for the module to the ELF file.
00081     bool doInitialization(Module &M);
00082 
00083     bool runOnMachineFunction(MachineFunction &MF);
00084 
00085 
00086     /// doFinalization - Now that the module has been completely processed, emit
00087     /// the ELF file to 'O'.
00088     bool doFinalization(Module &M);
00089 
00090   private:
00091     // The buffer we accumulate the file header into.  Note that this should be
00092     // changed into something much more efficient later (and the bytecode writer
00093     // as well!).
00094     DataBuffer FileHeader;
00095 
00096     /// ELFSection - This struct contains information about each section that is
00097     /// emitted to the file.  This is eventually turned into the section header
00098     /// table at the end of the file.
00099     struct ELFSection {
00100       std::string Name;       // Name of the section.
00101       unsigned NameIdx;       // Index in .shstrtab of name, once emitted.
00102       unsigned Type;
00103       unsigned Flags;
00104       uint64_t Addr;
00105       unsigned Offset;
00106       unsigned Size;
00107       unsigned Link;
00108       unsigned Info;
00109       unsigned Align;
00110       unsigned EntSize;
00111 
00112       /// SectionIdx - The number of the section in the Section Table.
00113       ///
00114       unsigned short SectionIdx;
00115 
00116       /// SectionData - The actual data for this section which we are building
00117       /// up for emission to the file.
00118       DataBuffer SectionData;
00119 
00120       enum { SHT_NULL = 0, SHT_PROGBITS = 1, SHT_SYMTAB = 2, SHT_STRTAB = 3,
00121              SHT_RELA = 4, SHT_HASH = 5, SHT_DYNAMIC = 6, SHT_NOTE = 7,
00122              SHT_NOBITS = 8, SHT_REL = 9, SHT_SHLIB = 10, SHT_DYNSYM = 11 };
00123       enum { SHN_UNDEF = 0, SHN_ABS = 0xFFF1, SHN_COMMON = 0xFFF2 };
00124       enum {   // SHF - ELF Section Header Flags
00125         SHF_WRITE            = 1 << 0, // Writable
00126         SHF_ALLOC            = 1 << 1, // Mapped into the process addr space
00127         SHF_EXECINSTR        = 1 << 2, // Executable
00128         SHF_MERGE            = 1 << 4, // Might be merged if equal
00129         SHF_STRINGS          = 1 << 5, // Contains null-terminated strings
00130         SHF_INFO_LINK        = 1 << 6, // 'sh_info' contains SHT index
00131         SHF_LINK_ORDER       = 1 << 7, // Preserve order after combining
00132         SHF_OS_NONCONFORMING = 1 << 8, // nonstandard OS support required
00133         SHF_GROUP            = 1 << 9, // Section is a member of a group
00134         SHF_TLS              = 1 << 10 // Section holds thread-local data
00135       };
00136 
00137       ELFSection(const std::string &name)
00138         : Name(name), Type(0), Flags(0), Addr(0), Offset(0), Size(0),
00139           Link(0), Info(0), Align(0), EntSize(0) {
00140       }
00141     };
00142 
00143     /// SectionList - This is the list of sections that we have emitted to the
00144     /// file.  Once the file has been completely built, the section header table
00145     /// is constructed from this info.
00146     std::list<ELFSection> SectionList;
00147     unsigned NumSections;   // Always = SectionList.size()
00148 
00149     /// SectionLookup - This is a mapping from section name to section number in
00150     /// the SectionList.
00151     std::map<std::string, ELFSection*> SectionLookup;
00152 
00153     /// getSection - Return the section with the specified name, creating a new
00154     /// section if one does not already exist.
00155     ELFSection &getSection(const std::string &Name,
00156                            unsigned Type, unsigned Flags = 0) {
00157       ELFSection *&SN = SectionLookup[Name];
00158       if (SN) return *SN;
00159 
00160       SectionList.push_back(Name);
00161       SN = &SectionList.back();
00162       SN->SectionIdx = NumSections++;
00163       SN->Type = Type;
00164       SN->Flags = Flags;
00165       return *SN;
00166     }
00167 
00168     ELFSection &getDataSection() {
00169       return getSection(".data", ELFSection::SHT_PROGBITS,
00170                         ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC);
00171     }
00172     ELFSection &getBSSSection() {
00173       return getSection(".bss", ELFSection::SHT_NOBITS,
00174                         ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC);
00175     }
00176 
00177     /// ELFSym - This struct contains information about each symbol that is
00178     /// added to logical symbol table for the module.  This is eventually
00179     /// turned into a real symbol table in the file.
00180     struct ELFSym {
00181       const GlobalValue *GV;    // The global value this corresponds to.
00182       unsigned NameIdx;         // Index in .strtab of name, once emitted.
00183       uint64_t Value;
00184       unsigned Size;
00185       unsigned char Info;
00186       unsigned char Other;
00187       unsigned short SectionIdx;
00188 
00189       enum { STB_LOCAL = 0, STB_GLOBAL = 1, STB_WEAK = 2 };
00190       enum { STT_NOTYPE = 0, STT_OBJECT = 1, STT_FUNC = 2, STT_SECTION = 3,
00191              STT_FILE = 4 };
00192       ELFSym(const GlobalValue *gv) : GV(gv), Value(0), Size(0), Info(0),
00193                                       Other(0), SectionIdx(0) {}
00194 
00195       void SetBind(unsigned X) {
00196         assert(X == (X & 0xF) && "Bind value out of range!");
00197         Info = (Info & 0x0F) | (X << 4);
00198       }
00199       void SetType(unsigned X) {
00200         assert(X == (X & 0xF) && "Type value out of range!");
00201         Info = (Info & 0xF0) | X;
00202       }
00203     };
00204 
00205     /// SymbolTable - This is the list of symbols we have emitted to the file.
00206     /// This actually gets rearranged before emission to the file (to put the
00207     /// local symbols first in the list).
00208     std::vector<ELFSym> SymbolTable;
00209 
00210     // As we complete the ELF file, we need to update fields in the ELF header
00211     // (e.g. the location of the section table).  These members keep track of
00212     // the offset in ELFHeader of these various pieces to update and other
00213     // locations in the file.
00214     unsigned ELFHeader_e_shoff_Offset;     // e_shoff    in ELF header.
00215     unsigned ELFHeader_e_shstrndx_Offset;  // e_shstrndx in ELF header.
00216     unsigned ELFHeader_e_shnum_Offset;     // e_shnum    in ELF header.
00217 
00218 
00219     // align - Emit padding into the file until the current output position is
00220     // aligned to the specified power of two boundary.
00221     static void align(DataBuffer &Output, unsigned Boundary) {
00222       assert(Boundary && (Boundary & (Boundary-1)) == 0 &&
00223              "Must align to 2^k boundary");
00224       size_t Size = Output.size();
00225       if (Size & (Boundary-1)) {
00226         // Add padding to get alignment to the correct place.
00227         size_t Pad = Boundary-(Size & (Boundary-1));
00228         Output.resize(Size+Pad);
00229       }
00230     }
00231 
00232     static void outbyte(DataBuffer &Output, unsigned char X) {
00233       Output.push_back(X);
00234     }
00235     void outhalf(DataBuffer &Output, unsigned short X) {
00236       if (isLittleEndian) {
00237         Output.push_back(X&255);
00238         Output.push_back(X >> 8);
00239       } else {
00240         Output.push_back(X >> 8);
00241         Output.push_back(X&255);
00242       }
00243     }
00244     void outword(DataBuffer &Output, unsigned X) {
00245       if (isLittleEndian) {
00246         Output.push_back((X >>  0) & 255);
00247         Output.push_back((X >>  8) & 255);
00248         Output.push_back((X >> 16) & 255);
00249         Output.push_back((X >> 24) & 255);
00250       } else {
00251         Output.push_back((X >> 24) & 255);
00252         Output.push_back((X >> 16) & 255);
00253         Output.push_back((X >>  8) & 255);
00254         Output.push_back((X >>  0) & 255);
00255       }
00256     }
00257     void outxword(DataBuffer &Output, uint64_t X) {
00258       if (isLittleEndian) {
00259         Output.push_back(unsigned(X >>  0) & 255);
00260         Output.push_back(unsigned(X >>  8) & 255);
00261         Output.push_back(unsigned(X >> 16) & 255);
00262         Output.push_back(unsigned(X >> 24) & 255);
00263         Output.push_back(unsigned(X >> 32) & 255);
00264         Output.push_back(unsigned(X >> 40) & 255);
00265         Output.push_back(unsigned(X >> 48) & 255);
00266         Output.push_back(unsigned(X >> 56) & 255);
00267       } else {
00268         Output.push_back(unsigned(X >> 56) & 255);
00269         Output.push_back(unsigned(X >> 48) & 255);
00270         Output.push_back(unsigned(X >> 40) & 255);
00271         Output.push_back(unsigned(X >> 32) & 255);
00272         Output.push_back(unsigned(X >> 24) & 255);
00273         Output.push_back(unsigned(X >> 16) & 255);
00274         Output.push_back(unsigned(X >>  8) & 255);
00275         Output.push_back(unsigned(X >>  0) & 255);
00276       }
00277     }
00278     void outaddr32(DataBuffer &Output, unsigned X) {
00279       outword(Output, X);
00280     }
00281     void outaddr64(DataBuffer &Output, uint64_t X) {
00282       outxword(Output, X);
00283     }
00284     void outaddr(DataBuffer &Output, uint64_t X) {
00285       if (!is64Bit)
00286         outword(Output, (unsigned)X);
00287       else
00288         outxword(Output, X);
00289     }
00290 
00291     // fix functions - Replace an existing entry at an offset.
00292     void fixhalf(DataBuffer &Output, unsigned short X, unsigned Offset) {
00293       unsigned char *P = &Output[Offset];
00294       P[0] = (X >> (isLittleEndian ?  0 : 8)) & 255;
00295       P[1] = (X >> (isLittleEndian ?  8 : 0)) & 255;
00296     }
00297 
00298     void fixword(DataBuffer &Output, unsigned X, unsigned Offset) {
00299       unsigned char *P = &Output[Offset];
00300       P[0] = (X >> (isLittleEndian ?  0 : 24)) & 255;
00301       P[1] = (X >> (isLittleEndian ?  8 : 16)) & 255;
00302       P[2] = (X >> (isLittleEndian ? 16 :  8)) & 255;
00303       P[3] = (X >> (isLittleEndian ? 24 :  0)) & 255;
00304     }
00305 
00306     void fixaddr(DataBuffer &Output, uint64_t X, unsigned Offset) {
00307       if (!is64Bit)
00308         fixword(Output, (unsigned)X, Offset);
00309       else
00310         assert(0 && "Emission of 64-bit data not implemented yet!");
00311     }
00312 
00313   private:
00314     void EmitGlobal(GlobalVariable *GV);
00315 
00316     void EmitSymbolTable();
00317 
00318     void EmitSectionTableStringTable();
00319     void OutputSectionsAndSectionTable();
00320   };
00321 }
00322 
00323 #endif