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

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.


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

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.


Problem reports:
Unsubscribe info:

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