OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tcl/] [win/] [winDumpExts.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * winDumpExts.c --
3
 * Author:   Gordon Chaffee, Scott Stanton
4
 *
5
 * History:  The real functionality of this file was written by
6
 *           Matt Pietrek in 1993 in his pedump utility.  I've
7
 *           modified it to dump the externals in a bunch of object
8
 *           files to create a .def file.
9
 *
10
 * 10/12/95  Modified by Scott Stanton to support Relocatable Object Module
11
 *           Format files for Borland C++ 4.5.
12
 *
13
 * Notes:    Visual C++ puts an underscore before each exported symbol.
14
 *           This file removes them.  I don't know if this is a problem
15
 *           this other compilers.  If _MSC_VER is defined,
16
 *           the underscore is removed.  If not, it isn't.  To get a
17
 *           full dump of an object file, use the -f option.  This can
18
 *           help determine the something that may be different with a
19
 *           compiler other than Visual C++.
20
 *----------------------------------------------------------------------
21
 *
22
 * RCS: @(#) $Id: winDumpExts.c,v 1.1.1.1 2002-01-16 10:25:39 markom Exp $
23
 */
24
 
25
#include <windows.h>
26
#include <stdio.h>
27
#include <string.h>
28
#include <process.h>
29
 
30
#ifdef _ALPHA_
31
#define e_magic_number IMAGE_FILE_MACHINE_ALPHA
32
#else
33
#define e_magic_number IMAGE_FILE_MACHINE_I386
34
#endif
35
 
36
/*
37
 *----------------------------------------------------------------------
38
 * GetArgcArgv --
39
 *
40
 *      Break up a line into argc argv
41
 *----------------------------------------------------------------------
42
 */
43
int
44
GetArgcArgv(char *s, char **argv)
45
{
46
    int quote = 0;
47
    int argc = 0;
48
    char *bp;
49
 
50
    bp = s;
51
    while (1) {
52
        while (isspace(*bp)) {
53
            bp++;
54
        }
55
        if (*bp == '\n' || *bp == '\0') {
56
            *bp = '\0';
57
            return argc;
58
        }
59
        if (*bp == '\"') {
60
            quote = 1;
61
            bp++;
62
        }
63
        argv[argc++] = bp;
64
 
65
        while (*bp != '\0') {
66
            if (quote) {
67
                if (*bp == '\"') {
68
                    quote = 0;
69
                    *bp = '\0';
70
                    bp++;
71
                    break;
72
                }
73
                bp++;
74
                continue;
75
            }
76
            if (isspace(*bp)) {
77
                *bp = '\0';
78
                bp++;
79
                break;
80
            }
81
            bp++;
82
        }
83
    }
84
}
85
 
86
/*
87
 *  The names of the first group of possible symbol table storage classes
88
 */
89
char * SzStorageClass1[] = {
90
    "NULL","AUTOMATIC","EXTERNAL","STATIC","REGISTER","EXTERNAL_DEF","LABEL",
91
    "UNDEFINED_LABEL","MEMBER_OF_STRUCT","ARGUMENT","STRUCT_TAG",
92
    "MEMBER_OF_UNION","UNION_TAG","TYPE_DEFINITION","UNDEFINED_STATIC",
93
    "ENUM_TAG","MEMBER_OF_ENUM","REGISTER_PARAM","BIT_FIELD"
94
};
95
 
96
/*
97
 * The names of the second group of possible symbol table storage classes
98
 */
99
char * SzStorageClass2[] = {
100
    "BLOCK","FUNCTION","END_OF_STRUCT","FILE","SECTION","WEAK_EXTERNAL"
101
};
102
 
103
/*
104
 *----------------------------------------------------------------------
105
 * GetSZStorageClass --
106
 *
107
 *      Given a symbol storage class value, return a descriptive
108
 *      ASCII string
109
 *----------------------------------------------------------------------
110
 */
111
PSTR
112
GetSZStorageClass(BYTE storageClass)
113
{
114
        if ( storageClass <= IMAGE_SYM_CLASS_BIT_FIELD )
115
                return SzStorageClass1[storageClass];
116
        else if ( (storageClass >= IMAGE_SYM_CLASS_BLOCK)
117
                      && (storageClass <= IMAGE_SYM_CLASS_WEAK_EXTERNAL) )
118
                return SzStorageClass2[storageClass-IMAGE_SYM_CLASS_BLOCK];
119
        else
120
                return "???";
121
}
122
 
123
/*
124
 *----------------------------------------------------------------------
125
 * GetSectionName --
126
 *
127
 *      Used by DumpSymbolTable, it gives meaningful names to
128
 *      the non-normal section number.
129
 *
130
 * Results:
131
 *      A name is returned in buffer
132
 *----------------------------------------------------------------------
133
 */
134
void
135
GetSectionName(WORD section, PSTR buffer, unsigned cbBuffer)
136
{
137
    char tempbuffer[10];
138
 
139
    switch ( (SHORT)section )
140
    {
141
      case IMAGE_SYM_UNDEFINED: strcpy(tempbuffer, "UNDEF"); break;
142
      case IMAGE_SYM_ABSOLUTE:  strcpy(tempbuffer, "ABS  "); break;
143
      case IMAGE_SYM_DEBUG:       strcpy(tempbuffer, "DEBUG"); break;
144
      default: wsprintf(tempbuffer, "%-5X", section);
145
    }
146
 
147
    strncpy(buffer, tempbuffer, cbBuffer-1);
148
}
149
 
150
/*
151
 *----------------------------------------------------------------------
152
 * DumpSymbolTable --
153
 *
154
 *      Dumps a COFF symbol table from an EXE or OBJ.  We only use
155
 *      it to dump tables from OBJs.
156
 *----------------------------------------------------------------------
157
 */
158
void
159
DumpSymbolTable(PIMAGE_SYMBOL pSymbolTable, FILE *fout, unsigned cSymbols)
160
{
161
    unsigned i;
162
    PSTR stringTable;
163
    char sectionName[10];
164
 
165
    fprintf(fout, "Symbol Table - %X entries  (* = auxillary symbol)\n",
166
            cSymbols);
167
 
168
    fprintf(fout,
169
     "Indx Name                 Value    Section    cAux  Type    Storage\n"
170
     "---- -------------------- -------- ---------- ----- ------- --------\n");
171
 
172
    /*
173
     * The string table apparently starts right after the symbol table
174
     */
175
    stringTable = (PSTR)&pSymbolTable[cSymbols];
176
 
177
    for ( i=0; i < cSymbols; i++ ) {
178
        fprintf(fout, "%04X ", i);
179
        if ( pSymbolTable->N.Name.Short != 0 )
180
            fprintf(fout, "%-20.8s", pSymbolTable->N.ShortName);
181
        else
182
            fprintf(fout, "%-20s", stringTable + pSymbolTable->N.Name.Long);
183
 
184
        fprintf(fout, " %08X", pSymbolTable->Value);
185
 
186
        GetSectionName(pSymbolTable->SectionNumber, sectionName,
187
                       sizeof(sectionName));
188
        fprintf(fout, " sect:%s aux:%X type:%02X st:%s\n",
189
               sectionName,
190
               pSymbolTable->NumberOfAuxSymbols,
191
               pSymbolTable->Type,
192
               GetSZStorageClass(pSymbolTable->StorageClass) );
193
#if 0
194
        if ( pSymbolTable->NumberOfAuxSymbols )
195
            DumpAuxSymbols(pSymbolTable);
196
#endif
197
 
198
        /*
199
         * Take into account any aux symbols
200
         */
201
        i += pSymbolTable->NumberOfAuxSymbols;
202
        pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
203
        pSymbolTable++;
204
    }
205
}
206
 
207
/*
208
 *----------------------------------------------------------------------
209
 * DumpExternals --
210
 *
211
 *      Dumps a COFF symbol table from an EXE or OBJ.  We only use
212
 *      it to dump tables from OBJs.
213
 *----------------------------------------------------------------------
214
 */
215
void
216
DumpExternals(PIMAGE_SYMBOL pSymbolTable, FILE *fout, unsigned cSymbols)
217
{
218
    unsigned i;
219
    PSTR stringTable;
220
    char *s, *f;
221
    char symbol[1024];
222
 
223
    /*
224
     * The string table apparently starts right after the symbol table
225
     */
226
    stringTable = (PSTR)&pSymbolTable[cSymbols];
227
 
228
    for ( i=0; i < cSymbols; i++ ) {
229
        if (pSymbolTable->SectionNumber > 0 && pSymbolTable->Type == 0x20) {
230
            if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
231
                if (pSymbolTable->N.Name.Short != 0) {
232
                    strncpy(symbol, pSymbolTable->N.ShortName, 8);
233
                    symbol[8] = 0;
234
                } else {
235
                    s = stringTable + pSymbolTable->N.Name.Long;
236
                    strcpy(symbol, s);
237
                }
238
                s = symbol;
239
                f = strchr(s, '@');
240
                if (f) {
241
                    *f = 0;
242
                }
243
#if defined(_MSC_VER) && defined(_X86_)
244
                if (symbol[0] == '_') {
245
                    s = &symbol[1];
246
                }
247
#endif
248
                if ((stricmp(s, "DllEntryPoint") != 0)
249
                        && (stricmp(s, "DllMain") != 0)) {
250
                    fprintf(fout, "\t%s\n", s);
251
                }
252
            }
253
        }
254
 
255
        /*
256
         * Take into account any aux symbols
257
         */
258
        i += pSymbolTable->NumberOfAuxSymbols;
259
        pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
260
        pSymbolTable++;
261
    }
262
}
263
 
264
/*
265
 *----------------------------------------------------------------------
266
 * DumpObjFile --
267
 *
268
 *      Dump an object file--either a full listing or just the exported
269
 *      symbols.
270
 *----------------------------------------------------------------------
271
 */
272
void
273
DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout, int full)
274
{
275
    PIMAGE_SYMBOL PCOFFSymbolTable;
276
    DWORD COFFSymbolCount;
277
 
278
    PCOFFSymbolTable = (PIMAGE_SYMBOL)
279
        ((DWORD)pImageFileHeader + pImageFileHeader->PointerToSymbolTable);
280
    COFFSymbolCount = pImageFileHeader->NumberOfSymbols;
281
 
282
    if (full) {
283
        DumpSymbolTable(PCOFFSymbolTable, fout, COFFSymbolCount);
284
    } else {
285
        DumpExternals(PCOFFSymbolTable, fout, COFFSymbolCount);
286
    }
287
}
288
 
289
/*
290
 *----------------------------------------------------------------------
291
 * SkipToNextRecord --
292
 *
293
 *      Skip over the current ROMF record and return the type of the
294
 *      next record.
295
 *----------------------------------------------------------------------
296
 */
297
 
298
BYTE
299
SkipToNextRecord(BYTE **ppBuffer)
300
{
301
    int length;
302
    (*ppBuffer)++;              /* Skip over the type.*/
303
    length = *((WORD*)(*ppBuffer))++; /* Retrieve the length. */
304
    *ppBuffer += length;        /* Skip over the rest. */
305
    return **ppBuffer;          /* Return the type. */
306
}
307
 
308
/*
309
 *----------------------------------------------------------------------
310
 * DumpROMFObjFile --
311
 *
312
 *      Dump a Relocatable Object Module Format file, displaying only
313
 *      the exported symbols.
314
 *----------------------------------------------------------------------
315
 */
316
void
317
DumpROMFObjFile(LPVOID pBuffer, FILE *fout)
318
{
319
    BYTE type, length;
320
    char symbol[1024], *s;
321
 
322
    while (1) {
323
        type = SkipToNextRecord(&(BYTE*)pBuffer);
324
        if (type == 0x90) {     /* PUBDEF */
325
            if (((BYTE*)pBuffer)[4] != 0) {
326
                length = ((BYTE*)pBuffer)[5];
327
                strncpy(symbol, ((char*)pBuffer) + 6, length);
328
                symbol[length] = '\0';
329
                s = symbol;
330
                if ((stricmp(s, "DllEntryPoint") != 0)
331
                        && (stricmp(s, "DllMain") != 0)) {
332
                    if (s[0] == '_') {
333
                        s++;
334
                        fprintf(fout, "\t_%s\n\t%s=_%s\n", s, s, s);
335
                    } else {
336
                        fprintf(fout, "\t%s\n", s);
337
                    }
338
                }
339
            }
340
        } else if (type == 0x8B || type == 0x8A) { /* MODEND */
341
            break;
342
        }
343
    }
344
}
345
 
346
/*
347
 *----------------------------------------------------------------------
348
 * DumpFile --
349
 *
350
 *      Open up a file, memory map it, and call the appropriate
351
 *      dumping routine
352
 *----------------------------------------------------------------------
353
 */
354
void
355
DumpFile(LPSTR filename, FILE *fout, int full)
356
{
357
    HANDLE hFile;
358
    HANDLE hFileMapping;
359
    LPVOID lpFileBase;
360
    PIMAGE_DOS_HEADER dosHeader;
361
 
362
    hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
363
                       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
364
 
365
    if (hFile == INVALID_HANDLE_VALUE) {
366
        fprintf(stderr, "Couldn't open file with CreateFile()\n");
367
        return;
368
    }
369
 
370
    hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
371
    if (hFileMapping == 0) {
372
        CloseHandle(hFile);
373
        fprintf(stderr, "Couldn't open file mapping with CreateFileMapping()\n");
374
        return;
375
    }
376
 
377
    lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
378
    if (lpFileBase == 0) {
379
        CloseHandle(hFileMapping);
380
        CloseHandle(hFile);
381
        fprintf(stderr, "Couldn't map view of file with MapViewOfFile()\n");
382
        return;
383
    }
384
 
385
    dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
386
    if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
387
#if 0
388
        DumpExeFile( dosHeader );
389
#else
390
        fprintf(stderr, "File is an executable.  I don't dump those.\n");
391
        return;
392
#endif
393
    }
394
    /* Does it look like a i386 COFF OBJ file??? */
395
    else if ((dosHeader->e_magic == e_magic_number)
396
            && (dosHeader->e_sp == 0)) {
397
        /*
398
         * The two tests above aren't what they look like.  They're
399
         * really checking for IMAGE_FILE_HEADER.Machine == i386 (0x14C)
400
         * and IMAGE_FILE_HEADER.SizeOfOptionalHeader == 0;
401
         */
402
        DumpObjFile((PIMAGE_FILE_HEADER) lpFileBase, fout, full);
403
    } else if (*((BYTE *)lpFileBase) == 0x80) {
404
        /*
405
         * This file looks like it might be a ROMF file.
406
         */
407
        DumpROMFObjFile(lpFileBase, fout);
408
    } else {
409
        printf("unrecognized file format\n");
410
    }
411
    UnmapViewOfFile(lpFileBase);
412
    CloseHandle(hFileMapping);
413
    CloseHandle(hFile);
414
}
415
 
416
void
417
main(int argc, char **argv)
418
{
419
    char *fargv[1000];
420
    char cmdline[10000];
421
    int i, arg;
422
    FILE *fout;
423
    int pos;
424
    int full = 0;
425
    char *outfile = NULL;
426
 
427
    if (argc < 3) {
428
      Usage:
429
        fprintf(stderr, "Usage: %s ?-o outfile? ?-f(ull)? <dllname> <object filenames> ..\n", argv[0]);
430
        exit(1);
431
    }
432
 
433
    arg = 1;
434
    while (argv[arg][0] == '-') {
435
        if (strcmp(argv[arg], "--") == 0) {
436
            arg++;
437
            break;
438
        } else if (strcmp(argv[arg], "-f") == 0) {
439
            full = 1;
440
        } else if (strcmp(argv[arg], "-o") == 0) {
441
            arg++;
442
            if (arg == argc) {
443
                goto Usage;
444
            }
445
            outfile = argv[arg];
446
        }
447
        arg++;
448
    }
449
    if (arg == argc) {
450
        goto Usage;
451
    }
452
 
453
    if (outfile) {
454
        fout = fopen(outfile, "w+");
455
        if (fout == NULL) {
456
            fprintf(stderr, "Unable to open \'%s\' for writing:\n",
457
                    argv[arg]);
458
            perror("");
459
            exit(1);
460
        }
461
    } else {
462
        fout = stdout;
463
    }
464
 
465
    if (! full) {
466
        char *dllname = argv[arg];
467
        arg++;
468
        if (arg == argc) {
469
            goto Usage;
470
        }
471
        fprintf(fout, "LIBRARY    %s\n", dllname);
472
        fprintf(fout, "EXETYPE WINDOWS\n");
473
        fprintf(fout, "CODE PRELOAD MOVEABLE DISCARDABLE\n");
474
        fprintf(fout, "DATA PRELOAD MOVEABLE MULTIPLE\n\n");
475
        fprintf(fout, "EXPORTS\n");
476
    }
477
 
478
    for (; arg < argc; arg++) {
479
        if (argv[arg][0] == '@') {
480
            FILE *fargs = fopen(&argv[arg][1], "r");
481
            if (fargs == NULL) {
482
                fprintf(stderr, "Unable to open \'%s\' for reading:\n",
483
                        argv[arg]);
484
                perror("");
485
                exit(1);
486
            }
487
            pos = 0;
488
            for (i = 0; i < arg; i++) {
489
                strcpy(&cmdline[pos], argv[i]);
490
                pos += strlen(&cmdline[pos]) + 1;
491
                fargv[i] = argv[i];
492
            }
493
            fgets(&cmdline[pos], sizeof(cmdline), fargs);
494
            fprintf(stderr, "%s\n", &cmdline[pos]);
495
            fclose(fargs);
496
            i += GetArgcArgv(&cmdline[pos], &fargv[i]);
497
            argc = i;
498
            argv = fargv;
499
        }
500
        DumpFile(argv[arg], fout, full);
501
    }
502
    exit(0);
503
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.