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"
37 #include "hashtbl.hxx"
45 int bUseDirectives
= 0;
47 int bExportByName
= 0;
49 class ExportSet
: public HashTable
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
)
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
);
95 cAPrefix
= new char[ 1 ];
108 pList
= fopen( cLibName
, "rb");
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);
124 // reading file containing symbols
125 while( !feof( pList
) )
128 if ( !bUseDirectives
)
130 // symbol komplett einlesen
133 int c
= fgetc( pList
);
138 if ( ((c
>= 33) && (c
<= 126)) && ( c
!=40 && c
!=41) )
139 aBuf
[i
] = static_cast< char >(c
);
152 fgets( aTmpBuf
, 4096, pList
);
156 pFound
= strchr( aTmpBuf
, 'E' );
159 if ( strncmp( "EXPORT:", pFound
, 7) == 0 )
162 pEnd
= strchr( pFound
, ',');
165 strncpy( aBuf
, pFound
, strlen( pFound
));
166 aBuf
[ strlen( pFound
) ] = '\0';
167 // fprintf( stderr, "\n--- %s\n", aBuf);
173 pFound
= strchr( pFound
, 'E' );
178 if ((aBuf
[0] =='?') || !strncmp(aBuf
, "__CT",4))
180 nLen
= (int) strlen(aBuf
);
181 memset( aName
, 0, sizeof( aName
) );
183 for( i
= 0; i
< nLen
; i
++ )
185 if ( (aBuf
[i
] != '\n') && (aBuf
[i
] != '\r') )
187 aName
[nName
] = aBuf
[i
];
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
) );
202 for( i
= 0; i
< nLen
; i
++ )
204 if ( (aBuf
[i
] != '\n') && (aBuf
[i
] != '\r') )
206 aName
[nName
] = aBuf
[i
];
210 //fprintf( stderr, "Gefundenen Prefix : %s %d \n", aTmpBuf, nPreLen );
212 nLen
= (int) strlen(aName
);
214 strcpy( aBuf
, &aName
[1] );
215 strncpy ( aTmpBuf
, aBuf
, (size_t) nPreLen
);
216 aTmpBuf
[nPreLen
] = '\0';
217 if ( !strcmp( aTmpBuf
, cAPrefix
))
221 char *pNeu
= strchr( aBuf
, nChar
);
222 int nPos
= pNeu
- aBuf
+ 1;
225 char aOldBuf
[MAX_MAN
];
226 strcpy( aOldBuf
, aBuf
);
228 strncpy( pChar
, aBuf
, (size_t) (nPos
-1) );
229 pChar
[nPos
-1] = '\0';
230 strcpy( aBuf
, pChar
);
232 strcat( aBuf
, aOldBuf
);
237 PrintSym( aBuf
, true );
245 bool LibDump::ReadFilter( char * cFilterName
)
252 pfFilter
= fopen( cFilterName
, "r" );
260 while( fgets( aBuf
, MAX_MAN
, pfFilter
) != 0 )
262 nLen
= (int) strlen(aBuf
);
263 pStr
= new char[(unsigned int) nLen
];
266 memcpy( pStr
, aBuf
, (unsigned int) nLen
);
267 if ( *(pStr
+nLen
-1) == '\n' )
268 *(pStr
+nLen
-1) = '\0';
269 pFilterLines
[nFilterLines
] = pStr
;
271 if ( nFilterLines
>= MAXFILT
)
279 bool LibDump::PrintSym(char *pName
, bool bName
)
285 if ( Filter( pName
) )
287 if ( strlen( pName
) > 3 )
293 fprintf( stdout
, "\t%s\n", pName
);
295 fprintf( stdout
, "\t%s\t\t@%lu\n", pName
, nDefStart
);
299 pData
= pBaseTab
->Find( pName
);
302 pData
->bExport
= true;
304 pData
->bByName
= true;
306 pData
->bByName
= false;
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;
319 pData
->bByName
= true;
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
);
333 printf( "%s\n", pName
);
340 bool LibDump::IsFromAnonymousNamespace (char *pExportName
) {
341 char* pattern1
= "@?A0x";
343 if (strstr(pExportName
, pattern1
)) {
349 bool LibDump::Filter(char *pExportName
)
354 // filter out symbols from anonymous namespaces
355 if (IsFromAnonymousNamespace (pExportName
))
358 // Kein Filter gesetzt
359 if ( ::bFilter
== 0 )
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
]))
372 strcpy(pTest
,&pFilterLines
[i
][1]);
373 if ( strstr( pExportName
, pTest
))
380 bool LibDump::SetFilter(char * cFilterName
)
382 ReadFilter( cFilterName
);
386 bool LibDump::CheckLibrary(char * cName
)
389 cLibName
= new char[ strlen( cName
) + 1 ];
390 strcpy( cLibName
, cName
);
394 bool LibDump::ReadDataBase()
403 pfBase
= fopen( cBName
, "r" );
412 while( fgets( aBuf
, MAX_MAN
, pfBase
) != 0 )
414 nLen
= (int) strlen(aBuf
);
415 pStr
= new char[(unsigned int) nLen
];
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
)
428 ltoa( (long) pData
->nOrdinal
, cBuffer
, 10 );
429 if (pIndexTab
->Insert( cBuffer
, pData
) == NULL
)
432 if ( nBaseLines
>= MAXBASE
)
439 class ExportSetIter
: public HashTableIterator
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(); }
455 void operator =(ExportSetIter
&); // not defined
458 bool LibDump::PrintDataBase()
463 pFp
= fopen (cBName
,"w+");
465 fprintf( stderr
, "Error opening DataBase File\n" );
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
);
475 fprintf(pFp
,"%s\n",pData
->cExportName
);
481 bool LibDump::PrintDefFile()
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());
497 fprintf(stdout
,"\t%s\t\t@%d NONAME\n",
498 pData
->sExportName
.GetBuffer(), pData
->nOrdinal
+nBegin
);
503 // sortiert nach Ordinals;
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
);
512 if ( pData
->bExport
)
514 if ( pData
->bByName
)
516 if ( strlen( pData
->cExportName
))
517 fprintf(stdout
,"\t%s\n",
522 if ( strlen( pData
->cExportName
))
523 fprintf(stdout
,"\t%s\t\t@%d NONAME\n",
524 pData
->cExportName
, pData
->nOrdinal
+nBegin
);
532 bool LibDump::CheckDataBase()
534 // existiert eine Datenbasis ?
537 cBName
= new char[ 2048 ];
538 char *pTmp
= "defs\\";
542 _mkdir ("defs", 0777);
548 strcat(cBName
,"gcc");
550 strcat(cBName
,getenv ("COMP_ENV"));
553 fp
= fopen (cBName
,"r");
560 fp
= fopen (cBName
,"w+");
577 // delete [] cLibName;
578 delete [] cFilterName
;
582 void LibDump::SetCExport( char* pName
)
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
)
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;
603 case 10: p
= "EXP file not found"; break;
604 case 11: p
= "No valid EXP file"; break;
606 case 10: p
= "Library file not found"; break;
607 case 11: p
= "No valid library file"; break;
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
);
628 /*********************************************************************
630 *********************************************************************/
635 LibDump::DumpError(99);
638 #define STATE_NON 0x0000
639 #define STATE_BEGIN 0x0001
640 #define STATE_FILTER 0x0002
641 #define STATE_CEXPORT 0x0003
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
;
658 for ( int i
= 1; i
< argc
; i
++ ) {
659 if (( !strcmp( argv
[ i
], "-H" )) ||
660 ( !strcmp( argv
[ i
], "-h" )) ||
661 ( !strcmp( argv
[ i
], "-?" )))
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
) {
675 else if (( !strcmp( argv
[ i
], "-E" )) || ( !strcmp( argv
[ i
], "-e" ))) {
676 if ( nState
!= STATE_NON
) {
679 nState
= STATE_BEGIN
;
681 else if (( !strcmp( argv
[ i
], "-F" )) || ( !strcmp( argv
[ i
], "-f" ))) {
682 if ( nState
!= STATE_NON
) {
685 nState
= STATE_FILTER
;
687 else if (( !strcmp( argv
[ i
], "-A" )) || ( !strcmp( argv
[ i
], "-a" ))) {
688 if ( nState
!= STATE_NON
) {
691 nState
= STATE_CEXPORT
;
692 pCExport
= new char[ 1 ];
695 else if (( !strcmp( argv
[ i
], "-D" )) || ( !strcmp( argv
[ i
], "-d" ))) {
696 if ( nState
!= STATE_NON
) {
701 else if (( !strcmp( argv
[ i
], "-N" )) || ( !strcmp( argv
[ i
], "-n" ))) {
702 if ( nState
!= STATE_NON
) {
707 else if (( !strcmp( argv
[ i
], "-V" )) || ( !strcmp( argv
[ i
], "-v" ))) {
708 if ( nState
!= STATE_NON
) {
716 nBegin
= static_cast< unsigned short >(atoi( argv
[ i
] ));
720 pFilterName
= new char[ strlen( argv
[ i
] ) + 1 ];
721 strcpy( pFilterName
, argv
[ i
] );
727 pCExport
= new char[ strlen( argv
[ i
] ) + 1 ];
728 strcpy( pCExport
, argv
[ i
] );
732 pLibName
= new char[ strlen( argv
[ i
] ) + 1 ];
733 strcpy( pLibName
, argv
[ i
] );
743 LibDump
*pDump
= new LibDump( pLibName
, bExportByName
);
744 pDump
->SetBeginExport(nBegin
);
746 pDump
->SetFilter( pFilterName
);
748 pDump
->SetCExport( pCExport
);
751 pDump
->SetCExport( pEmpty
);
754 pDump
->PrintDefFile();
755 pDump
->PrintDataBase();