This is the mail archive of the cygwin mailing list for the Cygwin project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Clang is using the wrong memory model

Thanks for your replies.

A Cygwin application with -mcmodel=small appears to work fine.

As I explained, -mcmodel=small does something else when the target is Windows. It does not require addresses to be below 2GB, it only requires the distance between a code section and it's data section to be below 2GB.

Your concern would be right if -mcmodel=small was doing the same thing as it does in Linux, but this is not the case.

It does not matter where the application and the Cygwin DLL are placed because Windows allows EXEs and DLLs to be placed at any address. There is no static linking between an application and the Cygwin DLL, so the distance between application and DLL does not matter.

I don't see any problem with fork() either, because there is no static link between parent and child process. The OS puts everything in place using virtual addresses.


On 16/08/2019 10.26, Corinna Vinschen wrote:
On Aug 16 08:06, Agner Fog wrote:
Cygwin Clang is using -mcmodel=medium as default for Win64, according to my
tests, while the right model is -mcmodel=small
-mcmodel=small is *only* the right model if the target is native
Windows.  If the target is a Cygwin application it *must* at least
be compiled with -mcmodel=medium.  The reason is the standarized
memory layout of Cygwin application and DLLs.

Linux Clang with --target=x86_64-pc-cygwin gives the small memory model.
Which is wrong.

I took this to the LLVM Bugzilla as you asked me to:

This gave the following conclusion:

-mcmodel=small does something different when the target is Windows. This
difference appears to be undocumented. The small memory model with a Linux
target puts everything below the 2GB limit so that 32-bit absolute addresses
can be used. The small memory model with a Windows target is using 32-bit
relative addresses instead, which is the correct thing to do in Windows.
Yes, but not for Cygwin applications and DLLs.  The reason is that Cygwin
apps and DLLs reside in the memory beyond the first 2 Gigs in a standarized
way so as not to collide with Windows code and datastructures.  And that
in turn was necessary to make fork() more reliable on 64 bit.

Here's the memory layout:

0000:00000000	Windows
0000:80000000	Thread stacks
0001:00400000	Executable
0001:80000000	*The* Cygwin DLL
0002:00000000	Rebased Cygwin DLLs
0004:00000000	Unrebased Cygwin DLLs(*)

0006:00000000	Heap (up to Cygwin 3.0)
0008:00000000	Heap (starting with Cygwin 3.1)

0700:00000000	Top-down start address for mmaps up to Windows 8
		or up to Cygwin 3.0
7000:00000000	Top-down start address for mmaps starting with Windows 8.1
		and Cygwin 3.1

So there's a difference between non-Cygwin (-mcmodel=small as default)
and Cygwin (at least -mcmodel=medium).


Problem reports:
Unsubscribe info:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]