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