Warning, /tools/winedump/README is written in an unsupported language. File is not indexed.
d786a12d5… Eric*0001 Winedump - A Wine DLL tool
0002 --------------------------
c7a3fec5b… Jon *0003
0004 Background
0005 ----------
0006
0007 Most of the functions available in Windows, and in Windows applications, are
02c25a898… Fran*0008 made available to applications from DLLs. Wine implements the Win32 API by
0009 providing replacements for the essential Windows DLLs in the form of Unix
c7a3fec5b… Jon *0010 shared library (.so) files, and provides a tool, winebuild, to allow Winelib
02c25a898… Fran*0011 applications to link to functions exported from shared libraries/DLLs.
c7a3fec5b… Jon *0012
02c25a898… Fran*0013 The first thing to note is that there are many DLLs that aren't yet
c7a3fec5b… Jon *0014 implemented in Wine. Mostly this doesn't present a problem because the native
02c25a898… Fran*0015 Win32 versions of lots of DLLs can be used without problems, at least on
c7a3fec5b… Jon *0016 x86 platforms. However, one of Wine's goals is the eventual replacement of
0017 every essential O/S DLL so that the whole API is implemented. This not only
0018 means that a copy of the real O/S is not needed, but also that non-x86
0019 platforms can run most Win32 programs after recompiling.
0020
0021 The second thing to note is that applications commonly use their own or 3rd
02c25a898… Fran*0022 party DLLs to provide functionality. In order to call these functions with
c7a3fec5b… Jon *0023 a Winelib program, some 'glue' is needed. This 'glue' comes in the form of
0024 a .spec file. The .spec file, along with some dummy code, is used to create
0025 a Wine .so corresponding to the Windows DLL. The winebuild program can then
0026 resolve calls made to DLL functions to call your dummy DLL. You then tell
0027 Wine to only use the native Win32 version of the DLL, and at runtime your
c95385a35… Mich*0028 calls will be made to the Win32 DLL. If you want to re-implement the dll,
c7a3fec5b… Jon *0029 you simply add the code for the DLL calls to your stub .so, and then tell
0030 Wine to use the .so version instead [1].
0031
0032 These two factors mean that if you are:
0033
0034 A: Reimplementing a Win32 DLL for use within Wine, or
02c25a898… Fran*0035 B: Compiling a Win32 application with Winelib that uses x86 DLLs
c7a3fec5b… Jon *0036
0037 Then you will need to create a .spec file (amongst other things). If you
d786a12d5… Eric*0038 won't be doing either of the above, then you won't need winedump.
c7a3fec5b… Jon *0039
0040 Creating a .spec file is a labour intensive task during which it is easy
d786a12d5… Eric*0041 to make a mistake. The idea of winedump is to automate this task and create
c7a3fec5b… Jon *0042 the majority of the support code needed for your DLL. In addition you can
c95385a35… Mich*0043 have winedump create code to help you re-implement a DLL, by providing
c7a3fec5b… Jon *0044 tracing of calls to the DLL, and (in some cases) automatically determining
c95385a35… Mich*0045 the parameters, calling conventions, and return values of the DLL's functions.
c7a3fec5b… Jon *0046
d786a12d5… Eric*0047 You can think of winedump as somewhat similar to the IMPLIB tool when
d756a0ac9… Jon *0048 only its basic functionality is used. In addition, winedump can be used to
0049 dump other information from PE files; See the section 'Dumping' below.
c7a3fec5b… Jon *0050
0051
0052 Usage
0053 -----
c95385a35… Mich*0054 Winedump is a command line tool. For the list of options and the basic usage
c4b1195c0… Fran*0055 see the winedump(1) man page.
0056
c7a3fec5b… Jon *0057
02c25a898… Fran*0058 Spec mode: Generating stub DLLs
d756a0ac9… Jon *0059 -------------------------------
c7a3fec5b… Jon *0060
0061 If all you want to do is generate a stub DLL to allow you to link your
0062 Winelib application to an x86 DLL, the above options are all you need.
0063
0064 As an example, lets assume the application you are porting uses functions
0065 from a 3rd party dll called 'zipextra.dll', and the functions in the DLL
0066 use the __stdcall calling convention. Copy zipextra.dll to an empty directory,
d786a12d5… Eric*0067 change to it, and run winedump as follows:
c7a3fec5b… Jon *0068
d786a12d5… Eric*0069 winedump spec zipextra (Note: this assumes winedump is in your path)
c7a3fec5b… Jon *0070
0071 The output will look something like the following:
0072
dd2247817… Jon *0073 22 named symbols in DLL, 22 in total ...
c7a3fec5b… Jon *0074 Export 1 - '_OpenZipFile' ... [Ignoring]
0075 Export 2 - '_UnZipFile' ... [Ignoring]
0076 ...
0077
d786a12d5… Eric*0078 "[Ignoring]" Just tells you that winedump isn't trying to determine the
02c25a898… Fran*0079 parameters or return types of the functions, it's just creating stubs.
c7a3fec5b… Jon *0080
0081 The following files are created:
0082
0083 zipextra.spec
0084 This is the .spec file. Each exported function is listed as a stub:
0085
0086 @ stub _OpenZipFile
0087 @ stub _UnZipFile
0088 ...
0089
0090 This means that winebuild will generate dummy code for this function. That
d756a0ac9… Jon *0091 doesn't concern us, because all we want is for winebuild to allow the symbols
0092 to be resolved when linking. At run-time, the functions in the native DLL will
c7a3fec5b… Jon *0093 be called; this just allows us to link.
0094
0095 zipextra_dll.h zipextra_main.c
0096 These are source code files containing the minimum set of code to build
0097 a stub DLL. The C file contains one function, ZIPEXTRA_Init, which does
d756a0ac9… Jon *0098 nothing (but must be present).
c7a3fec5b… Jon *0099
0100 Makefile.in
0101 This is a template for 'configure' to produce a makefile. It is designed
0102 for a DLL that will be inserted into the Wine source tree. If your DLL
0103 will not be part of Wine, or you don't wish to build it this way,
0104 you should look at the Wine tool 'winemaker' to generate a DLL project.
0105
0106 FIXME: winemaker could run this tool automatically when generating projects
02c25a898… Fran*0107 that use extra DLLs (*.lib in the "ADD LINK32" line in .dsp) ....
c7a3fec5b… Jon *0108
0109 zipextra_install
0110 A shell script for adding zipextra to the Wine source tree (see below).
0111
0112
d756a0ac9… Jon *0113 Spec mode: Inserting a stub DLL into the Wine tree
0114 --------------------------------------------------
c7a3fec5b… Jon *0115
0116 To build your stub DLL as part of Wine, do the following:
0117
0118 chmod a+x ./zipextra_install
0119 ./zipextra_install <wine-path>
0120 cd <wine-path>
0121 autoconf
0122 ./configure
0123 make depend && make
0124 make install
0125
0126 Your application can now link with the DLL.
0127
c5f775a9c… Fran*0128 If you receive the following error when running autoconf:
d756a0ac9… Jon *0129
0130 autoconf: configure.in: No such file or directory
0131
0132 Then you need to install a newer version of autoconf. At the time of writing
0133 version 2.53 or later is required to re-generate configure.
0134
0135 If you have problems with this step, you can post to the wine-devel mailing
0136 list for help. The build process can change regularly and winebuild may lag
0137 behind in support.
0138
02c25a898… Fran*0139 NOTE: **DO NOT** submit patches to Wine for 3rd party DLLs! Building DLLs
c7a3fec5b… Jon *0140 into your copy of the tree is just a simple way for you to link. When
0141 you release your application you won't be distributing the Unix .so
0142 anyway, just the Win32 DLL. As you update your version of Wine
0143 you can simply re-run the procedure above (Since no patches are
c95385a35… Mich*0144 involved, it should be pretty resilient to changes).
c7a3fec5b… Jon *0145
0146
d756a0ac9… Jon *0147 Spec mode: Advanced Options
0148 ---------------------------
c7a3fec5b… Jon *0149
d786a12d5… Eric*0150 This section discusses features of winedump that are useful to Wine Hackers
c95385a35… Mich*0151 or developers looking to re-implement a Win32 DLL for Unix. Using these
c7a3fec5b… Jon *0152 features means you will need to be able to resolve compilation problems and
0153 have a general understanding of Wine programming.
0154
0155
d756a0ac9… Jon *0156 For all advanced functionality, you must give winedump a directory or file that
c95385a35… Mich*0157 contains prototypes for the DLL.
c7a3fec5b… Jon *0158
0159 Once you have created your DLL, if you generated code (see below), you can
0160 backup the DLL header file created and use it for rebuilding the DLL (you
0161 should remove the DLLNAME_ prefix from the prototypes to make this work). This
0162 allows you to add names to the function arguments, for example, so that the
0163 comments and prototype in the regenerated DLL will be clearer.
0164
d786a12d5… Eric*0165 Winedump searches for prototypes using 'grep', and then retrieves each
c7a3fec5b… Jon *0166 prototype by calling 'function_grep.pl', a Perl script. When you pass the -v
0167 option on the command line, the calls to both of these programs are logged.
0168 This allows you to see where each function definition has come from. Should
d786a12d5… Eric*0169 winedump take an excessively long time to locate a prototype, you can check
c7a3fec5b… Jon *0170 that it is searching the right files; you may want to limit the number of files
0171 searched if locating the prototype takes too long.
0172
0173 You can compile function_grep.pl for a slight increase in performance; see
0174 'man perlcc' for details.
0175
0176
d786a12d5… Eric*0177 If winedump does not find a prototype, it emits code like the following:
c7a3fec5b… Jon *0178
0179 In the .spec file:
0180
0181 @stub _OpenZipFile
0182
0183 in the header file:
0184
0185 /* __cdecl ZIPEXTRA__OpenZipFile() */
0186
0187 in the C source file:
0188
0189 /*********************************************************************
0190 * _OpenZipFile (ZIPEXTRA.@)
0191 *
0192 */
0193 #if 0
0194 __stdcall ZIPEXTRA__OpenZipFile()
0195 {
0196 /* '@Stubbed'ed in .spec */
0197 }
0198 #endif
0199
0200 If a prototype is found, or correctly demangled, the following is emitted:
0201
0202 .spec:
0203 @ stdcall _OpenZipFile ZIPEXTRA__OpenZipFile
0204
0205 .h:
d259eaf28… Aust*0206 BOOL __stdcall ZIPEXTRA__OpenZipFile(const char *filename);
c7a3fec5b… Jon *0207
0208 .c:
d259eaf28… Aust*0209 BOOL __stdcall ZIPEXTRA__OpenZipFile(const char *filename)
c7a3fec5b… Jon *0210 {
6a5ba8fba… Vinc*0211 TRACE("stub\n");
c7a3fec5b… Jon *0212 return 0;
0213 }
0214
d786a12d5… Eric*0215 Note that if the prototype does not contain argument names, winedump will
c7a3fec5b… Jon *0216 add them following the convention arg0, arg1 ... argN. If the function is
0217 demangled C++, the first argument will be called '_this' if an implicit this
0218 pointer is passed (i.e. the function is a non-static class member function).
0219
0220
0221 OPTION: -f dll Forward calls to 'dll' (implies -t)
0222
0223 This is the most complicated level of code generation. The same code is
0224 generated as -t, however support is added for forwarding calls to another
0225 DLL. The DLL to forward to is given as 'dll'. Lets suppose we built the
0226 examples above using "-f real_zipextra". The code generated will look like
0227 the following:
0228
0229 .spec
0230 As for -c, except if a function prototype was not found:
0231
0232 @ forward _OpenZipFile real_zipextra._OpenZipFile
0233
0234 In this case the function is forwarded to the destination DLL rather
0235 than stubbed.
0236
0237 .h
0238 As for -c.
0239
0240 .c
0241
0242 A variable "hDLL" is added to hold a pointer to the DLL to forward to, and
c95385a35… Mich*0243 the initialization code in ZIPEXTRA_Init is changed to load and free the
c7a3fec5b… Jon *0244 forward DLL automatically:
0245
0246 HMODULE hDLL = 0; /* DLL to call through to */
0247
d259eaf28… Aust*0248 BOOL WINAPI ZIPEXTRA_Init(HINSTANCE dll, DWORD reason, void *reserved)
c7a3fec5b… Jon *0249 {
d259eaf28… Aust*0250 TRACE("(0x%08x, %u, %p)\n", dll, reason, reserved);
c7a3fec5b… Jon *0251
d259eaf28… Aust*0252 if (reason == DLL_PROCESS_ATTACH)
c7a3fec5b… Jon *0253 {
0254 hDLL = LoadLibraryA( "real_zipextra" );
0255 TRACE ("Forwarding DLL (real_zipextra) loaded\n" );
0256 }
d259eaf28… Aust*0257 else if (reason == DLL_PROCESS_DETACH)
c7a3fec5b… Jon *0258 {
0259 FreeLibrary( hDLL );
0260 TRACE ("Forwarding DLL (real_zipextra) freed\n" );
0261 }
0262
0263 return TRUE;
0264 }
0265
0266 The stub function is changed to call the forwarding DLL and return that value.
0267
d259eaf28… Aust*0268 BOOL __stdcall ZIPEXTRA__OpenZipFile(const char *filename)
c7a3fec5b… Jon *0269 {
d259eaf28… Aust*0270 BOOL (__stdcall *pFunc)(const char *) = (void*)GetProcAddress(hDLL,"_OpenZipFile");
c7a3fec5b… Jon *0271 BOOL retVal;
d259eaf28… Aust*0272 TRACE("((const char *)%s) stub\n", filename);
0273 retVal = pFunc(filename);
c7a3fec5b… Jon *0274 TRACE("returned (%ld)\n",(LONG)retVal));
0275 return retVal;
0276 }
0277
0278 This allows you to investigate the workings of a DLL without interfering in
0279 its operation in any way (unless you want to).
0280
0281 In the example I have been using, we probably should have used the -o option
c95385a35… Mich*0282 to change the output name of our DLL to something else, and used the -f
c7a3fec5b… Jon *0283 option to forward to the real zipextra DLL:
0284
d786a12d5… Eric*0285 winedump spec zipextra -f zipextra -o myzipextra -I "~/zipextra/include/*h"
c7a3fec5b… Jon *0286
0287 Then in the .spec file for our Winelib application, we add the line:
0288
0289 import myzipextra
0290
0291 When we build our application, winebuild resolves the calls to our Unix .so.
0292 As our application runs we can see the values of all parameters passed to
0293 the DLL, and any values returned, without having to write code to dump
0294 them ourselves (see below for a better way to wrap a DLL for forwarding).
0295
0296 This isn't a very realistic example of the usefulness of this feature,
0297 however, since we could print out the results anyway, because it is our
0298 application making the calls to the DLL. Where DLL forwarding is most useful
0299 is where an application or DLL we didn't write calls functions in the DLL.
0300 In this case we can capture the sequence of calls made, and the values passed
0301 around. This is an aid in reimplementing the DLL, since we can add code for a
0302 function, print the results, and then call the real DLL and compare. Only
0303 when our code is the same do we need to remove the function pointer and the
0304 call to the real DLL. A similar feature in wine is +relay debugging. Using a
c95385a35… Mich*0305 forwarding DLL allows more granular reporting of arguments, because you can
c7a3fec5b… Jon *0306 write code to dump out the contents of types/structures rather than just
d786a12d5… Eric*0307 their address in memory. A future version of winedump may generate this
c7a3fec5b… Jon *0308 code automatically for common Win32 types.
0309
0310 See below for more information on setting up a forwarding DLL.
0311
0312
d756a0ac9… Jon *0313 Spec mode: Problems compiling a DLL containing generated code
0314 -------------------------------------------------------------
c7a3fec5b… Jon *0315
0316 Unless you are very lucky, you will need to do a small amount of work to
0317 get a DLL generated with -c, -t or -f to compile. The reason for this is
02c25a898… Fran*0318 that most DLLs will use custom types such as structs whose definition
c7a3fec5b… Jon *0319 is not known to the code in the DLL.
0320
0321 Heres an example prototype from crtdll:
0322
0323 double __cdecl _cabs(struct _complex arg0)
0324
0325 The definition for the _complex struct needs to be given. Since it is passed
0326 by value, its size also needs to be correct in order to forward the call
0327 correctly to a native DLL. In this case the structure is 8 bytes in size, which
0328 means that the gcc compile flag -freg-struct-return must be given when
c5f775a9c… Fran*0329 compiling the function in order to be compatible with the native DLL. (In
c7a3fec5b… Jon *0330 general this is not an issue, but you need to be aware of such issues if you
0331 encounter problems with your forwarding DLL).
0332
02c25a898… Fran*0333 For third party (non C++) DLLs, the header(s) supplied with the DLL can
0334 normally be added as an include to the generated DLL header. For other DLLs
c5f775a9c… Fran*0335 I suggest creating a separate header in the DLL directory and adding any
c7a3fec5b… Jon *0336 needed types to that. This allows you to rebuild the DLL at whim, for example
d786a12d5… Eric*0337 if a new version of winedump brings increased functionality, then you
c7a3fec5b… Jon *0338 only have to overwrite the generated files and re-include the header to take
0339 advantage of it.
0340
0341 Usually there isn't much work to do to get the DLL to compile if you have
0342 headers. As an example, building a forwarded crtdll, which contains 520
0343 functions, required 20 types to be defined before it compiled. Of these,
0344 about half were structures, so about 35 lines of code were needed. The only
0345 change to the generated code was one line in the header to include the type
0346 definitions.
0347
d786a12d5… Eric*0348 To save some typing in case you don't have headers for your DLL type, winedump
c7a3fec5b… Jon *0349 will dump dummy declarations for unknown classes and types it encounters,
0350 if you use the -v option. These can be piped directly into a fix-up header
d786a12d5… Eric*0351 file for use in compiling your DLL. For example, if winedump encounters the
c7a3fec5b… Jon *0352 (C++ ) symbol:
0353
0354 ??0foobar@@QAE@ABV0@@Z (Which is a constructor for a foobar object)
0355
0356 It will emit the following with -v set:
0357
0358 struct foobar { int _FIXME; };
0359
0360 (Classes are mapped to C structs when generating code).
0361
0362 The output should be piped through 'sort' and 'uniq' to remove multiple
0363 declarations, e.g:
0364
52097fd70… Andr*0365 winedump foo -c -I "inc/*.h" -v | grep FIXME | sort | uniq > fixup.h
c7a3fec5b… Jon *0366
0367 By adding '#include "fixup.h"' to foobar_dll.h your compile errors will be
0368 greatly reduced.
0369
640cc3f3e… Fran*0370 If winedump encounters a type it doesn't know that is passed by value (as in
c7a3fec5b… Jon *0371 the _cabs example above), it also prints a FIXME message like:
0372
0373 /* FIXME: By value type: Assumed 'int' */ typedef int ldiv_t;
52097fd70… Andr*0374
c7a3fec5b… Jon *0375 If the type is not an int, you will need to change the code and possibly
0376 the .spec entry in order to forward correctly. Otherwise, include the typedef
0377 in your fixup header to avoid compile errors.
0378
0379
d756a0ac9… Jon *0380 Spec mode: Using a forwarding DLL
0381 ---------------------------------
c7a3fec5b… Jon *0382
0383 To create and use a forwarding DLL to trace DLL calls, you need to first
0384 create a DLL using the -f option as outlined above, and get it to compile.
0385 In order to forward calls the following procedure can be used (for this
0386 example we are going to build a forwarding msvcrt.dll for the purpose
0387 of reimplementing it).
0388
0389 First we create the forwarding DLL. We will rename the real msvcrt.dll on our
0390 system to ms_msvcrt.dll, and our msvcrt implementation will call it:
0391
d786a12d5… Eric*0392 winedump spec msvcrt -C -f ms_msvcrt -I "inc/*.h"
c7a3fec5b… Jon *0393
0394 We then install this DLL into the Wine tree and add the types we need to
0395 make it compile. Once the DLL compiles, we create a dummy ms_msvcrt DLL so
d786a12d5… Eric*0396 winebuild will resolve our forward calls to it (for the cases where winedump
c7a3fec5b… Jon *0397 couldn't generate code and has placed an '@forward' line in the .spec file):
0398
d786a12d5… Eric*0399 winedump spec msvcrt -C -o ms_msvcrt
c7a3fec5b… Jon *0400
0f2bed51b… Fréd*0401 Install this DLL into the wine tree (since it's a stub DLL, no changes are
c7a3fec5b… Jon *0402 needed to the code).
0403
d786a12d5… Eric*0404 Now uncomment the line that winedump inserted into msvcrt.spec:
c7a3fec5b… Jon *0405
12e701c31… Jon *0406 #import ms_msvcrt.dll
c7a3fec5b… Jon *0407
0408 And recompile Wine.
0409
c95385a35… Mich*0410 Finally, we must tell Wine to only use the built in msvcrt.dll and to only use
c7a3fec5b… Jon *0411 the native (Win32) ms_msvcrt.dll. Add the following two lines to ~/.wine/config
0412 under the [DllOverrides] section:
0413
c5f775a9c… Fran*0414 ;Use our implementation of msvcrt
c7a3fec5b… Jon *0415 "msvcrt" = "builtin, so"
0416 ;Use only the Win32 ms_msvcrt
0417 "ms_msvcrt" = "native"
0418
c5f775a9c… Fran*0419 At this point, when any call is made to msvcrt.dll, Our libmsvcrt.so receives
c7a3fec5b… Jon *0420 the call. It then forwards or calls ms_msvcrt.dll, which is the native dll. We
c5f775a9c… Fran*0421 receive a return value and pass it back to our caller, having TRACEd the
c7a3fec5b… Jon *0422 arguments on the way.
0423
0424 At this point you are ready to start reimplementing the calls.
0425
0426
d756a0ac9… Jon *0427
c7a3fec5b… Jon *0428 Final comments
0429 --------------
0430
0431 If you have any suggestions for improving this tool, please let me know.
0432 If anyone can help answer the FIXME questions in msmangle.c or can fill me in
0433 on any aspect of the C++ mangling scheme, I would appreciate it. In particular
0434 I want to know what _E and _G represent.
0435
0436 If you encounter a C++ symbol that doesn't demangle **AND** you have the
d786a12d5… Eric*0437 prototype for it, please send me the symbol as reported by winedump and the
c95385a35… Mich*0438 prototype. The more examples I have the easier it is to decipher the scheme,
c7a3fec5b… Jon *0439 and generating them myself is very slow.
0440
0441 Finally, although it is easy to generate a DLL, I _very strongly_ suggest that
640cc3f3e… Fran*0442 you don't submit a generated DLL for inclusion into Wine unless you have
c7a3fec5b… Jon *0443 actually implemented a fairly reasonable portion of it. Even then, you should
0444 only send the portions of the DLL you have implemented. Thousands of lines of
0445 stub code don't help the project at all.
0446
0447 Please send questions and bug reports to jon_p_griffiths@yahoo.com.
0448
0449
0450 References
0451 ----------
0452
cccad9d97… Andr*0453 [1] See the wine man page for details on how to tell Wine
c95385a35… Mich*0454 whether to use native (Win32) or internal DLL's.