1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
36 #include "hashtbl.hxx"
44 int bUseDirectives
= 0;
46 int bExportByName
= 0;
48 class ExportSet
: public HashTable
54 double dMaxLoadFactor
= HashTable::m_defMaxLoadFactor
,
55 double dGrowFactor
= HashTable::m_defDefGrowFactor
57 : HashTable(lSize
,false,dMaxLoadFactor
,dGrowFactor
) {}
59 virtual ~ExportSet() {}
61 LibExport
* Find (char * const& Key
) const
62 { return (LibExport
*) HashTable::Find((char *) Key
); }
64 bool Insert (char * const& Key
, LibExport
* Object
)
65 { return HashTable::Insert((char *) Key
, (void*) Object
); }
67 LibExport
* Delete (char * const&Key
)
68 { return (LibExport
*) HashTable::Delete ((char *) Key
); }
71 LibDump::LibDump( char *cFileName
, int bExportByName
)
78 fprintf( stderr
, "LIB-NT File Dumper v4.00 (C) 2000 Sun Microsystems, Inc.\n\n" );
79 fprintf( stderr
, "%s ", cFileName
);
81 bExportName
= bExportByName
;
83 unsigned long nSlots
= 0xfffff;
84 pBaseTab
= new ExportSet( nSlots
);
85 pIndexTab
= new ExportSet( nSlots
);
86 pFilterLines
= new char * [MAXFILT
];
87 CheckLibrary(cFileName
);
94 cAPrefix
= new char[ 1 ];
107 pList
= fopen( cLibName
, "rb");
111 // forget about offset when working on linker directives
112 if ( !bUseDirectives
)
114 // calculating offset for name section
115 unsigned char TmpBuffer
[4];
116 fread( TmpBuffer
, 1, 4, pList
);
117 // anzahl bigendian mal laenge + ueberspringen der naechsten laengenangabe
118 unsigned long nOffSet
= (unsigned long) ( TmpBuffer
[2] * 256 + TmpBuffer
[3] ) * 4 + 4;
119 fseek( pList
, (long) nOffSet
, 0);
123 // reading file containing symbols
124 while( !feof( pList
) )
127 if ( !bUseDirectives
)
129 // symbol komplett einlesen
132 int c
= fgetc( pList
);
137 if ( ((c
>= 33) && (c
<= 126)) && ( c
!=40 && c
!=41) )
138 aBuf
[i
] = static_cast< char >(c
);
151 fgets( aTmpBuf
, 4096, pList
);
155 pFound
= strchr( aTmpBuf
, 'E' );
158 if ( strncmp( "EXPORT:", pFound
, 7) == 0 )
161 pEnd
= strchr( pFound
, ',');
164 strncpy( aBuf
, pFound
, strlen( pFound
));
165 aBuf
[ strlen( pFound
) ] = '\0';
171 pFound
= strchr( pFound
, 'E' );
178 nLen
= (int) strlen(aBuf
);
179 memset( aName
, 0, sizeof( aName
) );
181 for( i
= 0; i
< nLen
; i
++ )
183 if ( (aBuf
[i
] != '\n') && (aBuf
[i
] != '\r') )
185 aName
[nName
] = aBuf
[i
];
190 PrintSym( aName
, bExportByName
);
192 else if ( bAll
== true &&
193 strncmp(aBuf
, "__real@", 7) != 0 &&
194 strncmp(aBuf
, "__CT",4) != 0 &&
195 strncmp(aBuf
, "__TI3?", 6) != 0 )
197 int nPreLen
= (int) strlen( cAPrefix
);
199 nLen
= (int) strlen(aBuf
);
200 memset( aName
, 0, sizeof( aName
) );
203 for( i
= 0; i
< nLen
; i
++ )
205 if ( (aBuf
[i
] != '\n') && (aBuf
[i
] != '\r') )
207 aName
[nName
] = aBuf
[i
];
212 nLen
= (int) strlen(aName
);
215 strcpy( aBuf
, &aName
[1] );
217 strncpy ( aTmpBuf
, aBuf
, (size_t) nPreLen
);
218 aTmpBuf
[nPreLen
] = '\0';
219 if ( !strcmp( aTmpBuf
, cAPrefix
))
223 char *pNeu
= strchr( aBuf
, nChar
);
224 size_t nPos
= pNeu
- aBuf
+ 1;
227 char aOldBuf
[MAX_MAN
];
228 strcpy( aOldBuf
, aBuf
);
230 strncpy( pChar
, aBuf
, nPos
- 1 );
231 pChar
[nPos
-1] = '\0';
232 strcpy( aBuf
, pChar
);
234 strcat( aBuf
, aOldBuf
);
239 PrintSym( aBuf
, true );
247 bool LibDump::ReadFilter( char * cFilterName
)
254 pfFilter
= fopen( cFilterName
, "r" );
262 while( fgets( aBuf
, MAX_MAN
, pfFilter
) != 0 )
264 nLen
= (int) strlen(aBuf
);
265 pStr
= new char[(unsigned int) nLen
];
268 memcpy( pStr
, aBuf
, (unsigned int) nLen
);
269 if ( *(pStr
+nLen
-1) == '\n' )
270 *(pStr
+nLen
-1) = '\0';
271 pFilterLines
[nFilterLines
] = pStr
;
273 if ( nFilterLines
>= MAXFILT
)
281 bool LibDump::PrintSym(char *pName
, bool bName
)
287 if ( Filter( pName
) )
289 if ( strlen( pName
) > 3 )
295 fprintf( stdout
, "\t%s\n", pName
);
297 fprintf( stdout
, "\t%s\t\t@%lu\n", pName
, nDefStart
);
301 pData
= pBaseTab
->Find( pName
);
304 pData
->bExport
= true;
306 pData
->bByName
= true;
308 pData
->bByName
= false;
314 // neuen Export eintragen
315 pData
= new LibExport
;
316 pData
->cExportName
= new char[ strlen( pName
) + 1 ];
317 strcpy( pData
->cExportName
, pName
);
318 pData
->nOrdinal
= nBaseLines
++;
319 pData
->bExport
= true;
321 pData
->bByName
= true;
323 pData
->bByName
= false;
324 pBaseTab
->Insert( pData
->cExportName
, pData
);
325 char *cBuffer
= new char[ 30 ];
326 sprintf( cBuffer
, "%lu", pData
->nOrdinal
);
327 pIndexTab
->Insert( cBuffer
, pData
);
335 printf( "%s\n", pName
);
342 bool LibDump::IsFromAnonymousNamespace (char *pExportName
) {
343 char* pattern1
= "@?A0x";
345 if (strstr(pExportName
, pattern1
)) {
351 bool LibDump::Filter(char *pExportName
)
356 // filter out symbols from anonymous namespaces
357 if (IsFromAnonymousNamespace (pExportName
))
360 // Kein Filter gesetzt
361 if ( ::bFilter
== 0 )
364 for ( i
=0; i
<nFilterLines
; i
++ )
366 //Zum vergleichen muá das Plus abgeschnitteb werden
367 if(pFilterLines
[i
][0] != '+')
369 if ( strstr( pExportName
, pFilterLines
[i
]))
374 strcpy(pTest
,&pFilterLines
[i
][1]);
375 if ( strstr( pExportName
, pTest
))
382 bool LibDump::SetFilter(char * cFilterName
)
384 ReadFilter( cFilterName
);
388 bool LibDump::CheckLibrary(char * cName
)
391 cLibName
= new char[ strlen( cName
) + 1 ];
392 strcpy( cLibName
, cName
);
396 bool LibDump::ReadDataBase()
405 pfBase
= fopen( cBName
, "r" );
414 while( fgets( aBuf
, MAX_MAN
, pfBase
) != 0 )
416 nLen
= (int) strlen(aBuf
);
417 pStr
= new char[(unsigned int) nLen
];
420 memcpy( pStr
, aBuf
, (size_t) nLen
);
421 if ( *(pStr
+nLen
-1) == '\n' )
422 *(pStr
+nLen
-1) = '\0';
423 pData
= new LibExport
;
424 pData
->cExportName
= pStr
;
425 pData
->nOrdinal
= nBaseLines
;
426 pData
->bExport
=false;
428 if (pBaseTab
->Insert(pData
->cExportName
, pData
) == NULL
)
430 ltoa( (long) pData
->nOrdinal
, cBuffer
, 10 );
431 if (pIndexTab
->Insert( cBuffer
, pData
) == NULL
)
434 if ( nBaseLines
>= MAXBASE
)
441 class ExportSetIter
: public HashTableIterator
444 ExportSetIter(HashTable
const& aTable
)
445 : HashTableIterator(aTable
) {}
447 LibExport
* GetFirst()
448 { return (LibExport
*)HashTableIterator::GetFirst(); }
449 LibExport
* GetNext()
450 { return (LibExport
*)HashTableIterator::GetNext(); }
451 LibExport
* GetLast()
452 { return (LibExport
*)HashTableIterator::GetLast(); }
453 LibExport
* GetPrev()
454 { return (LibExport
*)HashTableIterator::GetPrev(); }
457 void operator =(ExportSetIter
&); // not defined
460 bool LibDump::PrintDataBase()
465 pFp
= fopen (cBName
,"w+");
467 fprintf( stderr
, "Error opening DataBase File\n" );
470 for ( unsigned long i
=0; i
< nBaseLines
+10; i
++ )
472 char * cBuffer
= new char[ 30 ];
473 sprintf( cBuffer
, "%lu", i
);
474 pData
= pIndexTab
->Find( cBuffer
);
477 fprintf(pFp
,"%s\n",pData
->cExportName
);
483 bool LibDump::PrintDefFile()
486 ExportSetIter
aIterator( *pBaseTab
);
487 for ( LibExport
*pData
= aIterator
.GetFirst(); pData
!= NULL
;
488 pData
= aIterator
.GetNext() )
490 if ( pData
->bExport
)
492 if ( pData
->bByName
)
494 fprintf(stdout
,"\t%s\n",
495 pData
->sExportName
.GetBuffer());
499 fprintf(stdout
,"\t%s\t\t@%d NONAME\n",
500 pData
->sExportName
.GetBuffer(), pData
->nOrdinal
+nBegin
);
505 // sortiert nach Ordinals;
507 for ( unsigned long i
=0; i
<nBaseLines
+1; i
++)
509 char * cBuffer
= new char[ 30 ];
510 sprintf( cBuffer
, "%lu", i
);
511 pData
= pIndexTab
->Find( cBuffer
);
514 if ( pData
->bExport
)
516 if ( pData
->bByName
)
518 if ( strlen( pData
->cExportName
))
519 fprintf(stdout
,"\t%s\n",
524 if ( strlen( pData
->cExportName
))
525 fprintf(stdout
,"\t%s\t\t@%d NONAME\n",
526 pData
->cExportName
, pData
->nOrdinal
+nBegin
);
534 bool LibDump::CheckDataBase()
536 // existiert eine Datenbasis ?
539 cBName
= new char[ 2048 ];
540 char *pTmp
= "defs\\";
545 strcat(cBName
,getenv ("COMP_ENV"));
547 fp
= fopen (cBName
,"r");
554 fp
= fopen (cBName
,"w+");
571 delete [] cFilterName
;
575 void LibDump::SetCExport( char* pName
)
578 cAPrefix
= new char[ strlen( pName
) + 1 ];
579 strcpy( cAPrefix
, pName
);bAll
= true;
582 //******************************************************************
583 //* Error() - Gibt Fehlermeldumg aus
584 //******************************************************************
586 void LibDump::DumpError( unsigned long n
)
592 case 1: p
= "Input error in library file"; break;
593 case 2: p
= "Position error in library file (no THEADR set)"; break;
594 case 3: p
= "Overflow of symbol table"; break;
596 case 10: p
= "EXP file not found"; break;
597 case 11: p
= "No valid EXP file"; break;
599 case 10: p
= "Library file not found"; break;
600 case 11: p
= "No valid library file"; break;
602 case 98: p
= "Out of memory"; break;
603 case 99: p
= "LDUMP [-LD3] [-D] [-N] [-A] [-E nn] [-F name] Filename[.LIB]\n"
604 "-LD3 : Supports feature set of ldump3 (default: ldump/ldump2)\n"
605 "-A : all symbols (default: only C++)\n"
606 "-E nn : gerenration of export table beginning with number nn\n"
607 "-F name: Filter file\n"
608 "-D : file contains \"dumpbin\" directives\n"
609 "-N : export by name\n"
610 "-V : be verbose\n"; break;
611 case 500: p
= "Unable to open filter file\n"; break;
612 case 510: p
= "Overflow of filter table\n"; break;
613 case 600: p
= "Unable to open base database file\n"; break;
614 case 610: p
= "Overflow in base database table\n"; break;
615 default: p
= "Unspecified error";
617 fprintf( stdout
, "%s\n", p
);
621 /*********************************************************************
623 *********************************************************************/
628 LibDump::DumpError(99);
631 #define STATE_NON 0x0000
632 #define STATE_BEGIN 0x0001
633 #define STATE_FILTER 0x0002
634 #define STATE_CEXPORT 0x0003
640 main( int argc
, char **argv
)
642 char *pLibName
= NULL
, *pFilterName
= NULL
, *pCExport
= NULL
;
643 unsigned short nBegin
=1;
645 unsigned short nState
= STATE_NON
;
651 for ( int i
= 1; i
< argc
; i
++ ) {
652 if (( !strcmp( argv
[ i
], "-H" )) ||
653 ( !strcmp( argv
[ i
], "-h" )) ||
654 ( !strcmp( argv
[ i
], "-?" )))
658 else if (( !strcmp( argv
[ i
], "-LD3" )) ||
659 ( !strcmp( argv
[ i
], "-Ld3" )) ||
660 ( !strcmp( argv
[ i
], "-ld3" )) ||
661 ( !strcmp( argv
[ i
], "-lD3" )))
663 if ( nState
!= STATE_NON
) {
668 else if (( !strcmp( argv
[ i
], "-E" )) || ( !strcmp( argv
[ i
], "-e" ))) {
669 if ( nState
!= STATE_NON
) {
672 nState
= STATE_BEGIN
;
674 else if (( !strcmp( argv
[ i
], "-F" )) || ( !strcmp( argv
[ i
], "-f" ))) {
675 if ( nState
!= STATE_NON
) {
678 nState
= STATE_FILTER
;
680 else if (( !strcmp( argv
[ i
], "-A" )) || ( !strcmp( argv
[ i
], "-a" ))) {
681 if ( nState
!= STATE_NON
) {
684 nState
= STATE_CEXPORT
;
685 pCExport
= new char[ 1 ];
688 else if (( !strcmp( argv
[ i
], "-D" )) || ( !strcmp( argv
[ i
], "-d" ))) {
689 if ( nState
!= STATE_NON
) {
694 else if (( !strcmp( argv
[ i
], "-N" )) || ( !strcmp( argv
[ i
], "-n" ))) {
695 if ( nState
!= STATE_NON
) {
700 else if (( !strcmp( argv
[ i
], "-V" )) || ( !strcmp( argv
[ i
], "-v" ))) {
701 if ( nState
!= STATE_NON
) {
709 nBegin
= static_cast< unsigned short >(atoi( argv
[ i
] ));
713 pFilterName
= new char[ strlen( argv
[ i
] ) + 1 ];
714 strcpy( pFilterName
, argv
[ i
] );
720 pCExport
= new char[ strlen( argv
[ i
] ) + 1 ];
721 strcpy( pCExport
, argv
[ i
] );
725 pLibName
= new char[ strlen( argv
[ i
] ) + 1 ];
726 strcpy( pLibName
, argv
[ i
] );
736 LibDump
*pDump
= new LibDump( pLibName
, bExportByName
);
737 pDump
->SetBeginExport(nBegin
);
739 pDump
->SetFilter( pFilterName
);
741 pDump
->SetCExport( pCExport
);
744 pDump
->SetCExport( pEmpty
);
747 pDump
->PrintDefFile();
748 pDump
->PrintDataBase();
754 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */