Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6429 siemargl 1
/* -------------------------------------------------------------- */
2
/*
3
 * tiny_impdef creates an export definition file (.def) from a dll
4
 * on MS-Windows. Usage: tiny_impdef library.dll [-o outputfile]"
5
 *
6
 *  Copyright (c) 2005,2007 grischka
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
 */
22
 
23
#ifndef TINY_IMPDEF_GET_EXPORT_NAMES_ONLY
24
 
25
#define WIN32_LEAN_AND_MEAN
26
#include 
27
#include 
28
#include 
29
#include 
30
 
31
char *get_export_names(int fd);
32
#define tcc_free free
33
#define tcc_realloc realloc
34
 
35
/* extract the basename of a file */
36
static char *file_basename(const char *name)
37
{
38
    const char *p = strchr(name, 0);
39
    while (p > name
40
        && p[-1] != '/'
41
        && p[-1] != '\\'
42
        )
43
        --p;
44
    return (char*)p;
45
}
46
 
47
int main(int argc, char **argv)
48
{
49
    int ret, v, i;
50
    char infile[MAX_PATH];
51
    char outfile[MAX_PATH];
52
 
53
    static const char *ext[] = { ".dll", ".exe", NULL };
54
    const char *file, **pp;
55
    char path[MAX_PATH], *p, *q;
56
    FILE *fp, *op;
57
 
58
    infile[0] = 0;
59
    outfile[0] = 0;
60
    fp = op = NULL;
61
    v = 0;
62
    ret = 1;
63
    p = NULL;
64
 
65
    for (i = 1; i < argc; ++i) {
66
        const char *a = argv[i];
67
        if ('-' == a[0]) {
68
            if (0 == strcmp(a, "-v")) {
69
                v = 1;
70
            } else if (0 == strcmp(a, "-o")) {
71
                if (++i == argc)
72
                    goto usage;
73
                strcpy(outfile, argv[i]);
74
            } else
75
                goto usage;
76
        } else if (0 == infile[0])
77
            strcpy(infile, a);
78
        else
79
            goto usage;
80
    }
81
 
82
    if (0 == infile[0]) {
83
usage:
84
        fprintf(stderr,
85
            "tiny_impdef: create export definition file (.def) from a dll\n"
86
            "Usage: tiny_impdef library.dll [-o outputfile]\n"
87
            );
88
        goto the_end;
89
    }
90
 
91
    if (0 == outfile[0])
92
    {
93
        strcpy(outfile, file_basename(infile));
94
        q = strrchr(outfile, '.');
95
        if (NULL == q)
96
            q = strchr(outfile, 0);
97
        strcpy(q, ".def");
98
    }
99
 
100
    file = infile;
101
 
102
#ifdef _WIN32
103
    pp = ext;
104
    do if (SearchPath(NULL, file, *pp, sizeof path, path, NULL)) {
105
       file = path;
106
       break;
107
    } while (*pp++);
108
#endif
109
 
110
    fp = fopen(file, "rb");
111
    if (NULL == fp) {
112
        fprintf(stderr, "tiny_impdef: no such file: %s\n", infile);
113
        goto the_end;
114
    }
115
    if (v)
116
        printf("--> %s\n", file);
117
 
118
    p = get_export_names(fileno(fp));
119
    if (NULL == p) {
120
        fprintf(stderr, "tiny_impdef: could not get exported function names.\n");
121
        goto the_end;
122
    }
123
 
124
    op = fopen(outfile, "w");
125
    if (NULL == op) {
126
        fprintf(stderr, "tiny_impdef: could not create output file: %s\n", outfile);
127
        goto the_end;
128
    }
129
 
130
    fprintf(op, "LIBRARY %s\n\nEXPORTS\n", file_basename(file));
131
    for (q = p, i = 0; *q; ++i) {
132
        fprintf(op, "%s\n", q);
133
        q += strlen(q) + 1;
134
    }
135
 
136
    if (v) {
137
        printf("<-- %s\n", outfile);
138
        printf("%d symbol(s) found\n", i);
139
    }
140
 
141
    ret = 0;
142
 
143
the_end:
144
    if (p)
145
        free(p);
146
    if (fp)
147
        fclose(fp);
148
    if (op)
149
        fclose(op);
150
    return ret;
151
}
152
 
153
int read_mem(int fd, unsigned offset, void *buffer, unsigned len)
154
{
155
    lseek(fd, offset, SEEK_SET);
156
    return len == read(fd, buffer, len);
157
}
158
 
159
/* -------------------------------------------------------------- */
160
 
161
#if defined TCC_TARGET_X86_64
162
# define IMAGE_FILE_MACHINE 0x8664
163
#elif defined TCC_TARGET_ARM
164
# define IMAGE_FILE_MACHINE 0x01C0
165
#elif 1 /* defined TCC_TARGET_I386 */
166
# define IMAGE_FILE_MACHINE 0x014C
167
#endif
168
 
169
/* -------------------------------------------------------------- */
170
#endif
171
 
172
char *get_export_names(int fd)
173
{
174
    int l, i, n, n0;
175
    char *p;
176
 
177
    IMAGE_SECTION_HEADER ish;
178
    IMAGE_EXPORT_DIRECTORY ied;
179
    IMAGE_DOS_HEADER dh;
180
    IMAGE_FILE_HEADER ih;
181
    DWORD sig, ref, addr, ptr, namep;
182
#ifdef TCC_TARGET_X86_64
183
    IMAGE_OPTIONAL_HEADER64 oh;
184
#else
185
    IMAGE_OPTIONAL_HEADER32 oh;
186
#endif
187
    int pef_hdroffset, opt_hdroffset, sec_hdroffset;
188
 
189
    n = n0 = 0;
190
    p = NULL;
191
 
192
    if (!read_mem(fd, 0, &dh, sizeof dh))
193
        goto the_end;
194
    if (!read_mem(fd, dh.e_lfanew, &sig, sizeof sig))
195
        goto the_end;
196
    if (sig != 0x00004550)
197
        goto the_end;
198
    pef_hdroffset = dh.e_lfanew + sizeof sig;
199
    if (!read_mem(fd, pef_hdroffset, &ih, sizeof ih))
200
        goto the_end;
201
    if (IMAGE_FILE_MACHINE != ih.Machine)
202
        goto the_end;
203
    opt_hdroffset = pef_hdroffset + sizeof ih;
204
    sec_hdroffset = opt_hdroffset + sizeof oh;
205
    if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
206
        goto the_end;
207
 
208
    if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
209
        goto the_end;
210
 
211
    addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
212
    //printf("addr: %08x\n", addr);
213
    for (i = 0; i < ih.NumberOfSections; ++i) {
214
        if (!read_mem(fd, sec_hdroffset + i * sizeof ish, &ish, sizeof ish))
215
            goto the_end;
216
        //printf("vaddr: %08x\n", ish.VirtualAddress);
217
        if (addr >= ish.VirtualAddress && addr < ish.VirtualAddress + ish.SizeOfRawData)
218
            goto found;
219
    }
220
    goto the_end;
221
 
222
found:
223
    ref = ish.VirtualAddress - ish.PointerToRawData;
224
    if (!read_mem(fd, addr - ref, &ied, sizeof ied))
225
        goto the_end;
226
 
227
    namep = ied.AddressOfNames - ref;
228
    for (i = 0; i < ied.NumberOfNames; ++i) {
229
        if (!read_mem(fd, namep, &ptr, sizeof ptr))
230
            goto the_end;
231
        namep += sizeof ptr;
232
        for (l = 0;;) {
233
            if (n+1 >= n0)
234
                p = tcc_realloc(p, n0 = n0 ? n0 * 2 : 256);
235
            if (!read_mem(fd, ptr - ref + l++, p + n, 1)) {
236
                tcc_free(p), p = NULL;
237
                goto the_end;
238
            }
239
            if (p[n++] == 0)
240
                break;
241
        }
242
    }
243
    if (p)
244
        p[n] = 0;
245
the_end:
246
    return p;
247
}
248
 
249
/* -------------------------------------------------------------- */