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
30 char *get_export_names(FILE *fp
);
32 #define tcc_realloc realloc
34 /* extract the basename of a file */
35 static char *file_basename(const char *name
)
37 const char *p
= strchr(name
, 0);
46 int main(int argc
, char **argv
)
49 char infile
[MAX_PATH
];
50 char outfile
[MAX_PATH
];
52 static const char *ext
[] = { ".dll", ".exe", NULL
};
53 const char *file
, **pp
;
54 char path
[MAX_PATH
], *p
, *q
;
64 for (i
= 1; i
< argc
; ++i
) {
65 const char *a
= argv
[i
];
67 if (0 == strcmp(a
, "-v")) {
69 } else if (0 == strcmp(a
, "-o")) {
72 strcpy(outfile
, argv
[i
]);
75 } else if (0 == infile
[0])
84 "tiny_impdef: create export definition file (.def) from a dll\n"
85 "Usage: tiny_impdef library.dll [-o outputfile]\n"
92 strcpy(outfile
, file_basename(infile
));
93 q
= strrchr(outfile
, '.');
95 q
= strchr(outfile
, 0);
103 do if (SearchPath(NULL
, file
, *pp
, sizeof path
, path
, NULL
)) {
109 fp
= fopen(file
, "rb");
111 fprintf(stderr
, "tiny_impdef: no such file: %s\n", infile
);
115 printf("--> %s\n", file
);
117 p
= get_export_names(fp
);
119 fprintf(stderr
, "tiny_impdef: could not get exported function names.\n");
123 op
= fopen(outfile
, "w");
125 fprintf(stderr
, "tiny_impdef: could not create output file: %s\n", outfile
);
129 fprintf(op
, "LIBRARY %s\n\nEXPORTS\n", file_basename(file
));
130 for (q
= p
, i
= 0; *q
; ++i
) {
131 fprintf(op
, "%s\n", q
);
136 printf("<-- %s\n", outfile
);
137 printf("%d symbol(s) found\n", i
);
152 /* -------------------------------------------------------------- */
154 int read_mem(FILE *fp
, unsigned offset
, void *buffer
, unsigned len
)
156 fseek(fp
, offset
, 0);
157 return len
== fread(buffer
, 1, len
, fp
);
160 /* -------------------------------------------------------------- */
163 char *get_export_names(FILE *fp
)
168 IMAGE_SECTION_HEADER ish
;
169 IMAGE_EXPORT_DIRECTORY ied
;
171 IMAGE_FILE_HEADER ih
;
172 DWORD sig
, ref
, addr
, ptr
, namep
;
173 #ifdef TCC_TARGET_X86_64
174 IMAGE_OPTIONAL_HEADER64 oh
;
175 const int MACHINE
= 0x8664;
177 IMAGE_OPTIONAL_HEADER32 oh
;
178 const int MACHINE
= 0x014C;
180 int pef_hdroffset
, opt_hdroffset
, sec_hdroffset
;
185 if (!read_mem(fp
, 0, &dh
, sizeof dh
))
187 if (!read_mem(fp
, dh
.e_lfanew
, &sig
, sizeof sig
))
189 if (sig
!= 0x00004550)
191 pef_hdroffset
= dh
.e_lfanew
+ sizeof sig
;
192 if (!read_mem(fp
, pef_hdroffset
, &ih
, sizeof ih
))
194 if (MACHINE
!= ih
.Machine
)
196 opt_hdroffset
= pef_hdroffset
+ sizeof ih
;
197 sec_hdroffset
= opt_hdroffset
+ sizeof oh
;
198 if (!read_mem(fp
, opt_hdroffset
, &oh
, sizeof oh
))
201 if (IMAGE_DIRECTORY_ENTRY_EXPORT
>= oh
.NumberOfRvaAndSizes
)
204 addr
= oh
.DataDirectory
[IMAGE_DIRECTORY_ENTRY_EXPORT
].VirtualAddress
;
205 //printf("addr: %08x\n", addr);
206 for (i
= 0; i
< ih
.NumberOfSections
; ++i
) {
207 if (!read_mem(fp
, sec_hdroffset
+ i
* sizeof ish
, &ish
, sizeof ish
))
209 //printf("vaddr: %08x\n", ish.VirtualAddress);
210 if (addr
>= ish
.VirtualAddress
&& addr
< ish
.VirtualAddress
+ ish
.SizeOfRawData
)
216 ref
= ish
.VirtualAddress
- ish
.PointerToRawData
;
217 if (!read_mem(fp
, addr
- ref
, &ied
, sizeof ied
))
220 namep
= ied
.AddressOfNames
- ref
;
221 for (i
= 0; i
< ied
.NumberOfNames
; ++i
) {
222 if (!read_mem(fp
, namep
, &ptr
, sizeof ptr
))
227 p
= tcc_realloc(p
, n0
= n0
? n0
* 2 : 256);
228 if (!read_mem(fp
, ptr
- ref
+ l
, p
+ n
, 1) || ++l
>= 80) {
229 tcc_free(p
), p
= NULL
;
242 /* -------------------------------------------------------------- */