xref: /aoo41x/main/soltools/ldump/ldump.cxx (revision 7a4715d3)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_soltools.hxx"
26 
27 #include <string.h>
28 #include <direct.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 
32 #include "ldump.hxx"
33 #include "hashtbl.hxx"
34 
35 #define MAXSYM     65536
36 #define MAXBASE    98304
37 #define MAX_MAN		4096
38 
39 int	bFilter = 0;
40 int bLdump3 = 0;
41 int bUseDirectives = 0;
42 int bVerbose = 0;
43 int bExportByName = 0;
44 
45 class ExportSet : public HashTable
46 {
47 public:
ExportSet(unsigned long lSize,double dMaxLoadFactor=HashTable::m_defMaxLoadFactor,double dGrowFactor=HashTable::m_defDefGrowFactor)48     ExportSet
49     (
50         unsigned long lSize,
51         double	dMaxLoadFactor = HashTable::m_defMaxLoadFactor,
52         double	dGrowFactor = HashTable::m_defDefGrowFactor
53     )
54         : HashTable(lSize,false,dMaxLoadFactor,dGrowFactor) {}
55 
~ExportSet()56     virtual ~ExportSet() {}
57 
Find(char * const & Key) const58     LibExport *  Find (char * const& Key) const
59     { return (LibExport *) HashTable::Find((char *) Key); }
60 
Insert(char * const & Key,LibExport * Object)61     bool Insert (char * const& Key, LibExport * Object)
62     { return HashTable::Insert((char *) Key, (void*) Object); }
63 
Delete(char * const & Key)64     LibExport *  Delete (char * const&Key)
65     { return (LibExport *) HashTable::Delete ((char *) Key); }
66 };
67 
LibDump(char * cFileName,int bExportByName)68 LibDump::LibDump( char *cFileName, int bExportByName )
69 				: cBName( NULL ),
70 				cAPrefix( NULL ),
71 				cLibName( NULL ),
72 				cFilterName( NULL ),
73 				cModName( NULL )
74 {
75 	fprintf( stderr, "LIB-NT File Dumper v4.00 (C) 2000 Sun Microsystems, Inc.\n\n" );
76 	fprintf( stderr, "%s ", cFileName );
77 
78     bExportName = bExportByName;
79 
80 	unsigned long nSlots =  0xfffff;
81 	pBaseTab = new ExportSet( nSlots );
82 	pIndexTab = new ExportSet( nSlots );
83 	pFilterLines = new char * [MAXFILT];
84 	CheckLibrary(cFileName);
85 	bBase = 0;
86 	bAll = false;
87 	nDefStart = 0;
88 	nBaseLines = 0;
89 	nFilterLines = 0;
90 	bDef = true;
91 	cAPrefix = new char[ 1 ];
92 	cAPrefix[ 0 ] = 0;
93     if (!bExportName)
94 	    CheckDataBase();
95 }
96 
Dump()97 bool LibDump::Dump()
98 {
99 	FILE *pList;
100     char  aBuf[MAX_MAN];
101     int   nLen;
102     char  aName[MAX_MAN];
103 
104     pList = fopen( cLibName, "rb");
105 	if (!pList)
106 		DumpError(10);
107 
108     // forget about offset when working on linker directives
109     if ( !bUseDirectives )
110     {
111         // calculating offset for name section
112     	unsigned char TmpBuffer[4];
113 	    fread( TmpBuffer, 1, 4, pList);
114     	// anzahl bigendian mal laenge + ueberspringen der naechsten laengenangabe
115     	unsigned long nOffSet = (unsigned long) ( TmpBuffer[2] * 256 + TmpBuffer[3] ) * 4 + 4;
116     	fseek( pList, (long) nOffSet, 0);
117     }
118 
119 	char aTmpBuf[4096];
120 	// reading file containing symbols
121     while( !feof( pList ) )
122     {
123    		int i = 0;
124         if ( !bUseDirectives )
125         {
126 	    	// symbol komplett einlesen
127             for (;;)
128             {
129                 int c = fgetc( pList );
130                 if ( c == '\0' )
131                 {
132                     break;
133                 }
134                 if ( ((c >= 33) && (c <= 126)) && ( c!=40 && c!=41) )
135                 	aBuf[i] = static_cast< char >(c);
136                 else
137                 {
138                     aBuf[0] = '\0';
139                     break;
140                 }
141             	i++;
142             }
143     		// Namen found
144             aBuf[i] = '\0';
145         }
146         else
147         {
148             fgets( aTmpBuf, 4096, pList );
149             char * pEnd = 0;
150             char *pFound = 0;
151             aBuf[0] = '\0';
152             pFound = strchr( aTmpBuf, 'E' );
153             while ( pFound )
154             {
155                 if ( strncmp( "EXPORT:", pFound, 7) == 0 )
156                 {
157                     pFound += 7;
158                     pEnd = strchr( pFound, ',');
159                     if ( pEnd )
160                         *pEnd = '\0';
161                     strncpy( aBuf, pFound, strlen( pFound));
162                     aBuf[ strlen( pFound) ] = '\0';
163 //                    fprintf( stderr, "\n--- %s\n", aBuf);
164                     break;
165                 }
166                 else
167                 {
168                     pFound++;
169                     pFound = strchr( pFound, 'E' );
170                 }
171             }
172         }
173 
174 	    if ((aBuf[0] =='?') || !strncmp(aBuf, "__CT",4))
175 		{
176 			nLen = (int) strlen(aBuf);
177             memset( aName, 0, sizeof( aName ) );
178             int nName = 0;
179             for( i = 0; i < nLen; i++ )
180             {
181                 if ( (aBuf[i] != '\n') && (aBuf[i] != '\r') )
182                 {
183                     aName[nName] = aBuf[i];
184                     nName++;
185                 }
186             }
187 			// und raus damit
188             PrintSym( aName, bExportByName );
189 		}
190 		else if ( bAll == true )
191 		{
192 			int nPreLen = (int) strlen( cAPrefix );
193 
194             nLen = (int) strlen(aBuf);
195             memset( aName, 0, sizeof( aName ) );
196             int nName = 0;
197 
198             for( i = 0; i < nLen; i++ )
199             {
200               if ( (aBuf[i] != '\n') && (aBuf[i] != '\r') )
201               {
202                   aName[nName] = aBuf[i];
203                   nName++;
204 			  }
205 			}
206 			//fprintf( stderr, "Gefundenen Prefix : %s %d \n", aTmpBuf, nPreLen );
207 			// den ersten _ raus
208             nLen = (int) strlen(aName);
209             if (aName[0] == '_')
210 				strcpy( aBuf , &aName[1] );
211 			strncpy ( aTmpBuf, aBuf, (size_t) nPreLen );
212 			aTmpBuf[nPreLen] = '\0';
213 			if ( !strcmp( aTmpBuf, cAPrefix ))
214 			{
215 				if ( bLdump3 ) {
216 					int nChar = '@';
217 					char *pNeu = strchr( aBuf, nChar );
218 					int nPos = pNeu - aBuf + 1;
219 					if ( nPos > 0 )
220 					{
221 						char aOldBuf[MAX_MAN];
222 						strcpy( aOldBuf, aBuf );
223 						char pChar[MAX_MAN];
224 						strncpy( pChar, aBuf, (size_t) (nPos -1) );
225 						pChar[nPos-1] = '\0';
226 						strcpy( aBuf, pChar );
227 						strcat( aBuf, "=" );
228 						strcat( aBuf, aOldBuf );
229 						strcpy( pChar, "" );
230 					}
231 				}
232 				// und raus damit
233             	PrintSym( aBuf, true );
234 			}
235 		}
236     }
237 	fclose(pList);
238 	return true;
239 }
240 
ReadFilter(char * cFilterName)241 bool LibDump::ReadFilter( char * cFilterName )
242 {
243 	FILE* pfFilter = 0;
244     char  aBuf[MAX_MAN];
245     char* pStr;
246     int   nLen;
247 
248     pfFilter = fopen( cFilterName, "r" );
249 
250     if ( !pfFilter )
251     {
252         ::bFilter = 0;
253         DumpError( 500 );
254     }
255 
256     while( fgets( aBuf, MAX_MAN, pfFilter ) != 0 )
257     {
258         nLen = (int) strlen(aBuf);
259         pStr = new char[(unsigned int) nLen];
260         if ( !pStr )
261             DumpError( 98 );
262         memcpy( pStr, aBuf, (unsigned int) nLen );
263         if ( *(pStr+nLen-1) == '\n' )
264             *(pStr+nLen-1) = '\0';
265 		pFilterLines[nFilterLines] = pStr;
266 		nFilterLines++;
267 		if ( nFilterLines >= MAXFILT )
268 				DumpError( 510 );
269     }
270 
271 	fclose( pfFilter );
272 	return true;
273 }
274 
PrintSym(char * pName,bool bName)275 bool LibDump::PrintSym(char *pName, bool bName )
276 {
277 	LibExport *pData;
278 
279 
280     // Filter auswerten
281     if ( Filter( pName ) )
282     {
283         if ( strlen( pName ) > 3 )
284         {
285             if ( bDef )
286 		    {
287 		        if (!bBase)
288                     if (bExportName) {
289 						fprintf( stdout, "\t%s\n", pName );
290                     } else {
291 						fprintf( stdout, "\t%s\t\t@%lu\n", pName, nDefStart );
292                     }
293 				else
294 				{
295 					 pData = pBaseTab->Find( pName );
296 					 if ( pData )
297 					 {
298 						pData->bExport = true;
299 						if ( bName )
300 							pData->bByName = true;
301 						else
302 							pData->bByName = false;
303 						if ( bVerbose )
304 							fprintf(stderr,".");
305 					 }
306 					 else
307 					 {
308 					 	// neuen Export eintragen
309 					 	pData = new LibExport;
310 						pData->cExportName = new char[ strlen( pName ) + 1 ];
311 						strcpy( pData->cExportName, pName );
312 						pData->nOrdinal = nBaseLines++;
313 						pData->bExport = true;
314 						if ( bName )
315 							pData->bByName = true;
316 						else
317 							pData->bByName = false;
318 						pBaseTab->Insert( pData->cExportName, pData );
319 						char *cBuffer = new char[ 30 ];
320 						sprintf( cBuffer, "%lu", pData->nOrdinal );
321 						pIndexTab->Insert( cBuffer, pData );
322 						delete [] cBuffer;
323 						if ( bVerbose )
324 							fprintf(stderr,"n");
325 					 }
326 				}
327 		    }
328             else
329                 printf( "%s\n", pName );
330             nDefStart++;
331         }
332     }
333 	return true;
334 }
335 
IsFromAnonymousNamespace(char * pExportName)336 bool LibDump::IsFromAnonymousNamespace (char *pExportName) {
337     char* pattern1 = "@?A0x";
338 
339     if (strstr(pExportName, pattern1)) {
340         return true;
341     };
342     return false;
343 };
344 
Filter(char * pExportName)345 bool LibDump::Filter(char *pExportName)
346 {
347 	unsigned long i;
348 	char pTest[256];
349 
350     // filter out symbols from anonymous namespaces
351     if (IsFromAnonymousNamespace (pExportName))
352         return false;
353 
354     // Kein Filter gesetzt
355     if ( ::bFilter == 0 )
356         return true;
357 
358 	for ( i=0; i<nFilterLines; i++ )
359 	{
360 		//Zum vergleichen mu� das Plus abgeschnitteb werden
361 		if(pFilterLines[i][0] != '+')
362 		{
363 			if ( strstr( pExportName, pFilterLines[i]))
364 				return false;
365 		}
366 		else
367 		{
368 			strcpy(pTest,&pFilterLines[i][1]);
369 			if ( strstr( pExportName, pTest))
370 				return true;
371 		}
372 	}
373     return true;
374 }
375 
SetFilter(char * cFilterName)376 bool LibDump::SetFilter(char * cFilterName)
377 {
378 	ReadFilter( cFilterName );
379 	return true;
380 }
381 
CheckLibrary(char * cName)382 bool LibDump::CheckLibrary(char * cName)
383 {
384 	delete [] cLibName;
385 	cLibName = new char[ strlen( cName ) + 1 ];
386 	strcpy( cLibName, cName );
387 	return true;
388 }
389 
ReadDataBase()390 bool LibDump::ReadDataBase()
391 {
392 	FILE* pfBase = 0;
393     char  aBuf[MAX_MAN];
394     char* pStr;
395     char  cBuffer[ 30 ];
396     int   nLen;
397 	LibExport *pData;
398 
399     pfBase = fopen( cBName, "r" );
400 
401     if ( !pfBase )
402     {
403         bBase = 0;
404         DumpError( 600 );
405     }
406 
407 	bool bRet = true;
408 	while( fgets( aBuf, MAX_MAN, pfBase ) != 0 )
409     {
410         nLen = (int) strlen(aBuf);
411         pStr = new char[(unsigned int) nLen];
412         if ( !pStr )
413             DumpError( 98 );
414         memcpy( pStr, aBuf, (size_t) nLen );
415         if ( *(pStr+nLen-1) == '\n' )
416             *(pStr+nLen-1) = '\0';
417 		pData = new LibExport;
418 		pData->cExportName = pStr;
419 		pData->nOrdinal = nBaseLines;
420 		pData->bExport=false;
421 
422 		if (pBaseTab->Insert(pData->cExportName, pData ) == NULL)
423 			bRet = false;
424         ltoa( (long) pData->nOrdinal, cBuffer, 10 );
425 		if (pIndexTab->Insert( cBuffer, pData ) == NULL)
426 			bRet = false;
427         nBaseLines++;
428         if ( nBaseLines >= MAXBASE )
429             DumpError( 610 );
430     }
431     fclose( pfBase );
432 	return bRet;
433 }
434 
435 class ExportSetIter : public HashTableIterator
436 {
437 public:
ExportSetIter(HashTable const & aTable)438     ExportSetIter(HashTable const& aTable)
439 		: HashTableIterator(aTable)	{}
440 
GetFirst()441     LibExport * GetFirst()
442     { return (LibExport *)HashTableIterator::GetFirst(); }
GetNext()443     LibExport * GetNext()
444     { return (LibExport *)HashTableIterator::GetNext();  }
GetLast()445     LibExport * GetLast()
446     { return (LibExport *)HashTableIterator::GetLast();  }
GetPrev()447     LibExport * GetPrev()
448     { return (LibExport *)HashTableIterator::GetPrev();  }
449 
450 private:
451     void operator =(ExportSetIter &); // not defined
452 };
453 
PrintDataBase()454 bool LibDump::PrintDataBase()
455 {
456     if (bExportName)
457         return true;
458 	FILE *pFp;
459 	pFp = fopen (cBName,"w+");
460 	if (!pFp)
461 		fprintf( stderr, "Error opening DataBase File\n" );
462 
463 	LibExport *pData;
464 	for ( unsigned long i=0; i < nBaseLines+10; i++ )
465 	{
466 		char * cBuffer = new char[ 30 ];
467 		sprintf( cBuffer, "%lu", i );
468 		pData = pIndexTab->Find( cBuffer );
469 		delete [] cBuffer;
470 		if ( pData )
471 			fprintf(pFp,"%s\n",pData->cExportName);
472 	}
473 	fclose(pFp);
474 	return true;
475 }
476 
PrintDefFile()477 bool LibDump::PrintDefFile()
478 {
479 #ifdef FAST
480 	ExportSetIter aIterator( *pBaseTab );
481 	for ( LibExport *pData = aIterator.GetFirst(); pData != NULL;
482 										pData = aIterator.GetNext() )
483 	{
484 		if ( pData->bExport )
485 		{
486 			if ( pData->bByName )
487 			{
488 				fprintf(stdout,"\t%s\n",
489 					pData->sExportName.GetBuffer());
490 			}
491 			else
492 			{
493 				fprintf(stdout,"\t%s\t\t@%d NONAME\n",
494 					pData->sExportName.GetBuffer(), pData->nOrdinal+nBegin);
495 			}
496 		}
497 	}
498 #else
499 	// sortiert nach Ordinals;
500 	LibExport *pData;
501 	for ( unsigned long i=0; i<nBaseLines+1; i++)
502 	{
503 		char * cBuffer = new char[ 30 ];
504 		sprintf( cBuffer, "%lu", i );
505 		pData = pIndexTab->Find( cBuffer );
506 		delete [] cBuffer;
507 		if ( pData )
508 			if ( pData->bExport )
509 			{
510 				if ( pData->bByName )
511 				{
512 					if ( strlen( pData->cExportName ))
513 						fprintf(stdout,"\t%s\n",
514 							pData->cExportName);
515 				}
516 				else
517 				{
518 					if ( strlen( pData->cExportName ))
519 						fprintf(stdout,"\t%s\t\t@%d NONAME\n",
520 							pData->cExportName, pData->nOrdinal+nBegin);
521 				}
522 			}
523 	}
524 #endif
525 	return true;
526 }
527 
CheckDataBase()528 bool LibDump::CheckDataBase()
529 {
530     // existiert eine Datenbasis ?
531     if (!bBase)
532     {
533 		cBName = new char[ 2048 ];
534 		char *pTmp = "defs\\";
535 
536     	FILE *fp;
537 #ifdef OS2
538 		_mkdir ("defs", 0777);
539 #else
540 		_mkdir ("defs");
541 #endif
542 		strcpy(cBName,pTmp);
543 #ifdef OS2
544 		strcat(cBName,"gcc");
545 #else
546 		strcat(cBName,getenv ("COMP_ENV"));
547 #endif
548 
549 		fp = fopen (cBName,"r");
550 		if (fp)
551 		{
552 			bBase = true;
553 		}
554 		else
555 		{
556 			fp = fopen (cBName,"w+");
557 			bBase = true;
558 		}
559 		fclose (fp);
560     }
561     // lese Datenbasis !
562     if (bBase)
563 	{
564     	ReadDataBase();
565 	}
566 	return true;
567 }
568 
~LibDump()569 LibDump::~LibDump()
570 {
571 	delete [] cBName;
572 	delete [] cAPrefix;
573 //	delete [] cLibName;
574 	delete [] cFilterName;
575 	delete [] cModName;
576 }
577 
SetCExport(char * pName)578 void LibDump::SetCExport( char* pName )
579 {
580 	delete [] cAPrefix;
581 	cAPrefix = new char[ strlen( pName ) + 1 ];
582 	strcpy( cAPrefix, pName );bAll = true;
583 }
584 
585 //******************************************************************
586 //* Error() - Gibt Fehlermeldumg aus
587 //******************************************************************
588 
DumpError(unsigned long n)589 void LibDump::DumpError( unsigned long n )
590 {
591     char *p;
592 
593     switch (n)
594     {
595         case 1:  p = "Input error in library file"; break;
596         case 2:  p = "Position error in library file (no THEADR set)"; break;
597         case 3:  p = "Overflow of symbol table"; break;
598 #ifdef WNT
599         case 10: p = "EXP file not found"; break;
600         case 11: p = "No valid EXP file"; break;
601 #else
602         case 10: p = "Library file not found"; break;
603         case 11: p = "No valid library file"; break;
604 #endif
605         case 98: p = "Out of memory"; break;
606         case 99: p = "LDUMP [-LD3] [-D] [-N] [-A] [-E nn] [-F name] Filename[.LIB]\n"
607 					 "-LD3   : Supports feature set of ldump3 (default: ldump/ldump2)\n"
608                      "-A     : all symbols (default: only C++)\n"
609                      "-E nn  : gerenration of export table beginning with number nn\n"
610                      "-F name: Filter file\n"
611                      "-D     : file contains \"dumpbin\" directives\n"
612                      "-N     : export by name\n"
613                      "-V     : be verbose\n"; break;
614         case 500: p = "Unable to open filter file\n"; break;
615         case 510: p = "Overflow of filter table\n"; break;
616         case 600: p = "Unable to open base database file\n"; break;
617         case 610: p = "Overflow in base database table\n"; break;
618         default: p = "Unspecified error";
619     }
620 	fprintf( stdout, "%s\n", p );
621     exit (1);
622 }
623 
624 /*********************************************************************
625 		Test Funktionen
626 *********************************************************************/
627 
628 
usage()629 void usage()
630 {
631 	LibDump::DumpError(99);
632 }
633 
634 #define STATE_NON		0x0000
635 #define STATE_BEGIN		0x0001
636 #define STATE_FILTER	0x0002
637 #define STATE_CEXPORT	0x0003
638 
639 int
640 #ifdef WNT
641 __cdecl
642 #endif
main(int argc,char ** argv)643 main( int argc, char **argv )
644 {
645 	char *pLibName = NULL, *pFilterName = NULL, *pCExport= NULL;
646 	unsigned short nBegin=1;
647 
648 	unsigned short nState = STATE_NON;
649 
650 	if ( argc == 1 ) {
651 		usage();
652 	}
653 
654 	for ( int i = 1; i < argc; i++ ) {
655 		if (( !strcmp( argv[ i ], "-H" )) ||
656 			( !strcmp( argv[ i ], "-h" )) ||
657 			( !strcmp( argv[ i ], "-?" )))
658 		{
659 			usage();
660 		}
661 		else if (( !strcmp( argv[ i ], "-LD3" )) ||
662 			( !strcmp( argv[ i ], "-Ld3" )) ||
663 			( !strcmp( argv[ i ], "-ld3" )) ||
664 			( !strcmp( argv[ i ], "-lD3" )))
665 		{
666 			if ( nState != STATE_NON ) {
667 				usage();
668 			}
669 			bLdump3 = 1;
670 		}
671 		else if (( !strcmp( argv[ i ], "-E" )) || ( !strcmp( argv[ i ], "-e" ))) {
672 			if ( nState != STATE_NON ) {
673 				usage();
674 			}
675 			nState = STATE_BEGIN;
676 		}
677 		else if (( !strcmp( argv[ i ], "-F" )) || ( !strcmp( argv[ i ], "-f" ))) {
678 			if ( nState != STATE_NON ) {
679 				usage();
680 			}
681 			nState = STATE_FILTER;
682 		}
683 		else if (( !strcmp( argv[ i ], "-A" )) || ( !strcmp( argv[ i ], "-a" ))) {
684 			if ( nState != STATE_NON ) {
685 				usage();
686 			}
687 			nState = STATE_CEXPORT;
688 			pCExport = new char[ 1 ];
689 			pCExport[ 0 ] = 0;
690 		}
691 		else if (( !strcmp( argv[ i ], "-D" )) || ( !strcmp( argv[ i ], "-d" ))) {
692 			if ( nState != STATE_NON ) {
693 				usage();
694 			}
695             bUseDirectives = 1;
696 		}
697 		else if (( !strcmp( argv[ i ], "-N" )) || ( !strcmp( argv[ i ], "-n" ))) {
698 			if ( nState != STATE_NON ) {
699 				usage();
700 			}
701             bExportByName = 1;
702 		}
703 		else if (( !strcmp( argv[ i ], "-V" )) || ( !strcmp( argv[ i ], "-v" ))) {
704 			if ( nState != STATE_NON ) {
705 				usage();
706 			}
707             bVerbose = 1;
708 		}
709 		else {
710 			switch ( nState ) {
711 				case STATE_BEGIN:
712 					nBegin = static_cast< unsigned short >(atoi( argv[ i ] ));
713 					nState = STATE_NON;
714 				break;
715 				case STATE_FILTER:
716 					pFilterName = new char[ strlen( argv[ i ] ) + 1 ];
717 					strcpy( pFilterName, argv[ i ] );
718 					bFilter = 1;
719 					nState = STATE_NON;
720 				break;
721 				case STATE_CEXPORT:
722 					delete [] pCExport;
723 					pCExport = new char[ strlen( argv[ i ] ) + 1 ];
724 					strcpy( pCExport, argv[ i ] );
725 					nState = STATE_NON;
726 				break;
727 				default:
728 					pLibName = new char[ strlen( argv[ i ] ) + 1 ];
729 					strcpy( pLibName, argv[ i ] );
730 				break;
731 			}
732 		}
733 	}
734 
735 	if ( !pLibName ) {
736 		usage();
737 	}
738 
739 	LibDump *pDump = new LibDump( pLibName, bExportByName );
740 	pDump->SetBeginExport(nBegin);
741 	if ( bFilter != 0 )
742 		pDump->SetFilter( pFilterName );
743 	if ( pCExport )
744 		pDump->SetCExport( pCExport );
745 	else {
746 		char *pEmpty = "";
747 		pDump->SetCExport( pEmpty );
748 	}
749 	pDump->Dump();
750 	pDump->PrintDefFile();
751 	pDump->PrintDataBase();
752 	delete pDump;
753 	return 0;
754 }
755