Web lists-archives.com

Re: 32 bit vs 64 bit Cygwin, followup




On Sat, Feb 2, 2019 at 9:39 AM Sam Habiel <sam.habiel@xxxxxxxxx> wrote:
>
> On Thu, Nov 29, 2018 at 11:33 AM Corinna Vinschen
> <corinna-cygwin@xxxxxxxxxx> wrote:
> >
> > On Nov 29 10:18, Sam Habiel wrote:
> > > On Thu, Nov 29, 2018 at 3:58 AM Corinna Vinschen wrote:
> > > > On Nov 28 11:06, Sam Habiel wrote:
> > > > > On Wed, Nov 28, 2018 at 11:01 AM Yaakov Selkowitz wrote:
> > > > > > On Mon, 2018-11-26 at 14:07 -0500, Sam Habiel wrote:
> > > > > > > [...]
> > > > > > >  GT.M contains a large
> > > > > > > amount of assembly code, written to run on the x32 Linux ABI and the
> > > > > > > AMD x64 ABI. It's was very easy to get the x32 Linux ABI to run on
> > > > > > > Cygwin x32; Cygwin x64 on the other hand uses the Windows x64 ABI,
> > > > > > > which is very different than the AMD ABI (more detail here:
> > > > > > > https://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64/).
> > > > > > > I don't have the expertise nor the time to rewrite a lot of assembly
> > > > > > > code to use the Windows x64 ABI. There are about 100 source code files
> > > > > > > that are in assembly.
> > > > > >
> > > > > > -mabi=sysv ?
> > > > > >
> > > > > Are you telling me that gcc has a flag to support AMD ABI on Cygwin
> > > > > x64? The assembly code is not standalone; it gets called from C code
> > > > > and calls C code.
> > > >
> > > > That's what he's telling you.  However, you have to interact with the MS
> > > > ABI(*) as well as soon as you call external library functions so it
> > > > makes sense to keep your C code in MS ABI.  For the assembler functions,
> > > > you can just tell the compiler they are in SYSV ABI by adding a function
> > > > attribute to the declaration:
> > > >
> > > > int asm_func (args) __attribute__ ((sysv_abi))
> > > >
> > > > Good luck,
> > > > Corinna
> > > >
> > > > (*) Just keep in mind that Cygwin is LP64, not LLP64:
> > > >     https://cygwin.com/faq/faq.html#faq.programming.64bitporting
> > > > [...]
> > > [...]
> > > This sounds very promising, but I would like a clarification; because
> > > I think you covered 50% of the issue:
> > >
> > > 1. There are frequent calls from the C code to Assembly.
> > > 2. There are also frequent calls from Assembly to C code.
> > >
> > > Looks like compiling the .s files with the -mabi=sysv flag and
> > > declaring the function in C with the __attribute__ ((sysv_abi)) will
> > > fix #1.
> >
> > You shouldn't have to use the flag when building the assembler files,
> > they are using SYSV ABI anyway.  In fact, while Yaakov is right,
> > basically, I think in your scenario you should only use the GCC function
> > attribute since that allows more fine-grained control.  Just stick to MS
> > ABI by default and only perform the SYSV ABI juggle where required to
> > interact with the assembler code.
> >
> > > How about #2? I don't see an easy solution. The assembly code puts
> > > together the parameters in the registers in the sysv way (rdi, rsi,
> > > rdx, rcx, r8, r9), not rcx, rdx, r8, and r9.
> >
> > One way is to create a SYSV wrapper for each C function called from
> > assembler.  Assuming this simple scenario:
> >
> >   There's a C function foo(), which is called from assembler as
> >   well as from other C functions.
> >
> >     extern long foo (long, double, int, long);
> >
> >   For the "normal" (i.e. MS ABI) C code add this in front of the above
> >   declaration:
> >
> >     #define foo(a,b,c,d)        __foo((a),(b),(c),(d))
> >
> >   So the C function is renamed to __foo and C code will call __foo.
> >
> >   Add a wrapper C file to add a function foo with SYSV ABI, calling
> >   __foo:
> >
> >     #undef foo
> >     long __attribute__ ((sysv_abi))
> >     foo (long a, double b, int c, long d)
> >     {
> >       return __foo (a,b,c,d);
> >     }
> >
> > That should do it.  Of course there may be more complicated cases,
> > but I leave them as excercise for the reader, and only you are in
> > a position to know them ;)
> >
> >
> > HTH,
> > Corinna
> >
> > --
> > Corinna Vinschen
> > Cygwin Maintainer
>
> Corinna et al.,
>
> I and a colleague started the work to migrate the Linux x64 version to
> Cygwin. The results have been very promising; but I think we found a
> bug in gcc when dealing with va_start in sysv_abi compiled code. I
> have a simple test case. Can somebody confirm? It works fine without
> the attribute on PrintFloats.
>
> /* va_start example */
> #include <stdio.h>      /* printf */
> #include <stdarg.h>     /* va_list, va_start, va_arg, va_end */
>
> void __attribute__ ((sysv_abi)) PrintFloats (int n, ...)
> {
>   int i;
>   double val;
>   printf ("Printing floats:");
>   va_list vl;
>   va_start(vl,n);
>   for (i=0;i<n;i++)
>   {
>     val=va_arg(vl,double);
>     printf (" [%.2f]",val);
>   }
>   va_end(vl);
>   printf ("\n");
> }
>
> int main ()
> {
>   PrintFloats (3,3.14159,2.71828,1.41421);
>   return 0;
> }

Sorry. Should say what the error is:

Hp@memphis ~/fis-gtm/build
$ gdb a.exe
GNU gdb (GDB) (Cygwin 8.0.1-1) 8.0.1
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-pc-cygwin".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a.exe...done.
(gdb) b main
Breakpoint 1 at 0x1004011c2: file test.c, line 23.
(gdb) r
Starting program: /home/Hp/fis-gtm/build/a.exe
[New Thread 11672.0xdd0]
[New Thread 11672.0x1230]
[New Thread 11672.0x20ac]
[New Thread 11672.0x43f4]

Thread 1 "a" hit Breakpoint 1, main () at test.c:23
23        PrintFloats (3,3.14159,2.71828,1.41421);
(gdb) s
PrintFloats (n=1) at test.c:6
6       {
(gdb) s
9         printf ("Printing floats:");
(gdb) s
11        va_start(vl,n);
(gdb) s
12        for (i=0;i<n;i++)
(gdb) p vl
$1 = (va_list) 0x3000000008 <error: Cannot access memory at address
0x3000000008>
(gdb) s
[New Thread 11672.0x3f9c]
14          val=va_arg(vl,double);
(gdb) s

Thread 1 "a" received signal SIGSEGV, Segmentation fault.
0x000000010040112f in PrintFloats (n=3) at test.c:14

PS: Running this outside GDB causes Cygwin x64 to hang--and I don't
know how to make it unhang.

--Sam

--
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