Mail Archives: cygwin/1997/02/11/12:53:24
//Z,+PATCH,//ROOT/UTILS.
//Z,+DECK,BindExpLib,T=C++..
//*CMZ : 0.90/01 08/10/96 13.07.48 by Valery Fine(fine AT vxcern DOT cern DOT ch)
// project (http://root.cern.ch)
//*-- Author : Valery Fine(fine AT vxcern DOT cern DOT ch) 25/09/96
/*
*----------------------------------------------------------------------
* Program: dumpexts.exe
* Author: Gordon Chaffee
*
* History: The real functionality of this file was written by
* Matt Pietrek in 1993 in his pedump utility. I've
* modified it to dump the externals in a bunch of object
* files to create a .def file.
*
* Notes: Visual C++ puts an underscore before each exported symbol.
* This file removes them. I don't know if this is a problem
* this other compilers. If VISUAL_CPLUSCPLUS is defined,
* the underscore is removed. If not, it isn't. To get a
* full dump of an object file, use the -f option. This can
* help determine the something that may be different with a
* compiler other than Visual C++.
* ======================================
* Corrections (Valery Fine 16/09/96):
*
* It didn't work for C++ code with global variables and class definitons
* The DumpExternalObject function has been introduced to generate .DEF file
*
* Author: Valery Fine 16/09/96 (E-mail: fine AT vxcern DOT cern DOT ch)
*----------------------------------------------------------------------
*/
static char sccsid[] = "@(#) winDumpExts.c 1.2 95/10/03 15:27:34";
static int fort = 0;
#include <windows.h>
#include <stdio.h>
#include <string.h>
/*
*----------------------------------------------------------------------
* GetArgcArgv --
*
* Break up a line into argc argv
*----------------------------------------------------------------------
*/
int
GetArgcArgv(char *s, char **argv)
{
int quote = 0;
int argc = 0;
char *bp;
bp = s;
while (1) {
while (isspace(*bp)) {
bp++;
}
if (*bp == '\n' || *bp == '\0') {
*bp = '\0';
return argc;
}
if (*bp == '\"') {
quote = 1;
bp++;
}
argv[argc++] = bp;
while (*bp != '\0') {
if (quote) {
if (*bp == '\"') {
quote = 0;
*bp = '\0';
bp++;
break;
}
bp++;
continue;
}
if (isspace(*bp)) {
*bp = '\0';
bp++;
break;
}
bp++;
}
}
}
/*
* The names of the first group of possible symbol table storage classes
*/
char * SzStorageClass1[] = {
"NULL","AUTOMATIC","EXTERNAL","STATIC","REGISTER","EXTERNAL_DEF","LABEL",
"UNDEFINED_LABEL","MEMBER_OF_STRUCT","ARGUMENT","STRUCT_TAG",
"MEMBER_OF_UNION","UNION_TAG","TYPE_DEFINITION","UNDEFINED_STATIC",
"ENUM_TAG","MEMBER_OF_ENUM","REGISTER_PARAM","BIT_FIELD"
};
/*
* The names of the second group of possible symbol table storage classes
*/
char * SzStorageClass2[] = {
"BLOCK","FUNCTION","END_OF_STRUCT","FILE","SECTION","WEAK_EXTERNAL"
};
/*
*----------------------------------------------------------------------
* GetSZStorageClass --
*
* Given a symbol storage class value, return a descriptive
* ASCII string
*----------------------------------------------------------------------
*/
PSTR
GetSZStorageClass(BYTE storageClass)
{
if ( storageClass <= IMAGE_SYM_CLASS_BIT_FIELD )
return SzStorageClass1[storageClass];
else if ( (storageClass >= IMAGE_SYM_CLASS_BLOCK)
&& (storageClass <= IMAGE_SYM_CLASS_WEAK_EXTERNAL) )
return SzStorageClass2[storageClass-IMAGE_SYM_CLASS_BLOCK];
else
return "???";
}
/*
*----------------------------------------------------------------------
* GetSectionName --
*
* Used by DumpSymbolTable, it gives meaningful names to
* the non-normal section number.
*
* Results:
* A name is returned in buffer
*----------------------------------------------------------------------
*/
void
GetSectionName(WORD section, PSTR buffer, unsigned cbBuffer)
{
char tempbuffer[10];
switch ( (SHORT)section )
{
case IMAGE_SYM_UNDEFINED: strcpy(tempbuffer, "UNDEF"); break;
case IMAGE_SYM_ABSOLUTE: strcpy(tempbuffer, "ABS "); break;
case IMAGE_SYM_DEBUG: strcpy(tempbuffer, "DEBUG"); break;
default: sprintf(tempbuffer, "%-5X", section);
}
strncpy(buffer, tempbuffer, cbBuffer-1);
}
/*
*----------------------------------------------------------------------
* DumpSymbolTable --
*
* Dumps a COFF symbol table from an EXE or OBJ. We only use
* it to dump tables from OBJs.
*----------------------------------------------------------------------
*/
void
DumpSymbolTable(PIMAGE_SYMBOL pSymbolTable, FILE *fout, unsigned cSymbols)
{
unsigned i;
PSTR stringTable;
char sectionName[10];
fprintf(fout, "Symbol Table - %X entries (* = auxillary symbol)\n",
cSymbols);
fprintf(fout,
"Indx Name Value Section cAux Type Storage\n"
"---- -------------------- -------- ---------- ----- ------- --------\n");
/*
* The string table apparently starts right after the symbol table
*/
stringTable = (PSTR)&pSymbolTable[cSymbols];
for ( i=0; i < cSymbols; i++ ) {
fprintf(fout, "%04X ", i);
if ( pSymbolTable->N.Name.Short != 0 )
fprintf(fout, "%-20.8s", pSymbolTable->N.ShortName);
else
fprintf(fout, "%-20s", stringTable + pSymbolTable->N.Name.Long);
fprintf(fout, " %08X", pSymbolTable->Value);
GetSectionName(pSymbolTable->SectionNumber, sectionName,
sizeof(sectionName));
fprintf(fout, " sect:%s aux:%X type:%02X st:%s\n",
sectionName,
pSymbolTable->NumberOfAuxSymbols,
pSymbolTable->Type,
GetSZStorageClass(pSymbolTable->StorageClass) );
#if 0
if ( pSymbolTable->NumberOfAuxSymbols )
DumpAuxSymbols(pSymbolTable);
#endif
/*
* Take into account any aux symbols
*/
i += pSymbolTable->NumberOfAuxSymbols;
pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
pSymbolTable++;
}
}
/*
*----------------------------------------------------------------------
* DumpExternals --
*
* Dumps a COFF symbol table from an EXE or OBJ. We only use
* it to dump tables from OBJs.
*----------------------------------------------------------------------
*/
void
DumpExternals(PIMAGE_SYMBOL pSymbolTable, FILE *fout, unsigned cSymbols)
{
unsigned i;
PSTR stringTable;
char *s, *f;
char symbol[1024];
/*
* The string table apparently starts right after the symbol table
*/
stringTable = (PSTR)&pSymbolTable[cSymbols];
for ( i=0; i < cSymbols; i++ ) {
if (pSymbolTable->SectionNumber > 0 && pSymbolTable->Type == 0x20) {
if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
if (pSymbolTable->N.Name.Short != 0) {
strncpy(symbol, (const char *)(pSymbolTable->N.ShortName), 8);
symbol[8] = 0;
} else {
s = stringTable + pSymbolTable->N.Name.Long;
strcpy(symbol, s);
}
s = symbol;
f = strchr(s, '@');
if (f) {
*f = 0;
}
#ifndef VISUAL_CPLUSPLUS
fprintf(fout, "\t%s\n", symbol);
#else
fprintf(fout, "\t%s\n", &symbol[1]);
#endif
}
}
/*
* Take into account any aux symbols
*/
i += pSymbolTable->NumberOfAuxSymbols;
pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
pSymbolTable++;
}
}
/*
*----------------------------------------------------------------------
* DumpExternalsObjects --
*
* Dumps a COFF symbol table from an EXE or OBJ. We only use
* it to dump tables from OBJs.
*----------------------------------------------------------------------
*/
void
DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable, FILE *fout, unsigned cSymbols)
{
unsigned i;
PSTR stringTable;
char *s, *f;
char symbol[1024];
static int fImportFlag = -1; /* The status is nor defined yet */
/*
* The string table apparently starts right after the symbol table
*/
stringTable = (PSTR)&pSymbolTable[cSymbols];
for ( i=0; i < cSymbols; i++ ) {
if (pSymbolTable->SectionNumber > 0 && ( pSymbolTable->Type == 0x20 || pSymbolTable->Type == 0x0)) {
if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
/*
* The name of the Function entry points
*/
if (pSymbolTable->N.Name.Short != 0) {
strncpy(symbol, (const char *)pSymbolTable->N.ShortName, 8);
symbol[8] = 0;
} else {
s = stringTable + pSymbolTable->N.Name.Long;
strcpy(symbol, s);
}
s = symbol;
while (isspace(*s)) s++;
#ifdef VISUAL_CPLUSPLUS
if (*s == '_') s++;
if (fort) {
f = strchr(s, '@');
if (f)
*f = 0;
}
#endif
if (fImportFlag) {
fImportFlag = 0;
fprintf(fout,"EXPORTS \n");
}
fprintf(fout, "\t%s", s);
if (!pSymbolTable->Type
&&
// !(strstr(s,"?fg") == s) && // static class data members must be excluded
!(strstr(s,"?k" ) == s) && // global constants must be excluded
!(strstr(s,"?E AT TMath@@2NB") == s) && // This is an Exponent from TMath
!(strstr(s,"?Pi") == s) // This is a Pi number from TMath
) fprintf(fout, " \t DATA");
fprintf(fout, "\n");
}
}
else if (pSymbolTable->SectionNumber == IMAGE_SYM_UNDEFINED && !pSymbolTable->Type && 0){
/*
* The IMPORT global variable entry points
*/
if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
s = stringTable + pSymbolTable->N.Name.Long;
strcpy(symbol, s);
s = symbol;
while (isspace(*s)) s++;
if (*s == '_') s++;
if (!fImportFlag) {
fImportFlag = 1;
fprintf(fout,"IMPORTS \n");
}
fprintf(fout, "\t%s DATA \n", &symbol[1]);
}
}
/*
* Take into account any aux symbols
*/
i += pSymbolTable->NumberOfAuxSymbols;
pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
pSymbolTable++;
}
}
/*
*----------------------------------------------------------------------
* DumpObjFile --
*
* Dump an object file--either a full listing or just the exported
* symbols.
*----------------------------------------------------------------------
*/
void
DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout, int full)
{
PIMAGE_SYMBOL PCOFFSymbolTable;
DWORD COFFSymbolCount;
PCOFFSymbolTable = (PIMAGE_SYMBOL)
((DWORD)pImageFileHeader + pImageFileHeader->PointerToSymbolTable);
COFFSymbolCount = pImageFileHeader->NumberOfSymbols;
if (full) {
DumpSymbolTable(PCOFFSymbolTable, fout, COFFSymbolCount);
} else {
/* DumpExternals(PCOFFSymbolTable, fout, COFFSymbolCount); */
DumpExternalsObjects(PCOFFSymbolTable, fout, COFFSymbolCount);
}
}
/*
*----------------------------------------------------------------------
* DumpFile --
*
* Open up a file, memory map it, and call the appropriate
* dumping routine
*----------------------------------------------------------------------
*/
void
DumpFile(LPSTR filename, FILE *fout, int full)
{
HANDLE hFile;
HANDLE hFileMapping;
LPVOID lpFileBase;
PIMAGE_DOS_HEADER dosHeader;
hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE) {
fprintf(stderr, "Couldn't open file with CreateFile()\n");
return;
}
hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (hFileMapping == 0) {
CloseHandle(hFile);
fprintf(stderr, "Couldn't open file mapping with CreateFileMapping()\n");
return;
}
lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
if (lpFileBase == 0) {
CloseHandle(hFileMapping);
CloseHandle(hFile);
fprintf(stderr, "Couldn't map view of file with MapViewOfFile()\n");
return;
}
dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
#if 0
DumpExeFile( dosHeader );
#else
fprintf(stderr, "File is an executable. I don't dump those.\n");
return;
#endif
}
/* Does it look like a i386 COFF OBJ file??? */
else if ((dosHeader->e_magic == 0x014C) && (dosHeader->e_sp == 0)) {
/*
* The two tests above aren't what they look like. They're
* really checking for IMAGE_FILE_HEADER.Machine == i386 (0x14C)
* and IMAGE_FILE_HEADER.SizeOfOptionalHeader == 0;
*/
DumpObjFile((PIMAGE_FILE_HEADER) lpFileBase, fout, full);
} else {
printf("unrecognized file format\n");
}
UnmapViewOfFile(lpFileBase);
CloseHandle(hFileMapping);
CloseHandle(hFile);
}
void
main(int argc, char **argv)
{
char *fargv[1000];
char cmdline[10000];
int i, arg;
FILE *fargs, *fout;
int pos;
int full = 0;
char *dllname = "";
char *outfile = NULL;
if (argc < 3) {
Usage:
fprintf(stderr, "Usage: %s ?-o outfile? ?-f(ull)? <dllname> <object filenames> ..\n", argv[0]);
exit(1);
}
fargs = NULL;
arg = 1;
while (argv[arg][0] == '-') {
if (strcmp(argv[arg], "--") == 0) {
arg++;
break;
} else if (strcmp(argv[arg], "-f") == 0) {
full = 1;
} else if (strcmp(argv[arg], "-x") == 0) {
fort = 1;
} else if (strcmp(argv[arg], "-o") == 0) {
arg++;
if (arg == argc) {
goto Usage;
}
outfile = argv[arg];
}
arg++;
}
if (arg == argc) {
goto Usage;
}
if (outfile) {
fout = fopen(outfile, "w+");
if (fout == NULL) {
fprintf(stderr, "Unable to open \'%s\' for writing:\n",
argv[arg]);
perror("");
exit(1);
}
} else {
fout = stdout;
}
if (! full) {
dllname = argv[arg];
arg++;
if (arg == argc) {
goto Usage;
}
fprintf(fout, "LIBRARY %s\n", dllname);
fprintf(fout, "EXETYPE WINDOWS\n");
fprintf(fout, "CODE PRELOAD MOVEABLE DISCARDABLE\n");
fprintf(fout, "DATA PRELOAD MOVEABLE MULTIPLE\n\n");
}
for (; arg < argc; arg++) {
WIN32_FIND_DATA FindFileData;
HANDLE SearchFile;
if (argv[arg][0] == '@') {
fargs = fopen(&argv[arg][1], "r");
if (fargs == NULL) {
fprintf(stderr, "Unable to open \'%s\' for reading:\n",
argv[arg]);
perror("");
exit(1);
}
pos = 0;
for (i = 0; i < arg; i++) {
strcpy(&cmdline[pos], argv[i]);
pos += strlen(&cmdline[pos]) + 1;
fargv[i] = argv[i];
}
fgets(&cmdline[pos], sizeof(cmdline), fargs);
fprintf(stderr, "%s\n", &cmdline[pos]);
fclose(fargs);
i += GetArgcArgv(&cmdline[pos], &fargv[i]);
argc = i;
argv = fargv;
}
/*
* Argument can contain the wildcard names
*/
SearchFile = FindFirstFile(argv[arg],&FindFileData);
if (SearchFile == INVALID_HANDLE_VALUE){
fprintf(stderr, "Unable to find \'%s\' for reading:\n",
argv[arg]);
exit(1);
}
else {
/*
* Since WIN32_FIND_DATA has no path information one has to extract it himself.
*/
TCHAR *filename = argv[arg];
TCHAR path[2048];
int i = strlen(filename);
i--;
while( filename[i] != '\\' &&
filename[i] != '/' && i >=0) i--;
do {
if (i >= 0) strncpy( path, filename, i+1); /* Generate the 'path' info */
path[i+1] = '\0';
DumpFile(strcat(path, FindFileData.cFileName), fout, full);
} while (FindNextFile(SearchFile,&FindFileData));
FindClose(SearchFile);
}
}
exit(0);
}
-
For help on using this list, send a message to
"gnu-win32-request AT cygnus DOT com" with one line of text: "help".
- Raw text -