OOO330
[LibreOffice.git] / soltools / ldump / ldump.cxx
blob8c6e85b6259409a7d9f5752bb035d6cdf43f9452
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_soltools.hxx"
31 #include <string.h>
32 #include <direct.h>
33 #include <stdio.h>
34 #include <stdlib.h>
36 #include "ldump.hxx"
37 #include "hashtbl.hxx"
39 #define MAXSYM 65536
40 #define MAXBASE 98304
41 #define MAX_MAN 4096
43 int bFilter = 0;
44 int bLdump3 = 0;
45 int bUseDirectives = 0;
46 int bVerbose = 0;
47 int bExportByName = 0;
49 class ExportSet : public HashTable
51 public:
52 ExportSet
54 unsigned long lSize,
55 double dMaxLoadFactor = HashTable::m_defMaxLoadFactor,
56 double dGrowFactor = HashTable::m_defDefGrowFactor
58 : HashTable(lSize,false,dMaxLoadFactor,dGrowFactor) {}
60 virtual ~ExportSet() {}
62 LibExport * Find (char * const& Key) const
63 { return (LibExport *) HashTable::Find((char *) Key); }
65 bool Insert (char * const& Key, LibExport * Object)
66 { return HashTable::Insert((char *) Key, (void*) Object); }
68 LibExport * Delete (char * const&Key)
69 { return (LibExport *) HashTable::Delete ((char *) Key); }
72 LibDump::LibDump( char *cFileName, int bExportByName )
73 : cBName( NULL ),
74 cAPrefix( NULL ),
75 cLibName( NULL ),
76 cFilterName( NULL ),
77 cModName( NULL )
79 fprintf( stderr, "LIB-NT File Dumper v4.00 (C) 2000 Sun Microsystems, Inc.\n\n" );
80 fprintf( stderr, "%s ", cFileName );
82 bExportName = bExportByName;
84 unsigned long nSlots = 0xfffff;
85 pBaseTab = new ExportSet( nSlots );
86 pIndexTab = new ExportSet( nSlots );
87 pFilterLines = new char * [MAXFILT];
88 CheckLibrary(cFileName);
89 bBase = 0;
90 bAll = false;
91 nDefStart = 0;
92 nBaseLines = 0;
93 nFilterLines = 0;
94 bDef = true;
95 cAPrefix = new char[ 1 ];
96 cAPrefix[ 0 ] = 0;
97 if (!bExportName)
98 CheckDataBase();
101 bool LibDump::Dump()
103 FILE *pList;
104 char aBuf[MAX_MAN];
105 int nLen;
106 char aName[MAX_MAN];
108 pList = fopen( cLibName, "rb");
109 if (!pList)
110 DumpError(10);
112 // forget about offset when working on linker directives
113 if ( !bUseDirectives )
115 // calculating offset for name section
116 unsigned char TmpBuffer[4];
117 fread( TmpBuffer, 1, 4, pList);
118 // anzahl bigendian mal laenge + ueberspringen der naechsten laengenangabe
119 unsigned long nOffSet = (unsigned long) ( TmpBuffer[2] * 256 + TmpBuffer[3] ) * 4 + 4;
120 fseek( pList, (long) nOffSet, 0);
123 char aTmpBuf[4096];
124 // reading file containing symbols
125 while( !feof( pList ) )
127 int i = 0;
128 if ( !bUseDirectives )
130 // symbol komplett einlesen
131 for (;;)
133 int c = fgetc( pList );
134 if ( c == '\0' )
136 break;
138 if ( ((c >= 33) && (c <= 126)) && ( c!=40 && c!=41) )
139 aBuf[i] = static_cast< char >(c);
140 else
142 aBuf[0] = '\0';
143 break;
145 i++;
147 // Namen found
148 aBuf[i] = '\0';
150 else
152 fgets( aTmpBuf, 4096, pList );
153 char * pEnd = 0;
154 char *pFound = 0;
155 aBuf[0] = '\0';
156 pFound = strchr( aTmpBuf, 'E' );
157 while ( pFound )
159 if ( strncmp( "EXPORT:", pFound, 7) == 0 )
161 pFound += 7;
162 pEnd = strchr( pFound, ',');
163 if ( pEnd )
164 *pEnd = '\0';
165 strncpy( aBuf, pFound, strlen( pFound));
166 aBuf[ strlen( pFound) ] = '\0';
167 // fprintf( stderr, "\n--- %s\n", aBuf);
168 break;
170 else
172 pFound++;
173 pFound = strchr( pFound, 'E' );
178 if ((aBuf[0] =='?') || !strncmp(aBuf, "__CT",4))
180 nLen = (int) strlen(aBuf);
181 memset( aName, 0, sizeof( aName ) );
182 int nName = 0;
183 for( i = 0; i < nLen; i++ )
185 if ( (aBuf[i] != '\n') && (aBuf[i] != '\r') )
187 aName[nName] = aBuf[i];
188 nName++;
191 // und raus damit
192 PrintSym( aName, bExportByName );
194 else if ( bAll == true )
196 int nPreLen = (int) strlen( cAPrefix );
198 nLen = (int) strlen(aBuf);
199 memset( aName, 0, sizeof( aName ) );
200 int nName = 0;
202 for( i = 0; i < nLen; i++ )
204 if ( (aBuf[i] != '\n') && (aBuf[i] != '\r') )
206 aName[nName] = aBuf[i];
207 nName++;
210 //fprintf( stderr, "Gefundenen Prefix : %s %d \n", aTmpBuf, nPreLen );
211 // den ersten _ raus
212 nLen = (int) strlen(aName);
213 if (aName[0] == '_')
214 strcpy( aBuf , &aName[1] );
215 strncpy ( aTmpBuf, aBuf, (size_t) nPreLen );
216 aTmpBuf[nPreLen] = '\0';
217 if ( !strcmp( aTmpBuf, cAPrefix ))
219 if ( bLdump3 ) {
220 int nChar = '@';
221 char *pNeu = strchr( aBuf, nChar );
222 int nPos = pNeu - aBuf + 1;
223 if ( nPos > 0 )
225 char aOldBuf[MAX_MAN];
226 strcpy( aOldBuf, aBuf );
227 char pChar[MAX_MAN];
228 strncpy( pChar, aBuf, (size_t) (nPos -1) );
229 pChar[nPos-1] = '\0';
230 strcpy( aBuf, pChar );
231 strcat( aBuf, "=" );
232 strcat( aBuf, aOldBuf );
233 strcpy( pChar, "" );
236 // und raus damit
237 PrintSym( aBuf, true );
241 fclose(pList);
242 return true;
245 bool LibDump::ReadFilter( char * cFilterName )
247 FILE* pfFilter = 0;
248 char aBuf[MAX_MAN];
249 char* pStr;
250 int nLen;
252 pfFilter = fopen( cFilterName, "r" );
254 if ( !pfFilter )
256 ::bFilter = 0;
257 DumpError( 500 );
260 while( fgets( aBuf, MAX_MAN, pfFilter ) != 0 )
262 nLen = (int) strlen(aBuf);
263 pStr = new char[(unsigned int) nLen];
264 if ( !pStr )
265 DumpError( 98 );
266 memcpy( pStr, aBuf, (unsigned int) nLen );
267 if ( *(pStr+nLen-1) == '\n' )
268 *(pStr+nLen-1) = '\0';
269 pFilterLines[nFilterLines] = pStr;
270 nFilterLines++;
271 if ( nFilterLines >= MAXFILT )
272 DumpError( 510 );
275 fclose( pfFilter );
276 return true;
279 bool LibDump::PrintSym(char *pName, bool bName )
281 LibExport *pData;
284 // Filter auswerten
285 if ( Filter( pName ) )
287 if ( strlen( pName ) > 3 )
289 if ( bDef )
291 if (!bBase)
292 if (bExportName) {
293 fprintf( stdout, "\t%s\n", pName );
294 } else {
295 fprintf( stdout, "\t%s\t\t@%lu\n", pName, nDefStart );
297 else
299 pData = pBaseTab->Find( pName );
300 if ( pData )
302 pData->bExport = true;
303 if ( bName )
304 pData->bByName = true;
305 else
306 pData->bByName = false;
307 if ( bVerbose )
308 fprintf(stderr,".");
310 else
312 // neuen Export eintragen
313 pData = new LibExport;
314 pData->cExportName = new char[ strlen( pName ) + 1 ];
315 strcpy( pData->cExportName, pName );
316 pData->nOrdinal = nBaseLines++;
317 pData->bExport = true;
318 if ( bName )
319 pData->bByName = true;
320 else
321 pData->bByName = false;
322 pBaseTab->Insert( pData->cExportName, pData );
323 char *cBuffer = new char[ 30 ];
324 sprintf( cBuffer, "%lu", pData->nOrdinal );
325 pIndexTab->Insert( cBuffer, pData );
326 delete [] cBuffer;
327 if ( bVerbose )
328 fprintf(stderr,"n");
332 else
333 printf( "%s\n", pName );
334 nDefStart++;
337 return true;
340 bool LibDump::IsFromAnonymousNamespace (char *pExportName) {
341 char* pattern1 = "@?A0x";
343 if (strstr(pExportName, pattern1)) {
344 return true;
346 return false;
349 bool LibDump::Filter(char *pExportName)
351 unsigned long i;
352 char pTest[256];
354 // filter out symbols from anonymous namespaces
355 if (IsFromAnonymousNamespace (pExportName))
356 return false;
358 // Kein Filter gesetzt
359 if ( ::bFilter == 0 )
360 return true;
362 for ( i=0; i<nFilterLines; i++ )
364 //Zum vergleichen muá das Plus abgeschnitteb werden
365 if(pFilterLines[i][0] != '+')
367 if ( strstr( pExportName, pFilterLines[i]))
368 return false;
370 else
372 strcpy(pTest,&pFilterLines[i][1]);
373 if ( strstr( pExportName, pTest))
374 return true;
377 return true;
380 bool LibDump::SetFilter(char * cFilterName)
382 ReadFilter( cFilterName );
383 return true;
386 bool LibDump::CheckLibrary(char * cName)
388 delete [] cLibName;
389 cLibName = new char[ strlen( cName ) + 1 ];
390 strcpy( cLibName, cName );
391 return true;
394 bool LibDump::ReadDataBase()
396 FILE* pfBase = 0;
397 char aBuf[MAX_MAN];
398 char* pStr;
399 char cBuffer[ 30 ];
400 int nLen;
401 LibExport *pData;
403 pfBase = fopen( cBName, "r" );
405 if ( !pfBase )
407 bBase = 0;
408 DumpError( 600 );
411 bool bRet = true;
412 while( fgets( aBuf, MAX_MAN, pfBase ) != 0 )
414 nLen = (int) strlen(aBuf);
415 pStr = new char[(unsigned int) nLen];
416 if ( !pStr )
417 DumpError( 98 );
418 memcpy( pStr, aBuf, (size_t) nLen );
419 if ( *(pStr+nLen-1) == '\n' )
420 *(pStr+nLen-1) = '\0';
421 pData = new LibExport;
422 pData->cExportName = pStr;
423 pData->nOrdinal = nBaseLines;
424 pData->bExport=false;
426 if (pBaseTab->Insert(pData->cExportName, pData ) == NULL)
427 bRet = false;
428 ltoa( (long) pData->nOrdinal, cBuffer, 10 );
429 if (pIndexTab->Insert( cBuffer, pData ) == NULL)
430 bRet = false;
431 nBaseLines++;
432 if ( nBaseLines >= MAXBASE )
433 DumpError( 610 );
435 fclose( pfBase );
436 return bRet;
439 class ExportSetIter : public HashTableIterator
441 public:
442 ExportSetIter(HashTable const& aTable)
443 : HashTableIterator(aTable) {}
445 LibExport * GetFirst()
446 { return (LibExport *)HashTableIterator::GetFirst(); }
447 LibExport * GetNext()
448 { return (LibExport *)HashTableIterator::GetNext(); }
449 LibExport * GetLast()
450 { return (LibExport *)HashTableIterator::GetLast(); }
451 LibExport * GetPrev()
452 { return (LibExport *)HashTableIterator::GetPrev(); }
454 private:
455 void operator =(ExportSetIter &); // not defined
458 bool LibDump::PrintDataBase()
460 if (bExportName)
461 return true;
462 FILE *pFp;
463 pFp = fopen (cBName,"w+");
464 if (!pFp)
465 fprintf( stderr, "Error opening DataBase File\n" );
467 LibExport *pData;
468 for ( unsigned long i=0; i < nBaseLines+10; i++ )
470 char * cBuffer = new char[ 30 ];
471 sprintf( cBuffer, "%lu", i );
472 pData = pIndexTab->Find( cBuffer );
473 delete [] cBuffer;
474 if ( pData )
475 fprintf(pFp,"%s\n",pData->cExportName);
477 fclose(pFp);
478 return true;
481 bool LibDump::PrintDefFile()
483 #ifdef FAST
484 ExportSetIter aIterator( *pBaseTab );
485 for ( LibExport *pData = aIterator.GetFirst(); pData != NULL;
486 pData = aIterator.GetNext() )
488 if ( pData->bExport )
490 if ( pData->bByName )
492 fprintf(stdout,"\t%s\n",
493 pData->sExportName.GetBuffer());
495 else
497 fprintf(stdout,"\t%s\t\t@%d NONAME\n",
498 pData->sExportName.GetBuffer(), pData->nOrdinal+nBegin);
502 #else
503 // sortiert nach Ordinals;
504 LibExport *pData;
505 for ( unsigned long i=0; i<nBaseLines+1; i++)
507 char * cBuffer = new char[ 30 ];
508 sprintf( cBuffer, "%lu", i );
509 pData = pIndexTab->Find( cBuffer );
510 delete [] cBuffer;
511 if ( pData )
512 if ( pData->bExport )
514 if ( pData->bByName )
516 if ( strlen( pData->cExportName ))
517 fprintf(stdout,"\t%s\n",
518 pData->cExportName);
520 else
522 if ( strlen( pData->cExportName ))
523 fprintf(stdout,"\t%s\t\t@%d NONAME\n",
524 pData->cExportName, pData->nOrdinal+nBegin);
528 #endif
529 return true;
532 bool LibDump::CheckDataBase()
534 // existiert eine Datenbasis ?
535 if (!bBase)
537 cBName = new char[ 2048 ];
538 char *pTmp = "defs\\";
540 FILE *fp;
541 #ifdef OS2
542 _mkdir ("defs", 0777);
543 #else
544 _mkdir ("defs");
545 #endif
546 strcpy(cBName,pTmp);
547 #ifdef OS2
548 strcat(cBName,"gcc");
549 #else
550 strcat(cBName,getenv ("COMP_ENV"));
551 #endif
553 fp = fopen (cBName,"r");
554 if (fp)
556 bBase = true;
558 else
560 fp = fopen (cBName,"w+");
561 bBase = true;
563 fclose (fp);
565 // lese Datenbasis !
566 if (bBase)
568 ReadDataBase();
570 return true;
573 LibDump::~LibDump()
575 delete [] cBName;
576 delete [] cAPrefix;
577 // delete [] cLibName;
578 delete [] cFilterName;
579 delete [] cModName;
582 void LibDump::SetCExport( char* pName )
584 delete [] cAPrefix;
585 cAPrefix = new char[ strlen( pName ) + 1 ];
586 strcpy( cAPrefix, pName );bAll = true;
589 //******************************************************************
590 //* Error() - Gibt Fehlermeldumg aus
591 //******************************************************************
593 void LibDump::DumpError( unsigned long n )
595 char *p;
597 switch (n)
599 case 1: p = "Input error in library file"; break;
600 case 2: p = "Position error in library file (no THEADR set)"; break;
601 case 3: p = "Overflow of symbol table"; break;
602 #ifdef WNT
603 case 10: p = "EXP file not found"; break;
604 case 11: p = "No valid EXP file"; break;
605 #else
606 case 10: p = "Library file not found"; break;
607 case 11: p = "No valid library file"; break;
608 #endif
609 case 98: p = "Out of memory"; break;
610 case 99: p = "LDUMP [-LD3] [-D] [-N] [-A] [-E nn] [-F name] Filename[.LIB]\n"
611 "-LD3 : Supports feature set of ldump3 (default: ldump/ldump2)\n"
612 "-A : all symbols (default: only C++)\n"
613 "-E nn : gerenration of export table beginning with number nn\n"
614 "-F name: Filter file\n"
615 "-D : file contains \"dumpbin\" directives\n"
616 "-N : export by name\n"
617 "-V : be verbose\n"; break;
618 case 500: p = "Unable to open filter file\n"; break;
619 case 510: p = "Overflow of filter table\n"; break;
620 case 600: p = "Unable to open base database file\n"; break;
621 case 610: p = "Overflow in base database table\n"; break;
622 default: p = "Unspecified error";
624 fprintf( stdout, "%s\n", p );
625 exit (1);
628 /*********************************************************************
629 Test Funktionen
630 *********************************************************************/
633 void usage()
635 LibDump::DumpError(99);
638 #define STATE_NON 0x0000
639 #define STATE_BEGIN 0x0001
640 #define STATE_FILTER 0x0002
641 #define STATE_CEXPORT 0x0003
644 #ifdef WNT
645 __cdecl
646 #endif
647 main( int argc, char **argv )
649 char *pLibName = NULL, *pFilterName = NULL, *pCExport= NULL;
650 unsigned short nBegin=1;
652 unsigned short nState = STATE_NON;
654 if ( argc == 1 ) {
655 usage();
658 for ( int i = 1; i < argc; i++ ) {
659 if (( !strcmp( argv[ i ], "-H" )) ||
660 ( !strcmp( argv[ i ], "-h" )) ||
661 ( !strcmp( argv[ i ], "-?" )))
663 usage();
665 else if (( !strcmp( argv[ i ], "-LD3" )) ||
666 ( !strcmp( argv[ i ], "-Ld3" )) ||
667 ( !strcmp( argv[ i ], "-ld3" )) ||
668 ( !strcmp( argv[ i ], "-lD3" )))
670 if ( nState != STATE_NON ) {
671 usage();
673 bLdump3 = 1;
675 else if (( !strcmp( argv[ i ], "-E" )) || ( !strcmp( argv[ i ], "-e" ))) {
676 if ( nState != STATE_NON ) {
677 usage();
679 nState = STATE_BEGIN;
681 else if (( !strcmp( argv[ i ], "-F" )) || ( !strcmp( argv[ i ], "-f" ))) {
682 if ( nState != STATE_NON ) {
683 usage();
685 nState = STATE_FILTER;
687 else if (( !strcmp( argv[ i ], "-A" )) || ( !strcmp( argv[ i ], "-a" ))) {
688 if ( nState != STATE_NON ) {
689 usage();
691 nState = STATE_CEXPORT;
692 pCExport = new char[ 1 ];
693 pCExport[ 0 ] = 0;
695 else if (( !strcmp( argv[ i ], "-D" )) || ( !strcmp( argv[ i ], "-d" ))) {
696 if ( nState != STATE_NON ) {
697 usage();
699 bUseDirectives = 1;
701 else if (( !strcmp( argv[ i ], "-N" )) || ( !strcmp( argv[ i ], "-n" ))) {
702 if ( nState != STATE_NON ) {
703 usage();
705 bExportByName = 1;
707 else if (( !strcmp( argv[ i ], "-V" )) || ( !strcmp( argv[ i ], "-v" ))) {
708 if ( nState != STATE_NON ) {
709 usage();
711 bVerbose = 1;
713 else {
714 switch ( nState ) {
715 case STATE_BEGIN:
716 nBegin = static_cast< unsigned short >(atoi( argv[ i ] ));
717 nState = STATE_NON;
718 break;
719 case STATE_FILTER:
720 pFilterName = new char[ strlen( argv[ i ] ) + 1 ];
721 strcpy( pFilterName, argv[ i ] );
722 bFilter = 1;
723 nState = STATE_NON;
724 break;
725 case STATE_CEXPORT:
726 delete [] pCExport;
727 pCExport = new char[ strlen( argv[ i ] ) + 1 ];
728 strcpy( pCExport, argv[ i ] );
729 nState = STATE_NON;
730 break;
731 default:
732 pLibName = new char[ strlen( argv[ i ] ) + 1 ];
733 strcpy( pLibName, argv[ i ] );
734 break;
739 if ( !pLibName ) {
740 usage();
743 LibDump *pDump = new LibDump( pLibName, bExportByName );
744 pDump->SetBeginExport(nBegin);
745 if ( bFilter != 0 )
746 pDump->SetFilter( pFilterName );
747 if ( pCExport )
748 pDump->SetCExport( pCExport );
749 else {
750 char *pEmpty = "";
751 pDump->SetCExport( pEmpty );
753 pDump->Dump();
754 pDump->PrintDefFile();
755 pDump->PrintDataBase();
756 delete pDump;
757 return 0;