Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v31r0 (aeb156f0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
LibSymbolInfo.cpp
Go to the documentation of this file.
1 //==========================================
2 // Matt Pietrek
3 // Microsoft Systems Journal, April 1998
4 // Program: LibDump
5 // FILE: LibSymbolInfo.CPP
6 //==========================================
7 
8 // LibSymbolInfo.cpp: implementation of the CLibSymbolInfo class.
9 //
11 
12 #include "LibSymbolInfo.h"
13 
14 using namespace std;
15 
16 #define MakePtr( cast, ptr, addValue ) ( cast )( ( DWORD )( ptr ) + ( DWORD )( addValue ) )
17 
19 // CLibSymbolInfo
20 
22 
24 
25 //=============================================================================
26 // Function: DumpSymbols
27 //
28 // Parameters:
29 // LPTSTR lpszLibPathName - The library file path name
30 // CStdioFile* pFile - Address of the file in which to dump the symbols
31 //
32 // Description:
33 //
34 // Given a library file path name, the function dumps the symbol info into the file
35 // pointed to by pFile.
36 //=============================================================================
37 BOOL CLibSymbolInfo::DumpSymbols( LPTSTR lpszLibPathName, ostream& pFile ) {
38  if ( lpszLibPathName == NULL || pFile.bad() ) {
39  assert( lpszLibPathName != NULL );
40  assert( pFile.good() );
41  m_strErrorMsg.assign( "NULL <lpszLibPathName> or Invalid file handle." );
42  return FALSE;
43  }
44 
45  if ( !Dump( lpszLibPathName, pFile ) ) return FALSE;
46  return TRUE;
47 }
48 
49 //=============================================================================
50 // Function: Dump
51 //
52 // Parameters:
53 // As mentioned above.
54 //
55 // Description:
56 //
57 // Depending on the value specified in <m_bDump>/<m_bGrep> the routine dumps/greps
58 // the symbo info.
59 //=============================================================================
60 BOOL CLibSymbolInfo::Dump( LPTSTR lpszLibPathName, ostream& pFile ) {
61  string sBuff;
62  MEMORY_MAPPED_FILE libFile( lpszLibPathName );
63 
64  // Ensure that the file mapping worked
65  if ( FALSE == libFile.IsValid() ) {
66  m_strErrorMsg = "Unable to access file ";
67  m_strErrorMsg += lpszLibPathName;
68  return FALSE;
69  }
70  // All COFF libraries start with the string "!<arch>\n". Verify that this
71  // string is at the beginning of the mapped file
72 
73  PSTR pArchiveStartString = (PSTR)libFile.GetBase();
74 
75  if ( 0 != strncmp( pArchiveStartString, IMAGE_ARCHIVE_START, IMAGE_ARCHIVE_START_SIZE ) ) {
76  m_strErrorMsg.assign( "Not a valid COFF LIB file." );
77  return FALSE;
78  }
79 
80  // Point to the first archive member. This entry contains the LIB symbols,
81  // and immediately follows the archive start string ("!<arch>\n")
82  PIMAGE_ARCHIVE_MEMBER_HEADER pMbrHdr;
83  pMbrHdr = MakePtr( PIMAGE_ARCHIVE_MEMBER_HEADER, pArchiveStartString, IMAGE_ARCHIVE_START_SIZE );
84 
85  // First DWORD after this member header is a symbol count
86  PDWORD pcbSymbols = ( PDWORD )( pMbrHdr + 1 ); // Pointer math!
87 
88  // The symbol count is stored in big endian format, so adjust as
89  // appropriate for the target architecture
90  DWORD cSymbols = ConvertBigEndian( *pcbSymbols );
91 
92  // Following the symbol count is an array of offsets to archive members
93  // (essentially, embedded .OBJ files)
94  PDWORD pMemberOffsets = pcbSymbols + 1; // Pointer math!
95 
96  // Following the array of member offsets is an array of offsets to symbol
97  // names.
98  PSTR pszSymbolName = MakePtr( PSTR, pMemberOffsets, 4 * cSymbols );
99 
100  //
101  // Loop through every symbol in the first archive member
102  //
103  for ( unsigned i = 0; i < cSymbols; i++ ) {
104  DWORD offset;
105 
106  // The offsets to the archive member that contains the symbol is stored
107  // in big endian format, so convert it appropriately.
108  offset = ConvertBigEndian( *pMemberOffsets );
109 
110  // Call DisplayLibInfoForSymbol, which figures out what kind of symbol
111  // it is. The "IsRegularLibSymbol" filters out symbols that are
112  // internal to the linking process
113  if ( IsRegularLibSymbol( pszSymbolName ) ) {
114  string symbol( pszSymbolName );
115  if ( IsFiltedSymbol( symbol ) ) { pFile << symbol << endl; }
116  }
117  // Advanced to the next symbol offset and name. The MemberOffsets
118  // array has fixed length entries, while the symbol names are
119  // sequential null-terminated strings
120  pMemberOffsets++;
121  pszSymbolName += strlen( pszSymbolName ) + 1;
122  }
123  return TRUE;
124 }
125 
126 //=============================================================================
127 // Filters out symbols that are internal to the linking process, and which
128 // the programmer never explicitly sees.
129 //=============================================================================
130 BOOL CLibSymbolInfo::IsRegularLibSymbol( PSTR pszSymbolName ) {
131  if ( 0 == strncmp( pszSymbolName, "__IMPORT_DESCRIPTOR_", 20 ) ) return FALSE;
132 
133  if ( 0 == strncmp( pszSymbolName, "__NULL_IMPORT_DESCRIPTOR", 24 ) ) return FALSE;
134 
135  if ( strstr( pszSymbolName, "_NULL_THUNK_DATA" ) ) return FALSE;
136 
137  return TRUE;
138 }
139 //=============================================================================
140 // Filters out symbols that are not needed....
141 //=============================================================================
142 BOOL CLibSymbolInfo::IsFiltedSymbol( string& symbolName ) {
143  if ( symbolName.compare( 0, 2, "__" ) == 0 ) return FALSE;
144  if ( symbolName.compare( 0, 3, "??_" ) == 0 && symbolName[3] != '0' ) // Keep 'operator/=' [??_0]
145  return FALSE;
146  if ( symbolName[0] == '_' ) {
147  symbolName.erase( 0, 1 ); // C functions ...
148  }
149  // Filter the internal Boost symbols
150  if ( symbolName.find( "detail@boost" ) != string::npos ) return FALSE;
151  if ( symbolName.find( "details@boost" ) != string::npos ) return FALSE;
152  return TRUE;
153 }
154 
155 //=============================================================================
156 // Converts from big endian to little endian numbers.
157 //=============================================================================
158 DWORD CLibSymbolInfo::ConvertBigEndian( DWORD bigEndian ) {
159  DWORD temp = 0;
160 
161  temp |= bigEndian >> 24;
162  temp |= ( ( bigEndian & 0x00FF0000 ) >> 8 );
163  temp |= ( ( bigEndian & 0x0000FF00 ) << 8 );
164  temp |= ( ( bigEndian & 0x000000FF ) << 24 );
165 
166  return temp;
167 }
168 
169 string CLibSymbolInfo::GetLastError() const { return m_strErrorMsg; }
170 
172 
173  //
174  // Given a filename, the constructor opens a file handle, creates a file
175  // mapping, and maps the entire file into memory.
176  //
177  m_hFile = INVALID_HANDLE_VALUE;
178  m_hFileMapping = 0;
179  m_pMemoryMappedFileBase = 0;
180  m_cbFile = 0;
181  m_errCode = errMMF_FileOpen; // Initial error code: not found
182  // First get a file handle
183  m_hFile =
184  CreateFile( pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE)0 );
185 
186  if ( m_hFile == INVALID_HANDLE_VALUE ) {
187  m_errCode = errMMF_FileOpen;
188  return;
189  }
190  m_cbFile = ::GetFileSize( m_hFile, 0 );
191  // Now, create a file mapping
192  m_hFileMapping = CreateFileMapping( m_hFile, NULL, PAGE_READONLY, 0, 0, NULL );
193  if ( m_hFileMapping == 0 ) {
194  // Oops. Something went wrong. Clean up.
195  CloseHandle( m_hFile );
196  m_hFile = INVALID_HANDLE_VALUE;
197  m_errCode = errMMF_FileMapping;
198  return;
199  }
200  m_pMemoryMappedFileBase = (PCHAR)MapViewOfFile( m_hFileMapping, FILE_MAP_READ, 0, 0, 0 );
201  if ( m_pMemoryMappedFileBase == 0 ) {
202  // Oops. Something went wrong. Clean up.
203  CloseHandle( m_hFileMapping );
204  m_hFileMapping = 0;
205  CloseHandle( m_hFile );
206  m_hFile = INVALID_HANDLE_VALUE;
207  m_errCode = errMMF_MapView;
208  return;
209  }
210  m_errCode = errMMF_NoError;
211 }
212 
214  // Clean up everything that was created by the constructor
215  if ( m_pMemoryMappedFileBase ) UnmapViewOfFile( m_pMemoryMappedFileBase );
216 
217  if ( m_hFileMapping ) CloseHandle( m_hFileMapping );
218 
219  if ( m_hFile != INVALID_HANDLE_VALUE ) CloseHandle( m_hFile );
220 
221  m_errCode = errMMF_FileOpen;
222 }
PVOID GetBase(void)
Definition: LibSymbolInfo.h:39
std::string GetLastError() const
T good(T...args)
T endl(T...args)
STL namespace.
#define MakePtr(cast, ptr, addValue)
T strlen(T...args)
BOOL Dump(LPTSTR lpszLibPathName, std::ostream &pFile)
T erase(T...args)
BOOL IsValid(void)
Definition: LibSymbolInfo.h:41
T find(T...args)
T strncmp(T...args)
BOOL IsFiltedSymbol(std::string &pszSymbolName)
T strstr(T...args)
DWORD ConvertBigEndian(DWORD bigEndian)
MEMORY_MAPPED_FILE(PSTR pszFileName)
STL class.
T bad(T...args)
BOOL DumpSymbols(LPTSTR lpszLibPathName, std::ostream &pFile)
T compare(T...args)
virtual ~CLibSymbolInfo()
BOOL IsRegularLibSymbol(PSTR pszSymbolName)