~ [ source navigation ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/tools/winedump/

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

Name Size Last modified (GMT) Description
Back Parent directory 2009-04-24 17:06:21
File Makefile.in 1128 bytes 2009-04-24 16:59:03
File README 17743 bytes 2009-04-24 16:59:03
C file debug.c 26209 bytes 2009-04-24 16:59:03
C file dos.c 2332 bytes 2009-04-24 16:59:03
C file dump.c 8570 bytes 2009-04-24 16:59:03
C file emf.c 8714 bytes 2009-04-24 16:59:03
File function_grep.pl 8187 bytes 2009-04-24 16:59:03
C file le.c 12620 bytes 2009-04-24 16:59:03
C file lib.c 7616 bytes 2009-04-24 16:59:03
C file lnk.c 14329 bytes 2009-04-24 16:59:03
C file main.c 12372 bytes 2009-04-24 16:59:03
C file minidump.c 17282 bytes 2009-04-24 16:59:03
C file misc.c 4984 bytes 2009-04-24 16:59:03
C file msc.c 54063 bytes 2009-04-24 16:59:03
C file msmangle.c 25796 bytes 2009-04-24 16:59:03
C file ne.c 14043 bytes 2009-04-24 16:59:03
C file output.c 16594 bytes 2009-04-24 16:59:03
C file pdb.c 24566 bytes 2009-04-24 16:59:03
C file pe.c 51320 bytes 2009-04-24 16:59:03
C file search.c 8916 bytes 2009-04-24 16:59:03
C file symbol.c 7235 bytes 2009-04-24 16:59:03
C file winedump.h 8804 bytes 2009-04-24 16:59:03
File winedump.man.in 8324 bytes 2009-04-24 16:59:03

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

~ [ source navigation ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.