Back to home page

Wine source

 
 

    


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.