X-Recipient: archive-cygwin AT delorie DOT com X-SWARE-Spam-Status: No, hits=1.5 required=5.0 tests=AWL,BAYES_50,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Message-ID: From: Jay K To: cygwin , Subject: RE: resolving _glGetString AT 4 by linking to _glGetString Date: Mon, 12 Jul 2010 06:59:45 +0000 In-Reply-To: <1278906997.3324.ezmlm@cygwin.com> References: <1278906997 DOT 3324 DOT ezmlm AT cygwin DOT com> Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com =A0 > Not so much of an issue any more (still a bit curious about it, but).= I soon=20 =A0 > found that providing a '-lopengl32' link instead of=20 =A0 > '/cygdrive/c/Windows/System32/opengl32.dll' fixed the problem.=20 Linking to /cygdrive/c/windows/system32/whatever is "never" right. It is not easy to explain this though. In the "Unix model", the "headers and libraries" come with the operating sy= stem. =A0 /usr/include, /lib, /usr/lib, etc. In the "Windows model", they come separately with the compiler or a "develo= pment kit". The "Unix model" advantages: =A0=A0 system is "self describing"=20 =A0=A0 smaller: no separate "import libraries", just the dynamic libraries= =20 The "Windows model" advantages: =A0 Sort of more amenable to cross builds. Including targeting an older or = newer OS release. I say "sort of" because, like, adding additional headers and libraries does= n't change the model. In the "Unix model", any headers/libraries apart from "the OS" are sort of = following a different model, where in the "Windows model", they are all following the same model. This isn't the "Unix" or "Windows" model really, it is just how things tend= to be done on those systems. If you look at Mac OS X development systems, they are closer to Windows. If you have ever used "sysroot" with gcc, well, that is like Windows then. Personally I prefer the Windows model. And Cygwin follows it, because, well, again, the main difference is if the = operating system contains the headers/libraries needed. Cygwin can be as Gnuy/Linuxy/Posixy = as it wants, but the operating system doesn't contain the files it needs, so it includes the= m. Now, there is something funny to this term "libraries". You know, modern systems are heavily dynamically linked, and the informatio= n needed by the dynamic linker and the "static linker" is similar/same, in particula= r for the "static linker" to build an executable or library that references symbols dynamically. The main information is just a list of function names. =A0Sometimes what library contains what function, depending on the system a= nd compiler/linker flags. =A0 Thus it becomes reasonable seeming to point at the "running code" for libra= ries, instead of some separate libraries, sometimes called "stub libraries" or "import li= braries", etc. =A0(These "import libraries" basically just contain lists of function names= , no actual code; =A0 older forms of them do contain a jmp per function, but that hardly coun= ts.) Now, then, what is the difference between the file -lopengl32 found, vs. /c= ygdrive/c/windows/system32/opengl32.dll? Well, Windows on x86 does have something uniquely slightly bad about it: Th= ere are multiple calling conventions. And the different calling conventions lead to a form of "name mangling", ev= en in C code. There are generally three calling conventions. Though some compilers let you declare custom ones, e.g. I believe gcc and O= penWatcom. As well the compiler can create custom calling conventions for "static" fun= ctions. That is a different more general point and =A0 true on many systems. Anyway, the three usual Windows/x86 calling conventions are "stdcall", "cde= cl", "fastcall". "cdecl" is usually the default. Parameters passed on the stack, right to left, callER pops, function "Foo" = is "mangled" to "_Foo". "stdcall" is heavily used. Parameters passed on the stack, right to left, callEE pops, function "Foo" = is "mangled" to "_Foo AT N" where "N" is the decimal number of bytes of parameters, e.g. 0, 4, 8, 16, e= tc. "fastcall" I don't know entirely, but roughly speaking, it passes the first= 8 bytes of parameters in ecx, edx, right to left, the rest on the stack, callEE pops, "Foo" becomes "_ AT Foo@N". "cdecl" is "needed" for varargs i.e. printf, because caller pops. "stdcall" is smaller/faster because callee pops. Now, I said "stdcall" is heavily used. Almost all public Windows functions (aka APIs) are stdcall. So instead of generating a reference to " _glGetString", the compiler gener= ates a reference to " _glGetString AT 4". However presumably because it looks nicer or maybe for consistency with the= other architectures, the exported names are not "mangled" (or "decorated"). ("other architectures": NT on MIPS, Alpha, PowerPC, IA64, AMD64, only one c= alling convention each) If you run link -dump -exports %windir%\system32\opengl32.dll, you'll see p= lain "glGetString". =A0There is no clear indication in the .dll that glGetString takes 4 bytes = of parameters (maybe if you disassemble it...) The file -lopengl32 found though, contains some stuff in it with both strin= gs "_glGetString AT 4" and "glGetString". The first is what symbol the linker should resolve against, the second is w= hat it should stuck in the special data in the file it is outputing. Make sense? (To repeat, I think distributing headers/libraries separate is good, but ha= ving multiple calling conventions is clearly mixed/bad.) =A0- Jay =20=09=09=20=09=20=20=20=09=09=20=20 -- 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