Update ooo320-m1
[ooovba.git] / soltools / ldump / ldump.cxx
blob3d2199b6680e58e47a81801063a9420a0472d584
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ldump.cxx,v $
10 * $Revision: 1.19 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_soltools.hxx"
34 #include <string.h>
35 #include <direct.h>
36 #include <stdio.h>
37 #include <stdlib.h>
39 #include "ldump.hxx"
40 #include "hashtbl.hxx"
42 #define MAXSYM 65536
43 #define MAXBASE 98304
44 #define MAX_MAN 4096
46 int bFilter = 0;
47 int bLdump3 = 0;
48 int bUseDirectives = 0;
49 int bVerbose = 0;
50 int bExportByName = 0;
52 class ExportSet : public HashTable
54 public:
55 ExportSet
57 unsigned long lSize,
58 double dMaxLoadFactor = HashTable::m_defMaxLoadFactor,
59 double dGrowFactor = HashTable::m_defDefGrowFactor
61 : HashTable(lSize,false,dMaxLoadFactor,dGrowFactor) {}
63 virtual ~ExportSet() {}
65 LibExport * Find (char * const& Key) const
66 { return (LibExport *) HashTable::Find((char *) Key); }
68 bool Insert (char * const& Key, LibExport * Object)
69 { return HashTable::Insert((char *) Key, (void*) Object); }
71 LibExport * Delete (char * const&Key)
72 { return (LibExport *) HashTable::Delete ((char *) Key); }
75 LibDump::LibDump( char *cFileName, int bExportByName )
76 : cBName( NULL ),
77 cAPrefix( NULL ),
78 cLibName( NULL ),
79 cFilterName( NULL ),
80 cModName( NULL )
82 fprintf( stderr, "LIB-NT File Dumper v4.00 (C) 2000 Sun Microsystems, Inc.\n\n" );
83 fprintf( stderr, "%s ", cFileName );
85 bExportName = bExportByName;
87 unsigned long nSlots = 0xfffff;
88 pBaseTab = new ExportSet( nSlots );
89 pIndexTab = new ExportSet( nSlots );
90 pFilterLines = new char * [MAXFILT];
91 CheckLibrary(cFileName);
92 bBase = 0;
93 bAll = false;
94 nDefStart = 0;
95 nBaseLines = 0;
96 nFilterLines = 0;
97 bDef = true;
98 cAPrefix = new char[ 1 ];
99 cAPrefix[ 0 ] = 0;
100 if (!bExportName)
101 CheckDataBase();
104 bool LibDump::Dump()
106 FILE *pList;
107 char aBuf[MAX_MAN];
108 int nLen;
109 char aName[MAX_MAN];
111 pList = fopen( cLibName, "rb");
112 if (!pList)
113 DumpError(10);
115 // forget about offset when working on linker directives
116 if ( !bUseDirectives )
118 // calculating offset for name section
119 unsigned char TmpBuffer[4];
120 fread( TmpBuffer, 1, 4, pList);
121 // anzahl bigendian mal laenge + ueberspringen der naechsten laengenangabe
122 unsigned long nOffSet = (unsigned long) ( TmpBuffer[2] * 256 + TmpBuffer[3] ) * 4 + 4;
123 fseek( pList, (long) nOffSet, 0);
126 char aTmpBuf[4096];
127 // reading file containing symbols
128 while( !feof( pList ) )
130 int i = 0;
131 if ( !bUseDirectives )
133 // symbol komplett einlesen
134 for (;;)
136 int c = fgetc( pList );
137 if ( c == '\0' )
139 break;
141 if ( ((c >= 33) && (c <= 126)) && ( c!=40 && c!=41) )
142 aBuf[i] = static_cast< char >(c);
143 else
145 aBuf[0] = '\0';
146 break;
148 i++;
150 // Namen found
151 aBuf[i] = '\0';
153 else
155 fgets( aTmpBuf, 4096, pList );
156 char * pEnd = 0;
157 char *pFound = 0;
158 aBuf[0] = '\0';
159 pFound = strchr( aTmpBuf, 'E' );
160 while ( pFound )
162 if ( strncmp( "EXPORT:", pFound, 7) == 0 )
164 pFound += 7;
165 pEnd = strchr( pFound, ',');
166 if ( pEnd )
167 *pEnd = '\0';
168 strncpy( aBuf, pFound, strlen( pFound));
169 aBuf[ strlen( pFound) ] = '\0';
170 // fprintf( stderr, "\n--- %s\n", aBuf);
171 break;
173 else
175 pFound++;
176 pFound = strchr( pFound, 'E' );
181 if ((aBuf[0] =='?') || !strncmp(aBuf, "__CT",4))
183 nLen = (int) strlen(aBuf);
184 memset( aName, 0, sizeof( aName ) );
185 int nName = 0;
186 for( i = 0; i < nLen; i++ )
188 if ( (aBuf[i] != '\n') && (aBuf[i] != '\r') )
190 aName[nName] = aBuf[i];
191 nName++;
194 // und raus damit
195 PrintSym( aName, bExportByName );
197 else if ( bAll == true )
199 int nPreLen = (int) strlen( cAPrefix );
201 nLen = (int) strlen(aBuf);
202 memset( aName, 0, sizeof( aName ) );
203 int nName = 0;
205 for( i = 0; i < nLen; i++ )
207 if ( (aBuf[i] != '\n') && (aBuf[i] != '\r') )
209 aName[nName] = aBuf[i];
210 nName++;
213 //fprintf( stderr, "Gefundenen Prefix : %s %d \n", aTmpBuf, nPreLen );
214 // den ersten _ raus
215 nLen = (int) strlen(aName);
216 if (aName[0] == '_')
217 strcpy( aBuf , &aName[1] );
218 strncpy ( aTmpBuf, aBuf, (size_t) nPreLen );
219 aTmpBuf[nPreLen] = '\0';
220 if ( !strcmp( aTmpBuf, cAPrefix ))
222 if ( bLdump3 ) {
223 int nChar = '@';
224 char *pNeu = strchr( aBuf, nChar );
225 int nPos = pNeu - aBuf + 1;
226 if ( nPos > 0 )
228 char aOldBuf[MAX_MAN];
229 strcpy( aOldBuf, aBuf );
230 char pChar[MAX_MAN];
231 strncpy( pChar, aBuf, (size_t) (nPos -1) );
232 pChar[nPos-1] = '\0';
233 strcpy( aBuf, pChar );
234 strcat( aBuf, "=" );
235 strcat( aBuf, aOldBuf );
236 strcpy( pChar, "" );
239 // und raus damit
240 PrintSym( aBuf, true );
244 fclose(pList);
245 return true;
248 bool LibDump::ReadFilter( char * cFilterName )
250 FILE* pfFilter = 0;
251 char aBuf[MAX_MAN];
252 char* pStr;
253 int nLen;
255 pfFilter = fopen( cFilterName, "r" );
257 if ( !pfFilter )
259 ::bFilter = 0;
260 DumpError( 500 );
263 while( fgets( aBuf, MAX_MAN, pfFilter ) != 0 )
265 nLen = (int) strlen(aBuf);
266 pStr = new char[(unsigned int) nLen];
267 if ( !pStr )
268 DumpError( 98 );
269 memcpy( pStr, aBuf, (unsigned int) nLen );
270 if ( *(pStr+nLen-1) == '\n' )
271 *(pStr+nLen-1) = '\0';
272 pFilterLines[nFilterLines] = pStr;
273 nFilterLines++;
274 if ( nFilterLines >= MAXFILT )
275 DumpError( 510 );
278 fclose( pfFilter );
279 return true;
282 bool LibDump::PrintSym(char *pName, bool bName )
284 LibExport *pData;
287 // Filter auswerten
288 if ( Filter( pName ) )
290 if ( strlen( pName ) > 3 )
292 if ( bDef )
294 if (!bBase)
295 if (bExportName) {
296 fprintf( stdout, "\t%s\n", pName );
297 } else {
298 fprintf( stdout, "\t%s\t\t@%lu\n", pName, nDefStart );
300 else
302 pData = pBaseTab->Find( pName );
303 if ( pData )
305 pData->bExport = true;
306 if ( bName )
307 pData->bByName = true;
308 else
309 pData->bByName = false;
310 if ( bVerbose )
311 fprintf(stderr,".");
313 else
315 // neuen Export eintragen
316 pData = new LibExport;
317 pData->cExportName = new char[ strlen( pName ) + 1 ];
318 strcpy( pData->cExportName, pName );
319 pData->nOrdinal = nBaseLines++;
320 pData->bExport = true;
321 if ( bName )
322 pData->bByName = true;
323 else
324 pData->bByName = false;
325 pBaseTab->Insert( pData->cExportName, pData );
326 char *cBuffer = new char[ 30 ];
327 sprintf( cBuffer, "%lu", pData->nOrdinal );
328 pIndexTab->Insert( cBuffer, pData );
329 delete [] cBuffer;
330 if ( bVerbose )
331 fprintf(stderr,"n");
335 else
336 printf( "%s\n", pName );
337 nDefStart++;
340 return true;
343 bool LibDump::IsFromAnonymousNamespace (char *pExportName) {
344 char* pattern1 = "@?A0x";
346 if (strstr(pExportName, pattern1)) {
347 return true;
349 return false;
352 bool LibDump::Filter(char *pExportName)
354 unsigned long i;
355 char pTest[256];
357 // filter out symbols from anonymous namespaces
358 if (IsFromAnonymousNamespace (pExportName))
359 return false;
361 // Kein Filter gesetzt
362 if ( ::bFilter == 0 )
363 return true;
365 for ( i=0; i<nFilterLines; i++ )
367 //Zum vergleichen muá das Plus abgeschnitteb werden
368 if(pFilterLines[i][0] != '+')
370 if ( strstr( pExportName, pFilterLines[i]))
371 return false;
373 else
375 strcpy(pTest,&pFilterLines[i][1]);
376 if ( strstr( pExportName, pTest))
377 return true;
380 return true;
383 bool LibDump::SetFilter(char * cFilterName)
385 ReadFilter( cFilterName );
386 return true;
389 bool LibDump::CheckLibrary(char * cName)
391 delete [] cLibName;
392 cLibName = new char[ strlen( cName ) + 1 ];
393 strcpy( cLibName, cName );
394 return true;
397 bool LibDump::ReadDataBase()
399 FILE* pfBase = 0;
400 char aBuf[MAX_MAN];
401 char* pStr;
402 char cBuffer[ 30 ];
403 int nLen;
404 LibExport *pData;
406 pfBase = fopen( cBName, "r" );
408 if ( !pfBase )
410 bBase = 0;
411 DumpError( 600 );
414 bool bRet = true;
415 while( fgets( aBuf, MAX_MAN, pfBase ) != 0 )
417 nLen = (int) strlen(aBuf);
418 pStr = new char[(unsigned int) nLen];
419 if ( !pStr )
420 DumpError( 98 );
421 memcpy( pStr, aBuf, (size_t) nLen );
422 if ( *(pStr+nLen-1) == '\n' )
423 *(pStr+nLen-1) = '\0';
424 pData = new LibExport;
425 pData->cExportName = pStr;
426 pData->nOrdinal = nBaseLines;
427 pData->bExport=false;
429 if (pBaseTab->Insert(pData->cExportName, pData ) == NULL)
430 bRet = false;
431 ltoa( (long) pData->nOrdinal, cBuffer, 10 );
432 if (pIndexTab->Insert( cBuffer, pData ) == NULL)
433 bRet = false;
434 nBaseLines++;
435 if ( nBaseLines >= MAXBASE )
436 DumpError( 610 );
438 fclose( pfBase );
439 return bRet;
442 class ExportSetIter : public HashTableIterator
444 public:
445 ExportSetIter(HashTable const& aTable)
446 : HashTableIterator(aTable) {}
448 LibExport * GetFirst()
449 { return (LibExport *)HashTableIterator::GetFirst(); }
450 LibExport * GetNext()
451 { return (LibExport *)HashTableIterator::GetNext(); }
452 LibExport * GetLast()
453 { return (LibExport *)HashTableIterator::GetLast(); }
454 LibExport * GetPrev()
455 { return (LibExport *)HashTableIterator::GetPrev(); }
457 private:
458 void operator =(ExportSetIter &); // not defined
461 bool LibDump::PrintDataBase()
463 if (bExportName)
464 return true;
465 FILE *pFp;
466 pFp = fopen (cBName,"w+");
467 if (!pFp)
468 fprintf( stderr, "Error opening DataBase File\n" );
470 LibExport *pData;
471 for ( unsigned long i=0; i < nBaseLines+10; i++ )
473 char * cBuffer = new char[ 30 ];
474 sprintf( cBuffer, "%lu", i );
475 pData = pIndexTab->Find( cBuffer );
476 delete [] cBuffer;
477 if ( pData )
478 fprintf(pFp,"%s\n",pData->cExportName);
480 fclose(pFp);
481 return true;
484 bool LibDump::PrintDefFile()
486 #ifdef FAST
487 ExportSetIter aIterator( *pBaseTab );
488 for ( LibExport *pData = aIterator.GetFirst(); pData != NULL;
489 pData = aIterator.GetNext() )
491 if ( pData->bExport )
493 if ( pData->bByName )
495 fprintf(stdout,"\t%s\n",
496 pData->sExportName.GetBuffer());
498 else
500 fprintf(stdout,"\t%s\t\t@%d NONAME\n",
501 pData->sExportName.GetBuffer(), pData->nOrdinal+nBegin);
505 #else
506 // sortiert nach Ordinals;
507 LibExport *pData;
508 for ( unsigned long i=0; i<nBaseLines+1; i++)
510 char * cBuffer = new char[ 30 ];
511 sprintf( cBuffer, "%lu", i );
512 pData = pIndexTab->Find( cBuffer );
513 delete [] cBuffer;
514 if ( pData )
515 if ( pData->bExport )
517 if ( pData->bByName )
519 if ( strlen( pData->cExportName ))
520 fprintf(stdout,"\t%s\n",
521 pData->cExportName);
523 else
525 if ( strlen( pData->cExportName ))
526 fprintf(stdout,"\t%s\t\t@%d NONAME\n",
527 pData->cExportName, pData->nOrdinal+nBegin);
531 #endif
532 return true;
535 bool LibDump::CheckDataBase()
537 // existiert eine Datenbasis ?
538 if (!bBase)
540 cBName = new char[ 2048 ];
541 char *pTmp = "defs\\";
543 FILE *fp;
544 #ifdef OS2
545 _mkdir ("defs", 0777);
546 #else
547 _mkdir ("defs");
548 #endif
549 strcpy(cBName,pTmp);
550 #ifdef OS2
551 strcat(cBName,"gcc");
552 #else
553 strcat(cBName,getenv ("COMP_ENV"));
554 #endif
556 fp = fopen (cBName,"r");
557 if (fp)
559 bBase = true;
561 else
563 fp = fopen (cBName,"w+");
564 bBase = true;
566 fclose (fp);
568 // lese Datenbasis !
569 if (bBase)
571 ReadDataBase();
573 return true;
576 LibDump::~LibDump()
578 delete [] cBName;
579 delete [] cAPrefix;
580 // delete [] cLibName;
581 delete [] cFilterName;
582 delete [] cModName;
585 void LibDump::SetCExport( char* pName )
587 delete [] cAPrefix;
588 cAPrefix = new char[ strlen( pName ) + 1 ];
589 strcpy( cAPrefix, pName );bAll = true;
592 //******************************************************************
593 //* Error() - Gibt Fehlermeldumg aus
594 //******************************************************************
596 void LibDump::DumpError( unsigned long n )
598 char *p;
600 switch (n)
602 case 1: p = "Input error in library file"; break;
603 case 2: p = "Position error in library file (no THEADR set)"; break;
604 case 3: p = "Overflow of symbol table"; break;
605 #ifdef WNT
606 case 10: p = "EXP file not found"; break;
607 case 11: p = "No valid EXP file"; break;
608 #else
609 case 10: p = "Library file not found"; break;
610 case 11: p = "No valid library file"; break;
611 #endif
612 case 98: p = "Out of memory"; break;
613 case 99: p = "LDUMP [-LD3] [-D] [-N] [-A] [-E nn] [-F name] Filename[.LIB]\n"
614 "-LD3 : Supports feature set of ldump3 (default: ldump/ldump2)\n"
615 "-A : all symbols (default: only C++)\n"
616 "-E nn : gerenration of export table beginning with number nn\n"
617 "-F name: Filter file\n"
618 "-D : file contains \"dumpbin\" directives\n"
619 "-N : export by name\n"
620 "-V : be verbose\n"; break;
621 case 500: p = "Unable to open filter file\n"; break;
622 case 510: p = "Overflow of filter table\n"; break;
623 case 600: p = "Unable to open base database file\n"; break;
624 case 610: p = "Overflow in base database table\n"; break;
625 default: p = "Unspecified error";
627 fprintf( stdout, "%s\n", p );
628 exit (1);
631 /*********************************************************************
632 Test Funktionen
633 *********************************************************************/
636 void usage()
638 LibDump::DumpError(99);
641 #define STATE_NON 0x0000
642 #define STATE_BEGIN 0x0001
643 #define STATE_FILTER 0x0002
644 #define STATE_CEXPORT 0x0003
647 #ifdef WNT
648 __cdecl
649 #endif
650 main( int argc, char **argv )
652 char *pLibName = NULL, *pFilterName = NULL, *pCExport= NULL;
653 unsigned short nBegin=1;
655 unsigned short nState = STATE_NON;
657 if ( argc == 1 ) {
658 usage();
661 for ( int i = 1; i < argc; i++ ) {
662 if (( !strcmp( argv[ i ], "-H" )) ||
663 ( !strcmp( argv[ i ], "-h" )) ||
664 ( !strcmp( argv[ i ], "-?" )))
666 usage();
668 else if (( !strcmp( argv[ i ], "-LD3" )) ||
669 ( !strcmp( argv[ i ], "-Ld3" )) ||
670 ( !strcmp( argv[ i ], "-ld3" )) ||
671 ( !strcmp( argv[ i ], "-lD3" )))
673 if ( nState != STATE_NON ) {
674 usage();
676 bLdump3 = 1;
678 else if (( !strcmp( argv[ i ], "-E" )) || ( !strcmp( argv[ i ], "-e" ))) {
679 if ( nState != STATE_NON ) {
680 usage();
682 nState = STATE_BEGIN;
684 else if (( !strcmp( argv[ i ], "-F" )) || ( !strcmp( argv[ i ], "-f" ))) {
685 if ( nState != STATE_NON ) {
686 usage();
688 nState = STATE_FILTER;
690 else if (( !strcmp( argv[ i ], "-A" )) || ( !strcmp( argv[ i ], "-a" ))) {
691 if ( nState != STATE_NON ) {
692 usage();
694 nState = STATE_CEXPORT;
695 pCExport = new char[ 1 ];
696 pCExport[ 0 ] = 0;
698 else if (( !strcmp( argv[ i ], "-D" )) || ( !strcmp( argv[ i ], "-d" ))) {
699 if ( nState != STATE_NON ) {
700 usage();
702 bUseDirectives = 1;
704 else if (( !strcmp( argv[ i ], "-N" )) || ( !strcmp( argv[ i ], "-n" ))) {
705 if ( nState != STATE_NON ) {
706 usage();
708 bExportByName = 1;
710 else if (( !strcmp( argv[ i ], "-V" )) || ( !strcmp( argv[ i ], "-v" ))) {
711 if ( nState != STATE_NON ) {
712 usage();
714 bVerbose = 1;
716 else {
717 switch ( nState ) {
718 case STATE_BEGIN:
719 nBegin = static_cast< unsigned short >(atoi( argv[ i ] ));
720 nState = STATE_NON;
721 break;
722 case STATE_FILTER:
723 pFilterName = new char[ strlen( argv[ i ] ) + 1 ];
724 strcpy( pFilterName, argv[ i ] );
725 bFilter = 1;
726 nState = STATE_NON;
727 break;
728 case STATE_CEXPORT:
729 delete [] pCExport;
730 pCExport = new char[ strlen( argv[ i ] ) + 1 ];
731 strcpy( pCExport, argv[ i ] );
732 nState = STATE_NON;
733 break;
734 default:
735 pLibName = new char[ strlen( argv[ i ] ) + 1 ];
736 strcpy( pLibName, argv[ i ] );
737 break;
742 if ( !pLibName ) {
743 usage();
746 LibDump *pDump = new LibDump( pLibName, bExportByName );
747 pDump->SetBeginExport(nBegin);
748 if ( bFilter != 0 )
749 pDump->SetFilter( pFilterName );
750 if ( pCExport )
751 pDump->SetCExport( pCExport );
752 else {
753 char *pEmpty = "";
754 pDump->SetCExport( pEmpty );
756 pDump->Dump();
757 pDump->PrintDefFile();
758 pDump->PrintDataBase();
759 delete pDump;
760 return 0;