1 Winedump - A Wine DLL tool
2 --------------------------
7 Most of the functions available in Windows, and in Windows applications, are
8 made available to applications from DLL's. Wine implements the Win32 API by
9 providing replacement's for the essential Windows DLLs in the form of Unix
10 shared library (.so) files, and provides a tool, winebuild, to allow Winelib
11 applications to link to functions exported from shared libraries/DLLs.
13 The first thing to note is that there are many DLLs that aren't yet
14 implemented in Wine. Mostly this doesn't present a problem because the native
15 Win32 versions of lots of DLLs can be used without problems, at least on
16 x86 platforms. However, one of Wine's goals is the eventual replacement of
17 every essential O/S DLL so that the whole API is implemented. This not only
18 means that a copy of the real O/S is not needed, but also that non-x86
19 platforms can run most Win32 programs after recompiling.
21 The second thing to note is that applications commonly use their own or 3rd
22 party DLLs to provide functionality. In order to call these functions with
23 a Winelib program, some 'glue' is needed. This 'glue' comes in the form of
24 a .spec file. The .spec file, along with some dummy code, is used to create
25 a Wine .so corresponding to the Windows DLL. The winebuild program can then
26 resolve calls made to DLL functions to call your dummy DLL. You then tell
27 Wine to only use the native Win32 version of the DLL, and at runtime your
28 calls will be made to the Win32 DLL. If you want to reimplement the dll,
29 you simply add the code for the DLL calls to your stub .so, and then tell
30 Wine to use the .so version instead [1].
32 These two factors mean that if you are:
34 A: Reimplementing a Win32 DLL for use within Wine, or
35 B: Compiling a Win32 application with Winelib that uses x86 DLLs
37 Then you will need to create a .spec file (amongst other things). If you
38 won't be doing either of the above, then you won't need winedump.
40 Creating a .spec file is a labour intensive task during which it is easy
41 to make a mistake. The idea of winedump is to automate this task and create
42 the majority of the support code needed for your DLL. In addition you can
43 have winedump create code to help you reimplement a DLL, by providing
44 tracing of calls to the DLL, and (in some cases) automatically determining
45 the parameters, calling conventions, and return values of the DLLs functions.
47 You can think of winedump as somewhat similar to the IMPLIB tool when
48 only its basic functionality is used. In addition, winedump can be used to
49 dump other information from PE files; See the section 'Dumping' below.
55 Winedump is a command line tool. Running it with no arguments or passing
56 it '-h' on the command line lists the available options:
58 Usage: winedump [-h | sym <sym> | spec <dll> | dump <dll>] [mode options]
60 Winedump can be used in several different modes. The first argument to the
61 program determines the mode winedump will run in.
63 -h Help mode. Basic usage help is printed.
64 sym Symbol mode. Used to demangle C++ symbols
65 spec For generating .spec files and stub DLL's
66 dump To dump the contents of a PE file.
68 [mode options] depend on the mode given as the first argument.
71 No options are used. The program prints help and then exits
74 <sym> Demangles C++ symbol <sym>' and then exits.
77 <dll> Use dll for input file and generate implementation code
78 -I dir Look for prototypes in 'dir' (implies -c)
79 -c Generate skeleton code (requires -I)
80 -t TRACE arguments (implies -c)
81 -f dll Forward calls to 'dll' (implies -t)
82 -D Generate documentation
83 -o name Set the output dll name (default: dll)
84 -C Assume __cdecl calls (default: __stdcall)
85 -s num Start prototype search after symbol 'num'
86 -e num End prototype search after symbol 'num'
87 -S symfile Search only prototype names found in 'symfile'
88 -q Don't show progress (quiet).
89 -v Show lots of detail while working (verbose).
92 <dll> Dumps the content of the dll named <dll>
93 -C Turns on symbol demangling
94 -f Dumps file header information
95 -j sect_name Dumps only the content of section sect_name (import, export, debug)
98 Each modes options are explained below.
100 Spec mode: Basic options
101 ------------------------
103 OPTION: -o name Set the output dll name (default: dll)
105 By default, if winedump is run on DLL 'foo', it creates files called
106 'foo.spec', 'foo_main.c' etc, and prefixes any functions generated
107 with 'FOO_'. If '-o bar' is given, these will become 'bar.spec',
108 'bar_main.c' and 'BAR_' respectively.
110 This option is mostly useful when generating a forwarding DLL. See below
111 for more information.
113 OPTION: -q Don't show progress (quiet).
114 -v Show lots of detail while working (verbose).
116 There are 3 levels of output while winedump is running. The default level,
117 when neither -q or -v are given, prints the number of exported functions
118 found in the dll, followed by the name of each function as it is processed,
119 and a status indication of whether it was processed OK. With -v given, a
120 lot of information is dumped while winedump works: this is intended to help
121 debug any problems. Giving -q means nothing will be printed unless a fatal
122 error occurs, and could be used when calling winedump from a script.
125 OPTION: -C Assume __cdecl calls (default: __stdcall)
127 This option determines the default calling convention used by the functions
128 in the DLL. If specbuild cannot determine the convention, __stdcall is
129 used by default, unless this option has been given.
131 Unless -q is given, a warning will be printed for every function that
132 winedump determines the calling convention for and which does not match
133 the assumed calling convention.
136 Spec mode: Generating stub DLLS
137 -------------------------------
139 If all you want to do is generate a stub DLL to allow you to link your
140 Winelib application to an x86 DLL, the above options are all you need.
142 As an example, lets assume the application you are porting uses functions
143 from a 3rd party dll called 'zipextra.dll', and the functions in the DLL
144 use the __stdcall calling convention. Copy zipextra.dll to an empty directory,
145 change to it, and run winedump as follows:
147 winedump spec zipextra (Note: this assumes winedump is in your path)
149 The output will look something like the following:
151 22 named symbols in DLL, 22 in total ...
152 Export 1 - '_OpenZipFile' ... [Ignoring]
153 Export 2 - '_UnZipFile' ... [Ignoring]
156 "[Ignoring]" Just tells you that winedump isn't trying to determine the
157 parameters or return types of the functions, its just creating stubs.
159 The following files are created:
162 This is the .spec file. Each exported function is listed as a stub:
168 This means that winebuild will generate dummy code for this function. That
169 doesn't concern us, because all we want is for winebuild to allow the symbols
170 to be resolved when linking. At run-time, the functions in the native DLL will
171 be called; this just allows us to link.
173 zipextra_dll.h zipextra_main.c
174 These are source code files containing the minimum set of code to build
175 a stub DLL. The C file contains one function, ZIPEXTRA_Init, which does
176 nothing (but must be present).
179 This is a template for 'configure' to produce a makefile. It is designed
180 for a DLL that will be inserted into the Wine source tree. If your DLL
181 will not be part of Wine, or you don't wish to build it this way,
182 you should look at the Wine tool 'winemaker' to generate a DLL project.
184 FIXME: winemaker could run this tool automatically when generating projects
185 that use extra DLL's (*.lib in the "ADD LINK32" line in .dsp) ....
188 A shell script for adding zipextra to the Wine source tree (see below).
191 Spec mode: Inserting a stub DLL into the Wine tree
192 --------------------------------------------------
194 To build your stub DLL as part of Wine, do the following:
196 chmod a+x ./zipextra_install
197 ./zipextra_install <wine-path>
204 Your application can now link with the DLL.
206 If you recieve the following error when running autoconf:
208 autoconf: configure.in: No such file or directory
210 Then you need to install a newer version of autoconf. At the time of writing
211 version 2.53 or later is required to re-generate configure.
213 If you have problems with this step, you can post to the wine-devel mailing
214 list for help. The build process can change regularly and winebuild may lag
217 NOTE: **DO NOT** submit patches to Wine for 3rd party DLLs! Building DLLs
218 into your copy of the tree is just a simple way for you to link. When
219 you release your application you won't be distributing the Unix .so
220 anyway, just the Win32 DLL. As you update your version of Wine
221 you can simply re-run the procedure above (Since no patches are
222 involved, it should be pretty resiliant to changes).
225 Spec mode: Advanced Options
226 ---------------------------
228 This section discusses features of winedump that are useful to Wine Hackers
229 or developers looking to reimplement a Win32 DLL for Unix. Using these
230 features means you will need to be able to resolve compilation problems and
231 have a general understanding of Wine programming.
234 OPTION: -I dir Look for prototypes in 'dir' (implies -c)
236 For all advanced functionality, you must give winedump a directory or file that
237 contains prototypes for the DLL. In the case of Windows DLLs, this could be
238 either the standard include directory from your compiler, or an SDK include
239 directory. If you have a text document with prototypes (such as documentation)
240 that can be used also, however you may need to delete some non-code lines to
241 ensure that prototypes are parsed correctly.
243 The 'dir' argument can also be a file specification (e.g. "include/*"). If
244 it contains wildcards you must quote it to prevent the shell from expanding it.
246 If you have no prototypes, specify /dev/null for 'dir'. Winedump may still
247 be able to generate some working stub code for you.
249 Once you have created your DLL, if you generated code (see below), you can
250 backup the DLL header file created and use it for rebuilding the DLL (you
251 should remove the DLLNAME_ prefix from the prototypes to make this work). This
252 allows you to add names to the function arguments, for example, so that the
253 comments and prototype in the regenerated DLL will be clearer.
255 Winedump searches for prototypes using 'grep', and then retrieves each
256 prototype by calling 'function_grep.pl', a Perl script. When you pass the -v
257 option on the command line, the calls to both of these programs are logged.
258 This allows you to see where each function definition has come from. Should
259 winedump take an excessively long time to locate a prototype, you can check
260 that it is searching the right files; you may want to limit the number of files
261 searched if locating the prototype takes too long.
263 You can compile function_grep.pl for a slight increase in performance; see
264 'man perlcc' for details.
267 OPTION: -s num Start prototype search after symbol 'num'
268 -e num End prototype search after symbol 'num'
270 By passing the -s or -e options you can have winedump try to generate code
271 for only some functions in your DLL. This may be used to generate a single
272 function, for example, if you wanted to add functionality to an existing DLL.
274 They is also useful for debugging problems, in conjunction with -v.
276 OPTION: -S symfile Search only prototype names found in 'symfile'
278 If you want to only generate code for a subset of exported functions from
279 your source DLL, you can use this option to provide a text file containing
280 the names of the symbols to extract, one per line. Only the symbols present
281 in this file will be used in your output DLL.
283 OPTION: -D Generate documentation
285 By default, winedump generates a standard comment at the header of each
286 function it generates. Passing this option makes winedump output a full
287 header template for standard Wine documentation, listing the parameters
288 and return value of the function.
291 OPTION: -c Generate skeleton code (requires -I)
293 This option tells winedump that you want to create function stubs for
294 each function in the DLL. This is the most basic level of code generation.
295 As winedump reads each exported symbol from the source DLL, it first tries
296 to demangle the name. If the name is a C++ symbol, the arguments, class and
297 return value are all encoded into the symbol name. Winedump converts this
298 information into a C function prototype. If this fails, the file(s) specified
299 in the -I argument are scanned for a function prototype. If one is found it
300 is used for the next step of the process, code generation.
302 Note: C++ name demangling is currently under development. Since the algorithm
303 used is not documented, it must be decoded. Many simple prototypes are already
306 If winedump does not find a prototype, it emits code like the following:
314 /* __cdecl ZIPEXTRA__OpenZipFile() */
316 in the C source file:
318 /*********************************************************************
319 * _OpenZipFile (ZIPEXTRA.@)
323 __stdcall ZIPEXTRA__OpenZipFile()
325 /* '@Stubbed'ed in .spec */
329 If a prototype is found, or correctly demangled, the following is emitted:
332 @ stdcall _OpenZipFile ZIPEXTRA__OpenZipFile
335 BOOL __stdcall ZIPEXTRA__OpenZipFile(LPCSTR pszFileName);
338 BOOL __stdcall ZIPEXTRA__OpenZipFile(LPCSTR pszFileName)
344 Note that if the prototype does not contain argument names, winedump will
345 add them following the convention arg0, arg1 ... argN. If the function is
346 demangled C++, the first argument will be called '_this' if an implicit this
347 pointer is passed (i.e. the function is a non-static class member function).
350 OPTION: -t TRACE arguments (implies -c)
352 This option produces the same code as -c, except that arguments are printed
353 out when the function is called, so the FIXME in the above example becomes:
355 FIXME("(%s) stub", pszFileName);
357 Structs that are passed by value are printed as "struct", and functions
358 that take variable argument lists print "...".
361 OPTION: -f dll Forward calls to 'dll' (implies -t)
363 This is the most complicated level of code generation. The same code is
364 generated as -t, however support is added for forwarding calls to another
365 DLL. The DLL to forward to is given as 'dll'. Lets suppose we built the
366 examples above using "-f real_zipextra". The code generated will look like
370 As for -c, except if a function prototype was not found:
372 @ forward _OpenZipFile real_zipextra._OpenZipFile
374 In this case the function is forwarded to the destination DLL rather
382 A variable "hDLL" is added to hold a pointer to the DLL to forward to, and
383 the initialisation code in ZIPEXTRA_Init is changed to load and free the
384 forward DLL automatically:
386 HMODULE hDLL = 0; /* DLL to call through to */
388 BOOL WINAPI ZIPEXTRA_Init(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
390 TRACE("(0x%08x, %ld, %p)\n", hinstDLL, fdwReason, lpvReserved);
392 if (fdwReason == DLL_PROCESS_ATTACH)
394 hDLL = LoadLibraryA( "real_zipextra" );
395 TRACE ("Forwarding DLL (real_zipextra) loaded\n" );
397 else if (fdwReason == DLL_PROCESS_DETACH)
400 TRACE ("Forwarding DLL (real_zipextra) freed\n" );
406 The stub function is changed to call the forwarding DLL and return that value.
408 BOOL __stdcall ZIPEXTRA__OpenZipFile(LPCSTR pszFileName)
410 BOOL (__stdcall *pFunc)(LPCSTR) = (void*)GetProcAddress(hDLL,"_OpenZipFile");
412 TRACE("((LPCSTR)%s) stub\n", pszFileName);
413 retVal = pFunc(pszFileName);
414 TRACE("returned (%ld)\n",(LONG)retVal));
418 This allows you to investigate the workings of a DLL without interfering in
419 its operation in any way (unless you want to).
421 In the example I have been using, we probably should have used the -o option
422 to change the ouput name of our DLL to something else, and used the -f
423 option to forward to the real zipextra DLL:
425 winedump spec zipextra -f zipextra -o myzipextra -I "~/zipextra/include/*h"
427 Then in the .spec file for our Winelib application, we add the line:
431 When we build our application, winebuild resolves the calls to our Unix .so.
432 As our application runs we can see the values of all parameters passed to
433 the DLL, and any values returned, without having to write code to dump
434 them ourselves (see below for a better way to wrap a DLL for forwarding).
436 This isn't a very realistic example of the usefulness of this feature,
437 however, since we could print out the results anyway, because it is our
438 application making the calls to the DLL. Where DLL forwarding is most useful
439 is where an application or DLL we didn't write calls functions in the DLL.
440 In this case we can capture the sequence of calls made, and the values passed
441 around. This is an aid in reimplementing the DLL, since we can add code for a
442 function, print the results, and then call the real DLL and compare. Only
443 when our code is the same do we need to remove the function pointer and the
444 call to the real DLL. A similar feature in wine is +relay debugging. Using a
445 fowarding DLL allows more granular reporting of arguments, because you can
446 write code to dump out the contents of types/structures rather than just
447 their address in memory. A future version of winedump may generate this
448 code automatically for common Win32 types.
450 See below for more information on setting up a forwarding DLL.
453 Spec mode: Problems compiling a DLL containing generated code
454 -------------------------------------------------------------
456 Unless you are very lucky, you will need to do a small amount of work to
457 get a DLL generated with -c, -t or -f to compile. The reason for this is
458 that most DLLs will use custom types such as structs whose definition
459 is not known to the code in the DLL.
461 Heres an example prototype from crtdll:
463 double __cdecl _cabs(struct _complex arg0)
465 The definition for the _complex struct needs to be given. Since it is passed
466 by value, its size also needs to be correct in order to forward the call
467 correctly to a native DLL. In this case the structure is 8 bytes in size, which
468 means that the gcc compile flag -freg-struct-return must be given when
469 compiling the function in order to be compatable with the native DLL. (In
470 general this is not an issue, but you need to be aware of such issues if you
471 encounter problems with your forwarding DLL).
473 For third party (non C++) DLL's, the header(s) supplied with the DLL can
474 normally be added as an include to the generated DLL header. For other DLLs
475 I suggest creating a seperate header in the DLL directory and adding any
476 needed types to that. This allows you to rebuild the DLL at whim, for example
477 if a new version of winedump brings increased functionality, then you
478 only have to overwrite the generated files and re-include the header to take
481 Usually there isn't much work to do to get the DLL to compile if you have
482 headers. As an example, building a forwarded crtdll, which contains 520
483 functions, required 20 types to be defined before it compiled. Of these,
484 about half were structures, so about 35 lines of code were needed. The only
485 change to the generated code was one line in the header to include the type
488 To save some typing in case you don't have headers for your DLL type, winedump
489 will dump dummy declarations for unknown classes and types it encounters,
490 if you use the -v option. These can be piped directly into a fix-up header
491 file for use in compiling your DLL. For example, if winedump encounters the
494 ??0foobar@@QAE@ABV0@@Z (Which is a constructor for a foobar object)
496 It will emit the following with -v set:
498 struct foobar { int _FIXME; };
500 (Classes are mapped to C structs when generating code).
502 The output should be piped through 'sort' and 'uniq' to remove multiple
505 winedump foo -c -I "inc/*.h" -v | grep FIXME | sort | uniq > fixup.h
507 By adding '#include "fixup.h"' to foobar_dll.h your compile errors will be
510 If winedump encounters a type it doesnt know that is passed by value (as in
511 the _cabs example above), it also prints a FIXME message like:
513 /* FIXME: By value type: Assumed 'int' */ typedef int ldiv_t;
515 If the type is not an int, you will need to change the code and possibly
516 the .spec entry in order to forward correctly. Otherwise, include the typedef
517 in your fixup header to avoid compile errors.
520 Spec mode: Using a forwarding DLL
521 ---------------------------------
523 To create and use a forwarding DLL to trace DLL calls, you need to first
524 create a DLL using the -f option as outlined above, and get it to compile.
525 In order to forward calls the following procedure can be used (for this
526 example we are going to build a forwarding msvcrt.dll for the purpose
527 of reimplementing it).
529 First we create the forwarding DLL. We will rename the real msvcrt.dll on our
530 system to ms_msvcrt.dll, and our msvcrt implementation will call it:
532 winedump spec msvcrt -C -f ms_msvcrt -I "inc/*.h"
534 We then install this DLL into the Wine tree and add the types we need to
535 make it compile. Once the DLL compiles, we create a dummy ms_msvcrt DLL so
536 winebuild will resolve our forward calls to it (for the cases where winedump
537 couldn't generate code and has placed an '@forward' line in the .spec file):
539 winedump spec msvcrt -C -o ms_msvcrt
541 Install this DLL into the wine tree (since its a stub DLL, no changes are
544 Now uncomment the line that winedump inserted into msvcrt.spec:
546 #inport ms_msvcrt.dll
550 Finally, we must tell Wine to only use the builtin msvcrt.dll and to only use
551 the native (Win32) ms_msvcrt.dll. Add the following two lines to ~/.wine/config
552 under the [DllOverrides] section:
554 ;Use our implmentation of msvcrt
555 "msvcrt" = "builtin, so"
556 ;Use only the Win32 ms_msvcrt
557 "ms_msvcrt" = "native"
559 At this point, when any call is made to msvcrt.dll, Our libmsvcrt.so recieves
560 the call. It then forwards or calls ms_msvcrt.dll, which is the native dll. We
561 recieve a return value and pass it back to our caller, having TRACEd the
562 arguments on the way.
564 At this point you are ready to start reimplementing the calls.
570 If you need to demangle a single C++ symbol, you can use the demangling mode
571 of winedump. This is useful for testing the demangler or implementing
572 C++ functions in partially implemented wine DLLS. As an example:
574 winedump sym "??3@YAXPAX@Z"
578 void __cdecl _global_operator_delete_1(void * arg0)
580 Which is enough information to begin implementing the function.
583 Dump Mode: Dumping a PE file
584 ----------------------------
586 Another use for this tool is to diplay information about a 32bit DLL or PE
587 format image file. When used in this way winedump functions similarly to tools
588 such as pedump provided by many Win32 compiler vendors.
591 winedump dump <dllname.dll> [switches]
594 -h Display this help message
595 -C Turns on symbol demangling
596 -f Dump file header information
597 -j dir_name Dump only the contents of directory dir_name (import, export, debug)
604 OPTION: -x Dump everything
606 This command prints all available information about the file. You may wish to
607 pipe the output through more/less or into a file, since a lot of output will
610 If you are only interested in a subset of the available information, you can
611 use one of the following switches:
613 OPTION: -f Dump file header information-x Dump everything
615 This option dumps only the standard PE header structures, along with the COFF
616 sections available in the file.
618 OPTION: -j dir_name Dump directory dir_name (import, export, debug)
620 To dump only a given directory, specify them using this option. Currently only
621 the import, export and debug directories are implemented.
626 If you have any suggestions for improving this tool, please let me know.
627 If anyone can help answer the FIXME questions in msmangle.c or can fill me in
628 on any aspect of the C++ mangling scheme, I would appreciate it. In particular
629 I want to know what _E and _G represent.
631 If you encounter a C++ symbol that doesn't demangle **AND** you have the
632 prototype for it, please send me the symbol as reported by winedump and the
633 prototype. The more examples I have the easier it is to decypher the scheme,
634 and generating them myself is very slow.
636 Finally, although it is easy to generate a DLL, I _very strongly_ suggest that
637 you dont submit a generated DLL for inclusion into Wine unless you have
638 actually implemented a fairly reasonable portion of it. Even then, you should
639 only send the portions of the DLL you have implemented. Thousands of lines of
640 stub code don't help the project at all.
642 Please send questions and bug reports to jon_p_griffiths@yahoo.com.
648 [1] See the Wine and Wine.conf man pages for details on how to tell Wine
649 whether to use native (Win32) or internal DLLs.