BinaryFile.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1997-2001, The University of Queensland
00003  * Copyright (C) 2001, Sun Microsystems, Inc
00004  * Copyright (C) 2002, Trent Waddington
00005  *
00006  * See the file "LICENSE.TERMS" for information on usage and
00007  * redistribution of this file, and for a DISCLAIMER OF ALL
00008  * WARRANTIES.
00009  *
00010  */
00011 
00012 /* File: BinaryFile.cpp
00013  * Desc: This file contains the implementation of the class BinaryFile
00014  * 
00015  * This file implements the abstract BinaryFile class.
00016  * All classes derived from this class must implement the Load()
00017  *function.
00018 */
00019 
00020 /*
00021  *  MVE 30/9/97 Created
00022  * 21 Apr 02 - Mike: mods for boomerang
00023  * 03 Jun 02 - Trent: if WIN32, no dynamic linking
00024  * 14 Jun 02 - Mike: Fixed a bug where Windows programs chose the Exe loader
00025 */
00026 
00027 /*==============================================================================
00028  * Dependencies.
00029  *============================================================================*/
00030 
00031 #if defined(_MSC_VER) && _MSC_VER <= 1200
00032 #pragma warning(disable:4786)
00033 #endif
00034 
00035 #include "BinaryFile.h"
00036 #include <iostream>
00037 #include <stdio.h>
00038 
00039 
00040 BinaryFile::BinaryFile(bool bArch /*= false*/)
00041 {
00042     m_bArchive = bArch;         // Remember whether an archive member
00043     m_iNumSections = 0;         // No sections yet
00044     m_pSections = 0;            // No section data yet
00045 }
00046 
00047 // This struct used to be initialised with a memset, but now that overwrites the virtual table (if compiled under gcc
00048 // and possibly others)
00049 SectionInfo::SectionInfo() :
00050     pSectionName(NULL), uNativeAddr(0), uHostAddr(0), uSectionSize(0), uSectionEntrySize(0), uType(0),
00051     bCode(false), bData(false), bBss(0), bReadOnly(0)
00052 {}
00053 
00054 SectionInfo::~SectionInfo()
00055 {}
00056 
00057 int BinaryFile::GetNumSections() const
00058 {
00059     return m_iNumSections;
00060 }
00061 
00062 PSectionInfo BinaryFile::GetSectionInfo(int idx) const
00063 {
00064     return m_pSections + idx;
00065 }
00066 
00067 int BinaryFile::GetSectionIndexByName(const char* sName)
00068 {
00069     for (int i=0; i < m_iNumSections; i++)
00070     {
00071         if (strcmp(m_pSections[i].pSectionName, sName) == 0)
00072         {
00073             return i;
00074         }
00075     }
00076     return -1;
00077 }
00078 
00079 PSectionInfo BinaryFile::GetSectionInfoByAddr(ADDRESS uEntry) const
00080 {
00081     PSectionInfo pSect;
00082     for (int i=0; i < m_iNumSections; i++)
00083     {
00084         pSect = &m_pSections[i];
00085         if ((uEntry >= pSect->uNativeAddr) &&
00086             (uEntry < pSect->uNativeAddr + pSect->uSectionSize))
00087         {
00088             // We have the right section
00089             return pSect;
00090         }
00091     }
00092     // Failed to find the address
00093     return NULL;
00094 }
00095 
00096 PSectionInfo BinaryFile::GetSectionInfoByName(const char* sName)
00097 {
00098     int i = GetSectionIndexByName(sName);
00099     if (i == -1) return 0;
00100     return &m_pSections[i];
00101 }
00102 
00103 
00104     ///////////////////////
00105     // Trivial functions //
00106     // Overridden if reqd//
00107     ///////////////////////
00108 
00109 const char* BinaryFile::SymbolByAddress(ADDRESS uNative) {
00110     return 0;       // Overridden by subclasses that support syms
00111 }
00112 
00113 ADDRESS BinaryFile::GetAddressByName(const char* pName, bool bNoTypeOK) {
00114     return 0;
00115 }
00116 
00117 int BinaryFile::GetSizeByName(const char* pName, bool bNoTypeOK) {
00118     return 0;
00119 }
00120 
00121 bool BinaryFile::IsDynamicLinkedProc(ADDRESS uNative) {
00122     return false;
00123 }
00124 
00125 bool BinaryFile::IsStaticLinkedLibProc(ADDRESS uNative) {
00126     return false;
00127 }
00128 
00129 bool BinaryFile::IsDynamicLinkedProcPointer(ADDRESS uNative)
00130 {
00131     return false;
00132 }
00133 
00134 ADDRESS BinaryFile::IsJumpToAnotherAddr(ADDRESS uNative)
00135 {
00136     return NO_ADDRESS;
00137 }
00138 
00139 const char *BinaryFile::GetDynamicProcName(ADDRESS uNative)
00140 {
00141     return "dynamic";
00142 }
00143 
00144 bool BinaryFile::DisplayDetails(const char* fileName, FILE* f /* = stdout */)
00145 {
00146     return false;           // Should always be overridden
00147                             // Should display file header, program 
00148                             // headers and section headers, as well 
00149                             // as contents of each of the sections. 
00150 }
00151 
00152 // Specific to BinaryFile objects that implement a "global pointer"
00153 // Gets a pair of unsigned integers representing the address of %agp, and
00154 // a machine specific value (GLOBALOFFSET)
00155 // This is a stub routine that should be overridden if required
00156 std::pair<unsigned,unsigned> BinaryFile::GetGlobalPointerInfo()
00157 {
00158     return std::pair<unsigned, unsigned>(0, 0);
00159 }
00160 
00161 // Get a pointer to a new map of dynamic global data items.
00162 // If the derived class doesn't implement this function, return an empty map
00163 // Caller should delete the returned map
00164 std::map<ADDRESS, const char*>* BinaryFile::GetDynamicGlobalMap()
00165 {
00166     return new std::map<ADDRESS, const char*>;
00167 }
00168 
00169 // Get an array of exported function stub addresses. Normally overridden.
00170 ADDRESS* BinaryFile::GetImportStubs(int& numExports)
00171 {
00172     numExports = 0;
00173     return NULL;
00174 }
00175 
00176 void BinaryFile::getTextLimits()
00177 {
00178     int n = GetNumSections();
00179     limitTextLow = 0xFFFFFFFF;
00180     limitTextHigh = 0;
00181     textDelta = 0;
00182     for (int i=0; i < n; i++) {
00183         SectionInfo* pSect = GetSectionInfo(i);
00184         if (pSect->bCode) {
00185             // The .plt section is an anomaly. It's code, but we never want to
00186             // decode it, and in Sparc ELF files, it's actually in the data
00187             // segment (so it can be modified). For now, we make this ugly
00188             // exception
00189             if (strcmp(".plt", pSect->pSectionName) == 0)
00190                 continue;
00191             if (pSect->uNativeAddr < limitTextLow)
00192                 limitTextLow = pSect->uNativeAddr;
00193             ADDRESS hiAddress = pSect->uNativeAddr + pSect->uSectionSize;
00194             if (hiAddress > limitTextHigh)
00195                 limitTextHigh = hiAddress;
00196             if (textDelta == 0)
00197                 textDelta = pSect->uHostAddr - pSect->uNativeAddr;
00198             else {
00199                 if (textDelta != (int) (pSect->uHostAddr - pSect->uNativeAddr))
00200                     std::cerr << "warning: textDelta different for section " << pSect->pSectionName <<
00201                         " (ignoring).\n";
00202             }
00203         }
00204     }
00205 }

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