Wine Traffic #2 For 27 Jun 1999

By Eric Pouech

Table Of Contents

Introduction

This is the second 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).

Bertho Stultiens (provider and sysop of the European winehq.com, among other stuff) warned about the fragility of the machine currently hosting www.winehq.com. Since, he won't be around next week (and won't be able to fix the hardware before), there may be some service interruption next week (I just hope there won't).

Don't forget for more high level information Wine Weekly News (http://www.arcticnet.no/~ovek/wine) .

There is a book from IDG regarding system administration for Wine underway. James Sutherland is likely to be the technical editor (http://www.integrita.com/cgi-local/lwgate.pl/WINE-DEVEL/archives/1999-06/Subject/article-340.html) .

Marcus Meissner reported some press release (http://linuxtoday.com/stories/7017.html) from Corel.

Despite the good feed-back from the first issue, I still haven't decided to really open Wine's Kernel Cousin. Thanks to Pascal Cuoq for his help crafting this KC.

1. DLL modref and instance data (Service thread cont'd

 Archive Link: "DLL instance data"

People: Bertho StultiensAlexandre JulliardUlrich WeigandEric Pouech

Last week, from a question of Eric Pouech regarding where to store data for a DLL to be instanciated for each attached process, Ulrich Weigand proposed to add a field to the WINE_MODREF structure to handle this.

Eric Pouech agreed and wrote the extension to WINE_MODREF as well as an use of this new field for the multimedia timers (implementation was bogus when two processes attached the multimedia DLL).

Bertho Stultiens disagreed
Noop. The patch is doing it at wine-kernel-level and I suggested that this is a user-level problem. I.e. IMO the DLL's implementation must deal with duplicate instantiation, not the *loader* (or the responsibility gets divided wrt instantiation and relocation).

Alexandre Julliard also disliked the proposal:
IMO it is very ugly to hook that to the modref structure, especially since you have to retrieve it through the DLL name. As Bertho said, there is no need of any kernel support for this: you can simply have the DLL manage a list of its instances, indexed by process id or whatever. The list can be stored in a global variable, since they are shared; and when they are no longer shared, the global list will magically turn into a per-process list that will always contain a single instance.

Ulrich Weigand approved the comments:

Well, yes; I just wanted to avoid having to implement this process ID indexed list in every DLL that needs it; that's why I thought to use the already present modref list.

If you prefer it this way, that's fine with me, too ... Anyway, scaning a process list will typically be faster than scanning a module list, so it might even be more efficient ;-)

Eric Pouech then rewrote the multimedia timer patch according to the output of this thread (which requires several tries, but that's another story).

Patch has been committed to CVS, end of the thread. Anyway, this started another discussion about the correctness of global variables in DLLs wrt attached processes (is it a per process variable or a global variable ?)

2. Global variables in Wine DLLs

 Archive Link: "Use of global variables in Wine"

People: Ulrich WeigandBertho Stultiens

On the topic of global variables, Ulrich Weigand published an impressive list of them, gathered thru nm. He pointed out that the use of each of them will have to be at least analysed, and maybe changed, to make wine handle correctly multiple address spaces and threads.

Bertho Stultiens latter gave an explanation for a few of these variables: some belong to code that will have to be rewritten anyway, some will simply have to be made thread-specific, and many are harmless, since they are used only during initialization.

3. elfdlls

 Archive Link: "Elfdlls"

People: Ulrich CzekallaBertho StultiensGav StateManu

Before getting to Ulrich Czekalla's question, a quick introduction to Wine and DLLs. When it comes to loading DLLs, Wine supports four types of DLLs:

Bertho Stultiens provided first versions of a new tool called dllglue allowing to built the elfdlls. The process requires to provide for each DLL the list of exported functions (the one you wish the other DLLs to see) and the imported functions (the one your DLL wishes to call).

So, Ulrich asked
I thought it might be desirable for libwine apps to simply be able link the application without using the import/export tables and maintaining spec files for each module. One problem is that 'regular' linking does not 'register' the library with wine and thus cannot reference the library as a regular wine module. So the question is what are the pros/cons with simply having a LoadLibrary (or slightly modified) call in the module's initialization code. This would simplify the dllglue process. Of course we would have to ensure a certain library load order since wine itself must be initialized first. I realize that this is not an a alternative for wine itself when it's broken into its modules but for libwine apps it may be okay. Any thoughts?

Bertho Stultiens answered:

You need the import/export mechanism to ensure proper linking. Only these references should be resolved. The whole point is to generate the specs automatically from the declspec() extensions as used in MS compilers. This requires either a home-made parser or a modification of the compiler.

Anyhow, you still need to genererate the import table references to ensure that libraries are loaded in a specific order. I'd prefer to stick to the current strategy of generating full tables over hacking the loader (which only will give problems).

Winelib apps will first benefit from elfdlls to the fullest extent when everything is modularized properly (i.e. the wine-startup equals wine-lib startup).

Gav State from Corel backed up Ulrich:

Writing another compiler extension or parser is going to be a fair bit of work, for relatively little gain. The ELF loader already takes care of symbol resolution for us - the only thing having a full PE header gives us for WineLib apps is the load order for the dlls. Manually ensuring that your load order is correct isn't *that* big a deal, and it only has to be done once.

Think of this as a half-way mix between ELF-DLLs and plain ELF .so - it lets one write a Winelib app with proper handling of resources and other module stuff without having to write any more parsers or compiler extensions. It doesn't require any significant hacks to the loader - it's just a simple change to dllglue to add an explicit call to LoadLibrary into the ELF initialization section. This is controlled by an optional switch in dllglue, of course, so it wouldn't affect anything other than WineLib apps that want to use the half-way scheme.

We're using this technique internally now to get some of our test apps working. It works quite nicely - and we've been able to remove several hacks that we had put in place to get around our resource issues. Most importantly, we've got it working NOW. We don't have to wait for more compiler/linker level work.

Bertho fired back:

The problem with ELF linking is that it does not discriminate between symbols from different libraries. You can have duplicate symbols from different libraries where only one is supposed to be imported from another lib. You cannot be sure which you get unless you introduce load-order dependencies. The importtable is supposed to deal with this problem (because there *are* duplicate names in the API).

Yet another problem with dangling symbols in plain ELF linking is that they can interfere with other symbols in unexpected ways due to copy relocation. That is why I have the localization step in the linking. This is just to get rid of these problems.

Gav also asked Bertho whether he could put the dllglue under CVS. Bertho agreed (with some questions regarding which version of his was the best...). Since current dllglue puts more constraints on regular tools (
binutils >= 2.9.1 or at least "objcopy -L sym" working, alignment check of data with gcc/egcs. Gcc 2.7 refuses to align on 4096 boundary and additional assembly is required to do the trick
), Bertho also proposed to write before committing to CVS the proper extension to Makefile.in to check for those requirements.

4. gcc-2.95 to support anonymous unions

 Archive Link: "gcc-2.95-19990609"

People: Gav StatePavel Roskin

As the title says, Pavel Roskin reported that the latest gcc snapshot includes support for anonymous unions (i.e. an extension to C allowing to use anonymous, or nameless, unions in structure. Windows relies on this feature for some of its API structures.

This new feature will ease porting huge program written with windows compiler (providing this feature) without having to change throughout the code the access to the anonymous unions (Wine systematicaly names u the anonymous unions).

Gav State (from Corel) was happy to see some of the extents that Corel subcontracted to Cygnus surface to gcc:
Cool. It looks as though some of the compiler changes we've been working on with Cygnus are beginning to make it into gcc. There are several other changes that are still in progress, like precompiled headers, etc. Note that all the code you need for playing with COM interfaces in C++ Winelib applications is already there in wine/include/wine/obj_base.h. You just have to flip a couple of #defines...

5. Sig11 and gcc

 Archive Link: "Sig11 with cvs990622 and --enable-dll"

People: Ulrich WeigandOve Kaaven

Robert W. Hall reported another problem of sig11 when compiling with gcc. This was definitively not a hardware problem (some other people experienced it).

The known solution to this bug in gcc are:

Ove Kaaven reminded us:
Didn't Alexandre have a good theory once? He thought that it's probably some internal tables in gcc that's overflowing, rather than the code sequence itself... (and with that explanation he rejected a patch that decreased efficiency in order to work around the sig11)

6. Small implementation of win32 api

 Archive Link: "Light wine"

People: Greg HaerrPatrick StridvallPatrick Stridval

Greg Haerr copied wine-devel a message he's sent to Alexandre Juliard:

I have created a small, completely working re-implementation of the win32 user and gdi api's in about 42k ram, which I call Micro-Windows. This project started out of a project I ran into called nanoGUI, which was based on a small implementation of X for linux, called mini-x. In any case, the project had just started, and I became the main contributor. I completely redesigned the lower-level drivers so that the mini-x api ran on top of linux 2.2 framebuffers, linux 2.0 svgalib, MSDOS, ELKS and raw VGA hardware. As well, bare hardware and multi-os device drivers for the keyboard and mouse were created.

My expertise though actually is windows api programming, not X, so I decided to take the nano-X graphics engine that I created and implement the win32 graphics api on top of it. I have ended up with a small, portable, usable implementation. The idea was to build a small win32 source compatible implementation of a graphics engine that could be booted from floppy or run on a wide variety of devices.

I'm writing you because most of the linux graphics community seems centered around getting X or small versions of X moved forward. I am interested in your opinion as to the usefulness of Micro-Windows and whether there are any other developers that might be interested in this sort of thing. I've looked at wine, and think it's a great project. One of it's potential shortcomings is that it requires X. Perhaps I should work on getting it running on top of bare hardware or framebuffers... I have alot of cool ideas for projects that center around getting the windows api's running on more machines.

Micro-Windows currently supports, in < 64k, the following:

Greg also gave the list of supported API.

This project is (of course) Open Source (licence is MPL) and can be found at Censoft.com (ftp://microwindows.censoft.com/pub/microwindows)

Patrick Stridvall, who is working on removing X11 dependancy from Wine (and also allowing Wine to run on some other platforms) gave the current state of his effort:
Yes and no. I have been working on some kind of driver system for Wine and which moved all X code to special driver and make it possible to make other drivers. The work is almost done and most of the code is in the current distribution. I have a patch that does the rest and makes Wine _compile_ (but not work) completely without X. There are some untested/unsolved issues in that patch that I haven't yet fixed, so it was been put on ice when I found other interesting things to work on.

Patrick was very interested in Greg's work, and proposed a joint effort to reduce size of Wine, like
to add compilation flags to Wine that makes only the core USER, GDI, KEYBOARD, MOUSE and CRTDLL compile. Of course it is easily said but more hard to be done.
This would allow the creation of a light Wine (in fact a subset of current Wine) that could mimic Windows CE, and also be ported to PDAs (running Linux).

In order to make this happen, Patrick Stridvall provided a TODO list:

  1. There are dependencies that shouldn't exist between various parts of Wine. This will eventually be needed to be done anyway.
  2. All dependencies, in the core parts at least, to libc need to be eliminated. This should IMO be done anyway all such call go through the CRTDLL.
  3. If we really want low memory footprint, the calls between the 16 and 32 bit parts of should only go in the 16 bit to 32 direction to make it possible to disable the 16 bit parts. This should IMO be done anyway some day.
  4. If we really really want a low memory footprint, all dependencies between GDI/USER and the KERNEL, that is not absolutly needed, must be eliminated and/or #ifdef:ed. I am not sure Alexandre will like that, I am not even sure if I like it.
  5. Drivers for Linux Framebuffer etc need to be written.

The thread then forked in a more in-depth discussion of this Wine dependencies (http://www.integrita.com/cgi-local/lwgate.pl/WINE-DEVEL/archives/1999-06/Subject/article-310.html) list.

Patrick Stridvall got his hands on Greg's source, and gave his first understanding of the situation:

I think your orignal suggestion making Wine run on top off Micro-Windows driver is better.

It seems Micro-Windows driver systmem (graphics engine) is designed (optimized) with the assumption that the underlying drivers only can do very low-level operation like pixel drawing that is they are basicly dumb frame buffers.

Wine's driver system (graphics engine) on the other hand is designed (optimized) with the assumption that most drivers are capable of very high level operations like polygon drawing, font rendering etc.

Each of these assumptions make very much sense for the enviroments for which Wine and Micro-Windows was designed.

So having a unofied (Wine/Micro-Windows) driver system (graphics engine) really doesn't make sense. However a Wine driver system frame buffer driver (fbdrv) using Micro-Windows graphics engine does. Which was what you proposed in the beginning IIRC.

However I think both Wine and Micro-Windows will have its place in the future.

Wine, I think, will probably always be optimized for speed, with a driver system that makes it possible to make underlying drivers that can use the hardware (X on local computer) or bandwith (X Window on remote computer) efficiently.

Micro-Windows, I assume, will probably be optimized for size with a driver, system that makes it possible to write small underlying drivers.

A lot of the code Wine and Micro-Windows code, could be probably be shared. There are serveral things that could be done at an early stage.

  1. Making the USER controls implementation in Wine indepent of Wine's core, so that it could be used by Micro-Windows.
  2. Starting on a Wine frame buffer driver (fbdrv) that uses Micro-Windows graphics engine. This required that the concerned files in Micro-Windows is organized so that they could be used by Wine. Not very difficult I think."

Patrick and Greg agreed to keep on working: Patrick will be providing a frame buffer driver for Wine, and Greg will work on linking it to the Micro-Windows graphical engine and also to provide a portable controls implementation. Keep posted for more on this!

7. Some musing about OpenGL support

 Archive Link: "Accelerated OpenGL in Wine"

People: Lionel UlmerEric PouechPatrick Stridvall

Lionel Ulmer fired a thread about architectural issues he's facing while trying to add support into Wine for different OpenGL libraries (and starting with accelerated OpenGl libraries:
Precision Insight's DRI source, nVidia's accelerated X server and the specs to both the G200 and the G400),
).

Lionel proposed several architectural options (and issues with them):

There are three kinds of functions in 'opengl32.dll':

  1. windowing-system specific OpenGL functions. On X11, they are the 'glX*' functions, 'wgl*' on Windows
  2. 'core' OpenGL functions. These functions are mostly 'hard linked' by the application
  3. OpenGL extensions, that are queried by the application using the 'wglGetProcAddress' function

For 'glu32.dll', there is only type (2) functions (I do not of know any extensions to GLU).

The different possibilities to implement all this:

For the moment, I think I will send a patch with option (d). The problem is that I will be unable to hack anything on Wine for the next 5 / 6 weeks and I would like this to be included in Wine before I leave (otherwise I fear the merging I need to do with the 15 files my patch changes :-/ ).

Patrick Stridvall, to help with the overview of the situation, discussed then some issues with Lionel, mainly regarding if Direct 3D should be implemented on top of OpenGL (or the other way around) and ways to store (and exchange contexts) within the two.

Some other issues are linked to the version of OpenGL provided by the accelerated OpenGL libraries (which may not be the same), and thus, the level of functions to reflect into Wine. Achim Kaiser proposed to use the OpenGL 1.2 (which is what's currently provided by Mesa 3.0).

Lionel quite not agreed and give the following arguments:

I saw a mail by a guy from PI saying bascically that all open-sources drivers are based on Mesa, but there exists closed-source drivers that will be based on the SGI code base (it is understandable: if their engineers are familiar with this code by using it on Windows drivers, why change for Linux).

Moreover, even the Mesa code is not stable: for example, in one branch of the Mesa developpment tree, one set of extensions were removed because they were obsoleted... This means that if I base my work on the current 3.0 (or 3.1b) code, it won't link for people using this branch.

I once made the mistake to have the assumption that everybody did upgrade its Mesa library to 3.0... I do not remember how many people did ask in the newsgroup why their Wine did not compile anymore. Now I always plan for the worst :-)

 

 

 

 

 

 

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.