1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ldump.cxx,v $
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"
40 #include "hashtbl.hxx"
48 int bUseDirectives
= 0;
50 int bExportByName
= 0;
52 class ExportSet
: public HashTable
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
)
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
);
98 cAPrefix
= new char[ 1 ];
111 pList
= fopen( cLibName
, "rb");
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);
127 // reading file containing symbols
128 while( !feof( pList
) )
131 if ( !bUseDirectives
)
133 // symbol komplett einlesen
136 int c
= fgetc( pList
);
141 if ( ((c
>= 33) && (c
<= 126)) && ( c
!=40 && c
!=41) )
142 aBuf
[i
] = static_cast< char >(c
);
155 fgets( aTmpBuf
, 4096, pList
);
159 pFound
= strchr( aTmpBuf
, 'E' );
162 if ( strncmp( "EXPORT:", pFound
, 7) == 0 )
165 pEnd
= strchr( pFound
, ',');
168 strncpy( aBuf
, pFound
, strlen( pFound
));
169 aBuf
[ strlen( pFound
) ] = '\0';
170 // fprintf( stderr, "\n--- %s\n", aBuf);
176 pFound
= strchr( pFound
, 'E' );
181 if ((aBuf
[0] =='?') || !strncmp(aBuf
, "__CT",4))
183 nLen
= (int) strlen(aBuf
);
184 memset( aName
, 0, sizeof( aName
) );
186 for( i
= 0; i
< nLen
; i
++ )
188 if ( (aBuf
[i
] != '\n') && (aBuf
[i
] != '\r') )
190 aName
[nName
] = aBuf
[i
];
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
) );
205 for( i
= 0; i
< nLen
; i
++ )
207 if ( (aBuf
[i
] != '\n') && (aBuf
[i
] != '\r') )
209 aName
[nName
] = aBuf
[i
];
213 //fprintf( stderr, "Gefundenen Prefix : %s %d \n", aTmpBuf, nPreLen );
215 nLen
= (int) strlen(aName
);
217 strcpy( aBuf
, &aName
[1] );
218 strncpy ( aTmpBuf
, aBuf
, (size_t) nPreLen
);
219 aTmpBuf
[nPreLen
] = '\0';
220 if ( !strcmp( aTmpBuf
, cAPrefix
))
224 char *pNeu
= strchr( aBuf
, nChar
);
225 int nPos
= pNeu
- aBuf
+ 1;
228 char aOldBuf
[MAX_MAN
];
229 strcpy( aOldBuf
, aBuf
);
231 strncpy( pChar
, aBuf
, (size_t) (nPos
-1) );
232 pChar
[nPos
-1] = '\0';
233 strcpy( aBuf
, pChar
);
235 strcat( aBuf
, aOldBuf
);
240 PrintSym( aBuf
, true );
248 bool LibDump::ReadFilter( char * cFilterName
)
255 pfFilter
= fopen( cFilterName
, "r" );
263 while( fgets( aBuf
, MAX_MAN
, pfFilter
) != 0 )
265 nLen
= (int) strlen(aBuf
);
266 pStr
= new char[(unsigned int) nLen
];
269 memcpy( pStr
, aBuf
, (unsigned int) nLen
);
270 if ( *(pStr
+nLen
-1) == '\n' )
271 *(pStr
+nLen
-1) = '\0';
272 pFilterLines
[nFilterLines
] = pStr
;
274 if ( nFilterLines
>= MAXFILT
)
282 bool LibDump::PrintSym(char *pName
, bool bName
)
288 if ( Filter( pName
) )
290 if ( strlen( pName
) > 3 )
296 fprintf( stdout
, "\t%s\n", pName
);
298 fprintf( stdout
, "\t%s\t\t@%lu\n", pName
, nDefStart
);
302 pData
= pBaseTab
->Find( pName
);
305 pData
->bExport
= true;
307 pData
->bByName
= true;
309 pData
->bByName
= false;
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;
322 pData
->bByName
= true;
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
);
336 printf( "%s\n", pName
);
343 bool LibDump::IsFromAnonymousNamespace (char *pExportName
) {
344 char* pattern1
= "@?A0x";
346 if (strstr(pExportName
, pattern1
)) {
352 bool LibDump::Filter(char *pExportName
)
357 // filter out symbols from anonymous namespaces
358 if (IsFromAnonymousNamespace (pExportName
))
361 // Kein Filter gesetzt
362 if ( ::bFilter
== 0 )
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
]))
375 strcpy(pTest
,&pFilterLines
[i
][1]);
376 if ( strstr( pExportName
, pTest
))
383 bool LibDump::SetFilter(char * cFilterName
)
385 ReadFilter( cFilterName
);
389 bool LibDump::CheckLibrary(char * cName
)
392 cLibName
= new char[ strlen( cName
) + 1 ];
393 strcpy( cLibName
, cName
);
397 bool LibDump::ReadDataBase()
406 pfBase
= fopen( cBName
, "r" );
415 while( fgets( aBuf
, MAX_MAN
, pfBase
) != 0 )
417 nLen
= (int) strlen(aBuf
);
418 pStr
= new char[(unsigned int) nLen
];
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
)
431 ltoa( (long) pData
->nOrdinal
, cBuffer
, 10 );
432 if (pIndexTab
->Insert( cBuffer
, pData
) == NULL
)
435 if ( nBaseLines
>= MAXBASE
)
442 class ExportSetIter
: public HashTableIterator
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(); }
458 void operator =(ExportSetIter
&); // not defined
461 bool LibDump::PrintDataBase()
466 pFp
= fopen (cBName
,"w+");
468 fprintf( stderr
, "Error opening DataBase File\n" );
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
);
478 fprintf(pFp
,"%s\n",pData
->cExportName
);
484 bool LibDump::PrintDefFile()
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());
500 fprintf(stdout
,"\t%s\t\t@%d NONAME\n",
501 pData
->sExportName
.GetBuffer(), pData
->nOrdinal
+nBegin
);
506 // sortiert nach Ordinals;
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
);
515 if ( pData
->bExport
)
517 if ( pData
->bByName
)
519 if ( strlen( pData
->cExportName
))
520 fprintf(stdout
,"\t%s\n",
525 if ( strlen( pData
->cExportName
))
526 fprintf(stdout
,"\t%s\t\t@%d NONAME\n",
527 pData
->cExportName
, pData
->nOrdinal
+nBegin
);
535 bool LibDump::CheckDataBase()
537 // existiert eine Datenbasis ?
540 cBName
= new char[ 2048 ];
541 char *pTmp
= "defs\\";
545 _mkdir ("defs", 0777);
551 strcat(cBName
,"gcc");
553 strcat(cBName
,getenv ("COMP_ENV"));
556 fp
= fopen (cBName
,"r");
563 fp
= fopen (cBName
,"w+");
580 // delete [] cLibName;
581 delete [] cFilterName
;
585 void LibDump::SetCExport( char* pName
)
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
)
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;
606 case 10: p
= "EXP file not found"; break;
607 case 11: p
= "No valid EXP file"; break;
609 case 10: p
= "Library file not found"; break;
610 case 11: p
= "No valid library file"; break;
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
);
631 /*********************************************************************
633 *********************************************************************/
638 LibDump::DumpError(99);
641 #define STATE_NON 0x0000
642 #define STATE_BEGIN 0x0001
643 #define STATE_FILTER 0x0002
644 #define STATE_CEXPORT 0x0003
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
;
661 for ( int i
= 1; i
< argc
; i
++ ) {
662 if (( !strcmp( argv
[ i
], "-H" )) ||
663 ( !strcmp( argv
[ i
], "-h" )) ||
664 ( !strcmp( argv
[ i
], "-?" )))
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
) {
678 else if (( !strcmp( argv
[ i
], "-E" )) || ( !strcmp( argv
[ i
], "-e" ))) {
679 if ( nState
!= STATE_NON
) {
682 nState
= STATE_BEGIN
;
684 else if (( !strcmp( argv
[ i
], "-F" )) || ( !strcmp( argv
[ i
], "-f" ))) {
685 if ( nState
!= STATE_NON
) {
688 nState
= STATE_FILTER
;
690 else if (( !strcmp( argv
[ i
], "-A" )) || ( !strcmp( argv
[ i
], "-a" ))) {
691 if ( nState
!= STATE_NON
) {
694 nState
= STATE_CEXPORT
;
695 pCExport
= new char[ 1 ];
698 else if (( !strcmp( argv
[ i
], "-D" )) || ( !strcmp( argv
[ i
], "-d" ))) {
699 if ( nState
!= STATE_NON
) {
704 else if (( !strcmp( argv
[ i
], "-N" )) || ( !strcmp( argv
[ i
], "-n" ))) {
705 if ( nState
!= STATE_NON
) {
710 else if (( !strcmp( argv
[ i
], "-V" )) || ( !strcmp( argv
[ i
], "-v" ))) {
711 if ( nState
!= STATE_NON
) {
719 nBegin
= static_cast< unsigned short >(atoi( argv
[ i
] ));
723 pFilterName
= new char[ strlen( argv
[ i
] ) + 1 ];
724 strcpy( pFilterName
, argv
[ i
] );
730 pCExport
= new char[ strlen( argv
[ i
] ) + 1 ];
731 strcpy( pCExport
, argv
[ i
] );
735 pLibName
= new char[ strlen( argv
[ i
] ) + 1 ];
736 strcpy( pLibName
, argv
[ i
] );
746 LibDump
*pDump
= new LibDump( pLibName
, bExportByName
);
747 pDump
->SetBeginExport(nBegin
);
749 pDump
->SetFilter( pFilterName
);
751 pDump
->SetCExport( pCExport
);
754 pDump
->SetCExport( pEmpty
);
757 pDump
->PrintDefFile();
758 pDump
->PrintDataBase();