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