Francois Gouget wrote:

>    Hi,
>
> David Elliott wrote:
> [...]
> > Are Winelib programs also supposed to use the wine CRTDLL?
>
>    Yes and no. They need a C library (badly).
>    Frankly I've never used 'crtdll.dll' and don't know it very well. All
> I know is that it seems very similar to a C library except I'm not sure
> who is supposed to use it. All the windows programs I've worked on/know
> of use the standard 'msvcrt.dll'. And all the 'C library' headers in the
> Windows directory are for 'msvcrt.dll'.
>

Yeah, and Wine doesn't even provide MSVCRT because "Applications will install
it".  However, newer versions of windows include it (at least it is in my
98SE cab files, and I think IE uses it).  Although if one installed IE, then it
would presumably install MSVCRT.DLL, and since IE is free for download, no one
has yet done MSVCRT.  At least that is my understanding of the situation.

I have already looked at MSDN, and noticed that all new windows development seems
to link against MSVCRT and not CRTDLL (like you mention).  And yet CRTDLL is
included in Wine because it came with Win95.  This situation seems to be entirely
bass ackwards for Winelib development.

>
> > If so then it's
> > necessary to provide headers like stdlib.h and math.h to Winelib programs
> > and to link the winelib programs against the wine crtdll instead of the
> > native libc.
>
>    Yes, we'll need 'our' C library headers for WineLib programs, one
> day. I've given some (_some_) thought on that. Here's a dump of how I
> see things currently. Keep in mind that it will need to be further
> discussed and refined.
>
>    First we must put these headers 'out of the way' so that their use is
> optional. There are multiple reasons for that the most important being
> that we still need to be able to get access to the native (unix) headers
> for compiling Wine. The best seems to be a subdirectory of 'include'.
>

Yes, I agree.  I like the names you are using too.

>    Then I think we should have three different configurations:
>
>  * native C library - Unix semantics
>
>    This is what we currently have. The WineLib application compiles with
> the native (unix) headers, and links with the native C library. The
> semantics of all the C library functions is therefore the Unix
> semantics: fopen takes a Unix path, does not understand O_TEXT, etc.
>

Okay, that's what I thought.  This is probably not very ideal for porting source
seeing as how this is definitely going to require changes to the apps source.

>
>  * MSVCRT C library - Windows semantics
>
>    With this solution we provide C headers that are compatible with
> those of Microsoft. We provide them in 'include/msvcrt' and the user
> puts '-I$(WINE_ROOT)/msvcrt' in his include path. The WineLib
> application is linked with a library called 'libmsvcrt.so' in such a way
> that the he actually calls the C functions of this library rather than
> those of the native C library (playing with the link order and no-sys
> library options and such I guess). I say 'libmsvcrt.so' because that's
> what I know. Maybe 'libcrtdll.so' would work too. The semantics of the
> functions implemented by this library are the Windows semantics: fopen
> takes a dos path and recognises O_TEXT, we implement _beginthread and
> friends, etc.
>

We want to use libmsvcrt.so and implement MSVCRT.  CRTDLL seems to be deprecated
by Microsoft, and I have heard it is not very threadsafe, and I remember
Alexandre saying that if a function is documented as not being threadsafe there
shouldn't be additional overhead to make it threadsafe.  However, supposedly
CRTDLL is /supposed/ to be threadsafe, it's just that it isn't very much so in
practice.  At least that is what I gather from discussion on this list and from
MSDN.  It does export funtions like _beginthread.  Personally I feel that sharing
the CRTDLL implementation with MSVCRT would be better than specifically writing a
non-threadsafe version of a function for CRTDLL.

>
>  * 'Mixed' C library - Unix semantics
>
>    This is an intermediate solution. The semantics is that of Unix like
> in the 'native C library' case. But we provide a specially designed set
> of headers to ease compilation:
>    - macros map things like '_hypot' to 'hypot'
>    - macros provide replacements for things like _itoa
>    - macros fake support for 'O_TEXT'
>    - maybe some macros would map an API to a CRTDLL_xxx function
>    - provide additional headers like 'direct.h'
>    - maybe approximate a little bit: map _flushall to sync
>    - etc.
>    The headers would be in 'include/mixedcrt' and a WineLib application
> would link with the native C library and possibly with crtdll if it uses
> APIs that have been remapped to one of the CRTDLL_xxx functions.
>    The important thing here is: 'Unix semantics' plus some compatibility
> features.
>

So basically if it's implemented by the libc use it, but if it's not then use the
MSVCRT implementation.

>
> Notes:
>  * Unicode
>    We should provide the appropriate prototypes so that it works in the
> 'MSVCRT C library' case. For the other two solutions Unicode will not be
> supported (because of the 2 vs. 4 chars difference).
>

This answers the question I was about to ask.  I assume if a function is
implemented by the native libc then we go with the native libc implementation
since it would be rather hard to include a UNIX header leaving out the parts that
would conflict.

>
>  * Thread safeness
>    Again the MSVCRT solution should be thread safe because it is on
> Windows. For the other two it all depends on the native C library, i.e.
> it's most likely not thread safe.
>

Aren't all the glibc's threadsafe?  Especially with Wine exporting the pthreads
primitives?  Is anyone still living in the darkages with non-threadsafe libc
5???  Although I do agree that it may be necessary to modify the applications
code to deal with the non-threadsafeness when using the mixed/UNIX modes.  For
the MSVCRT mode I agree that it should most definitely be threadsafe (and will
need to be for the emulator to work right).

>
>  * This scheme leaves the door open for adding other C library
> implementations. If Borland has their own slightly different C library
> then we add the corresponding headers in 'include/bcrt' and provide
> another library.
>

Ahh yes, good idea.

>
>    I have actually implemented some of the headers for the 'Mixed C
> library' solution. I attached a tarball containing the new files.
>

Hmm.. okay.  I suppose that the mixed-mode headers should be a seperate thing.
Nice comments in stdlib.h... /* Embrace */ ... /* Extend */, I wonder if the real
internal MS header files look like that ;-).

I will begin putting headers for MSVCRT into the include/msvcrt/ directory since
that makes the most sense.

In the wine source itself I will refer to them with #include "msvcrt/stdlib.h"
and so on.  A winelib application wanting the MSVCRT-only mode will simply need
to juggle with linking and use -I${PREFIX}/include/wine/msvcrt  Assuming that is
where the headers have been installed.

It is my understanding that when compiling Winelib programs __WINE__ is not
supposed to be defined, but when compiling Wine itself, it is.  So the headers
could use that to determine whether they should name things with a MSVCRT_ prefix
(when compiling wine) or not (when compiling apps in MSVCRT mode).

I am not entirely sure how mixed mode should be handled.  I originally thought of
simply straight-out using libc functions when available and using the
MSVCRT provided implementation when not.  I was thinking of making the mixed-mode
headers actually #include "../msvcrt/headername.h" with something defined that
would make them only provide definitions for certain functions.  However, it
occurred to me that the implementations of several functions will be different
for the two cases.  And looking at your examples, Macros using the native libc's
functionality would be a much better solution.  When it all boils down to it,
very few things in mixed-mode should actually be imported from MSVCRT, especially
if you consider things like how errno is handled, you would want to update the
native UNIX errno, whereas for a clean implementation for the emulator and for
winelib apps using MSVCRT mode you would want to have your own errno.  In fact,
the only functions you could reliably import would be simple one or two line
jobs, and that could be better done with a macro anyway.

I did think of one solution to the linking problem:  If there was a library like
libobfuscatedmsvcrt.so that imported the real names from msvcrt (that is, was
linked against MSVCRT) and exported them with an MSVCRT_ prefix, then the headers
could use things like #define malloc(x) MSVCRT_malloc(x) and prototype the
functions with the MSVCRT_ prefix.  Therefore the unresolved symbols all have the
MSVCRT_ preifx.  The app would then be linked against the
libobfuscatedmsvcrt.so.  However IIRC .so files can't or shouldn't be linked
against other .so's in UNIX (although it is acceptable for a DLL to import from
other DLLs in windows), so that is probably not a very good idea, but I am
throwing it out for anyone to consider anyway.

[cut here to avoid discussion of implementation details and stay on the original
topic]
And off of the subject of header files and onto the subject of implementation
details....

_errno is a function that returns a pointer to errno, so:
#define _errno() &errno
would be the correct definition for the mixed-mode headers.  For the
MSVCRT headers I have implemented it as follows: _errno() is a real function
(cause it needs to be exported) and points to an integer in TLS space.  Actually,
right now it's not threadsafe and is declared as a static variable in the
function itself, but it will be once I read up on how to put stuff on the TLS.
Or I suppose on the heap would be okay too as a call to _beginthread can take
care of that.  What I really don't quite understand is why MS uses _beginthread
instead of simply making use of the THREAD_ATTACH case of the dllmain function.
There is an article at
http://msdn.microsoft.com/library/periodic/period99/win320799.htm that goes into
very good detail about how MSVCRT and the other C libraries work.  It notably
does not mention CRTDLL at all, leading me to believe that no new Win32
development uses CRTDLL.

I am using:
#define CRTDLL_errno *CRTDLL__errno()
Which according to MSDN is how each thread accesses it's own errno.  Of course
you should drop the CRTDLL_ prefix for real headers.

Anyway, I think that pretty much settles it about the MSVCRT header files.  It's
been discussed several times before and I think each time the consensus has been
what you have described.  So now it appears to be time to start implementing
MSVCRT.DLL.  There is some work done by Jon Griffiths located at
www.winehq.com/patches980927/CRTDLL_Updates{,.txt}  The file with the .txt
extension is a description of the changes, the file without it is actually a
.tar.bz2 containing a diff and a seperate C program used to test the
functionality.

The code is okay, but I have already written a much better atexit implementation
using a linked-list, which also follows MSDN docs which state you can have as
many atexit functions as heap space, and also makes hello more sense considering
that they get executed LIFO which is exactly how they get executed if you put
them on at the front of the list and take them off from the front of the list at
exit.

Looking through the code, some of the other things are okay.  There are some
binary compatible structure definitions and a lot of really good comments and
some good implementations.

Well, anyway, it is way past my bedtime now (6am) so I am going to hit the sack.
Hopefully you will have replied to this by the time I wake up!

-Dave

P.S. This message looks a lot longer than it was supposed to originally be.  To
summarize, I basically just agree with everything you say and provide a few
specifics and some tips.  I really gotta stop staying up so damn late.



Reply via email to