Wine Traffic #3 For 11 Jul 1999 By Eric Pouech Table Of Contents * Standard Format * Text Format * XML Source * Introduction * Threads Covered 1. DIBs rendering and speed up 2. elfdll and binding 3. controls and painting 4. DLLs loading 5. Porting to non-Intel architectures 6. Porting to BeOS Introduction This is the third release of the experimental Wine's kernel cousin publication. It's main goal is to distribute widely what's going on around Wine (the Un*x windows emulator). Wine Weekly News (http://www.winehq.com/News/) has made its way to winehq.com. You'll find there the merge of Ove's effort and these KC cousin pages. Jutta Wrage is currently updating the Wine HOWTO (http://www.westfalen.de/witch /wine-HOWTO.txt) with printing information. Douglas Ridgway posted the Wine presentation (http://bugs.winehq.com/~ridgway/ monterey99/index.html) intented for the O'Reilly Open Source Symposium, August 21-24, in Monterey, CA. 1. DIBs rendering and speed up Archive Link: "XShmemdibs, Corel" People: Alexander Larsson, Zygo Blaxell, , Gavriel State Alexander Larsson was seeing performance problems with Device Independent Bitmaps, and he inquired: I'm not very good at Win32, but i would like to add support for using MIT XShmem images for dibs. I've asked some core developers about this, and they said Corel was working on this. Is this true? How far from finished is it? Gavriel State explained the current state of this patch (Karl Lessard had written it, but it had not yet been reviewed enough to be sent to wine-patches). Zygo Blaxell, even though he was busy moving house, took the time to send the patch in its current state to wine-devel, with the following warning: Disclaimer: I scraped this patch together in the last ~45 minutes or so. The following code appears to run 'sol.exe' without segfaulting. This is the _only_ thing I'm willing to say about it. This is the first time in a couple of weeks that this code has actually worked at all for me, so I don't know yet if it's still chock full o' bugs. Alexander added the next day: Cool. After some minor changes i actually got a fairly large speedup. Went from maybe 10 seconds per frame to about 1 second per frame. I'll do some further optimization, profiling and clean-up tomorrow. Alexander Larsson then posted to wine-devel the result of his first shot (http: //www.integrita.com/cgi-local/lwgate.pl/WINE-DEVEL/archives/1999-06/date/ article-412.html) at the patch, asking Corel if they wanted to clean it up and/ or to submit to wine-patches. Gavriel State answered that Alexander could do it if he had the time, Corel poeple were more concentrating on porting issues right now, and it'd be better (and quicker) if Alexander took care of the clean-up. The patch has not yet made its way to wine-patches. 2. elfdll and binding Archive Link: "elfdll stuff" People: Ulrich Weigand, , Alexander Larsson Alexander Larsson proposed his experience in export symbol handling to be used in Wine (mainly by exporting symbols in a specific way (either in a non standard section or by marking them)). Ulrich Weigand reminded that: one of the requirements of the elfdll import/export handling is that is should transparently work between elfdll and PE modules, so that within the whole executable, DLLs can be arbitrarily replaced by PE or elfdll versions, and all imports/export still work. This means that not only the non-exported symbols should not be available for ELF linking, but rather *no* symbols at all should use ELF linking, because the side being linked to might be PE. So, Bertho's current experimental dllglue works like this: link everything belonging to one elfdll into an object, use the symbol table of the object together with the .spec files defining the exports of the various DLLs to create a PE header containing both an exports and an imports table, link the PE header into the object (thereby resolving all symbols originally imported by the elfdll to IAT stubs) and finally localize all ELF symbols (except one symbol pointing to the PE header itself). Thus, you get a .so file which the Wine loader loads using dlopen(), retrieves the PE header using dlsym(), and performs the usual PE import/export resolving. Ulrich nevertheless pointed to some areas that could be enhanced: * On the export side, it might be possible to avoid the necessity for an specific .spec file if the symbols intended to be exported could be marked in the source using a technique similar to the ones you mentioned. * On the import side, we could avoid the necessity for assembly glue code stubs if the compiler could be told that calls to an imported function should be coded as *indirect* calls, with the imported symbol actually pointing to a *pointer* to the function. This is exactly what the 'declspec (dllimport)' of MS compilers does. Alexander said that Mozilla and Cygnus were willing to add the needed support for "Export side" in egcs, but this wouldn't be present in egcs 2.95. On the "Import side", Alexander suggested to directly tweak with the GOT (Global Offset Table) [editor's note: the GOT is used to relocate symbols from an .so library on loading]. Both Ulrich and Bertho's Stultiens agreed this was not a very good solution because it was non portable (because use of assembly language and too much knowledge of .so internals were required) and it couldn't solve some elfdll specific issues (like importing two functions of same name from two different DLLs). 3. controls and painting Archive Link: "scrollbar" People: Dennis Bj?rklund, Girard Patel, Dennis Bjvrklund, , G?rard Patel Dennis Bj?rklund reported some issues he had (and provided a sample program to demonstrate them). 1. The file selection dialog does not work. Nothing happens when I press OK even if I have selected a file. (press left mouse button in my test example) 2. The scrollbar does not work when it is being draged. When I release the scrollbar it jumps back to the top. 3. There is a graphical problem with the scrollbar. The edges of the control is corrupted. I expected it to have a win95/98 look (I have WineLook=Win98 in ~/.winerc). But it does not look like it does in windows. Is it not implemented or do I do something wrong? 4. The application icon does not exist. All I get is a blank square. I guess that it's just a bitmap that's missing but I report it anyways since it is a bug. The code is: LoadIcon( NULL, IDI_APPLICATION ) G?rard Patel answered point by point: * 1/ Yes it's hosed. The Wine code here is a bit difficult to understand, though. I am not sure than fixing it will not lead to worse problems. If I had all the time in the world I would like to rewrite it. I guess that the motivation to fix it is gone now than people can use the so-called 'native' (read : BillG) controls. I think (but I am not sure at all) that somewhere someone hinted to want to write a 32 bit version of these openfile controls, so maybe this will be fixed. Corel will need it anyway, so all hope is not lost. * 2&3/ It's a recent problem. I intend to attack some scrollbar problems real soon now. Wether I will win or the scrollbar will win is an open question. I will probably try your code while I'm at it. In a week or two. * 4/ I have no intention to look at this problem soon, sorry. Dennis then applied G?rard's patches and replied: My scrollbar problem that has been there for a long time has gone away with wine-990704. But, he also noticed (after diving into the code) that there is still a lot of (graphical) problems with the scrollbars in win9x mode. So I started to fix some small problems. And since I have some free weeks now in the sommer I could spend some time fixing the scrollbars for real. and asked wether someone else was also looking at those issues. G?rard answered he was focusing on some other areas, but reminded a few guidelines: * scrollbars are used everywhere, breaking something with them should be real easy. I don't know how much code there is in Wine, but it could be near one million of lines...Enough to make it difficult to find where is the change that broke something. * if you want to pass just a few weeks on wine development and then pass to other things, please forget it. Problems could surface after you are gone and then who will be left to fix things you could have broken ??? Do changes only if you offer support :-) Dennis agreed on the guidelines and went on, with G?rard, on a more in depth discussion of the current state of the graphical behavior of scrollbars (and fixme:s in the code). 4. DLLs loading Archive Link: "Your opinion" People: Michele Petrovsky, Ulrich Weigand, Michele Petrovsky, the one who is writing the book regarding Wine admin, asked about a a generalized statement of the impact of controlling load order of DLLs in creating the WINE runtime. Beyond, of course, the idea that loading native Windows DLLs before built-in ones can tweak application performance. Are there areas of app behavior (for example, multimedia or data communications) for which this rule-of-thumb *doesn't* hold true? Or are there types of apps which might benefit more from attempting, for instance, to load a special DLL first? Ulrich Weigand gave a full answer regarding DLL loading, load order and al. Well, the problem is that you can *not* simply say 'native DLLs are better' or 'built-in DLLs are better'. There are basically two aspects to be considered that tend to contradict each other: * On the one hand, native DLLs of course guarantee 100% compatibility for those routines they implement. Examples: If you use native USER, the visual appearance of window borders, dialog controls etc. is more-or-less perfect, if you use built-in USER, it doesn't really look quite like Windows 95 ... Same holds for the common controls (COMMCTRL) or the common dialogs (COMMDLG). The native SHELL contains e.g. the routines used by installers to create desktop shortcuts; since the file format of a shortcut file is not documented, Wine doesn't correctly implement these routines yet, hence some installers might fail when using built-in SHELL. * On the other hand, a native DLL might try to access features of the rest of the system which are not quite correctly implemented in Wine (e.g. because they are undocumented). In this case, the native DLL might work much worse than the built-in one, or even not all. Examples: The native MPR requires shared PE sections to work, which is not yet supported by Wine, hence it doesn't run. The native GDI requires a Windows display driver to be present, which isn't the case under Wine. The native KERNEL doesn't work at all because it directly accesses the Win95 core which isn't there under Wine. * A probably minor point: In a few cases, the Wine built-in DLLs implement *more* features than the original Windows DLLs; these features will not work when using the native DLLs, of course. The one prime example of this is the integration of Wine with X provided by built-in USER; if you use native USER, you can only run Wine in -desktop mode, and using the clipboard or drag-and-drop between Wine windows and X windows will not work. So, unfortunately, there is no rule-of-thumb which load-order to use; you'll have to have a certain knowledge of what the DLL in question does, which other DLLs/features it requires etc. to make a case-by-case decision. For most users, it will probably be best to simply stay with the load-order settings laid out the the default wine.ini file. This default setting is determined as follows: for all DLLs where there is a proper Wine implementation at all (i.e. not just stubs), or where the native DLL is known *not* to work, use built-in first. All others, use native. If you do want to experiment with variations of the load-order settings, there are two fixed rules that must be complied with: * Always use the same setting for DLL pairs (i.e. the 16-bit and 32-bit DLL that form a tightly integrated whole). You can use both native COMMDLG and COMDLG32 or both built-in, but don't try to mix it. The same holds for the other DLLs listed in the [DllPairs] section. * If DLL A calls routines of DLL B, and you use the native version of DLL B, you *must* also use the native version of DLL A. [This will no longer be required once the elf-dll mechanism works.] Normally, this is only a concern when using native USER. Some candidates where it might be worth-while to try deviating from the standard setting (built-in) and use the native version would be: * SHELL/SHELL32 * COMMCTRL/COMCTL32 * COMMDLG/COMDLG32 The native versions of these seem to work quite well nowadays, and they tend to bring noticeable improvements over the built-in ones. But, of course, YMMV ;-) If you are especially daring, you might also try to use native USER/USER32 (if you do this, you *must* also use the native versions of the DLLs mentioned above). You'll have to live with the drawbacks (only -desktop mode, etc), but in some cases it does have advantages: e.g. some InstallShield apps run better with native USER, and if you are very lucky, you might even get Explorer to run a little ... Lots of people were very happy with this description and requested it to be added to the documentation directory. 5. Porting to non-Intel architectures Archive Link: "Non-Intel library fixes and Win64" People: Alexander Larsson, , Patrik Stridvall Patrik Stridvall sent a patch to wine-patches to let Winelib compile on non-Intel platforms (including 64 bit ones). (Editor note: Intel platform means i?86 and Pentium (I, II, III). Merced, when available, should be considered as non Intel in the following article :-/). Alexander Larsson rejected it because Making it compile is good, but making it work would be better ;-) I'm not going to apply patches that simply remove everything that doesn't compile. This is especially important since few people have access to these other platforms, so if you don't do the job nobody else will. So, Alexandre added a #error in the CONTEXT struct definition: to clearly mark that there is something here that you must think about when porting. I could have put in a dummy struct instead, it would have compiled just fine, and it would only have been fixed after someone spent hours trying to figure out why some obscure API function doesn't work right. I think a clear compile-time error is preferable. Patrik asked why there wasn't any alike #error in the library part to bark at compile time when __i386__ was not defined. Alexandre agreed and ended the thread with all the places that need a portable CONTEXT (mostly the exception stuff) will eventually have a #error added. 6. Porting to BeOS Archive Link: "A small step towards portability" People: Howard Abrams, Ulrich Weigand, , Marcus Meissner Howard Abrams sent to wine-patches some configuration stuff that helps Wine compile on BeOS. Marcus Meissner provided some improvement on the patch and asked wether BeOS was supporting mmap(). Howard answered there is talk about it for R5, not sure if it will happen. Howard also explained that his previous attempts at porting show that Be was missing some important calls (like mmap, socketpair, select() on file descriptors, send/recvmsg). He now wants to tackle the porting issue on a step by step approach, and may be requiring some feedback from Be, which stated they'd tend to be more and more Posix compliant. Ulrich and Howard then discussed the different points. mmap() could be implemented by reading all the file into memory (which would result in bad performances with MapViewOfFile on large files). mmap() is also now used as an improvement for passing data back and forth to the server (instead of sending them through the pipe); Ulrich asked wether a shared memory feature exists on Be? Howard said yes: Areas. Ulrich reminded that the current server implementation requires you need to be able to pass *file descriptors* over the pipe. This means that the server opens a file, passes the descriptor to the client, and the client then uses the descriptor to access the file. Of course, you cannot simply pass the numerical value of the descriptor, because the client is another process. Thus, we use a special feature of sockets that allows to pass open file descriptors ('access rights'). This is the reason for using sendmsg() instead of sendto() in the first place! Ulrich pinpointed the known troubleshooter while porting to other Unices: thread support, address spaces, Howard asked about using Be native synchronization methods. Ulrich listed all the objects Win32 sync methods were able to wait on: * signalled synchronization objects (semaphores, events, mutexes) * process or thread termination * I/O activity (files, pipes, sockets, mailslots) * Console I/O * file-change notifications and explained how the Wine server did this job: Thus, in Wine the thread calling WaitForMultipleObjects simply blocks on the socket to the server. It stays blocked until the server has decided that the wait condition is satisfied (it can do so because all actions relevant to the status of the objects waited on is reported to the server, either by the (other) clients or by the OS as a result of the main select() call), and then wakes the client up by sending the reply to the original message. From a Unix stand point, WaitForMultipleObjects has to wait on: * "real file" descriptors * pipes * connection to the X server * in a (near future) on network connections Regarding the LDT (Local Descriptor Table), Ulrich said: That's the Intel processor data structure used to define segments. Linux normally uses only one single data segment and a single code segment, both spanning the complete address space from 0 to 4 GB. All segment registers are usually set up by the OS on process startup with these values and never changed by the program. Thus, the illusion of a non-segmented address space is created, although the Intel processor actually *always* uses a segmented address space ; -) Wine, however, needs to define additional segments for its own use. This is obvious when executing 16-bit code, but is even necessary when executing Win32 processes (e.g. the TEB selector must be loaded into the %fs register). As accessing the LDT directly is protected, we need to use special system calls to do so (modify_ldt() on Linux, i386_set_ldt() on *BSD, and sysi86(SI86DSCR, ...) on Solaris/x86). So, the question is: * Does BeOS provide an analogous syscall at all? * Are the LDT settings shared for all threads in one address space (if they aren't, Wine won't work. This is broken on Linux 2.0.*) * Does the BeOS environment survive if segments are actually used? This means: + Can the libraries cope if they are called with segment registers %fs,%gs set up different than usual (e.g. the Solaris/x86 thread libraries crashed when the application modified the %gs segment register ...) + What happens when executing code in a 16-bit segment and/or with the stack in a 16-bit segment at the time an interrupt/signal/... needs to be processed by the OS? + Are the values of the segment registers preserved over process switches? Sharon And Joy Kernel Traffic is grateful to be developed on a computer donated by Professor Greg Benson and Professor Allan Cruse in the Department of Computer Science at the University of San Francisco. This is the same department that invented FlashMob Computing. Kernel Traffic is hosted by the generous folks at kernel.org. All pages on this site are copyright their original authors, and distributed under the terms of the GNU General Public License version 2.0.