cinvoke-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [cinvoke-dev] i686-pc-mingw32-gcc calling convention


From: Dwight Schauer
Subject: Re: [cinvoke-dev] i686-pc-mingw32-gcc calling convention
Date: Wed, 19 Jan 2011 17:27:26 -0600

Ok, well, I could not get gcc_x86_win to work (functions I'd call
either do nothing or crash the program no matter what calling
convention I specified.), so I created a gcc_x86_mingw_cdecl (added a
an option in the configure script to force an arch).

It is a merge of gcc_x86_unix and gcc_x86_win, cdecl only (I don't
need the other calling conventions for my project, all I need to
access is my own project code and occasionally msvcrt.dll, which is
cdecl and is working fine.

https://bitbucket.org/bogen/cinvoke/changeset/23fc04512f09

Functions I call with that act identically to the way on Linux. (Ran a
test script from I was running on linux, on windows the output is
identical using gcc_x86_mingw_cdecl).
(I'm using Lua).

However, unless I only do very simple stuff, I can't call
library:dispose () without having my program crash.

The libraries I'm crashing on are the glib and msvcrt dlls.

I've isolated the stuff that is making it crash, but it makes no sense
as to why those things would cause FreeLibrary(library->dl) to crash
without returning an error.


The code in question involves access to structure references (pointers
to structures).
    some_c_struct = cstructure.new (
      Cint, "a",
      Cstring, "s",
      Cint64, "b"
    )

    some_c_struct_ref = cinv.array (some_c_struct)

The code works fine in Linux, but that functions that operate on that
with gcc_x86_mingw_cdecl cause FreeLibrary(library->dl) to crash (even
though they appear to properly pass data back and forth).

I updated the alignments to be the same as gcc_x86_win, but that had no effect.

https://bitbucket.org/bogen/cinvoke/changeset/f4306a0a5218

Anyways, I'll continue digging into it.

--DAS

On Sat, Jan 15, 2011 at 9:34 AM, Will Weisser <address@hidden> wrote:
> The difference is that ECX and EDX are used to pass parameters in the
> fastcall calling convention.  If you look at cl_x86_win.c
> arch_set_register_parms or arch_is_register_parm you can see if the calling
> convention is not CINV_CC_FASTCALL then the register parameters struct will
> never get set to anything.   GCC is making the calls using the cdecl
> convention and so it doesn't need to set those registers, but c/invoke gives
> up a bit of performance in favor of code simplicity, by having one macro
> that works in both fastcall and cdecl; in the latter case, the ECX and EDX
> registers get set to zero but there is no debilitating effect from the
> called cdecl function's point of view.
>
>    -W.W.
>
> On Sat, Jan 15, 2011 at 10:08 AM, Dwight Schauer <address@hidden> wrote:
>>
>> I added tool prefix functional to configure.pl and the Makefile
>> templates so that I can cross compile from Linux.
>>
>> https://bitbucket.org/bogen/cinvoke/changeset/2e5f387b77aa
>> https://bitbucket.org/bogen/cinvoke/downloads (tag 1.03c)
>>
>> I also made the following two fixes:
>>
>> https://bitbucket.org/bogen/cinvoke/changeset/8cc4a9f17c34 Eliminated
>> printf error for windows (I64 vs ll)
>> https://bitbucket.org/bogen/cinvoke/changeset/1c1d36f6a300 Eliminated
>> assembly warning on call indirection
>>
>> The issue I have is this:
>>
>> ./configure.pl --tool-prefix=i686-pc-mingw32-
>> Using platform 'X86_WIN'
>> ...
>>
>> Ok, that is fine.
>>
>> However, the macro output from gcc_x86_win.h:
>>
>> ---< start clip >---
>> #define ARCH_CALL(regparms, ep) \
>>        __asm__("mov %0, %%ecx; \
>>                        mov %1, %%edx; \
>>                        call *%2" : \
>>                        : \
>>                                "m"((regparms).first), \
>>                                "m"((regparms).second), \
>>                 "m"(ep));
>> ---< end clip >---
>>
>> cl_x86_win.h appears to be the same, just a different assembler syntax.
>>
>> ---< start clip >---
>> #define ARCH_CALL(regparms, ep) \
>>        __asm mov ecx, [(regparms).first] \
>>        __asm mov edx, [(regparms).second] \
>>        __asm call dword ptr [ep]
>> ---< end clip >---
>>
>>
>> Neither don't seem to match the calling convention that
>> i686-pc-mingw32-gcc is laying down:
>>
>> ---< start clip >--- // snippets from cinvoke.s
>>        .loc 1 41 0
>>        movl    8(%ebp), %eax
>>        movl    4(%eax), %eax
>>        movl    %eax, (%esp)
>>        call    _arch_free_errstr
>> L2:
>> ...
>>        .loc 1 50 0
>>        movl    $0, 12(%esp)
>>        movl    $LC0, 8(%esp)
>>        movl    $0, 4(%esp)
>>        movl    8(%ebp), %eax
>>        movl    %eax, (%esp)
>>        call    _context_set_error
>>        .loc 1 51 0
>> ...
>>        .loc 1 54 0
>>        movl    $12, (%esp)
>>        call    _malloc
>>        movl    %eax, -12(%ebp)
>> ---
>>        .loc 1 66 0
>>        movl    8(%ebp), %eax
>>        movl    %eax, (%esp)
>>        call    _free
>>        .loc 1 67 0
>> ---< end clip >---
>>
>> I'm assuming I'll need to make another arch .h/.c file to match that
>> calling calling convention, as i686-pc-mingw32-gcc is what I'm using
>> to target 32 bit windows.
>>
>> i686-pc-mingw32-gcc --version
>> i686-pc-mingw32-gcc (GCC) 4.5.2
>>
>> i686-pc-mingw32-gcc -dumpmachine
>> i686-pc-mingw32
>>
>> I'm using http://www.gtk.org/download-windows.html and my cross
>> compiled programs that link against glib/gtk/etc do work.
>>
>> Any thoughts or comments concerning this?
>>
>> --DAS
>>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]