ElfBinaryFile.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1998-2001, The University of Queensland
00003  *
00004  * See the file "LICENSE.TERMS" for information on usage and
00005  * redistribution of this file, and for a DISCLAIMER OF ALL
00006  * WARRANTIES.
00007  *
00008  */
00009 
00010 /* File: ElfBinaryFile.h
00011  * Desc: This file contains the definition of the class ElfBinaryFile.
00012 */
00013 
00014 /* $Revision: 1.22 $
00015  * 12 Sep 01 - Mike: Replaced SymTab object with map from ADDRESS to string
00016  * 09 Mar 02 - Mike: Changes for stand alone compilation
00017  * 01 Oct 02 - Mike: Removed elf library (and include file) dependencies
00018  * 02 Oct 02 - Mike: elfRead2 and elfRead4 are const now
00019 */
00020 
00021 #ifndef __ELFBINARYFILE_H__
00022 #define __ELFBINARYFILE_H__
00023 
00024 /*==============================================================================
00025  * Dependencies.
00026  *============================================================================*/
00027 
00028 #include "BinaryFile.h"
00029 #include "SymTab.h"                 // For SymTab (probably unused)
00030 typedef std::map<ADDRESS,std::string,std::less<ADDRESS> >  RelocMap;
00031 
00032 typedef struct
00033 {
00034     ADDRESS     uSymAddr;           // Symbol native address
00035     int         iSymSize;           // Size associated with symbol
00036 } SymValue;
00037 
00038 // Internal elf info
00039 typedef struct {
00040         char  e_ident[4]; 
00041         char  e_class;
00042         char  endianness;
00043         char  version;
00044         char  osAbi;
00045         char  pad[8];
00046         short e_type;
00047         short e_machine;
00048         int   e_version;
00049         int   e_entry;
00050         int   e_phoff;
00051         int   e_shoff;
00052         int   e_flags;
00053         short e_ehsize;
00054         short e_phentsize;
00055         short e_phnum;
00056         short e_shentsize;
00057         short e_shnum;
00058         short e_shstrndx;
00059 } Elf32_Ehdr;
00060 
00061 #define EM_SPARC        2           // Sun SPARC
00062 #define EM_386          3           // Intel 80386 or higher
00063 #define EM_68K          4           // Motorola 68000
00064 #define EM_PA_RISC      15          // HP PA-RISC
00065 #define EM_SPARC32PLUS  18          // Sun SPARC 32+
00066 #define EM_PPC          20          // PowerPC
00067 #define EM_X86_64   62 
00068 #define EM_ST20         0xa8        // ST20 (made up... there is no official value?)
00069 
00070 #define ET_DYN  3       // Elf type (dynamic library)
00071 
00072 #define R_386_32 1
00073 #define R_386_PC32 2
00074 
00075 // Program header
00076 typedef struct {
00077     int  p_type;     /* entry type */
00078     int  p_offset;   /* file offset */
00079     int  p_vaddr;    /* virtual address */
00080     int  p_paddr;    /* physical address */
00081     int  p_filesz;   /* file size */
00082     int  p_memsz;    /* memory size */
00083     int  p_flags;    /* entry flags */
00084     int  p_align;    /* memory/file alignment */
00085 } Elf32_Phdr;
00086 
00087 // Section header
00088 typedef struct {
00089   int   sh_name;
00090   int   sh_type;
00091   int   sh_flags;
00092   int   sh_addr;
00093   int   sh_offset;
00094   int   sh_size;
00095   int   sh_link;
00096   int   sh_info;
00097   int   sh_addralign;
00098   int   sh_entsize;
00099 } Elf32_Shdr;
00100 
00101 #define SHF_WRITE       1       // Writeable
00102 #define SHF_ALLOC       2       // Consumes memory in exe
00103 #define SHF_EXECINSTR   4       // Executable
00104 
00105 #define SHT_NOBITS      8       // Bss
00106 #define SHT_REL         9       // Relocation table (no addend)
00107 #define SHT_RELA        4       // Relocation table (with addend, e.g. RISC)
00108 #define SHT_SYMTAB      2       // Symbol table
00109 #define SHT_DYNSYM      11      // Dynamic symbol table
00110 
00111 typedef struct {
00112     int             st_name;
00113     unsigned        st_value;
00114     int             st_size;
00115     unsigned char   st_info;
00116     unsigned char   st_other;
00117     short           st_shndx;
00118 } Elf32_Sym;
00119 
00120 typedef struct {
00121     unsigned r_offset;
00122     int r_info;
00123 } Elf32_Rel;
00124 
00125 #define  ELF32_R_SYM(info)       ((info)>>8)
00126 #define ELF32_ST_BIND(i)        ((i) >> 4)
00127 #define ELF32_ST_TYPE(i)        ((i) & 0xf)
00128 #define ELF32_ST_INFO(b, t)     (((b)<<4)+((t)&0xf))
00129 #define STT_NOTYPE  0           // Symbol table type: none
00130 #define STT_FUNC    2               // Symbol table type: function
00131 #define STT_SECTION 3
00132 #define STT_FILE 4
00133 #define STB_GLOBAL  1
00134 #define STB_WEAK    2
00135 
00136 typedef struct {
00137     short d_tag;                /* how to interpret value */
00138     union {
00139         int  d_val;
00140         int  d_ptr;
00141         int  d_off;
00142     } d_un;
00143 } Elf32_Dyn;
00144 
00145 // Tag values
00146 #define DT_NULL     0       // Last entry in list
00147 #define DT_STRTAB   5       // String table
00148 #define DT_NEEDED   1       // A needed link-type object
00149 
00150 #define E_REL       1       // Relocatable file type
00151 
00152 class ElfBinaryFile : public BinaryFile
00153 {
00154 public:
00155                     ElfBinaryFile(bool bArchive = false);   // Constructor
00156 virtual void        UnLoad();                       // Unload the image
00157 virtual             ~ElfBinaryFile();               // Destructor
00158         bool        GetNextMember();                // Load next member of archive
00159 virtual bool        Open(const char* sName);        // Open the file for r/w; pv
00160 virtual void        Close();                        // Close file opened with Open()
00161 virtual LOAD_FMT    GetFormat() const;          // Get format (e.g. LOADFMT_ELF)
00162 virtual MACHINE     GetMachine() const;         // Get machine (e.g. MACHINE_SPARC)
00163 virtual const char* getFilename() const { return m_pFileName; }
00164 virtual bool        isLibrary() const;
00165 virtual std::list<const char *> getDependencyList();
00166 virtual ADDRESS     getImageBase();
00167 virtual size_t      getImageSize();
00168 
00169 
00170         // Header functions
00171 //virtual ADDRESS   GetFirstHeaderAddress();        // Get ADDRESS of main header
00172 //      ADDRESS     GetNextHeaderAddress();         // Get any other headers
00173 
00174         int         readNative1(ADDRESS a);         // Read 1 bytes from native addr
00175         int         readNative2(ADDRESS a);         // Read 2 bytes from native addr
00176         int         readNative4(ADDRESS a);         // Read 4 bytes from native addr
00177         QWord       readNative8(ADDRESS a);         // Read 8 bytes from native addr
00178         float       readNativeFloat4(ADDRESS a);    // Read 4 bytes as float
00179         double      readNativeFloat8(ADDRESS a);    // Read 8 bytes as float
00180 
00181         void        writeNative4(ADDRESS nat, unsigned int n);
00182 
00183                     // Symbol functions
00184         const char* SymbolByAddress(ADDRESS uAddr); // Get name of symbol
00185                     // Get value of symbol, if any
00186         ADDRESS     GetAddressByName(const char* pName, bool bNoTypeOK = false);
00187                     // Get the size associated with the symbol
00188         int         GetSizeByName(const char* pName, bool bNoTypeOK = false);
00189                     // Get the size associated with the symbol; guess if necessary
00190         int         GetDistanceByName(const char* pName);
00191         int         GetDistanceByName(const char* pName, const char* pSectName);
00192                     // Add an extra symbol
00193         void        AddSymbol(ADDRESS uNative, const char *pName);
00194         void        dumpSymbols();              // For debugging
00195 
00196 virtual ADDRESS*    GetImportStubs(int& numImports);
00197 virtual std::vector<ADDRESS> GetExportedAddresses(bool funcsOnly = true);
00198 
00199 
00200                     // Relocation functions
00201         bool        IsAddressRelocatable(ADDRESS uNative);
00202         ADDRESS     GetRelocatedAddress(ADDRESS uNative);
00203         //ADDRESS       ApplyRelocation(ADDRESS uNative, ADDRESS uWord);
00204                     // Get symbol associated with relocation at address, if any
00205         //const char* GetRelocSym(ADDRESS uNative, ADDRESS *a = NULL, unsigned int *sz = NULL);
00206         virtual bool IsRelocationAt(ADDRESS uNative);
00207         virtual const char *getFilenameSymbolFor(const char *sym);
00208 
00209                     // Write an ELF object file for a given procedure
00210         void        writeObjectFile(std::string &path, const char* name, void *ptxt, int txtsz, RelocMap& reloc);
00211                     // Apply relocations; important when compiled without -fPIC
00212         void        applyRelocations();
00213 
00214 //
00215 //  --  --  --  --  --  --  --  --  --  --  --
00216 //
00217                 // Internal information
00218     // Dump headers, etc
00219 //virtual bool    DisplayDetails(const char* fileName, FILE* f = stdout);
00220 
00221 
00222                 // Analysis functions
00223 virtual std::list<SectionInfo*>& GetEntryPoints(const char* pEntry = "main");
00224 virtual ADDRESS     GetMainEntryPoint();
00225 virtual ADDRESS     GetEntryPoint();
00226 
00227         bool        IsDynamicLinkedProc(ADDRESS wNative);
00228         ADDRESS     NativeToHostAddress(ADDRESS uNative);
00229         // Get a map from ADDRESS to const char*. This map contains the native addresses and symbolic names of global
00230         // data items (if any) which are shared with dynamically linked libraries. Example: __iob (basis for stdout).
00231         // The ADDRESS is the native address of a pointer to the real dynamic data object.
00232 virtual std::map<ADDRESS, const char*>* GetDynamicGlobalMap();
00233 
00234 virtual std::map<ADDRESS, std::string> &getSymbols() { return m_SymTab; }
00235 
00236         // Not meant to be used externally, but sometimes you just have to have it.
00237         char*       GetStrPtr(int idx, int offset); // Calc string pointer
00238 
00239         // Similarly here; sometimes you just need to change a section's link and info fields
00240         // idx is the section index; link and info are indices to other
00241         // sections that will be idx's sh_link and sh_info respectively
00242         void        SetLinkAndInfo(int idx, int link, int info);
00243 
00244         const char* m_pFileName;            // Pointer to input file name
00245 protected:
00246 virtual bool        RealLoad(const char* sName); // Load the file; pure virtual
00247 
00248 private:
00249         void        Init();                 // Initialise most member variables
00250         int         ProcessElfFile();       // Does most of the work
00251         void        AddSyms(int secIndex);
00252         void        AddRelocsAsSyms(int secIndex);
00253         void        SetRelocInfo(PSectionInfo pSect);
00254         bool        ValueByName(const char* pName, SymValue* pVal, bool bNoTypeOK = false);
00255         bool        SearchValueByName(const char* pName, SymValue* pVal);
00256         bool        SearchValueByName(const char* pName, SymValue* pVal, const char* pSectName, const char* pStrName);
00257         bool        PostLoad(void* handle); // Called after archive member loaded
00258         // Search the .rel[a].plt section for an entry with symbol table index i.
00259         // If found, return the native address of the associated PLT entry.
00260         ADDRESS     findRelPltOffset(int i, ADDRESS addrRelPlt, int sizeRelPlt, int numRelPlt, ADDRESS addrPlt);
00261 
00262         // Internal elf reading methods
00263         int         elfRead2(short* ps) const;      // Read a short with endianness care
00264         int         elfRead4(int*   pi) const;      // Read an int with endianness care
00265         void        elfWrite4(int*  pi, int val);   // Write an int with endianness care
00266 
00267         FILE*       m_fd;                           // File stream
00268         long        m_lImageSize;                   // Size of image in bytes
00269         char*       m_pImage;                       // Pointer to the loaded image
00270         Elf32_Phdr* m_pPhdrs;                       // Pointer to program headers
00271         Elf32_Shdr* m_pShdrs;                       // Array of section header structs
00272         char*       m_pStrings;                     // Pointer to the string section
00273         char        m_elfEndianness;                // 1 = Big Endian
00274         std::map<ADDRESS, std::string> m_SymTab;    // Map from address to symbol name; contains symbols from the
00275                                                     // various elf symbol tables, and possibly some symbols with fake
00276                                                     // addresses
00277         SymTab      m_Reloc;                        // Object to store the reloc syms
00278         Elf32_Rel*  m_pReloc;                       // Pointer to the relocation section
00279         Elf32_Sym*  m_pSym;                         // Pointer to loaded symbol section
00280         bool        m_bAddend;                      // true if reloc table has addend
00281         ADDRESS     m_uLastAddr;                    // Save last address looked up
00282         int         m_iLastSize;                    // Size associated with that name
00283         ADDRESS     m_uPltMin;                      // Min address of PLT table
00284         ADDRESS     m_uPltMax;                      // Max address (1 past last) of PLT
00285         std::list<SectionInfo*>  m_EntryPoint;      // A list of one entry point
00286         ADDRESS*    m_pImportStubs;                 // An array of import stubs
00287         ADDRESS     m_uBaseAddr;                    // Base image virtual address
00288         size_t      m_uImageSize;                   // total image size (bytes)
00289         ADDRESS     first_extern;                   // where the first extern will be placed
00290         ADDRESS     next_extern;                    // where the next extern will be placed
00291         int*        m_sh_link;                      // pointer to array of sh_link values
00292         int*        m_sh_info;                      // pointer to array of sh_info values
00293 };
00294 
00295 #endif      // #ifndef __ELFBINARYFILE_H__

Generated on Tue Sep 19 21:18:23 2006 for Boomerang by  doxygen 1.4.6