Check that there are some methods to iterate through before iterating
[wine] / tools / winedump / README
1 Winedump - A Wine DLL tool
2 --------------------------
3
4 Background
5 ----------
6
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 DLL's 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/DLL's.
12
13 The first thing to note is that there are many DLL's that aren't yet
14 implemented in Wine. Mostly this doesn't present a problem because the native
15 Win32 versions of lots of DLL's 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.
20
21 The second thing to note is that applications commonly use their own or 3rd
22 party DLL's 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 re-implement 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].
31
32 These two factors mean that if you are:
33
34 A: Reimplementing a Win32 DLL for use within Wine, or
35 B: Compiling a Win32 application with Winelib that uses x86 DLL's
36
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.
39
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 re-implement 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 DLL's functions.
46
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.
50
51
52 Usage
53 -----
54 Winedump is a command line tool. For the list of options and the basic usage
55 see the the winedump(1) man page.
56
57 Spec mode: Generating stub DLL's
58 -------------------------------
59
60 If all you want to do is generate a stub DLL to allow you to link your
61 Winelib application to an x86 DLL, the above options are all you need.
62
63 As an example, lets assume the application you are porting uses functions
64 from a 3rd party dll called 'zipextra.dll', and the functions in the DLL
65 use the __stdcall calling convention. Copy zipextra.dll to an empty directory,
66 change to it, and run winedump as follows:
67
68 winedump spec zipextra  (Note: this assumes winedump is in your path)
69
70 The output will look something like the following:
71
72 22 named symbols in DLL, 22 in total ...
73 Export    1 - '_OpenZipFile' ... [Ignoring]
74 Export    2 - '_UnZipFile' ... [Ignoring]
75 ...
76
77 "[Ignoring]" Just tells you that winedump isn't trying to determine the
78 parameters or return types of the functions, its just creating stubs.
79
80 The following files are created:
81
82 zipextra.spec
83 This is the .spec file. Each exported function is listed as a stub:
84
85 @ stub _OpenZipFile
86 @ stub _UnZipFile
87 ...
88
89 This means that winebuild will generate dummy code for this function. That
90 doesn't concern us, because all we want is for winebuild to allow the symbols
91 to be resolved when linking. At run-time, the functions in the native DLL will
92 be called; this just allows us to link.
93
94 zipextra_dll.h zipextra_main.c
95 These are source code files containing the minimum set of code to build
96 a stub DLL. The C file contains one function, ZIPEXTRA_Init, which does
97 nothing (but must be present).
98
99 Makefile.in
100 This is a template for 'configure' to produce a makefile. It is designed
101 for a DLL that will be inserted into the Wine source tree. If your DLL
102 will not be part of Wine, or you don't wish to build it this way,
103 you should look at the Wine tool 'winemaker' to generate a DLL project.
104
105 FIXME: winemaker could run this tool automatically when generating projects
106 that use extra DLL's (*.lib in the "ADD LINK32" line in .dsp) ....
107
108 zipextra_install
109 A shell script for adding zipextra to the Wine source tree (see below).
110
111
112 Spec mode: Inserting a stub DLL into the Wine tree
113 --------------------------------------------------
114
115 To build your stub DLL as part of Wine, do the following:
116
117  chmod a+x ./zipextra_install
118  ./zipextra_install <wine-path>
119  cd <wine-path>
120  autoconf
121  ./configure
122  make depend && make
123  make install
124
125 Your application can now link with the DLL.
126
127 If you receive the following error when running autoconf:
128
129  autoconf: configure.in: No such file or directory
130
131 Then you need to install a newer version of autoconf. At the time of writing
132 version 2.53 or later is required to re-generate configure.
133
134 If you have problems with this step, you can post to the wine-devel mailing
135 list for help. The build process can change regularly and winebuild may lag
136 behind in support.
137
138 NOTE: **DO NOT** submit patches to Wine for 3rd party DLL's! Building DLL's
139       into your copy of the tree is just a simple way for you to link. When
140       you release your application you won't be distributing the Unix .so
141       anyway, just the Win32 DLL. As you update your version of Wine
142       you can simply re-run the procedure above (Since no patches are
143       involved, it should be pretty resilient to changes).
144
145
146 Spec mode: Advanced Options
147 ---------------------------
148
149 This section discusses features of winedump that are useful to Wine Hackers
150 or developers looking to re-implement a Win32 DLL for Unix. Using these
151 features means you will need to be able to resolve compilation problems and
152 have a general understanding of Wine programming.
153
154
155 For all advanced functionality, you must give winedump a directory or file that
156 contains prototypes for the DLL.
157
158 Once you have created your DLL, if you generated code (see below), you can
159 backup the DLL header file created and use it for rebuilding the DLL (you
160 should remove the DLLNAME_ prefix from the prototypes to make this work). This
161 allows you to add names to the function arguments, for example, so that the
162 comments and prototype in the regenerated DLL will be clearer.
163
164 Winedump searches for prototypes using 'grep', and then retrieves each
165 prototype by calling 'function_grep.pl', a Perl script. When you pass the -v
166 option on the command line, the calls to both of these programs are logged.
167 This allows you to see where each function definition has come from. Should
168 winedump take an excessively long time to locate a prototype, you can check
169 that it is searching the right files; you may want to limit the number of files
170 searched if locating the prototype takes too long.
171
172 You can compile function_grep.pl for a slight increase in performance; see
173 'man perlcc' for details.
174
175
176 If winedump does not find a prototype, it emits code like the following:
177
178 In the .spec file:
179
180 @stub _OpenZipFile
181
182 in the header file:
183
184 /* __cdecl ZIPEXTRA__OpenZipFile() */
185
186 in the C source file:
187
188 /*********************************************************************
189  *      _OpenZipFile     (ZIPEXTRA.@)
190  *
191  */
192 #if 0
193 __stdcall ZIPEXTRA__OpenZipFile()
194 {
195     /* '@Stubbed'ed in .spec */
196 }
197 #endif
198
199 If a prototype is found, or correctly demangled, the following is emitted:
200
201 .spec:
202 @ stdcall _OpenZipFile ZIPEXTRA__OpenZipFile
203
204 .h:
205 BOOL __stdcall ZIPEXTRA__OpenZipFile(LPCSTR pszFileName);
206
207 .c:
208 BOOL __stdcall ZIPEXTRA__OpenZipFile(LPCSTR pszFileName)
209 {
210   TRACE("stub\n");
211   return 0;
212 }
213
214 Note that if the prototype does not contain argument names, winedump will
215 add them following the convention arg0, arg1 ... argN. If the function is
216 demangled C++, the first argument will be called '_this' if an implicit this
217 pointer is passed (i.e. the function is a non-static class member function).
218
219
220 OPTION: -f dll   Forward calls to 'dll' (implies -t)
221
222 This is the most complicated level of code generation. The same code is
223 generated as -t, however support is added for forwarding calls to another
224 DLL. The DLL to forward to is given as 'dll'. Lets suppose we built the
225 examples above using "-f real_zipextra". The code generated will look like
226 the following:
227
228 .spec
229 As for -c, except if a function prototype was not found:
230
231 @ forward _OpenZipFile real_zipextra._OpenZipFile
232
233 In this case the function is forwarded to the destination DLL rather
234 than stubbed.
235
236 .h
237 As for -c.
238
239 .c
240
241 A variable "hDLL" is added to hold a pointer to the DLL to forward to, and
242 the initialization code in ZIPEXTRA_Init is changed to load and free the
243 forward DLL automatically:
244
245 HMODULE hDLL = 0; /* DLL to call through to */
246
247 BOOL WINAPI ZIPEXTRA_Init(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
248 {
249     TRACE("(0x%08x, %ld, %p)\n", hinstDLL, fdwReason, lpvReserved);
250
251     if (fdwReason == DLL_PROCESS_ATTACH)
252     {
253         hDLL = LoadLibraryA( "real_zipextra" );
254         TRACE ("Forwarding DLL (real_zipextra) loaded\n" );
255     }
256     else if (fdwReason == DLL_PROCESS_DETACH)
257     {
258         FreeLibrary( hDLL );
259         TRACE ("Forwarding DLL (real_zipextra) freed\n" );
260     }
261
262     return TRUE;
263 }
264
265 The stub function is changed to call the forwarding DLL and return that value.
266
267 BOOL __stdcall ZIPEXTRA__OpenZipFile(LPCSTR pszFileName)
268 {
269   BOOL (__stdcall *pFunc)(LPCSTR) = (void*)GetProcAddress(hDLL,"_OpenZipFile");
270   BOOL retVal;
271   TRACE("((LPCSTR)%s) stub\n", pszFileName);
272   retVal = pFunc(pszFileName);
273   TRACE("returned (%ld)\n",(LONG)retVal));
274   return retVal;
275 }
276
277 This allows you to investigate the workings of a DLL without interfering in
278 its operation in any way (unless you want to).
279
280 In the example I have been using, we probably should have used the -o option
281 to change the output name of our DLL to something else, and used the -f
282 option to forward to the real zipextra DLL:
283
284 winedump spec zipextra -f zipextra -o myzipextra -I "~/zipextra/include/*h"
285
286 Then in the .spec file for our Winelib application, we add the line:
287
288 import myzipextra
289
290 When we build our application, winebuild resolves the calls to our Unix .so.
291 As our application runs we can see the values of all parameters passed to
292 the DLL, and any values returned, without having to write code to dump
293 them ourselves (see below for a better way to wrap a DLL for forwarding).
294
295 This isn't a very realistic example of the usefulness of this feature,
296 however, since we could print out the results anyway, because it is our
297 application making the calls to the DLL. Where DLL forwarding is most useful
298 is where an application or DLL we didn't write calls functions in the DLL.
299 In this case we can capture the sequence of calls made, and the values passed
300 around. This is an aid in reimplementing the DLL, since we can add code for a
301 function, print the results, and then call the real DLL and compare. Only
302 when our code is the same do we need to remove the function pointer and the
303 call to the real DLL. A similar feature in wine is +relay debugging. Using a
304 forwarding DLL allows more granular reporting of arguments, because you can
305 write code to dump out the contents of types/structures rather than just
306 their address in memory. A future version of winedump may generate this
307 code automatically for common Win32 types.
308
309 See below for more information on setting up a forwarding DLL.
310
311
312 Spec mode: Problems compiling a DLL containing generated code
313 -------------------------------------------------------------
314
315 Unless you are very lucky, you will need to do a small amount of work to
316 get a DLL generated with -c, -t or -f to compile. The reason for this is
317 that most DLL's will use custom types such as structs whose definition
318 is not known to the code in the DLL.
319
320 Heres an example prototype from crtdll:
321
322 double __cdecl _cabs(struct _complex arg0)
323
324 The definition for the _complex struct needs to be given. Since it is passed
325 by value, its size also needs to be correct in order to forward the call
326 correctly to a native DLL. In this case the structure is 8 bytes in size, which
327 means that the gcc compile flag -freg-struct-return must be given when
328 compiling the function in order to be compatible with the native DLL. (In
329 general this is not an issue, but you need to be aware of such issues if you
330 encounter problems with your forwarding DLL).
331
332 For third party (non C++) DLL's, the header(s) supplied with the DLL  can
333 normally be added as an include to the generated DLL header. For other DLL's
334 I suggest creating a separate header in the DLL directory and adding any
335 needed types to that. This allows you to rebuild the DLL at whim, for example
336 if a new version of winedump brings increased functionality, then you
337 only have to overwrite the generated files and re-include the header to take
338 advantage of it.
339
340 Usually there isn't much work to do to get the DLL to compile if you have
341 headers. As an example, building a forwarded crtdll, which contains 520
342 functions, required 20 types to be defined before it compiled. Of these,
343 about half were structures, so about 35 lines of code were needed. The only
344 change to the generated code was one line in the header to include the type
345 definitions.
346
347 To save some typing in case you don't have headers for your DLL type, winedump
348 will dump dummy declarations for unknown classes and types it encounters,
349 if you use the -v option. These can be piped directly into a fix-up header
350 file for use in compiling your DLL. For example, if winedump encounters the
351 (C++ ) symbol:
352
353 ??0foobar@@QAE@ABV0@@Z   (Which is a constructor for a foobar object)
354
355 It will emit the following with -v set:
356
357 struct foobar { int _FIXME; };
358
359 (Classes are mapped to C structs when generating code).
360
361 The output should be piped through 'sort' and 'uniq' to remove multiple
362 declarations, e.g:
363
364 winedump foo -c -I "inc/*.h" -v | grep FIXME | sort | uniq > fixup.h
365
366 By adding '#include "fixup.h"' to foobar_dll.h your compile errors will be
367 greatly reduced.
368
369 If winedump encounters a type it doesn't know that is passed by value (as in
370 the _cabs example above), it also prints a FIXME message like:
371
372 /* FIXME: By value type: Assumed 'int' */ typedef int ldiv_t;
373
374 If the type is not an int, you will need to change the code and possibly
375 the .spec entry in order to forward correctly. Otherwise, include the typedef
376 in your fixup header to avoid compile errors.
377
378
379 Spec mode: Using a forwarding DLL
380 ---------------------------------
381
382 To create and use a forwarding DLL to trace DLL calls, you need to first
383 create a DLL using the -f option as outlined above, and get it to compile.
384 In order to forward calls the following procedure can be used (for this
385 example we are going to build a forwarding msvcrt.dll for the purpose
386 of reimplementing it).
387
388 First we create the forwarding DLL. We will rename the real msvcrt.dll on our
389 system to ms_msvcrt.dll, and our msvcrt implementation will call it:
390
391 winedump spec msvcrt -C -f ms_msvcrt -I "inc/*.h"
392
393 We then install this DLL into the Wine tree and add the types we need to
394 make it compile. Once the DLL compiles, we create a dummy ms_msvcrt DLL so
395 winebuild will resolve our forward calls to it (for the cases where winedump
396 couldn't generate code and has placed an '@forward' line in the .spec file):
397
398 winedump spec msvcrt -C -o ms_msvcrt
399
400 Install this DLL into the wine tree (since its a stub DLL, no changes are
401 needed to the code).
402
403 Now uncomment the line that winedump inserted into msvcrt.spec:
404
405 #import ms_msvcrt.dll
406
407 And recompile Wine.
408
409 Finally, we must tell Wine to only use the built in msvcrt.dll and to only use
410 the native (Win32) ms_msvcrt.dll. Add the following two lines to ~/.wine/config
411 under the [DllOverrides] section:
412
413 ;Use our implementation of msvcrt
414 "msvcrt" = "builtin, so"
415 ;Use only the Win32 ms_msvcrt
416 "ms_msvcrt" = "native"
417
418 At this point, when any call is made to msvcrt.dll, Our libmsvcrt.so receives
419 the call. It then forwards or calls ms_msvcrt.dll, which is the native dll. We
420 receive a return value and pass it back to our caller, having TRACEd the
421 arguments on the way.
422
423 At this point you are ready to start reimplementing the calls.
424
425
426
427 Final comments
428 --------------
429
430 If you have any suggestions for improving this tool, please let me know.
431 If anyone can help answer the FIXME questions in msmangle.c or can fill me in
432 on any aspect of the C++ mangling scheme, I would appreciate it. In particular
433 I want to know what _E and _G represent.
434
435 If you encounter a C++ symbol that doesn't demangle **AND** you have the
436 prototype for it, please send me the symbol as reported by winedump and the
437 prototype. The more examples I have the easier it is to decipher the scheme,
438 and generating them myself is very slow.
439
440 Finally, although it is easy to generate a DLL, I _very strongly_ suggest that
441 you don't submit a generated DLL for inclusion into Wine unless you have
442 actually implemented a fairly reasonable portion of it. Even then, you should
443 only send the portions of the DLL you have implemented. Thousands of lines of
444 stub code don't help the project at all.
445
446 Please send questions and bug reports to jon_p_griffiths@yahoo.com.
447
448
449 References
450 ----------
451
452 [1] See the wine and wine.conf man pages for details on how to tell Wine
453     whether to use native (Win32) or internal DLL's.