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