1 /* -------------------------------------------------------------- */
3 * tiny_impdef creates an export definition file (.def) from a dll
4 * on MS-Windows. Usage: tiny_impdef library.dll [-o outputfile]"
6 * Copyright (c) 2005,2007 grischka
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.
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.
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.
23 #ifndef TINY_IMPDEF_GET_EXPORT_NAMES_ONLY
25 #define WIN32_LEAN_AND_MEAN
31 char *get_export_names(int fd
);
33 #define tcc_realloc realloc
35 /* extract the basename of a file */
36 static char *file_basename(const char *name
)
38 const char *p
= strchr(name
, 0);
47 int main(int argc
, char **argv
)
50 char infile
[MAX_PATH
];
51 char outfile
[MAX_PATH
];
53 static const char *ext
[] = { ".dll", ".exe", NULL
};
54 const char *file
, **pp
;
55 char path
[MAX_PATH
], *p
, *q
;
65 for (i
= 1; i
< argc
; ++i
) {
66 const char *a
= argv
[i
];
68 if (0 == strcmp(a
, "-v")) {
70 } else if (0 == strcmp(a
, "-o")) {
73 strcpy(outfile
, argv
[i
]);
76 } else if (0 == infile
[0])
85 "tiny_impdef: create export definition file (.def) from a dll\n"
86 "Usage: tiny_impdef library.dll [-o outputfile]\n"
93 strcpy(outfile
, file_basename(infile
));
94 q
= strrchr(outfile
, '.');
96 q
= strchr(outfile
, 0);
104 do if (SearchPath(NULL
, file
, *pp
, sizeof path
, path
, NULL
)) {
110 fp
= fopen(file
, "rb");
112 fprintf(stderr
, "tiny_impdef: no such file: %s\n", infile
);
116 printf("--> %s\n", file
);
118 p
= get_export_names(fileno(fp
));
120 fprintf(stderr
, "tiny_impdef: could not get exported function names.\n");
124 op
= fopen(outfile
, "w");
126 fprintf(stderr
, "tiny_impdef: could not create output file: %s\n", outfile
);
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
);
137 printf("<-- %s\n", outfile
);
138 printf("%d symbol(s) found\n", i
);
153 int read_mem(int fd
, unsigned offset
, void *buffer
, unsigned len
)
155 lseek(fd
, offset
, SEEK_SET
);
156 return len
== read(fd
, buffer
, len
);
159 /* -------------------------------------------------------------- */
161 /* -------------------------------------------------------------- */
164 char *get_export_names(int fd
)
169 IMAGE_SECTION_HEADER ish
;
170 IMAGE_EXPORT_DIRECTORY ied
;
172 IMAGE_FILE_HEADER ih
;
173 DWORD sig
, ref
, addr
, ptr
, namep
;
174 #ifdef TCC_TARGET_X86_64
175 IMAGE_OPTIONAL_HEADER64 oh
;
176 const int MACHINE
= 0x8664;
178 IMAGE_OPTIONAL_HEADER32 oh
;
179 const int MACHINE
= 0x014C;
181 int pef_hdroffset
, opt_hdroffset
, sec_hdroffset
;
186 if (!read_mem(fd
, 0, &dh
, sizeof dh
))
188 if (!read_mem(fd
, dh
.e_lfanew
, &sig
, sizeof sig
))
190 if (sig
!= 0x00004550)
192 pef_hdroffset
= dh
.e_lfanew
+ sizeof sig
;
193 if (!read_mem(fd
, pef_hdroffset
, &ih
, sizeof ih
))
195 if (MACHINE
!= ih
.Machine
)
197 opt_hdroffset
= pef_hdroffset
+ sizeof ih
;
198 sec_hdroffset
= opt_hdroffset
+ sizeof oh
;
199 if (!read_mem(fd
, opt_hdroffset
, &oh
, sizeof oh
))
202 if (IMAGE_DIRECTORY_ENTRY_EXPORT
>= oh
.NumberOfRvaAndSizes
)
205 addr
= oh
.DataDirectory
[IMAGE_DIRECTORY_ENTRY_EXPORT
].VirtualAddress
;
206 //printf("addr: %08x\n", addr);
207 for (i
= 0; i
< ih
.NumberOfSections
; ++i
) {
208 if (!read_mem(fd
, sec_hdroffset
+ i
* sizeof ish
, &ish
, sizeof ish
))
210 //printf("vaddr: %08x\n", ish.VirtualAddress);
211 if (addr
>= ish
.VirtualAddress
&& addr
< ish
.VirtualAddress
+ ish
.SizeOfRawData
)
217 ref
= ish
.VirtualAddress
- ish
.PointerToRawData
;
218 if (!read_mem(fd
, addr
- ref
, &ied
, sizeof ied
))
221 namep
= ied
.AddressOfNames
- ref
;
222 for (i
= 0; i
< ied
.NumberOfNames
; ++i
) {
223 if (!read_mem(fd
, namep
, &ptr
, sizeof ptr
))
228 p
= tcc_realloc(p
, n0
= n0
? n0
* 2 : 256);
229 if (!read_mem(fd
, ptr
- ref
+ l
, p
+ n
, 1) || ++l
>= 80) {
230 tcc_free(p
), p
= NULL
;
243 /* -------------------------------------------------------------- */