Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 27 #ifdef _WIN32 28 // Disable a warning in Boost program_option 29 // inconsistent linkage in program_options/v 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_BA5 45 #define AFX_LIBSYMBOLINFO_H__1A7003B4_BA53_11D 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 58 class CLibSymbolInfo 59 { 60 public: 61 CLibSymbolInfo(); 62 virtual ~CLibSymbolInfo(); 63 BOOL DumpSymbols(LPTSTR lpszLibPathName, std 64 std::string GetLastError() const; 65 66 protected: 67 std::string m_strResultsString; 68 std::string m_strErrorMsg; 69 70 BOOL Dump(LPTSTR lpszLibPathName, std::ostre 71 BOOL IsRegularLibSymbol( PSTR pszSymbolName 72 BOOL IsFiltedSymbol( std::string& pszSymbolN 73 DWORD ConvertBigEndian(DWORD bigEndian); 74 }; 75 76 enum errMMF { errMMF_NoError, errMMF_FileOpe 77 errMMF_FileMapping, errMMF_Map 78 79 class MEMORY_MAPPED_FILE 80 { 81 public: 82 MEMORY_MAPPED_FILE( PSTR pszFileName ); 83 ~MEMORY_MAPPED_FILE(void); 84 85 PVOID GetBase( void ){ return m_pMemoryMap 86 DWORD GetFileSize( void ){ return m_cbFile 87 BOOL IsValid( void ) { return errMMF_NoEr 88 errMMF GetErrorType(){ return m_errCode; } 89 90 private: 91 92 HANDLE m_hFile; 93 HANDLE m_hFileMapping; // Handle of mem 94 PVOID m_pMemoryMappedFileBase; 95 DWORD m_cbFile; 96 errMMF m_errCode; 97 }; 98 99 typedef MEMORY_MAPPED_FILE* PMEMORY_MAPPED_FIL 100 101 #endif // !defined(AFX_LIBSYMBOLINFO_H__1A7003 102 103 using namespace std; 104 105 #define MakePtr( cast, ptr, addValue ) (cast)( 106 107 ////////////////////////////////////////////// 108 // CLibSymbolInfo 109 110 CLibSymbolInfo::CLibSymbolInfo() 111 { 112 } 113 114 CLibSymbolInfo::~CLibSymbolInfo() 115 { 116 } 117 118 //============================================ 119 // Function: DumpSymbols 120 // 121 // Parameters: 122 // LPTSTR lpszLibPathName - The librar 123 // CStdioFile* pFile - Address of 124 // 125 // Description: 126 // 127 // Given a library file path name, the functio 128 // pointed to by pFile. 129 //============================================ 130 BOOL CLibSymbolInfo::DumpSymbols(LPTSTR lpszLi 131 { 132 if(lpszLibPathName == NULL || pFile.bad() ) 133 assert(lpszLibPathName != NULL); 134 assert(pFile.good()); 135 m_strErrorMsg.assign("NULL <lpszLibPathNam 136 return FALSE; 137 } 138 139 if(!Dump(lpszLibPathName, pFile)) return FA 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_bDum 152 // the symbo info. 153 //============================================ 154 BOOL CLibSymbolInfo::Dump(LPTSTR lpszLibPathNa 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 166 // string is at the beginning of the mapped 167 168 PSTR pArchiveStartString = (PSTR)libFile.Get 169 170 if ( 0 != strncmp( pArchiveStartString, IMAG 171 IMAGE_ARCHIVE_START_SIZ 172 m_strErrorMsg.assign("Not a valid COFF L 173 return FALSE; 174 } 175 176 // Point to the first archive member. This 177 // and immediately follows the archive start 178 PIMAGE_ARCHIVE_MEMBER_HEADER pMbrHdr; 179 pMbrHdr = MakePtr( PIMAGE_ARCHIVE_MEMBER_HEA 180 IMAGE_ARCHIVE_START_SIZE 181 182 // First DWORD after this member header is a 183 PDWORD pcbSymbols = (PDWORD)(pMbrHdr + 1); 184 185 // The symbol count is stored in big endian 186 // appropriate for the target architecture 187 DWORD cSymbols = ConvertBigEndian( *pcbSymbo 188 189 // Following the symbol count is an array of 190 // (essentially, embedded .OBJ files) 191 PDWORD pMemberOffsets = pcbSymbols + 1; 192 193 // Following the array of member offsets is 194 // names. 195 PSTR pszSymbolName = MakePtr( PSTR, pMemberO 196 197 // 198 // Loop through every symbol in the first ar 199 // 200 for ( unsigned i = 0; i < cSymbols; i++ ) 201 { 202 DWORD offset; 203 204 // The offsets to the archive member that 205 // in big endian format, so convert it app 206 offset = ConvertBigEndian( *pMemberOffsets 207 208 // Call DisplayLibInfoForSymbol, which fig 209 // it is. The "IsRegularLibSymbol" filter 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 218 // array has fixed length entries, while t 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 th 228 // the programmer never explicitly sees. 229 //============================================ 230 BOOL CLibSymbolInfo::IsRegularLibSymbol( PSTR 231 { 232 if ( 0 == strncmp( pszSymbolName, "__IMPORT_ 233 return FALSE; 234 235 if ( 0 == strncmp( pszSymbolName, "__NULL_IM 236 return FALSE; 237 238 if ( strstr( pszSymbolName, "_NULL_THUNK_DAT 239 return FALSE; 240 241 return TRUE; 242 } 243 //============================================ 244 // Filters out symbols that are not needed.... 245 //============================================ 246 BOOL CLibSymbolInfo::IsFiltedSymbol( string& s 247 { 248 // Filter problematic symbols for Win64 249 if ( symbolName.substr(0,3) == "_CT" ) retur 250 if ( symbolName.substr(0,3) == "_TI" ) retur 251 // Filter other symbols 252 if ( symbolName.substr(0,2) == "__" ) 253 return FALSE; 254 if ( symbolName.substr(0,3) == "??_" && symb 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") != stri 261 return FALSE; 262 if (symbolName.find ("details@boost") != str 263 return FALSE; 264 return TRUE; 265 } 266 267 //============================================ 268 // Converts from big endian to little endian n 269 //============================================ 270 DWORD CLibSymbolInfo::ConvertBigEndian(DWORD b 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 282 string CLibSymbolInfo::GetLastError() const 283 { 284 return m_strErrorMsg; 285 } 286 287 288 MEMORY_MAPPED_FILE::MEMORY_MAPPED_FILE( PSTR p 289 290 // 291 // Given a filename, the constructor opens 292 // mapping, and maps the entire file into m 293 // 294 m_hFile = INVALID_HANDLE_VALUE; 295 m_hFileMapping = 0; 296 m_pMemoryMappedFileBase = 0; 297 m_cbFile = 0; 298 m_errCode = errMMF_FileOpen; // Initial 299 // First get a file handle 300 m_hFile = CreateFile(pszFileName, GENERIC_R 301 OPEN_EXISTING, FILE_ATT 302 303 if ( m_hFile == INVALID_HANDLE_VALUE ) 304 { 305 m_errCode = errMMF_FileOpen; 306 return; 307 } 308 m_cbFile = ::GetFileSize( m_hFile, 0 ); 309 // Now, create a file mapping 310 m_hFileMapping = CreateFileMapping(m_hFile, 311 if ( m_hFileMapping == 0 ) 312 { 313 // Oops. Something went wrong. Clean 314 CloseHandle(m_hFile); 315 m_hFile = INVALID_HANDLE_VALUE; 316 m_errCode = errMMF_FileMapping; 317 return; 318 } 319 m_pMemoryMappedFileBase = (PCHAR)MapViewOf 320 321 if ( m_pMemoryMappedFileBase == 0 ) 322 { 323 // Oops. Something went wrong. Clean 324 CloseHandle(m_hFileMapping); 325 m_hFileMapping = 0; 326 CloseHandle(m_hFile); 327 m_hFile = INVALID_HANDLE_VALUE; 328 m_errCode = errMMF_MapView; 329 return; 330 } 331 m_errCode = errMMF_NoError; 332 } 333 334 MEMORY_MAPPED_FILE::~MEMORY_MAPPED_FILE(void) 335 { 336 // Clean up everything that was created by 337 if ( m_pMemoryMappedFileBase ) 338 UnmapViewOfFile( m_pMemoryMappedFileBa 339 340 if ( m_hFileMapping ) 341 CloseHandle( m_hFileMapping ); 342 343 if ( m_hFile != INVALID_HANDLE_VALUE ) 344 CloseHandle( m_hFile ); 345 346 m_errCode = errMMF_FileOpen; 347 } 348 349 namespace windef { 350 void usage(){ 351 cerr << "Usage: genwindef [-l <dllname>] [ 352 exit(1); 353 } 354 } 355 356 357 //--- Command main program-------------------- 358 int 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) { 371 windef::usage(); 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 " << o 395 return 1; 396 } 397 out << "LIBRARY " << library << endl; 398 out << "EXPORTS" << endl; 399 400 libsymbols.DumpSymbols(const_cast<char*>(obj 401 402 out.close(); 403 404 405 return 0; 406 } 407