Bump for 3.6-28
[LibreOffice.git] / soltools / ldump / ldump.cxx
blobe16338aa30326fcd20d2a5697077166104f47060
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 ************************************************************************/
30 #include <string.h>
31 #include <direct.h>
32 #include <stdio.h>
33 #include <stdlib.h>
35 #include "ldump.hxx"
36 #include "hashtbl.hxx"
38 #define MAXSYM 65536
39 #define MAXBASE 98304
40 #define MAX_MAN 4096
42 int bFilter = 0;
43 int bLdump3 = 0;
44 int bUseDirectives = 0;
45 int bVerbose = 0;
46 int bExportByName = 0;
48 class ExportSet : public HashTable
50 public:
51 ExportSet
53 unsigned long lSize,
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 )
72 : cBName( NULL ),
73 cAPrefix( NULL ),
74 cLibName( NULL ),
75 cFilterName( NULL ),
76 cModName( NULL )
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);
88 bBase = 0;
89 bAll = false;
90 nDefStart = 0;
91 nBaseLines = 0;
92 nFilterLines = 0;
93 bDef = true;
94 cAPrefix = new char[ 1 ];
95 cAPrefix[ 0 ] = 0;
96 if (!bExportName)
97 CheckDataBase();
100 bool LibDump::Dump()
102 FILE *pList;
103 char aBuf[MAX_MAN];
104 int nLen;
105 char aName[MAX_MAN];
107 pList = fopen( cLibName, "rb");
108 if (!pList)
109 DumpError(10);
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);
122 char aTmpBuf[4096];
123 // reading file containing symbols
124 while( !feof( pList ) )
126 int i = 0;
127 if ( !bUseDirectives )
129 // symbol komplett einlesen
130 for (;;)
132 int c = fgetc( pList );
133 if ( c == '\0' )
135 break;
137 if ( ((c >= 33) && (c <= 126)) && ( c!=40 && c!=41) )
138 aBuf[i] = static_cast< char >(c);
139 else
141 aBuf[0] = '\0';
142 break;
144 i++;
146 // Namen found
147 aBuf[i] = '\0';
149 else
151 fgets( aTmpBuf, 4096, pList );
152 char * pEnd = 0;
153 char *pFound = 0;
154 aBuf[0] = '\0';
155 pFound = strchr( aTmpBuf, 'E' );
156 while ( pFound )
158 if ( strncmp( "EXPORT:", pFound, 7) == 0 )
160 pFound += 7;
161 pEnd = strchr( pFound, ',');
162 if ( pEnd )
163 *pEnd = '\0';
164 strncpy( aBuf, pFound, strlen( pFound));
165 aBuf[ strlen( pFound) ] = '\0';
166 break;
168 else
170 pFound++;
171 pFound = strchr( pFound, 'E' );
176 if (aBuf[0] =='?')
178 nLen = (int) strlen(aBuf);
179 memset( aName, 0, sizeof( aName ) );
180 int nName = 0;
181 for( i = 0; i < nLen; i++ )
183 if ( (aBuf[i] != '\n') && (aBuf[i] != '\r') )
185 aName[nName] = aBuf[i];
186 nName++;
189 // und raus damit
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 ) );
201 int nName = 0;
203 for( i = 0; i < nLen; i++ )
205 if ( (aBuf[i] != '\n') && (aBuf[i] != '\r') )
207 aName[nName] = aBuf[i];
208 nName++;
211 // den ersten _ raus
212 nLen = (int) strlen(aName);
213 #ifndef _WIN64
214 if (aName[0] == '_')
215 strcpy( aBuf , &aName[1] );
216 #endif
217 strncpy ( aTmpBuf, aBuf, (size_t) nPreLen );
218 aTmpBuf[nPreLen] = '\0';
219 if ( !strcmp( aTmpBuf, cAPrefix ))
221 if ( bLdump3 ) {
222 int nChar = '@';
223 char *pNeu = strchr( aBuf, nChar );
224 size_t nPos = pNeu - aBuf + 1;
225 if ( nPos > 0 )
227 char aOldBuf[MAX_MAN];
228 strcpy( aOldBuf, aBuf );
229 char pChar[MAX_MAN];
230 strncpy( pChar, aBuf, nPos - 1 );
231 pChar[nPos-1] = '\0';
232 strcpy( aBuf, pChar );
233 strcat( aBuf, "=" );
234 strcat( aBuf, aOldBuf );
235 strcpy( pChar, "" );
238 // und raus damit
239 PrintSym( aBuf, true );
243 fclose(pList);
244 return true;
247 bool LibDump::ReadFilter( char * cFilterName )
249 FILE* pfFilter = 0;
250 char aBuf[MAX_MAN];
251 char* pStr;
252 int nLen;
254 pfFilter = fopen( cFilterName, "r" );
256 if ( !pfFilter )
258 ::bFilter = 0;
259 DumpError( 500 );
262 while( fgets( aBuf, MAX_MAN, pfFilter ) != 0 )
264 nLen = (int) strlen(aBuf);
265 pStr = new char[(unsigned int) nLen];
266 if ( !pStr )
267 DumpError( 98 );
268 memcpy( pStr, aBuf, (unsigned int) nLen );
269 if ( *(pStr+nLen-1) == '\n' )
270 *(pStr+nLen-1) = '\0';
271 pFilterLines[nFilterLines] = pStr;
272 nFilterLines++;
273 if ( nFilterLines >= MAXFILT )
274 DumpError( 510 );
277 fclose( pfFilter );
278 return true;
281 bool LibDump::PrintSym(char *pName, bool bName )
283 LibExport *pData;
286 // Filter auswerten
287 if ( Filter( pName ) )
289 if ( strlen( pName ) > 3 )
291 if ( bDef )
293 if (!bBase)
294 if (bExportName) {
295 fprintf( stdout, "\t%s\n", pName );
296 } else {
297 fprintf( stdout, "\t%s\t\t@%lu\n", pName, nDefStart );
299 else
301 pData = pBaseTab->Find( pName );
302 if ( pData )
304 pData->bExport = true;
305 if ( bName )
306 pData->bByName = true;
307 else
308 pData->bByName = false;
309 if ( bVerbose )
310 fprintf(stderr,".");
312 else
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;
320 if ( bName )
321 pData->bByName = true;
322 else
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 );
328 delete [] cBuffer;
329 if ( bVerbose )
330 fprintf(stderr,"n");
334 else
335 printf( "%s\n", pName );
336 nDefStart++;
339 return true;
342 bool LibDump::IsFromAnonymousNamespace (char *pExportName) {
343 char* pattern1 = "@?A0x";
345 if (strstr(pExportName, pattern1)) {
346 return true;
348 return false;
351 bool LibDump::Filter(char *pExportName)
353 unsigned long i;
354 char pTest[256];
356 // filter out symbols from anonymous namespaces
357 if (IsFromAnonymousNamespace (pExportName))
358 return false;
360 // Kein Filter gesetzt
361 if ( ::bFilter == 0 )
362 return true;
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]))
370 return false;
372 else
374 strcpy(pTest,&pFilterLines[i][1]);
375 if ( strstr( pExportName, pTest))
376 return true;
379 return true;
382 bool LibDump::SetFilter(char * cFilterName)
384 ReadFilter( cFilterName );
385 return true;
388 bool LibDump::CheckLibrary(char * cName)
390 delete [] cLibName;
391 cLibName = new char[ strlen( cName ) + 1 ];
392 strcpy( cLibName, cName );
393 return true;
396 bool LibDump::ReadDataBase()
398 FILE* pfBase = 0;
399 char aBuf[MAX_MAN];
400 char* pStr;
401 char cBuffer[ 30 ];
402 int nLen;
403 LibExport *pData;
405 pfBase = fopen( cBName, "r" );
407 if ( !pfBase )
409 bBase = 0;
410 DumpError( 600 );
413 bool bRet = true;
414 while( fgets( aBuf, MAX_MAN, pfBase ) != 0 )
416 nLen = (int) strlen(aBuf);
417 pStr = new char[(unsigned int) nLen];
418 if ( !pStr )
419 DumpError( 98 );
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)
429 bRet = false;
430 ltoa( (long) pData->nOrdinal, cBuffer, 10 );
431 if (pIndexTab->Insert( cBuffer, pData ) == NULL)
432 bRet = false;
433 nBaseLines++;
434 if ( nBaseLines >= MAXBASE )
435 DumpError( 610 );
437 fclose( pfBase );
438 return bRet;
441 class ExportSetIter : public HashTableIterator
443 public:
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(); }
456 private:
457 void operator =(ExportSetIter &); // not defined
460 bool LibDump::PrintDataBase()
462 if (bExportName)
463 return true;
464 FILE *pFp;
465 pFp = fopen (cBName,"w+");
466 if (!pFp)
467 fprintf( stderr, "Error opening DataBase File\n" );
469 LibExport *pData;
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 );
475 delete [] cBuffer;
476 if ( pData )
477 fprintf(pFp,"%s\n",pData->cExportName);
479 fclose(pFp);
480 return true;
483 bool LibDump::PrintDefFile()
485 #ifdef FAST
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());
497 else
499 fprintf(stdout,"\t%s\t\t@%d NONAME\n",
500 pData->sExportName.GetBuffer(), pData->nOrdinal+nBegin);
504 #else
505 // sortiert nach Ordinals;
506 LibExport *pData;
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 );
512 delete [] cBuffer;
513 if ( pData )
514 if ( pData->bExport )
516 if ( pData->bByName )
518 if ( strlen( pData->cExportName ))
519 fprintf(stdout,"\t%s\n",
520 pData->cExportName);
522 else
524 if ( strlen( pData->cExportName ))
525 fprintf(stdout,"\t%s\t\t@%d NONAME\n",
526 pData->cExportName, pData->nOrdinal+nBegin);
530 #endif
531 return true;
534 bool LibDump::CheckDataBase()
536 // existiert eine Datenbasis ?
537 if (!bBase)
539 cBName = new char[ 2048 ];
540 char *pTmp = "defs\\";
542 FILE *fp;
543 _mkdir ("defs");
544 strcpy(cBName,pTmp);
545 strcat(cBName,getenv ("COMP_ENV"));
547 fp = fopen (cBName,"r");
548 if (fp)
550 bBase = true;
552 else
554 fp = fopen (cBName,"w+");
555 bBase = true;
557 fclose (fp);
559 // lese Datenbasis !
560 if (bBase)
562 ReadDataBase();
564 return true;
567 LibDump::~LibDump()
569 delete [] cBName;
570 delete [] cAPrefix;
571 delete [] cFilterName;
572 delete [] cModName;
575 void LibDump::SetCExport( char* pName )
577 delete [] cAPrefix;
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 )
588 char *p;
590 switch (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;
595 #ifdef WNT
596 case 10: p = "EXP file not found"; break;
597 case 11: p = "No valid EXP file"; break;
598 #else
599 case 10: p = "Library file not found"; break;
600 case 11: p = "No valid library file"; break;
601 #endif
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 );
618 exit (1);
621 /*********************************************************************
622 Test Funktionen
623 *********************************************************************/
626 void usage()
628 LibDump::DumpError(99);
631 #define STATE_NON 0x0000
632 #define STATE_BEGIN 0x0001
633 #define STATE_FILTER 0x0002
634 #define STATE_CEXPORT 0x0003
637 #ifdef WNT
638 __cdecl
639 #endif
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;
647 if ( argc == 1 ) {
648 usage();
651 for ( int i = 1; i < argc; i++ ) {
652 if (( !strcmp( argv[ i ], "-H" )) ||
653 ( !strcmp( argv[ i ], "-h" )) ||
654 ( !strcmp( argv[ i ], "-?" )))
656 usage();
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 ) {
664 usage();
666 bLdump3 = 1;
668 else if (( !strcmp( argv[ i ], "-E" )) || ( !strcmp( argv[ i ], "-e" ))) {
669 if ( nState != STATE_NON ) {
670 usage();
672 nState = STATE_BEGIN;
674 else if (( !strcmp( argv[ i ], "-F" )) || ( !strcmp( argv[ i ], "-f" ))) {
675 if ( nState != STATE_NON ) {
676 usage();
678 nState = STATE_FILTER;
680 else if (( !strcmp( argv[ i ], "-A" )) || ( !strcmp( argv[ i ], "-a" ))) {
681 if ( nState != STATE_NON ) {
682 usage();
684 nState = STATE_CEXPORT;
685 pCExport = new char[ 1 ];
686 pCExport[ 0 ] = 0;
688 else if (( !strcmp( argv[ i ], "-D" )) || ( !strcmp( argv[ i ], "-d" ))) {
689 if ( nState != STATE_NON ) {
690 usage();
692 bUseDirectives = 1;
694 else if (( !strcmp( argv[ i ], "-N" )) || ( !strcmp( argv[ i ], "-n" ))) {
695 if ( nState != STATE_NON ) {
696 usage();
698 bExportByName = 1;
700 else if (( !strcmp( argv[ i ], "-V" )) || ( !strcmp( argv[ i ], "-v" ))) {
701 if ( nState != STATE_NON ) {
702 usage();
704 bVerbose = 1;
706 else {
707 switch ( nState ) {
708 case STATE_BEGIN:
709 nBegin = static_cast< unsigned short >(atoi( argv[ i ] ));
710 nState = STATE_NON;
711 break;
712 case STATE_FILTER:
713 pFilterName = new char[ strlen( argv[ i ] ) + 1 ];
714 strcpy( pFilterName, argv[ i ] );
715 bFilter = 1;
716 nState = STATE_NON;
717 break;
718 case STATE_CEXPORT:
719 delete [] pCExport;
720 pCExport = new char[ strlen( argv[ i ] ) + 1 ];
721 strcpy( pCExport, argv[ i ] );
722 nState = STATE_NON;
723 break;
724 default:
725 pLibName = new char[ strlen( argv[ i ] ) + 1 ];
726 strcpy( pLibName, argv[ i ] );
727 break;
732 if ( !pLibName ) {
733 usage();
736 LibDump *pDump = new LibDump( pLibName, bExportByName );
737 pDump->SetBeginExport(nBegin);
738 if ( bFilter != 0 )
739 pDump->SetFilter( pFilterName );
740 if ( pCExport )
741 pDump->SetCExport( pCExport );
742 else {
743 char *pEmpty = "";
744 pDump->SetCExport( pEmpty );
746 pDump->Dump();
747 pDump->PrintDefFile();
748 pDump->PrintDataBase();
749 delete pDump;
750 delete [] pLibName;
751 return 0;
754 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */