Kernel Traffic
Home | News | RSS Feeds | Mailing Lists | Authors Info | Mirrors | Stalled Traffic

Wine Traffic #245 For 22�Oct�2004

By Brian Vincent

Table Of Contents


This is the 245th issue of the Wine Weekly News publication. Its main goal is to cough. It also serves to inform you of what's going on around Wine. Wine is an open source implementation of the Windows API on top of X and Unix. Think of it as a Windows compatibility layer. Wine does not require Microsoft Windows, as it is a completely alternative implementation consisting of 100% Microsoft-free code, but it can optionally use native system DLLs if they are available. You can find more info at

Mailing List Stats For This Week

We looked at 164 posts in 730K.

There were 61 different contributors. 30 posted more than once. 28 posted last week too.

The top posters of the week were:

1. News: Wine-20041019

16�Oct�2004�-�22�Oct�2004 (1 post) Archive Link: "News"

Topics: News

People: Alexandre Julliard,�Gerald Pfeifer,�,�Ivan Leo Puoti,�Ove K�ven,�News,�Marcus Meissner,�cvs

A new version of Wine is out. Alexandre noted the following changes in his announcement:

WHAT'S NEW with Wine-20041019: (see ChangeLog for details)

It looks like our packaging crew has been at work and you can find updated versions on Wine on our download page. It should also be pointed out that the FreeBSD and Debian packages haven't been updated in a while. Gerald Pfeifer has reported problems with the FreeBSD port for a while and apparently those issues still haven't been resolved. As far as the Debian package goes, I'm not sure why it hasn't been updated. Thanks goes out to Vincent B�ron, Marcus Meissner, Ivan Leo Puoti, Adam Schreiber, Ove K�ven, and Gerald Pfeifer for maintaining those.

2. Porting C++ With Winelib and Loader Issues

18�Oct�2004 (6 posts) Archive Link: "How to port c++ program to linux using winelib"

Topics: Winelib

People: Jia Wu,�Eric Frias,�Boaz Harrosh,�

Winelib seems to have attracted some attention recently. We've seen more questions than usual getting asked about it. Of course, it doesn't help that our Winelib documentation is out of date, but that's a problem for another day (hint, hint.. we need volunteers to update it.) This week Jia Wu asked about porting a large application:

I have a win32 program written in C++. I am trying to port it to linux using winelib. The software contanis one exe file and several dll files. I would like to keep this structure when moving them to linux. That is, I still would like to generate several corresponding shared libraries (instead of statically linking all files together) in llinux and they will be loaded at the runtime.

However using winelib tools (winemaker, configure, make) for shared library generation, I get unresolved symbols error.

It seems that I have to write a spec file for each dll to import(and export) functions provide by other dlls. However, since they all written in c++ and what need to be imported can either be class or class method, and parameters can be class either. SO I don't know how to handle this in spec file. Beside each dll file exports many functions or classes. It would be tedious to write a lengthy spec file manually.

My question is that if it is possible that linking is not invoked during shared library generation under wine (but during the runtime)? How should I do it?

Eric Frias described a similar situation:

I don't have an answer, just tagging along here. I'm curious what other people have come up with, both for the long-term solutions and the best way to get it working today.

I'm working on a large C++ application that is divided into many shared objects. We are currently using a version of wine that is about a year old. With that version, we were able to get C++ shared libraries to link together by bypassing wine's DLL mechanism for all of the C++ symbols -- we just let the native linux loader resolve the C++ symbols. We just created empty .spec files for all of the C++ DLLs we wrote. When we called winebuild to generate the .spec.c file for each DLL, we would only tell winebuild that we were linking against DLLs that were part of wine (kernel32, user32, etc). Then when we did the actual linking for the DLL we were building, we would pass in the names of the other DLLs we depend on the typical way (-lour_library.dll), and the native linker would resolve those symbols for us. This worked very well for us. I suspect there are a few things that this would have broken, like calling GetProcAddress on one of our C++ symbols, but that isn't a feature we ever used.

We got a rude suprise when we tried to update to a current version of wine a month or two ago. The DLL loading mechanism had changed during that span, and hack we were using would no longer work. It looks like the current version of wine won't allow you to link to a wine DLL with the native linker. It expects all linking between wine DLLs to be done through winebuild, and it gets confused when a DLL gets loaded (by the shared loader) that wine didn't explicitly load. We haven't yet figured out what to do about this.

We could try to modify wine's loading mechanism to allow the kind of hackery we were doing before, but I don't know much about this part of wine and I'm not sure what the consequences of loding DLLs out-of-order are. I guess the other option is to generate .spec files for all of our DLLs, which is an option that doesn't really appeal to me either. It'd be pretty easy to write a script that will massage the output of nm(1) to generate a .spec file, but if you do that you're going to be exporting every symbol, most of which will probably be unused.

I seem to recall that there are experimental(?) modifications to gcc and binutils that understand declspec(__dllexport)-type annotations. I think this was part of mingw. IIRC, gcc would somehow mark the exported symbols in the object files, and a separate utility would scan the object files and create a .def file with all of the exported symbols. I'm not sure this stuff even compiles on linux. Does anyone have a solution they're happy with?

Boaz Harrosh described an approach to the problem:

Do a .spec file for each C++ dll with one c function like:

In your app or in the dlls that use the above dll do a function like:

link every thing the regular wine way this way DLLS load in the right order, get initialized, and their Windows "import tables", like calls to kernel32 etc, gets initialized by the loader. But (and here is where I'm out of dated) also specify the .so as a link option to the gcc linker. (ld)

In the old system, before winegcc. One would do -lmydll on the winebuild command line. And than in turn -lmydll on the ld command line - for resolve of C++ symbols. Now that we use winegcc I'm not sure what is the switch for additional libs like .so and static libs. Look maybe it is documented. (Dimi how do you add external libs to a winelib link stage under winegcc?)

But be careful with this approach. It is an order of a magnitude slower on load time than DLL linkage on windows. I came to a dead end with one of my projects, where I managed to compile and run every thing but I had to revert to PE compiled code because it took my app 4-6 minutes to load. (PE takes 40 seconds). It was a 1.2 M lines of C++ code divided in to 37 DLLs + MFC in a dll.

We have talked about the right solution with Alexander on Wineconf. What he suggested was:

  1. make the __declspec( export ) macro expand to a gcc "section" declaration. So the compilers put all of them in a special section. No one knew how C++ classes behave with "sections" and we suspected each member function has to be put into the section by hand. On windows a __declspec( export ) on the class declaration automatically exports all members. Maybe MinGW could help out here.
  2. Use a tool like nm or readelf to extract all symbols (including C++), in above section, and with a script convert them to a .spec file.
  3. I think that current winebuild have problems with some variants of the C++ mangled symbols like the use of the "@" character. So maybe a new "C++" style function should be added to the .spec syntax, that will not try to interpret the symbols.

Eric thought the approach was sound and described more of the project he's working on:

Thanks for the suggestion! Even if it isn't elegant, it sounds like it will work (and is very close to what we were doing with the older wine). I might even be able to coax our build system into generating all of the *_export() and using_dlls() functions automatically.

I'm working on a large project too, well over a million lines as reported by 'wc -l'. We've got about 50 shared libraries, but only 10 of those use wine; the rest are entirely native. We think our application takes too long to load, but not nearly 4-6 minutes. On a fast machine if you run it a few times in a row, it takes around 8 seconds to load. On a lesser machine that has been doing other things, it will often take 40 seconds or so. I'm not really sure where all of the time is spent. I've been assuming that the majority of it is spent by Most of the DLLs have 200-300 symbols imported from the standard wine libraries, so the whole application is doing about 3000 fixups in our project. I can't see that taking too long (but I've never timed it). I think if I started using the method you suggested, it should add less than a hundred extra fixups for wine to perform -- we're really just changing what causes the libraries to load, not what they import.

Was all of the time your application took to load because of wine's DLL import mechanism, or because of the shared loader in linux? One of the reasons we are trying to upgrade to a more recent version of winelib is so that we can try some of the 'prelinking' tools to try to make our app load faster, so I'm curious where all of the time is spent.

Boaz described what he found with the loader:

Most definitely the Linux-shared loader. It took ages. The code is heavy C++ code full of templates with weak symbols, inline virtual functions, and plain horizontal code structure. almost any thing you can do to slow a linker down. The PE export-import tables are much better in this situation since there is no searching to do. (and no fixups) All searching if any is done in link-time. (Run time on the other hand is slower). Actually this app is very bad on Windows too. So we compile it: "all libraries static" when doing "Release" code. We use DLLs in debug because the static linking takes 15 minutes.

Speaking of which I was never able to statically link the winlib app on Linux. I put up a machine with 2-Gg of ram + setup 2Gg of swap space. The linker would work for 5-10 minutes than it would hit the swap space. Memory would go up and up until about 50 minutes where the kernel starts to kill every thing in sight including the Linker. MSVC++ does not do that, it uses temporary files. Lots of them, to finish the link. I did not even try none-debug builds because the all point of the winlib was that Developers could use full screen debugger (Kdevelop) to debug Linux problems. If we only have traces and relays than PE is Just good enough.

Thanks for letting me whine. ;-) Please do post your results on how to Link the .so on the winegcc command line. And also most important if you succeed with prelinking. I think that is the best way to go but I'm not a Linux guru and didn't manage to do it.

3. Start Menu Brokenness

18�Oct�2004�-�20�Oct�2004 (7 posts) Archive Link: "Startmenu"

Topics: Controls

People: Thorsten Kani,�Robert Shearman,�,�Rob Shearman

Apparently Thorsten Kani has been testing out Wine's controls with Windows 2000. He noticed some toolbar problems when run with Explorer and posted a patch. There was some back and forth discussion with Rob Shearman and Rob also posted a patch to fix some issues. Rob wondered how well the Start menu was rendered and Thorsten reported:

I took a look at the Startmenu. It does its job except for the following minor problems:

If the mouse hovers over the button, the text redraws at the right place

Rob asked for a screenshot and Thorsten provided two:

Rob seemed to recognize the problems and worked on them:

Thanks. Could you try the attached patch which should fix the white background issue?

Also, could you try setting both OFFSET_X and OFFSET_Y to 0 in wine/dlls/comctl32/toolbar.c

The strings being in the wrong position is a bigger issue. If you are interested, the problem is that we recalculate and redraw our toolbar control too much so that the code to create the Start Menu expects that it won't be refreshed until it has finished setting the various properties of the toolbar. I have some unfinished work in the toolbar control at the moment, but I plan to use controlspy to see which messages should cause a redraw and which shouldn't.

Thorsten reported that it fixed some issues, " Nice Patch - looks good now!" Thorsten also made some other changes, but Rob didn't think they were correct. Thorsten asked for any suggestions of how he could troubleshoot the problems. Rob gave a link to ControlSpy:

You can download controlspy here:

It is very useful for throwing messages at the common controls, but it cannot test custom draw functionality and it is becoming dated (it is missing new functionality from comctl32 v5.80 and new controls).

4. When Optimizations Aren't

20�Oct�2004 (5 posts) Archive Link: "Re: Tiny optimizations of bit testing operations"

Topics: Project Management

People: Dmitry Timoshkov,�Rein Klazes,�Alexandre Julliard,�,�Rein Klaze

Dmitry Timoshkov posted a small patch that changed about three different lines of code for optimization. For example, he changed this line:

To this:

Rein Klazes wrote back:

At any optimization level, gcc compiles this to identical code.

>From the C point of view these bit logics are identical. The compiler finds that out easy.

Dmitry explained it wasn't just about optimization, " Yes, I know. That's why the optimizations are "tiny". I believe that the code itself becomes more readable with my changes and makes it not depend on the optimizations a compiler is capable to perform. "

Alexandre was skeptical and outlined how he usually handles such changes, " Here it's not clear at all that one is more readable than the other; and in such a case the policy is that whoever writes the code in the first place gets to decide how it's done."

5. Windows Catch-22

21�Oct�2004 (3 posts) Archive Link: "Re: Cleanup config"

Topics: Configuration

People: Dimitrie Paun,�Alexandre Julliard,�,�Microsoft,�Dimi Paun

Here's a short thread I found amusing.

Dimi Paun went through the sample Wine config file and removed some of the options that have recently been moved into the registry. As part of that, he removed the "Windows" parameter that let's you specify where Wine should expect to find the windows directory. Most normal and sane people choose this to be the default c:\windows, but Microsoft does allow this to be configuable. Alexandre committed the patch except for that one parameter and mentioned that it's still being used by the registry code. Dimi wondered where specifically it was being read from the config file, " Heh, that's not nice, now we define it in two places. I can't quite find where it's been used, do you remember the filename? "

Alexandre explained the catch-22 posed by the situation:

It's in misc/registry.c. And no, it's definitely not nice at all; unfortunately we can't use the value from the registry in the code that's supposed to load the registry ;-) (well, we could, but that will require some serious restructuring of that code).

6. Winedbg: Broken Watchpoints

18�Oct�2004�-�21�Oct�2004 (6 posts) Archive Link: "Winedbg: watchpoints broken?"

Topics: Debugging

People: Walt Ogburn,�Eric Pouech,�

Wine's debugger has seen quite a bit of work over the past year. At various times things have been broken, however overall Eric Pouech has done a great job working on it. Walt Ogburn ran into a problem this week:

Winedbg's watchpoints don't seem to work for me: when I try to watch a memory location, winedbg responds that a watchpoint has been set at a different, always constant location (I suspect this is actually in winedbg's memory space). Nothing happens when the location I was trying to watch changes.

Here is a cut-and-paste from my winedbg session. I try to watch memory location 0x0041a5ec, but I can set other breakpoints and see that the value has changed without the watchpoint taking effect.

The fact that winedbg thinks the watchpoint is 0x405ae8c4 is especially puzzling, but it's entirely possible that the confusion lies with me rather than winedbg.

Eric posted a patch and Walt tried it out:

Thanks. That fixes the watchpoints, but introduces a couple of small problems:

  1. in dbg.y, break_add_watch_from_lvalue should take only one argument (drop second argument)
  2. in dbg.y, I have no minidump_write. Should this be replaced with dbg_printf("%s\n", $2);i ?

After fixing these two things, breakpoints work, although the instruction pointer displayed is the one just after the watched address gets written to. Perhaps this is the expected behavior, but it would be nice to have the instruction that makes the write instead.

Eric confirmed that Walt's fix for the first issue was correct. The second issue required something a little different. With regard to the instruction that gets displayed, Eric thought it would be difficult to fix, " in fact, it'll be hard to change it. ia-32 reports insn after the one that triggers the watch. The rationale being that you must execute the insn in order to know of the write change (unlike a seg fault where you cannot know execute the insn). GDB behaves the same (it shows the line after the one that triggered the watch)."

Eric didn't send his fix to wine-patches and he alluded that it was part of a bigger patch. In the mean time, you can find the watchpoints patch in the wine-devel archives.

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 All pages on this site are copyright their original authors, and distributed under the terms of the GNU General Public License version 2.0.