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