* Re: Inefficient use of 64-bit addresses in Clang
[not found] <1436640898.268382790.1565602671940.JavaMail.root@zimbra54-e10.priv.proxad.net>
@ 2019-08-12 9:45 ` falk.tannhauser
2019-08-14 5:51 ` Agner Fog
0 siblings, 1 reply; 17+ messages in thread
From: falk.tannhauser @ 2019-08-12 9:45 UTC (permalink / raw)
To: cygwin
References: <578eb489-9391-9009-82ad-676eeb4c1c92@agner.org>
In-Reply-To: <578eb489-9391-9009-82ad-676eeb4c1c92@agner.org>
Could the different behaviour between Cygwin and Linux simply be due to different Clang versions?
The current version under Cygwin is 5.0.1, while the latest version available under Linux
appears to be 8.0.1 .
Falk
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Inefficient use of 64-bit addresses in Clang
2019-08-12 9:45 ` Inefficient use of 64-bit addresses in Clang falk.tannhauser
@ 2019-08-14 5:51 ` Agner Fog
2019-08-16 6:06 ` Clang is using the wrong memory model Agner Fog
0 siblings, 1 reply; 17+ messages in thread
From: Agner Fog @ 2019-08-14 5:51 UTC (permalink / raw)
To: cygwin
It's a difference in memory model.
clang 6.0.0 under ubuntu with --target=x86_64-pc-cygwin gives relative
addresses, unless you specify -mcmodel=large.
Cygwin clang with -mcmodel=small does the right thing: use relative
addresses.
The -mcmodel=small option appears to work differently for Linux and for
Windows targets. I cannot find any documentation of this difference. See:
https://bugs.llvm.org/show_bug.cgi?id=42983
On 12/08/2019 11.45, falk.tannhauser@free.fr wrote:
> References: <578eb489-9391-9009-82ad-676eeb4c1c92@agner.org>
> In-Reply-To: <578eb489-9391-9009-82ad-676eeb4c1c92@agner.org>
>
> Could the different behaviour between Cygwin and Linux simply be due to different Clang versions?
> The current version under Cygwin is 5.0.1, while the latest version available under Linux
> appears to be 8.0.1 .
>
> Falk
>
> --
> Problem reports: http://cygwin.com/problems.html
> FAQ: http://cygwin.com/faq/
> Documentation: http://cygwin.com/docs.html
> Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
>
>
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
^ permalink raw reply [flat|nested] 17+ messages in thread
* Clang is using the wrong memory model
2019-08-14 5:51 ` Agner Fog
@ 2019-08-16 6:06 ` Agner Fog
2019-08-16 8:25 ` Mark Geisert
2019-08-16 8:26 ` Corinna Vinschen
0 siblings, 2 replies; 17+ messages in thread
From: Agner Fog @ 2019-08-16 6:06 UTC (permalink / raw)
To: cygwin
Cygwin Clang is using -mcmodel=medium as default for Win64, according to
my tests, while the right model is -mcmodel=small
Linux Clang with --target=x86_64-pc-cygwin gives the small memory model.
I took this to the LLVM Bugzilla as you asked me to:
https://bugs.llvm.org/show_bug.cgi?id=42983
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.
I told the LLVM guy that this difference needs to be documented so that
you can rely on it, but this request has so far been ignored.
He says that you must have modified the source code to change the
default memory model.
The medium memory model gives inefficient code because it uses an extra
instruction to load a 64-bit absolute address into a register before
every access to static data.
I cannot blame you Cygwin people for not using the small memory model as
long as it is undocumented.
I will ask you to please join the discussion at
https://bugs.llvm.org/show_bug.cgi?id=42983 so that we can clarify how
to solve this problem.
On 14/08/2019 07.51, Agner Fog wrote:
> It's a difference in memory model.
>
> clang 6.0.0 under ubuntu with --target=x86_64-pc-cygwin gives relative
> addresses, unless you specify -mcmodel=large.
>
> Cygwin clang with -mcmodel=small does the right thing: use relative
> addresses.
>
> The -mcmodel=small option appears to work differently for Linux and
> for Windows targets. I cannot find any documentation of this
> difference. See:
>
> https://bugs.llvm.org/show_bug.cgi?id=42983
>
>
> On 12/08/2019 11.45, falk.tannhauser@free.fr wrote:
>> References: <578eb489-9391-9009-82ad-676eeb4c1c92@agner.org>
>> In-Reply-To: <578eb489-9391-9009-82ad-676eeb4c1c92@agner.org>
>>
>> Could the different behaviour between Cygwin and Linux simply be due
>> to different Clang versions?
>> The current version under Cygwin is 5.0.1, while the latest version
>> available under Linux
>> appears to be 8.0.1 .
>>
>> Falk
>>
>> --
>> Problem reports:Â Â Â Â Â Â http://cygwin.com/problems.html
>> FAQ:Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â http://cygwin.com/faq/
>> Documentation:Â Â Â Â Â Â Â Â http://cygwin.com/docs.html
>> Unsubscribe info:Â Â Â Â Â http://cygwin.com/ml/#unsubscribe-simple
>>
>>
>
> --
> Problem reports:Â Â Â Â Â Â http://cygwin.com/problems.html
> FAQ:Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â http://cygwin.com/faq/
> Documentation:Â Â Â Â Â Â Â Â http://cygwin.com/docs.html
> Unsubscribe info:Â Â Â Â Â http://cygwin.com/ml/#unsubscribe-simple
>
>
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Clang is using the wrong memory model
2019-08-16 6:06 ` Clang is using the wrong memory model Agner Fog
@ 2019-08-16 8:25 ` Mark Geisert
2019-08-16 8:26 ` Corinna Vinschen
1 sibling, 0 replies; 17+ messages in thread
From: Mark Geisert @ 2019-08-16 8:25 UTC (permalink / raw)
To: cygwin
Hi, please don't start a new Subject: by replying on another thread. It fouls
up mail threading for folks trying to follow multiple threads. Just start a new
thread with your new Subject:. Thanks.
Agner Fog wrote:
> Cygwin Clang is using -mcmodel=medium as default for Win64, according to my
> tests, while the right model is -mcmodel=small
>
> Linux Clang with --target=x86_64-pc-cygwin gives the small memory model.
>
> I took this to the LLVM Bugzilla as you asked me to:
> https://bugs.llvm.org/show_bug.cgi?id=42983
Disclaimer: I am not a Cygwin maintainer or the Cygwin Clang maintainer. This
is a general Cygwin users' mailing list, not a private support channel. I'm
just some guy on the list, albeit somebody interested in solving your issue.
Cygwin is not Windows. Cygwin's shared libraries are more than 32 bits distant
from executables you build. -mcmodel=small won't work. There may be a better
-mcmodel setting, TBD, but small isn't it, unfortunately.
The reasons are longstanding and technical. The quick version is that there are
thousands of different DLLs that a Cygwin user might want installed on their
system. Cygwin is a Posix environment, and to support fork() the address space
for those DLLs is chosen to avoid Windows interference, so much as possible.
> 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.
>
> I told the LLVM guy that this difference needs to be documented so that you can
> rely on it, but this request has so far been ignored.
>
> He says that you must have modified the source code to change the default memory
> model.
Now that I've downloaded and unpacked the Clang source tree, I can confirm we
have a patch to set -mcmodel=medium on 64-bit Cygwin; it's left at small for
32-bit Cygwin.
> The medium memory model gives inefficient code because it uses an extra
> instruction to load a 64-bit absolute address into a register before every
> access to static data.
My understanding is that Clang makes an attempt to accept all the same options
as gcc. Could you please try your Clang build with option "-mcmodel=small"? I
suspect the link phase won't work because the Clang runtime library is more than
32 bits away from your executable's code. You might try another -mcmodel
setting. I don't know what all of them are.
First step is just getting the thing to link. Then testing whether it works
properly. Then code efficiency :-).
> I cannot blame you Cygwin people for not using the small memory model as long as
> it is undocumented.
The necessary reason for our patch was explained above.
> I will ask you to please join the discussion at
> https://bugs.llvm.org/show_bug.cgi?id=42983 so that we can clarify how to solve
> this problem.
This issue does now appear to be an issue with Cygwin's Clang build, so let's
keep discussing here. We can sync up with the LLVM bugtracker later on.
BTW is it a goal to be building for Cygwin? Or is it that you want
Windows-native executables built with Cygwin tools? If the latter, there are
cross-compilers provided by Cygwin that can do that. I don't think there's a
Clang for that situation yet, though.
..mark
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Clang is using the wrong memory model
2019-08-16 6:06 ` Clang is using the wrong memory model Agner Fog
2019-08-16 8:25 ` Mark Geisert
@ 2019-08-16 8:26 ` Corinna Vinschen
2019-08-16 9:27 ` Agner Fog
1 sibling, 1 reply; 17+ messages in thread
From: Corinna Vinschen @ 2019-08-16 8:26 UTC (permalink / raw)
To: Agner Fog; +Cc: cygwin
[-- Attachment #1: Type: text/plain, Size: 1996 bytes --]
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:
> https://bugs.llvm.org/show_bug.cgi?id=42983
>
> 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).
Corinna
--
Corinna Vinschen
Cygwin Maintainer
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Clang is using the wrong memory model
2019-08-16 8:26 ` Corinna Vinschen
@ 2019-08-16 9:27 ` Agner Fog
2019-08-16 9:52 ` Agner Fog
2019-08-16 10:39 ` Corinna Vinschen
0 siblings, 2 replies; 17+ messages in thread
From: Agner Fog @ 2019-08-16 9:27 UTC (permalink / raw)
To: Corinna Vinschen, cygwin
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.
Agner
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:
>> https://bugs.llvm.org/show_bug.cgi?id=42983
>>
>> 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).
>
>
> Corinna
>
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Clang is using the wrong memory model
2019-08-16 9:27 ` Agner Fog
@ 2019-08-16 9:52 ` Agner Fog
2019-08-16 10:39 ` Corinna Vinschen
1 sibling, 0 replies; 17+ messages in thread
From: Agner Fog @ 2019-08-16 9:52 UTC (permalink / raw)
To: Corinna Vinschen, cygwin
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.
Agner
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:
>> https://bugs.llvm.org/show_bug.cgi?id=42983
>>
>> 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).
>
>
> Corinna
>
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Clang is using the wrong memory model
2019-08-16 9:27 ` Agner Fog
2019-08-16 9:52 ` Agner Fog
@ 2019-08-16 10:39 ` Corinna Vinschen
2019-08-16 10:50 ` Agner Fog
1 sibling, 1 reply; 17+ messages in thread
From: Corinna Vinschen @ 2019-08-16 10:39 UTC (permalink / raw)
To: Agner Fog; +Cc: cygwin
[-- Attachment #1: Type: text/plain, Size: 580 bytes --]
On Aug 16 11:27, Agner Fog wrote:
> 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.
And that's the point. The distances are not guranteed to be within
2 GB. Think errno accessed from another DLL. Your application works
only by chance.
Corinna
--
Corinna Vinschen
Cygwin Maintainer
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Clang is using the wrong memory model
2019-08-16 10:39 ` Corinna Vinschen
@ 2019-08-16 10:50 ` Agner Fog
2019-08-16 11:25 ` Corinna Vinschen
0 siblings, 1 reply; 17+ messages in thread
From: Agner Fog @ 2019-08-16 10:50 UTC (permalink / raw)
To: cygwin
On 16/08/2019 11.52, Corinna Vinschen wrote:
> 2 GB. Think errno accessed from another DLL. Your application works
> only by chance.
Good example.
errno appears to be a global variable for historical reasons, but errno
is implemented as a macro that translates to a call to the imported
function __errno.
This function call goes through a 64-bit import table from cygwin1.dll
Works fine with -mcmodel=small
Static sharing of a global variable between exe and dll, or between
different dll's is not possible.
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Clang is using the wrong memory model
2019-08-16 10:50 ` Agner Fog
@ 2019-08-16 11:25 ` Corinna Vinschen
2019-08-16 13:28 ` Kai Tietz
2019-08-17 6:59 ` Agner Fog
0 siblings, 2 replies; 17+ messages in thread
From: Corinna Vinschen @ 2019-08-16 11:25 UTC (permalink / raw)
To: Agner Fog; +Cc: cygwin
[-- Attachment #1: Type: text/plain, Size: 1016 bytes --]
On Aug 16 12:38, Agner Fog wrote:
>
> On 16/08/2019 11.52, Corinna Vinschen wrote:
> > 2 GB. Think errno accessed from another DLL. Your application works only
> > by chance.
>
> Good example.
>
> errno appears to be a global variable for historical reasons, but errno is
> implemented as a macro that translates to a call to the imported function
> __errno.
>
> This function call goes through a 64-bit import table from cygwin1.dll
>
> Works fine with -mcmodel=small
>
> Static sharing of a global variable between exe and dll, or between
> different dll's is not possible.
So errno was a bad example but you can try accessing e.g. __ctype_ptr__,
__progname, optarg, h_errno, or use FE_DFL_ENV from another DLL, just
for kicks.
Just because lots of stuff works with the small mode doesn't mean it's
the right thing to do. Mcmodels medium and large have been introduced
into GCC during the Cygwin 64 bit port for a reason.
Corinna
--
Corinna Vinschen
Cygwin Maintainer
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Clang is using the wrong memory model
2019-08-16 11:25 ` Corinna Vinschen
@ 2019-08-16 13:28 ` Kai Tietz
2019-08-17 6:59 ` Agner Fog
1 sibling, 0 replies; 17+ messages in thread
From: Kai Tietz @ 2019-08-16 13:28 UTC (permalink / raw)
To: cygwin, Agner Fog
Hey,
Just my 5 cents to this. As Corinna pointed out, is the case, that a
"small" memory model application works for you, no valid prove that
all application will work on such a model. Another thing, which
cygwin depends heavily on is the pseudo-relocation stuff. It is not
guaranteed that code distance between DSOs are in valid range here to
fit in a single instruction to be relocated. So the distance allowed
for a "small model instruction" might be in some cases even less 4 GB.
For pseudo-relocation the large memory model is absolutely mandatory
for bigger application.
Kai
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Clang is using the wrong memory model
2019-08-16 11:25 ` Corinna Vinschen
2019-08-16 13:28 ` Kai Tietz
@ 2019-08-17 6:59 ` Agner Fog
2019-08-17 9:48 ` Corinna Vinschen
1 sibling, 1 reply; 17+ messages in thread
From: Agner Fog @ 2019-08-17 6:59 UTC (permalink / raw)
To: cygwin
> So errno was a bad example but you can try accessing e.g. __ctype_ptr__,
> __progname, optarg, h_errno, or use FE_DFL_ENV from another DLL, just
> for kicks.
__ctype_ptr__ is a function
h_errno works like errno with an imported function
FE_DFL_ENV is a macro
__progname and optarg are local variables to each exe or dll
Note that the 2GB limit applies to_static linking_, not to_dynamic linking_.
Allow me to explain the difference. Static linking is the linking of object files together into an EXE or DLL file. Dynamic linking is the linking between different EXE or DLL files.
Static linking is done by the linker. If function A() in a.cpp is calling function B() in b.cpp, then you can compile and link a.cpp and b.cpp together into ab.exe, using the linker. The linker will insert the relative address of B by directly modifying the call B instruction in a.o. The linker will give an error message if the address overflows beyond the 2GB limit. The same process applies when linking to a global variable in b.cpp. The call instruction always uses a 32-bit relative address. The link to a variable can use different addressing modes: 32-bit absolute address, 32-bit relative address, and 64-bit absolute address. The 32-bit absolute address can be used in Linux, but not in Win64 and MacOS. This is why the small memory model is different in Linux and Windows (64 bit).
Dynamic linking is done by the loader, not the linker. If a function in ab.exe calls function C() in C.DLL, then the process is different. D.DLL is loaded by the loader, and the address of C() is inserted into an import table. The import table contains 64-bit absolute addresses.
It is not possible to insert the address of a function or variable from a different EXE or DLL directly into a code instruction. The loader simply cannot do this, only the linker can.
This is the reason why the link to errno and other seemingly global variables are replaced by functions. errno was not a bad example, it shows how a variable in a different DLL is accessed.
gcc is using the small memory model by default in Cygwin64, and it works.
clang is using the small memory by default when cross-compiling for a Cygwin64 target from Linux, and it works.
Kai Tietz wrote:
> Another thing, which
> cygwin depends heavily on is the pseudo-relocation stuff. It is not
> guaranteed that code distance between DSOs are in valid range here to
> fit in a single instruction to be relocated. So the distance allowed
> for a "small model instruction" might be in some cases even less 4 GB.
> For pseudo-relocation the large memory model is absolutely mandatory
> for bigger application.
Kai, can you please point me to a description of the DSO and pseudo-relocation. I cannot find it. But I suppose it inserts 64-bit addresses into some sort of GOT or PLT without using the traditional linker.
Agner
On 16/08/2019 13.11, Corinna Vinschen wrote:
> On Aug 16 12:38, Agner Fog wrote:
>> On 16/08/2019 11.52, Corinna Vinschen wrote:
>>> 2 GB. Think errno accessed from another DLL. Your application works only
>>> by chance.
>> Good example.
>>
>> errno appears to be a global variable for historical reasons, but errno is
>> implemented as a macro that translates to a call to the imported function
>> __errno.
>>
>> This function call goes through a 64-bit import table from cygwin1.dll
>>
>> Works fine with -mcmodel=small
>>
>> Static sharing of a global variable between exe and dll, or between
>> different dll's is not possible.
> So errno was a bad example but you can try accessing e.g. __ctype_ptr__,
> __progname, optarg, h_errno, or use FE_DFL_ENV from another DLL, just
> for kicks.
>
> Just because lots of stuff works with the small mode doesn't mean it's
> the right thing to do. Mcmodels medium and large have been introduced
> into GCC during the Cygwin 64 bit port for a reason.
>
>
> Corinna
>
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Clang is using the wrong memory model
2019-08-17 6:59 ` Agner Fog
@ 2019-08-17 9:48 ` Corinna Vinschen
2019-08-18 11:37 ` Agner Fog
0 siblings, 1 reply; 17+ messages in thread
From: Corinna Vinschen @ 2019-08-17 9:48 UTC (permalink / raw)
To: cygwin
[-- Attachment #1: Type: text/plain, Size: 1725 bytes --]
Oe Aug 17 07:31, Agner Fog wrote:
> > So errno was a bad example but you can try accessing e.g. __ctype_ptr__,
> > __progname, optarg, h_errno, or use FE_DFL_ENV from another DLL, just
> > for kicks.
> __ctype_ptr__ is a function
>
> h_errno works like errno with an imported function
>
> FE_DFL_ENV is a macro
>
> __progname and optarg are local variables to each exe or dll
That would contradict what, e.g., __progname is for. Here's a test:
$ cat > dll.c <<EOF
#include <stdio.h>
extern char *__progname;
void
printprog ()
{
printf ("progname: %s\n", __progname);
}
EOF
$ cat > main.c <<EOF
extern void printprog();
int
main ()
{
printprog ();
}
EOF
$ uname -a
CYGWIN_NT-10.0 vmbert10 3.1.0(0.340/5/3) 2019-08-16 14:36 x86_64 Cygwin
Lets try the medium model first:
$ gcc -g -shared -mcmodel=medium -o dll.dll dll.c
$ gcc -g -mcmodel=medium -o main main.c dll.dll
$ ./main
progname: main
Now let's try the small model:
$ gcc -g -shared -mcmodel=small -o dll.dll dll.c
$ gcc -g -mcmodel=small -o main main.c dll.dll
$ ./main
Cygwin runtime failure: /home/corinna/main.exe: Invalid relocation. Offset
0xfffffffd80348989 at address 0x40000103b doesn't fit into 32 bits
Now let's try without explicit mcmodel on the CLI:
$ gcc -g -shared -o dll.dll dll.c
$ gcc -g -o main main.c dll.dll
$ ./main
progname: main
> gcc is using the small memory model by default in Cygwin64, and it works.
No, it's not, see above.
> clang is using the small memory by default when cross-compiling for a Cygwin64 target from Linux, and it works.
...in *your* example code.
Corinna
--
Corinna Vinschen
Cygwin Maintainer
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Clang is using the wrong memory model
2019-08-17 9:48 ` Corinna Vinschen
@ 2019-08-18 11:37 ` Agner Fog
2019-08-18 11:58 ` Corinna Vinschen
0 siblings, 1 reply; 17+ messages in thread
From: Agner Fog @ 2019-08-18 11:37 UTC (permalink / raw)
To: cygwin
Thanks a lot for your help in clarifying this.
When I complained here about the wasteful 64-bit addresses you said that
it was an LLVM issue. When I complained to LLVM they said it was a
Cygwin issue, and that you were using the wrong memory model.
All this confusion is due to a terrible lack of documentation of everything.
I had to do a lot of reverse engineering to figure out what is
happening. What I have found out so far is listed below. Much of this is
undocumented. Obviously, I would like to know if any or this is wrong or
if specific documentation is available other than the SysV ABI and
Windows ABI:
* Cygwin is using its own loader which is different from the Windows
loader.
* The Cygwin loader emulates the behavior of Linux shared objects. This
includes the ability to directly access a variable inside a DLL
* Access to a variable in a different DLL requires a 64-bit address.
This is obtained by using the medium memory model with a gcc or Clang
compiler.
* The small memory model works differently on different targets. A
-mcmodel=small with a Linux target puts everything below 2GB addresses.
32-bit absolute addresses are allowed. -mcmodel=small with a Windows or
Mac target allows addresses above 2GB, but limits the distance between
code and data in the same executable to 2GB. 32-bit absolute addresses
are not allowed. 32-bit relative addresses are used instead.
* The memory models work differently in gcc an Clang. Gcc with a medium
or large memory model is using 64-bit address tables to access a
variable in a different C/CPP file. Clang with a medium or large memory
model is using 64-bit addresses not only for external variables, but
also for local static data. This includes floating point constants,
string constants, array initializers, jump tables, global variables, and
more.
* Cygwin uses a medium memory model by default. The medium memory model
is necessary only for a program that makes direct access to a variable
in a different DLL. The medium memory model is wasteful, and more so
with Clang than with gcc.
Now I am speculating what we can do to avoid the wasteful 64-bit
address-load instructions to improve the performance of Cygwin programs.
We can improve performance by using the small memory model when
possible. The medium memory model is needed only for programs that link
to a variable in a different DLL. The DLL that contains the link target
does not need the medium memory model.
Direct access to a variable in a different DLL is considered bad
programming practice by modern standards. This should occur only in old
Linux code.
A link to a variable in a different DLL may be replaced by function
calls (this is done with errno). In some cases, static linking can be an
efficient alternative.
It would be helpful if the Cygwin loader could print the name of the
offending variable when relocation fails with the small memory model.
This could help programmers remove any obstacles to using the more
efficient small memory model.
Agner
On 17/08/2019 10.16, Corinna Vinschen wrote:
> Oe Aug 17 07:31, Agner Fog wrote:
>>> So errno was a bad example but you can try accessing e.g. __ctype_ptr__,
>>> __progname, optarg, h_errno, or use FE_DFL_ENV from another DLL, just
>>> for kicks.
>> __ctype_ptr__ is a function
>>
>> h_errno works like errno with an imported function
>>
>> FE_DFL_ENV is a macro
>>
>> __progname and optarg are local variables to each exe or dll
> That would contradict what, e.g., __progname is for. Here's a test:
>
> $ cat > dll.c <<EOF
> #include <stdio.h>
>
> extern char *__progname;
>
> void
> printprog ()
> {
> printf ("progname: %s\n", __progname);
> }
> EOF
> $ cat > main.c <<EOF
> extern void printprog();
>
> int
> main ()
> {
> printprog ();
> }
> EOF
> $ uname -a
> CYGWIN_NT-10.0 vmbert10 3.1.0(0.340/5/3) 2019-08-16 14:36 x86_64 Cygwin
>
> Lets try the medium model first:
>
> $ gcc -g -shared -mcmodel=medium -o dll.dll dll.c
> $ gcc -g -mcmodel=medium -o main main.c dll.dll
> $ ./main
> progname: main
>
> Now let's try the small model:
>
> $ gcc -g -shared -mcmodel=small -o dll.dll dll.c
> $ gcc -g -mcmodel=small -o main main.c dll.dll
> $ ./main
> Cygwin runtime failure: /home/corinna/main.exe: Invalid relocation. Offset
> 0xfffffffd80348989 at address 0x40000103b doesn't fit into 32 bits
>
> Now let's try without explicit mcmodel on the CLI:
>
> $ gcc -g -shared -o dll.dll dll.c
> $ gcc -g -o main main.c dll.dll
> $ ./main
> progname: main
>
>> gcc is using the small memory model by default in Cygwin64, and it works.
> No, it's not, see above.
>
>> clang is using the small memory by default when cross-compiling for a Cygwin64 target from Linux, and it works.
> ...in *your* example code.
>
>
> Corinna
>
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Clang is using the wrong memory model
2019-08-18 11:37 ` Agner Fog
@ 2019-08-18 11:58 ` Corinna Vinschen
2019-08-18 18:14 ` Agner Fog
0 siblings, 1 reply; 17+ messages in thread
From: Corinna Vinschen @ 2019-08-18 11:58 UTC (permalink / raw)
To: Agner Fog; +Cc: cygwin
[-- Attachment #1: Type: text/plain, Size: 1941 bytes --]
On Aug 18 08:04, Agner Fog wrote:
> Thanks a lot for your help in clarifying this.
>
> When I complained here about the wasteful 64-bit addresses you said that it
> was an LLVM issue.
I never said anything like that. The issue is that your clang
linux->cygwin cross compiler uses the wrong model, that's all. That's
a bug in clang or whatever it's using under the hood. Clang should
follow what GCC does for years, using the medium model on Cygwin.
> When I complained to LLVM they said it was a Cygwin
> issue, and that you were using the wrong memory model.
>
> All this confusion is due to a terrible lack of documentation of everything.
> I had to do a lot of reverse engineering to figure out what is happening.
> What I have found out so far is listed below. Much of this is undocumented.
> Obviously, I would like to know if any or this is wrong or if specific
> documentation is available other than the SysV ABI and Windows ABI:
>
> * Cygwin is using its own loader which is different from the Windows loader.
Nope, Cygwin uses the Windows loader.
> * The Cygwin loader emulates the behavior of Linux shared objects. This
> includes the ability to directly access a variable inside a DLL
See above.
> * Access to a variable in a different DLL requires a 64-bit address. This is
> obtained by using the medium memory model with a gcc or Clang compiler.
ACK
[...]
To me, the only interesting thing is that clang continues to use the
medium memory model *by default*. It doesn't make sense if package
maintainers and devs building something on Cygwin have to care for
memory models all of a sudden. The default should just work.
If you want to use the small model in your own projects, great, if it
works for you. If the medium model is wasteful in clang, that's a clang
optimization problem, not a Cygwin problem.
Corinna
--
Corinna Vinschen
Cygwin Maintainer
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Clang is using the wrong memory model
2019-08-18 11:58 ` Corinna Vinschen
@ 2019-08-18 18:14 ` Agner Fog
2019-08-19 8:58 ` Corinna Vinschen
0 siblings, 1 reply; 17+ messages in thread
From: Agner Fog @ 2019-08-18 18:14 UTC (permalink / raw)
To: cygwin
On 18/08/2019 13.57, Corinna Vinschen wrote:
> Nope, Cygwin uses the Windows loader.
Then, how do you do the extra linking? What is producing the "Cygwin
runtime failure" message when loading/linking a DLL fails?
> If the medium model is wasteful in clang, that's a clang
> optimization problem, not a Cygwin problem.
The medium model in Clang is not wasteful. It does exactly what it is
designed to do. It was never designed with Cygwin in mind. The program
build with a medium model is wasteful because it makes all addresses 64
bits when few or no addresses actually need to be 64 bits.
> If you want to use the small model in your own projects, great, if it
> works for you.
It is not for my own project. I am writing manuals on how to optimize
software.
Agner
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Clang is using the wrong memory model
2019-08-18 18:14 ` Agner Fog
@ 2019-08-19 8:58 ` Corinna Vinschen
0 siblings, 0 replies; 17+ messages in thread
From: Corinna Vinschen @ 2019-08-19 8:58 UTC (permalink / raw)
To: cygwin
[-- Attachment #1: Type: text/plain, Size: 1329 bytes --]
On Aug 18 18:24, Agner Fog wrote:
> On 18/08/2019 13.57, Corinna Vinschen wrote:
> > Nope, Cygwin uses the Windows loader.
>
> Then, how do you do the extra linking? What is producing the "Cygwin runtime
> failure" message when loading/linking a DLL fails?
>
> > If the medium model is wasteful in clang, that's a clang
> > optimization problem, not a Cygwin problem.
>
> The medium model in Clang is not wasteful.
Your words:
* The memory models work differently in gcc an Clang. Gcc with a medium or
large memory model is using 64-bit address tables to access a variable in a
different C/CPP file. Clang with a medium or large memory model is using
64-bit addresses not only for external variables, but also for local static
data. This includes floating point constants, string constants, array
initializers, jump tables, global variables, and more.
> designed to do. It was never designed with Cygwin in mind.
That's not Cygwin's fault, is it? You're asking to change the system to
pamper the compiler, rather than asking the compiler to work better for
a given system. That's not how this usually works.
Make sure that clang uses the medium memory model by default. If clang
is doing this inefficiently, clang needs fixing.
Corinna
--
Corinna Vinschen
Cygwin Maintainer
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2019-08-19 8:56 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <1436640898.268382790.1565602671940.JavaMail.root@zimbra54-e10.priv.proxad.net>
2019-08-12 9:45 ` Inefficient use of 64-bit addresses in Clang falk.tannhauser
2019-08-14 5:51 ` Agner Fog
2019-08-16 6:06 ` Clang is using the wrong memory model Agner Fog
2019-08-16 8:25 ` Mark Geisert
2019-08-16 8:26 ` Corinna Vinschen
2019-08-16 9:27 ` Agner Fog
2019-08-16 9:52 ` Agner Fog
2019-08-16 10:39 ` Corinna Vinschen
2019-08-16 10:50 ` Agner Fog
2019-08-16 11:25 ` Corinna Vinschen
2019-08-16 13:28 ` Kai Tietz
2019-08-17 6:59 ` Agner Fog
2019-08-17 9:48 ` Corinna Vinschen
2019-08-18 11:37 ` Agner Fog
2019-08-18 11:58 ` Corinna Vinschen
2019-08-18 18:14 ` Agner Fog
2019-08-19 8:58 ` Corinna Vinschen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).