Gaudi Framework, version v23r4

Home   Generated: Mon Sep 17 2012

LibSymbolInfo.cpp

Go to the documentation of this file.
00001 //==========================================
00002 // Matt Pietrek
00003 // Microsoft Systems Journal, April 1998
00004 // Program: LibDump
00005 // FILE: LibSymbolInfo.CPP
00006 //==========================================
00007 
00008 // LibSymbolInfo.cpp: implementation of the CLibSymbolInfo class.
00009 //
00011 
00012 
00013 #include "LibSymbolInfo.h"
00014 
00015 using namespace std;
00016 
00017 
00018 #define MakePtr( cast, ptr, addValue ) (cast)( (DWORD)(ptr) + (DWORD)(addValue))
00019 
00021 // CLibSymbolInfo
00022 
00023 CLibSymbolInfo::CLibSymbolInfo()
00024 {
00025 }
00026 
00027 CLibSymbolInfo::~CLibSymbolInfo()
00028 {
00029 }
00030 
00031 //=============================================================================
00032 // Function: DumpSymbols
00033 //
00034 // Parameters:
00035 //      LPTSTR lpszLibPathName    - The library file path name
00036 //      CStdioFile* pFile         - Address of the file in which to dump the symbols
00037 //
00038 // Description:
00039 //
00040 // Given a library file path name, the function dumps the symbol info into the file
00041 // pointed to by pFile.
00042 //=============================================================================
00043 BOOL CLibSymbolInfo::DumpSymbols(LPTSTR lpszLibPathName, ostream& pFile)
00044 {
00045   if(lpszLibPathName == NULL || pFile.bad() ) {
00046     assert(lpszLibPathName != NULL);
00047     assert(pFile.good());
00048     m_strErrorMsg.assign("NULL <lpszLibPathName> or Invalid file handle.");
00049     return FALSE;
00050   }
00051 
00052   if(!Dump(lpszLibPathName, pFile))  return FALSE;
00053   return TRUE;
00054 }
00055 
00056 //=============================================================================
00057 // Function: Dump
00058 //
00059 // Parameters:
00060 //      As mentioned above.
00061 //
00062 // Description:
00063 //
00064 // Depending on the value specified in <m_bDump>/<m_bGrep> the routine dumps/greps
00065 // the symbo info.
00066 //=============================================================================
00067 BOOL CLibSymbolInfo::Dump(LPTSTR lpszLibPathName, ostream& pFile) 
00068 {
00069   string sBuff;
00070   MEMORY_MAPPED_FILE libFile(lpszLibPathName);
00071         
00072   // Ensure that the file mapping worked
00073   if( FALSE == libFile.IsValid() ) {
00074         m_strErrorMsg = "Unable to access file ";
00075     m_strErrorMsg+= lpszLibPathName;
00076     return FALSE;
00077   }
00078   // All COFF libraries start with the string "!<arch>\n".  Verify that this
00079   // string is at the beginning of the mapped file
00080 
00081   PSTR pArchiveStartString = (PSTR)libFile.GetBase();
00082 
00083   if ( 0 != strncmp( pArchiveStartString, IMAGE_ARCHIVE_START,
00084                        IMAGE_ARCHIVE_START_SIZE )  )  {
00085       m_strErrorMsg.assign("Not a valid COFF LIB file.");
00086         return FALSE;
00087   }
00088     
00089   // Point to the first archive member.  This entry contains the LIB symbols,
00090   // and immediately follows the archive start string ("!<arch>\n")
00091   PIMAGE_ARCHIVE_MEMBER_HEADER pMbrHdr;
00092   pMbrHdr = MakePtr( PIMAGE_ARCHIVE_MEMBER_HEADER, pArchiveStartString,
00093                      IMAGE_ARCHIVE_START_SIZE );
00094 
00095   // First DWORD after this member header is a symbol count
00096   PDWORD pcbSymbols = (PDWORD)(pMbrHdr + 1);  // Pointer math!
00097 
00098   // The symbol count is stored in big endian format, so adjust as
00099   // appropriate for the target architecture
00100   DWORD cSymbols = ConvertBigEndian( *pcbSymbols );
00101 
00102   // Following the symbol count is an array of offsets to archive members
00103   // (essentially, embedded .OBJ files)
00104   PDWORD pMemberOffsets = pcbSymbols + 1;     // Pointer math!
00105 
00106   // Following the array of member offsets is an array of offsets to symbol
00107   // names.
00108   PSTR pszSymbolName = MakePtr( PSTR, pMemberOffsets, 4 * cSymbols );
00109 
00110   //
00111   // Loop through every symbol in the first archive member
00112   //      
00113   for ( unsigned i = 0; i < cSymbols; i++ )
00114   {
00115     DWORD offset;
00116 
00117     // The offsets to the archive member that contains the symbol is stored
00118     // in big endian format, so convert it appropriately.        
00119     offset = ConvertBigEndian( *pMemberOffsets );
00120 
00121     // Call DisplayLibInfoForSymbol, which figures out what kind of symbol
00122     // it is.  The "IsRegularLibSymbol" filters out symbols that are
00123     // internal to the linking process
00124     if ( IsRegularLibSymbol( pszSymbolName ) ) {
00125       string symbol(pszSymbolName);
00126       if (IsFiltedSymbol(symbol) ) {
00127         pFile << symbol << endl;
00128           }
00129     }            
00130     // Advanced to the next symbol offset and name.  The MemberOffsets
00131     // array has fixed length entries, while the symbol names are
00132     // sequential null-terminated strings
00133     pMemberOffsets++;
00134     pszSymbolName += strlen(pszSymbolName) + 1;
00135   }
00136   return TRUE;
00137 }
00138 
00139 //=============================================================================
00140 // Filters out symbols that are internal to the linking process, and which
00141 // the programmer never explicitly sees.
00142 //=============================================================================
00143 BOOL CLibSymbolInfo::IsRegularLibSymbol( PSTR pszSymbolName )
00144 {
00145   if ( 0 == strncmp( pszSymbolName, "__IMPORT_DESCRIPTOR_", 20 ) )
00146       return FALSE;
00147 
00148   if ( 0 == strncmp( pszSymbolName, "__NULL_IMPORT_DESCRIPTOR", 24 ) )
00149       return FALSE;
00150       
00151   if ( strstr( pszSymbolName, "_NULL_THUNK_DATA" ) )
00152       return FALSE;
00153         
00154   return TRUE;
00155 }
00156 //=============================================================================
00157 // Filters out symbols that are not needed....
00158 //=============================================================================
00159 BOOL CLibSymbolInfo::IsFiltedSymbol( string& symbolName )
00160 {
00161   if ( symbolName.substr(0,2) == "__" ) 
00162     return FALSE;
00163   if ( symbolName.substr(0,3) == "??_" && symbolName[3] != '0') // Keep 'operator/='  [??_0]
00164     return FALSE;
00165   if( symbolName[0] == '_') {
00166     symbolName.erase(0, 1);  // C functions ...
00167   }
00168   // Filter the internal Boost symbols
00169   if (symbolName.find ("detail@boost") != string::npos )
00170         return FALSE;
00171   if (symbolName.find ("details@boost") != string::npos ) 
00172         return FALSE;
00173   return TRUE;
00174 }
00175 
00176 //=============================================================================
00177 // Converts from big endian to little endian numbers.
00178 //=============================================================================
00179 DWORD CLibSymbolInfo::ConvertBigEndian(DWORD bigEndian)
00180 {
00181   DWORD temp = 0;
00182 
00183   temp |= bigEndian >> 24;
00184   temp |= ((bigEndian & 0x00FF0000) >> 8);
00185   temp |= ((bigEndian & 0x0000FF00) << 8);
00186   temp |= ((bigEndian & 0x000000FF) << 24);
00187 
00188   return temp;
00189 }
00190 
00191 string CLibSymbolInfo::GetLastError() const
00192 {
00193   return m_strErrorMsg;
00194 }
00195 
00196 
00197 MEMORY_MAPPED_FILE::MEMORY_MAPPED_FILE( PSTR pszFileName ) {
00198 
00199    //
00200    // Given a filename, the constructor opens a file handle, creates a file
00201    // mapping, and maps the entire file into memory.
00202    //
00203    m_hFile = INVALID_HANDLE_VALUE;
00204    m_hFileMapping = 0;
00205    m_pMemoryMappedFileBase = 0;
00206    m_cbFile = 0;
00207    m_errCode = errMMF_FileOpen;    // Initial error code: not found
00208     // First get a file handle      
00209    m_hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
00210                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE)0);
00211                    
00212    if ( m_hFile == INVALID_HANDLE_VALUE )
00213    {
00214        m_errCode = errMMF_FileOpen;
00215        return;
00216    }
00217     m_cbFile = ::GetFileSize( m_hFile, 0 );
00218     // Now, create a file mapping   
00219    m_hFileMapping = CreateFileMapping(m_hFile,NULL, PAGE_READONLY, 0, 0,NULL);
00220    if ( m_hFileMapping == 0 )
00221    {
00222        // Oops.  Something went wrong.  Clean up.
00223        CloseHandle(m_hFile);
00224        m_hFile = INVALID_HANDLE_VALUE;
00225        m_errCode = errMMF_FileMapping;
00226        return;
00227    }
00228     m_pMemoryMappedFileBase = (PCHAR)MapViewOfFile( m_hFileMapping,
00229                                                    FILE_MAP_READ, 0, 0, 0);
00230     if ( m_pMemoryMappedFileBase == 0 )
00231    {
00232        // Oops.  Something went wrong.  Clean up.
00233        CloseHandle(m_hFileMapping);
00234        m_hFileMapping = 0;
00235        CloseHandle(m_hFile);
00236        m_hFile = INVALID_HANDLE_VALUE;
00237        m_errCode = errMMF_MapView;
00238        return;
00239    }
00240     m_errCode = errMMF_NoError;
00241 }
00242 
00243 MEMORY_MAPPED_FILE::~MEMORY_MAPPED_FILE(void)
00244 {
00245     // Clean up everything that was created by the constructor
00246     if ( m_pMemoryMappedFileBase )
00247         UnmapViewOfFile( m_pMemoryMappedFileBase );
00248 
00249     if ( m_hFileMapping )
00250         CloseHandle( m_hFileMapping );
00251 
00252     if ( m_hFile != INVALID_HANDLE_VALUE )
00253         CloseHandle( m_hFile ); 
00254 
00255     m_errCode = errMMF_FileOpen;
00256 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Mon Sep 17 2012 13:49:35 for Gaudi Framework, version v23r4 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004