Geant4-11
genwindef.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26
27#ifdef _WIN32
28 // Disable a warning in Boost program_options headers:
29 // inconsistent linkage in program_options/variables_map.hpp
30 #pragma warning ( disable : 4273 )
31 #define popen _popen
32 #define pclose _pclose
33 #define fileno _fileno
34 #include <stdlib.h>
35#endif
36
37// Include files----------------------------------------------------------------
38#include <vector>
39#include <string>
40#include <iostream>
41#include <fstream>
42
43// LibSymbolinfo----------------------------------------------------------------
44#if !defined(AFX_LIBSYMBOLINFO_H__1A7003B4_BA53_11D1_AE46_1CFB51000000__INCLUDED_)
45#define AFX_LIBSYMBOLINFO_H__1A7003B4_BA53_11D1_AE46_1CFB51000000__INCLUDED_
46
47#if _MSC_VER >= 1000
48#pragma once
49#endif // _MSC_VER >= 1000
50
51#include <string>
52#include <iostream>
53
54#include <stdio.h>
55#include <assert.h>
56#include <windows.h>
57
59{
60public:
62 virtual ~CLibSymbolInfo();
63 BOOL DumpSymbols(LPTSTR lpszLibPathName, std::ostream& pFile);
64 std::string GetLastError() const;
65
66protected:
67 std::string m_strResultsString;
68 std::string m_strErrorMsg;
69
70 BOOL Dump(LPTSTR lpszLibPathName, std::ostream& pFile);
71 BOOL IsRegularLibSymbol( PSTR pszSymbolName );
72 BOOL IsFiltedSymbol( std::string& pszSymbolName );
73 DWORD ConvertBigEndian(DWORD bigEndian);
74};
75
78
80{
81 public:
82 MEMORY_MAPPED_FILE( PSTR pszFileName );
84
85 PVOID GetBase( void ){ return m_pMemoryMappedFileBase; }
86 DWORD GetFileSize( void ){ return m_cbFile; }
87 BOOL IsValid( void ) { return errMMF_NoError == m_errCode; }
89
90 private:
91
92 HANDLE m_hFile;
93 HANDLE m_hFileMapping; // Handle of memory mapped file
95 DWORD m_cbFile;
97};
98
100
101#endif // !defined(AFX_LIBSYMBOLINFO_H__1A7003B4_BA53_11D1_AE46_1CFB51000000__INCLUDED_)
102
103using namespace std;
104
105#define MakePtr( cast, ptr, addValue ) (cast)( (DWORD_PTR)(ptr) + (DWORD_PTR)(addValue))
106
108// CLibSymbolInfo
109
111{
112}
113
115{
116}
117
118//=============================================================================
119// Function: DumpSymbols
120//
121// Parameters:
122// LPTSTR lpszLibPathName - The library file path name
123// CStdioFile* pFile - Address of the file in which to dump the symbols
124//
125// Description:
126//
127// Given a library file path name, the function dumps the symbol info into the file
128// pointed to by pFile.
129//=============================================================================
130BOOL CLibSymbolInfo::DumpSymbols(LPTSTR lpszLibPathName, ostream& pFile)
131{
132 if(lpszLibPathName == NULL || pFile.bad() ) {
133 assert(lpszLibPathName != NULL);
134 assert(pFile.good());
135 m_strErrorMsg.assign("NULL <lpszLibPathName> or Invalid file handle.");
136 return FALSE;
137 }
138
139 if(!Dump(lpszLibPathName, pFile)) return FALSE;
140 return TRUE;
141}
142
143//=============================================================================
144// Function: Dump
145//
146// Parameters:
147// As mentioned above.
148//
149// Description:
150//
151// Depending on the value specified in <m_bDump>/<m_bGrep> the routine dumps/greps
152// the symbo info.
153//=============================================================================
154BOOL CLibSymbolInfo::Dump(LPTSTR lpszLibPathName, ostream& pFile)
155{
156 string sBuff;
157 MEMORY_MAPPED_FILE libFile(lpszLibPathName);
158
159 // Ensure that the file mapping worked
160 if( FALSE == libFile.IsValid() ) {
161 m_strErrorMsg = "Unable to access file ";
162 m_strErrorMsg+= lpszLibPathName;
163 return FALSE;
164 }
165 // All COFF libraries start with the string "!<arch>\n". Verify that this
166 // string is at the beginning of the mapped file
167
168 PSTR pArchiveStartString = (PSTR)libFile.GetBase();
169
170 if ( 0 != strncmp( pArchiveStartString, IMAGE_ARCHIVE_START,
171 IMAGE_ARCHIVE_START_SIZE ) ) {
172 m_strErrorMsg.assign("Not a valid COFF LIB file.");
173 return FALSE;
174 }
175
176 // Point to the first archive member. This entry contains the LIB symbols,
177 // and immediately follows the archive start string ("!<arch>\n")
178 PIMAGE_ARCHIVE_MEMBER_HEADER pMbrHdr;
179 pMbrHdr = MakePtr( PIMAGE_ARCHIVE_MEMBER_HEADER, pArchiveStartString,
180 IMAGE_ARCHIVE_START_SIZE );
181
182 // First DWORD after this member header is a symbol count
183 PDWORD pcbSymbols = (PDWORD)(pMbrHdr + 1); // Pointer math!
184
185 // The symbol count is stored in big endian format, so adjust as
186 // appropriate for the target architecture
187 DWORD cSymbols = ConvertBigEndian( *pcbSymbols );
188
189 // Following the symbol count is an array of offsets to archive members
190 // (essentially, embedded .OBJ files)
191 PDWORD pMemberOffsets = pcbSymbols + 1; // Pointer math!
192
193 // Following the array of member offsets is an array of offsets to symbol
194 // names.
195 PSTR pszSymbolName = MakePtr( PSTR, pMemberOffsets, 4 * cSymbols );
196
197 //
198 // Loop through every symbol in the first archive member
199 //
200 for ( unsigned i = 0; i < cSymbols; i++ )
201 {
202 DWORD offset;
203
204 // The offsets to the archive member that contains the symbol is stored
205 // in big endian format, so convert it appropriately.
206 offset = ConvertBigEndian( *pMemberOffsets );
207
208 // Call DisplayLibInfoForSymbol, which figures out what kind of symbol
209 // it is. The "IsRegularLibSymbol" filters out symbols that are
210 // internal to the linking process
211 if ( IsRegularLibSymbol( pszSymbolName ) ) {
212 string symbol(pszSymbolName);
213 if (IsFiltedSymbol(symbol) ) {
214 pFile << symbol << endl;
215 }
216 }
217 // Advanced to the next symbol offset and name. The MemberOffsets
218 // array has fixed length entries, while the symbol names are
219 // sequential null-terminated strings
220 pMemberOffsets++;
221 pszSymbolName += strlen(pszSymbolName) + 1;
222 }
223 return TRUE;
224}
225
226//=============================================================================
227// Filters out symbols that are internal to the linking process, and which
228// the programmer never explicitly sees.
229//=============================================================================
230BOOL CLibSymbolInfo::IsRegularLibSymbol( PSTR pszSymbolName )
231{
232 if ( 0 == strncmp( pszSymbolName, "__IMPORT_DESCRIPTOR_", 20 ) )
233 return FALSE;
234
235 if ( 0 == strncmp( pszSymbolName, "__NULL_IMPORT_DESCRIPTOR", 24 ) )
236 return FALSE;
237
238 if ( strstr( pszSymbolName, "_NULL_THUNK_DATA" ) )
239 return FALSE;
240
241 return TRUE;
242}
243//=============================================================================
244// Filters out symbols that are not needed....
245//=============================================================================
246BOOL CLibSymbolInfo::IsFiltedSymbol( string& symbolName )
247{
248 // Filter problematic symbols for Win64
249 if ( symbolName.substr(0,3) == "_CT" ) return FALSE;
250 if ( symbolName.substr(0,3) == "_TI" ) return FALSE;
251 // Filter other symbols
252 if ( symbolName.substr(0,2) == "__" )
253 return FALSE;
254 if ( symbolName.substr(0,3) == "??_" && symbolName[3] != '0') // Keep 'operator/=' [??_0]
255 return FALSE;
256 if( symbolName[0] == '_') {
257 symbolName.erase(0, 1); // C functions ...
258 }
259 // Filter the internal Boost symbols
260 if (symbolName.find ("detail@boost") != string::npos )
261 return FALSE;
262 if (symbolName.find ("details@boost") != string::npos )
263 return FALSE;
264 return TRUE;
265}
266
267//=============================================================================
268// Converts from big endian to little endian numbers.
269//=============================================================================
271{
272 DWORD temp = 0;
273
274 temp |= bigEndian >> 24;
275 temp |= ((bigEndian & 0x00FF0000) >> 8);
276 temp |= ((bigEndian & 0x0000FF00) << 8);
277 temp |= ((bigEndian & 0x000000FF) << 24);
278
279 return temp;
280}
281
283{
284 return m_strErrorMsg;
285}
286
287
289
290 //
291 // Given a filename, the constructor opens a file handle, creates a file
292 // mapping, and maps the entire file into memory.
293 //
294 m_hFile = INVALID_HANDLE_VALUE;
295 m_hFileMapping = 0;
297 m_cbFile = 0;
298 m_errCode = errMMF_FileOpen; // Initial error code: not found
299 // First get a file handle
300 m_hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
301 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE)0);
302
303 if ( m_hFile == INVALID_HANDLE_VALUE )
304 {
306 return;
307 }
309 // Now, create a file mapping
310 m_hFileMapping = CreateFileMapping(m_hFile,NULL, PAGE_READONLY, 0, 0,NULL);
311 if ( m_hFileMapping == 0 )
312 {
313 // Oops. Something went wrong. Clean up.
314 CloseHandle(m_hFile);
315 m_hFile = INVALID_HANDLE_VALUE;
317 return;
318 }
319 m_pMemoryMappedFileBase = (PCHAR)MapViewOfFile( m_hFileMapping,
320 FILE_MAP_READ, 0, 0, 0);
321 if ( m_pMemoryMappedFileBase == 0 )
322 {
323 // Oops. Something went wrong. Clean up.
324 CloseHandle(m_hFileMapping);
325 m_hFileMapping = 0;
326 CloseHandle(m_hFile);
327 m_hFile = INVALID_HANDLE_VALUE;
329 return;
330 }
332}
333
335{
336 // Clean up everything that was created by the constructor
338 UnmapViewOfFile( m_pMemoryMappedFileBase );
339
340 if ( m_hFileMapping )
341 CloseHandle( m_hFileMapping );
342
343 if ( m_hFile != INVALID_HANDLE_VALUE )
344 CloseHandle( m_hFile );
345
347}
348
349namespace windef {
350 void usage(){
351 cerr << "Usage: genwindef [-l <dllname>] [-o <output-file> | exports.def] <obj or lib filenames>" << endl;
352 exit(1);
353 }
354}
355
356
357//--- Command main program-----------------------------------------------------
358int main ( int argc, char** argv )
359//-----------------------------------------------------------------------------
360{
361 string outfile("exports.def");
362 string library("UnknownLib");
363 string objfiles;
364 bool debug(false);
365
366 int arg;
367 if (argc < 3) windef::usage();
368 arg = 1;
369 while (argv[arg][0] == '-') {
370 if (strcmp(argv[arg], "--") == 0) {
372 }
373 else if (strcmp(argv[arg], "-l") == 0) {
374 arg++;
375 if (arg == argc) windef::usage();
376 library = argv[arg];
377 }
378 else if (strcmp(argv[arg], "-o") == 0) {
379 arg++;
380 if (arg == argc) windef::usage();
381 outfile = argv[arg];
382 }
383 arg++;
384 }
385 if (arg == argc) windef::usage();
386 for (arg; arg < argc; arg++) {
387 objfiles += argv[arg];
388 if( arg+1 < argc) objfiles += " ";
389 }
390
391 CLibSymbolInfo libsymbols;
392 ofstream out(outfile.c_str());
393 if(out.fail()) {
394 cerr << "windef: Error opening file " << outfile << endl;
395 return 1;
396 }
397 out << "LIBRARY " << library << endl;
398 out << "EXPORTS" << endl;
399
400 libsymbols.DumpSymbols(const_cast<char*>(objfiles.c_str()), out);
401
402 out.close();
403
404
405 return 0;
406}
#define TRUE
Definition: Globals.hh:27
#define FALSE
Definition: Globals.hh:23
std::string m_strErrorMsg
Definition: genwindef.cc:68
std::string GetLastError() const
Definition: genwindef.cc:282
virtual ~CLibSymbolInfo()
Definition: genwindef.cc:114
BOOL IsRegularLibSymbol(PSTR pszSymbolName)
Definition: genwindef.cc:230
std::string m_strResultsString
Definition: genwindef.cc:67
BOOL IsFiltedSymbol(std::string &pszSymbolName)
Definition: genwindef.cc:246
BOOL Dump(LPTSTR lpszLibPathName, std::ostream &pFile)
Definition: genwindef.cc:154
DWORD ConvertBigEndian(DWORD bigEndian)
Definition: genwindef.cc:270
BOOL DumpSymbols(LPTSTR lpszLibPathName, std::ostream &pFile)
Definition: genwindef.cc:130
PVOID m_pMemoryMappedFileBase
Definition: genwindef.cc:94
~MEMORY_MAPPED_FILE(void)
Definition: genwindef.cc:334
PVOID GetBase(void)
Definition: genwindef.cc:85
MEMORY_MAPPED_FILE(PSTR pszFileName)
Definition: genwindef.cc:288
DWORD GetFileSize(void)
Definition: genwindef.cc:86
HANDLE m_hFileMapping
Definition: genwindef.cc:93
errMMF GetErrorType()
Definition: genwindef.cc:88
BOOL IsValid(void)
Definition: genwindef.cc:87
#define MakePtr(cast, ptr, addValue)
Definition: genwindef.cc:105
int main(int argc, char **argv)
Definition: genwindef.cc:358
MEMORY_MAPPED_FILE * PMEMORY_MAPPED_FILE
Definition: genwindef.cc:99
errMMF
Definition: genwindef.cc:76
@ errMMF_NoError
Definition: genwindef.cc:76
@ errMMF_FileOpen
Definition: genwindef.cc:76
@ errMMF_FileMapping
Definition: genwindef.cc:77
@ errMMF_MapView
Definition: genwindef.cc:77
def exit()
Definition: g4zmq.py:99
def debug(dflag)
Definition: g4zmq.py:30
void usage()
Definition: genwindef.cc:350