On Thursday 02 January 2025 11:36:26 Martin Storsjö wrote:
> On Thu, 2 Jan 2025, Pali Rohár wrote:
> 
> > > No, 0x0601 for __MSVCRT_VERSION__ doesn't mean Windows 7. I think you've
> > > made way too much conclusions based on the info in msvcrt.def.in, which 
> > > does
> > > not seem to be using the same numbering scheme as the headers.
> > 
> > I see, I was wrong, based on that file which I found...
> > 
> > > 
> > > I believe the version numbering for __MSVCRT_VERSION__ in headers was 
> > > meant
> > > to use both the msvcrXX.dll version numbers, just like we do, but also 
> > > based
> > > on the actual embedded version number of the msvcrt.dll that shipped with
> > > the OS.
> > > 
> > > I don't have a copy of msvcrt.dll from win9x or older versions handy for
> > > looking at, but I have a set of the modern ones. Using "peres -v 
> > > msvcrt.dll"
> > > (the "peres" tool from the "pev" or "readpe" package on Ubuntu), I'm 
> > > getting
> > > the following version:
> > > 
> > > Win2k 6.1.8637.0
> > > WinXP 7.0.2600.5512
> > > Vista 7.0.6002.18551
> > > Win7 7.0.7601.17744
> > 
> > So for completeness, I run peres -v on these system versions:
> > 
> > NT4.0    4.20.0.6201
> > Win98    5.0.0.7128
> > Win98SE  6.0.8397.0
> > WinMe    6.1.8637.0
> > Win2k    6.1.8637.0
> > Win2ksp3 6.1.9359.0
> > Win2ksp4 6.1.9844.0
> > WinXP    7.0.2600.0
> > WinXPsp1 7.0.2600.1106
> > WinXPsp2 7.0.2600.2180
> > WinXPsp3 7.0.2600.5512
> > WinXPx64 7.0.3790.1830
> > 
> > NT4 msvcrt.dll has same set of symbols as VC4.2 msvcrt version, Win98 FE
> > has same set as VC5.0SP1, and Win98 SE has same as as VC6.0. So it looks
> > like that version numbers from peres for NT4/Win98 matches the VC++
> > versions.
> 
> Yep. And to make things clear - msvcrt.dll in XP doesn't have the same set
> of symbols as the real msvcr70.dll, right? So the divergence started at that
> point (and/or at the 6.1 versions used in 2k and Me)

Yes. The correct list of symbols for msvcrt.dll in XP and in msvcr70.dll
are already documented in mingw-w64 files:

mingw-w64-crt/lib-common/msvcrt.def.in
mingw-w64-crt/lib32/msvcr70.def.in

> > > This also lines up perfectly with some of the ifdefs you referenced - e.g.
> > > _aligned_malloc exists in msvcrt.dll since XP, and is guarded by
> > > __MSVCRT_VERSION__ >= 0x0700. And _wstat64 which is guarded by
> > > __MSVCRT_VERSION__ >= 0x0601 is available since Win2k.
> > 
> > That make sense. I checked in our msvcrt.def.in and _wstat64 symbol is in
> > Windows ME/2000 section.
> > 
> > > So the mythical __MSVCR61_DLL means Win2k.
> > 
> > Yes, that would make sense.
> > 
> > > > So, based on this investigation, I think that changing default value of
> > > > __MSVCRT_VERSION__ again should not be needed. I would suggest to just
> > > > adjust checks in mingw-w64 header files for:
> > > > 
> > > > * OS system msvcrt.dll version (any OS):
> > > >  - #if __MSVCRT_VERSION__ > 0x400 && __MSVCRT_VERSION__ < 0x700
> > > >  - This will match any mingw32 OS system msvcrt.dll version except the 
> > > > Windows NT4
> > > >  - It does not conflict with neither mingw-w64 msvcrt40 (== 0x400) nor 
> > > > with msvcr70 (== 0x700)
> > > 
> > > I don't think they used __MSVCRT_VERSION__ < 0x600 for anything, other 
> > > than
> > > potentially msvcrXX.dll versions just like we do.
> > 
> > Probably yes. So the condition could be:
> > 
> > #if __MSVCRT_VERSION__ >= 0x600 && __MSVCRT_VERSION__ < 0x700
> 
> Yes, that sounds good to me.
> 
> > > > * msvcr100+:
> > > >  - (__MSVCRT_VERSION__ >= 0xA00 && __MSVCRT_VERSION__ < 0x1000) || 
> > > > (__MSVCRT_VERSION__ >= 0x1000)
> > > >  - First part is for mingw-w64, second for mingw32
> > > > 
> > > > * msvcr110+:
> > > >  - (__MSVCRT_VERSION__ >= 0xB00 && __MSVCRT_VERSION__ < 0x1000) || 
> > > > (__MSVCRT_VERSION__ >= 0x1100)
> > > >  - First part is for mingw-w64, second for mingw32
> > > > 
> > > > * msvcr120+:
> > > >  - (__MSVCRT_VERSION__ >= 0xC00 && __MSVCRT_VERSION__ < 0x1000) || 
> > > > (__MSVCRT_VERSION__ >= 0x1200)
> > > >  - First part is for mingw-w64, second for mingw32
> > > 
> > > I don't think we should do anything to complicate things for numbered
> > > msvcrXX.dll here - using anything other than msvcrt.dll and UCRT is
> > > exceedingly rare. (I only practically know of two cases; you, and VLC did
> > > need to target msvcr120*.dll for Windows Store distribution at some point,
> > > and that's no longer relevant for them.)
> > 
> > Ok. It was just a suggestion for completeness. As nobody complained
> > then it is not needed.
> > 
> > > > Would be this enough to finally fix those issues with 
> > > > __MSVCRT_VERSION__?
> > > 
> > > I don't think this would make any difference here at all.
> > > 
> > > 
> > > I believe that the issues that can be caused by our changes fall into two
> > > classes: (Sorry, I didn't browse all the code search results to see what
> > > other concrete cases there were.)
> > > 
> > > - Projects that look at __MSVCRT_VERSION__ and conditionally compile 
> > > things.
> > > This may lead to projects building with fewer features (by skipping things
> > > that would require a newer msvcrt.dll), or trying to use extra compat
> > > routines that wouldn't be necessary. Or there can be clashes, if they see
> > > our __MSVCRT_VERSION__ and conclude that function X isn't provided, and 
> > > they
> > > try to provide their own replacement function X, and they can get 
> > > duplicate
> > > conflicting definitions.
> > > 
> > > Or the ifdefs are only tested in one configuration and simply break in the
> > > other one, like I think was the case in the linked msys2 issue.
> > > 
> > > Addapting our header ifdefs to also recognize different values from
> > > mingw.org toolchains won't make any difference here at all.
> > > 
> > > Most of the cases I saw in the code search I browsed earlier seemed to be
> > > this case - e.g. trying to provide workarounds for 64 bit stat functions 
> > > or
> > > similar. I haven't tried compiling them to see if our new definitions
> > > actually cause a problem or not.
> > > 
> > > - Projects that themselves try to change __MSVCRT_VERSION__ to expose more
> > > features, e.g. setting __MSVCRT_VERSION__ to 0x700 to get XP level 
> > > features
> > > like _aligned_malloc available. This is mostly harmless for us, even if it
> > > in corner cases could cause problems (by exposing msvcr70.dll features 
> > > when
> > > they actually meant msvcrt.dll/XP - but mingw.org headers also seem to
> > > generally consider the two equal).
> > > 
> > > One such case is familiar to me,
> > > https://github.com/FFmpeg/FFmpeg/blob/n7.1/configure#L6036-L6037. But that
> > > one is only done if the headers are mingw.org headers, not mingw-w64, so 
> > > it
> > > doesn't make any difference for us. (It's used for getting specifically
> > > _aligned_malloc.)
> > > 
> > > 
> > > 
> > > So I think the main source of problems for user code is that we used to
> > > default to __MSVCRT_VERSION__ == 0x700 and now we default to something 
> > > else.
> > > 
> > > We could consider defaulting to 0x0601 (or 0x06FF); this would pick the 
> > > same
> > > branch as before, for all the cases of __MSVCRT_VERSION__ >= 0x0601. So it
> > > could reduce the amount of breakage that we cause.
> > > 
> > > For any code that checks __MSVCRT_VERSION__ >= 0x700 though, things would
> > > unfortunately change.
> > > 
> > > // Martin
> > 
> > I see. But if we change the default value again then it would be
> > necessary to updates also mingw-w64 headers with new check for system
> > msvcrt.dll value. Something what I wrote above (just first two cases).
> 
> Yes - we could change that in any case, to allow any value between 0x600 and
> 0x6FF, in case users override it.
> 
> Then for our default value; either 0x0601 or 0x06FF would be ok with me. At
> this point, I'm actually leaning towards 0x06FF.
> 
> This makes it clearer that it's not specifically the 2k/Me version (not ==
> 0x0601), and that it's "almost" the 0x0700 that we had before (even if that
> "almost" wouldn't functionally have any effect anywhere). With 0x06FF we
> would get the right behaviour if there's any condition which is "> 0x0601"
> (not sure if that one exists anywhere though).

This makes sense. Better to use 0x06FF.

> (This also leaves the door open if we'd want to add more header ifdefs to
> differentiate between the various versions of msvcrt.dll. Not saying that we
> should, but it makes it possible.)
> 
> Then, the only issue is just that we no longer claim to be >= 0x0700 as we
> did before - and this is by design, as we want to differentiate between the
> real msvcr70.dll and the somewhat-similar-to-msvcr70.dll msvcrt.dll from XP
> and similar.
> 
> // Martin


_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to