cinvoke-svn
[Top][All Lists]
Advanced

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

[cinvoke-svn] r153 - in trunk/cinvoke: . lib lib/arch


From: will
Subject: [cinvoke-svn] r153 - in trunk/cinvoke: . lib lib/arch
Date: 28 Jul 2008 20:29:39 -0700

Author: will
Date: 2008-07-28 20:29:39 -0700 (Mon, 28 Jul 2008)
New Revision: 153

Added:
   trunk/cinvoke/lib/arch/gcc_x86_win.c
   trunk/cinvoke/lib/arch/gcc_x86_win.h
Modified:
   trunk/cinvoke/configure.pl
   trunk/cinvoke/lib/cinvoke-arch.h
Log:
Adding GCC/Windows port, courtesy of Mooneer Salem


Modified: trunk/cinvoke/configure.pl
===================================================================
--- trunk/cinvoke/configure.pl  2007-09-01 18:59:08 UTC (rev 152)
+++ trunk/cinvoke/configure.pl  2008-07-29 03:29:39 UTC (rev 153)
@@ -50,6 +50,20 @@
        $DYNCFLAGS = '-dynamic';
        $BUILDSTATIC = 'libtool -static -o';
        $RANLIB = 'echo';
+} else if ($platform =~ m/_WIN$/) {
+       $DYNEXT = 'dll';
+       $JNIDYNEXT = 'dll';
+    my $jni_include_dir = find_jni();
+       if ($jni_include_dir) {
+               $JNIINCLUDE = "-I$jni_include_dir";
+       } else {
+               $JNIINCLUDE = "";
+       }
+       $BUILDSHARED = 'gcc -shared -o';
+       $CXXBUILDSHARED = 'g++ -shared -o';
+       $DYNCFLAGS = ''; # PIC is the default on Windows.
+       $BUILDSTATIC = 'rm -f $(TARGET) && ar rs';
+       $RANLIB = 'ranlib';
 } else {
        $DYNEXT = 'so';
        $JNIDYNEXT = 'so';
@@ -115,6 +129,8 @@
        if ($? != 0) { die "error executing uname: $!"; }
        if ($uname =~ m/Darwin/) {
                $os = "OSX";
+       } elsif ($gccout =~ m/mingw|cygwin/) {
+               $os = "WIN"
        } else {
                $os = "UNIX"; # hey why not
 

Added: trunk/cinvoke/lib/arch/gcc_x86_win.c
===================================================================
--- trunk/cinvoke/lib/arch/gcc_x86_win.c                                (rev 0)
+++ trunk/cinvoke/lib/arch/gcc_x86_win.c        2008-07-29 03:29:39 UTC (rev 
153)
@@ -0,0 +1,327 @@
+/*
+C/Invoke Source Code File
+
+Copyright (c) 2006 Will Weisser
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+   2. Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+   3. The name of the author may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifdef CINVOKE_BUILD
+#include "../cinvoke.h"
+#include "../cinvoke-private.h"
+#else
+#include "cinvoke.h"
+#include "cinvoke-private.h"
+#endif
+
+char *GetWin32ErrMsg(DWORD err) {
+       char *str;
+       if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+               FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
+               MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+               (LPTSTR)&str, 0, NULL)) {
+                       str = NULL;
+       }
+       return str;
+}
+
+void context_set_win32_error(CInvContext *context) {
+       DWORD err = GetLastError();
+       char *str = GetWin32ErrMsg(err);
+
+       context_set_error(context, err, str, 1);
+}
+
+void arch_free_errstr(char *str) {
+       LocalFree(str);
+}
+
+cinv_status_t arch_library_create(CInvContext *context, const char *path,
+       ArchLibrary *library_out) {
+       HANDLE lib = LoadLibrary(path);
+       if (!lib) {
+               context_set_win32_error(context);
+               return CINV_ERROR;
+       }
+               
+       library_out->dl = lib;
+
+       return CINV_SUCCESS;
+}
+cinv_status_t arch_library_get_entrypoint(CInvContext *context,
+       ArchLibrary *library, const char *name, void **entrypoint_out) {
+       void *sym = GetProcAddress(library->dl, name);
+       if (!sym) {
+               context_set_win32_error(context);
+               return CINV_ERROR;
+       }
+
+       *entrypoint_out = sym;
+
+       return CINV_SUCCESS;
+}
+cinv_status_t arch_library_delete(CInvContext *context, ArchLibrary *library) {
+       if (!FreeLibrary(library->dl)) {
+               context_set_win32_error(context);
+               return CINV_ERROR;
+       }
+
+       return CINV_SUCCESS;
+}
+const static int LEN = 4096;
+
+char *arch_callback_stub(void *functionp, void *param,
+       short stacksize, cinv_callconv_t cc, cinv_type_t types[], int 
numparams) {
+       int codesize;
+       const char *code;
+       char *ret;
+
+       if (cc != CINV_CC_STDCALL && cc != CINV_CC_FASTCALL) {
+               // void f() { ((void (__cdecl *)(void *))0xAAAAAAAA)((void 
*)0xBBBBBBBB); }
+               codesize = 31;
+               code = "\x55\x8b\xec\x83\xec\x40\x53\x56\x57\x68"
+                               "\xbb\xbb\xbb\xbb\xb8\xaa\xaa\xaa\xaa\xff"
+                               "\xd0\x83\xc4\x04\x5f\x5e\x5b\x8b\xe5\x5d"
+                               "\xc3";
+       } else {
+               // same thing except with an additional stack-cleanup argument 
placeholder
+               // note that the below code does not modify ecx or edx, so we 
handle
+               // fastcall correctly
+               codesize = 33;
+               code = "\x55\x8b\xec\x83\xec\x40\x53\x56\x57\x68"
+                               "\xbb\xbb\xbb\xbb\xb8\xaa\xaa\xaa\xaa\xff"
+                               "\xd0\x83\xc4\x04\x5f\x5e\x5b\x8b\xe5\x5d"
+                               "\xc2\xdd\xdd"; 
+       }
+
+       ret = VirtualAlloc(NULL, LEN, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+       if (!ret)
+               return NULL;
+       
+       memcpy(ret, code, codesize);
+
+       memcpy(ret + 10, &param, 4);
+       memcpy(ret + 15, &functionp, 4);
+
+       if (cc == CINV_CC_STDCALL || cc == CINV_CC_FASTCALL)
+               memcpy(ret + 31, &stacksize, 2);
+       
+       return ret;
+}
+void arch_free_stub(char *stub) {
+       VirtualFree(stub, 0, MEM_RELEASE);
+}
+
+int is_ok_register(cinv_type_t type) {
+       return (type != CINV_T_FLOAT) &&
+               (type != CINV_T_DOUBLE) &&
+               (type != CINV_T_EXTRALONG);
+}
+
+int arch_is_register_parm(cinv_callconv_t callingconvention, int index,
+       int num_params, cinv_type_t types[]) {
+       int numeligible = 0, i;
+
+       if (callingconvention != CINV_CC_FASTCALL) return 0;
+       
+       for (i = 0; i < index; i++) {
+               if (is_ok_register(types[i]))
+                       numeligible++;
+               if (numeligible == 2) break;
+       }
+       return (numeligible < 2 && is_ok_register(types[i]));
+}
+int convert_to_int(void *ptr, cinv_type_t type) {
+       switch (type) {
+       case CINV_T_CHAR:
+               return (int)*(char *)ptr;
+       case CINV_T_SHORT:
+               return (int)*(short *)ptr;
+       case CINV_T_INT:
+               return *(int *)ptr;
+       case CINV_T_LONG:
+               return (int)*(long *)ptr;
+       case CINV_T_PTR:
+               return (int)*(void **)ptr;
+       default:
+               return -1;
+       }
+}
+void set_from_int(void *ptr_out, cinv_type_t type, int val) {
+       switch (type) {
+       case CINV_T_CHAR:
+               *(char *)ptr_out = (char)val;
+               break;
+       case CINV_T_SHORT:
+               *(short *)ptr_out = (short)val;
+               break;
+       case CINV_T_INT:
+               *(int *)ptr_out = val;
+               break;
+       case CINV_T_LONG:
+               *(long *)ptr_out = (long)val;
+               break;
+       case CINV_T_PTR:
+               *(void **)ptr_out = (void *)val;
+               break;
+       default:
+               break;
+       }
+}
+void arch_set_register_parms(ArchRegParms *regparms, 
+       cinv_callconv_t callingconvention, int num_params, void *parameters[], 
+       cinv_type_t types[]) {
+       int numeligible = 0, i;
+
+       if (callingconvention != CINV_CC_FASTCALL) return;
+
+       for (i = 0; i < num_params; i++) {
+               if (is_ok_register(types[i])) {
+                       if (numeligible == 0)
+                               regparms->first = convert_to_int(parameters[i], 
types[i]);
+                       else
+                               regparms->second = 
convert_to_int(parameters[i], types[i]);
+                       numeligible++;
+               }
+               if (numeligible == 2) break;
+       }
+}
+
+void arch_get_register_parms(ArchRegParms *regparms,
+       cinv_callconv_t callingconvention, int num_params, void 
*parameters_out[],
+       cinv_type_t types[]) {
+       int numeligible = 0, i;
+
+       if (callingconvention != CINV_CC_FASTCALL) return;
+       
+       for (i = 0; i < num_params; i++) {
+               if (is_ok_register(types[i])) {
+                       if (numeligible == 0)
+                               set_from_int(parameters_out[i], types[i], 
regparms->first);
+                       else
+                               set_from_int(parameters_out[i], types[i], 
regparms->second);
+                       numeligible++;
+               }
+               if (numeligible == 2) break;
+       }
+}
+
+void arch_getval_char(ArchRetValue *archval, char *outval) {
+       *outval = archval->ivallow;
+}
+void arch_getval_short(ArchRetValue *archval, short *outval) {
+       *outval = archval->ivallow;
+}
+void arch_getval_int(ArchRetValue *archval, int *outval) {
+       *outval = archval->ivallow;
+}
+void arch_getval_long(ArchRetValue *archval, long int *outval) {
+       *outval = archval->ivallow;
+}
+void arch_getval_extralong(ArchRetValue *archval, long long int *outval) {
+       *outval = archval->ivalhigh;
+       *outval <<= 32;
+       *outval |= archval->ivallow;
+}
+void arch_getval_float(ArchRetValue *archval, float *outval) {
+       *outval = (float)archval->dval;
+}
+void arch_getval_double(ArchRetValue *archval, double *outval) {
+       *outval = archval->dval;
+}
+void arch_getval_ptr(ArchRetValue *archval, void **outval) {
+       *outval = (void *)archval->ivallow;
+}
+
+void arch_setval_char(ArchRetValue *archval, char val) {
+       archval->ivallow = val;
+}
+void arch_setval_short(ArchRetValue *archval, short val) {
+       archval->ivallow = val;
+}
+void arch_setval_int(ArchRetValue *archval, int val) {
+       archval->ivallow = val;
+}
+void arch_setval_long(ArchRetValue *archval, long int val) {
+       archval->ivallow = val;
+}
+void arch_setval_extralong(ArchRetValue *archval, long long int val) {
+       archval->ivalhigh = (int)(val >> 32);
+       archval->ivallow = (int)val;
+}
+void arch_setval_float(ArchRetValue *archval, float val) {
+       archval->dval = val;
+}
+void arch_setval_double(ArchRetValue *archval, double val) {
+       archval->dval = val;
+}
+void arch_setval_ptr(ArchRetValue *archval, void *val) {
+       archval->ivallow = (int)val;
+}
+
+void arch_size_char(int *stacksize_out, int *structsize_out,
+       int *structalign_out) {
+       *stacksize_out = 4;
+       *structsize_out = 1;
+}
+void arch_size_short(int *stacksize_out, int *structsize_out,
+       int *structalign_out) {
+       *stacksize_out = 4;
+       *structsize_out = 2;
+       *structalign_out = 2;
+}
+void arch_size_int(int *stacksize_out, int *structsize_out,
+       int *structalign_out) {
+       *stacksize_out = 4;
+       *structsize_out = 4;
+       *structalign_out = 4;
+}
+void arch_size_long(int *stacksize_out, int *structsize_out,
+       int *structalign_out) {
+       *stacksize_out = 4;
+       *structsize_out = 4;
+       *structalign_out = 4;
+}
+void arch_size_extralong(int *stacksize_out, int *structsize_out,
+       int *structalign_out) {
+       *stacksize_out = 8;
+       *structsize_out = 8;
+       *structalign_out = 8;
+}
+void arch_size_float(int *stacksize_out, int *structsize_out,
+       int *structalign_out) {
+       *stacksize_out = 4;
+       *structsize_out = 4;
+       *structalign_out = 4;
+}
+void arch_size_double(int *stacksize_out, int *structsize_out,
+       int *structalign_out) {
+       *stacksize_out = 8;
+       *structsize_out = 8;
+       *structalign_out = 8;
+}
+void arch_size_ptr(int *stacksize_out, int *structsize_out,
+       int *structalign_out) {
+       *stacksize_out = 4;
+       *structsize_out = 4;
+       *structalign_out = 4;
+}

Added: trunk/cinvoke/lib/arch/gcc_x86_win.h
===================================================================
--- trunk/cinvoke/lib/arch/gcc_x86_win.h                                (rev 0)
+++ trunk/cinvoke/lib/arch/gcc_x86_win.h        2008-07-29 03:29:39 UTC (rev 
153)
@@ -0,0 +1,136 @@
+/*
+C/Invoke Source Code File
+
+Copyright (c) 2006 Will Weisser
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+   2. Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+   3. The name of the author may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef _ARCH_CL_X86_WIN_H
+#define _ARCH_CL_X86_WIN_H
+
+#include <windows.h>
+
+char *GetWin32ErrMsg(DWORD err);
+
+typedef struct _ArchLibrary {
+       HANDLE dl;
+} ArchLibrary;
+
+typedef struct _ArchRetValue {
+       int ivallow;
+       int ivalhigh;
+       double dval;
+} ArchRetValue;
+
+typedef struct _ArchRegParms {
+       int first;
+       int second;
+} ArchRegParms;
+
+typedef char cinv_int8_t;
+typedef short cinv_int16_t;
+typedef int cinv_int32_t;
+typedef long long cinv_int64_t;
+
+#define CINV_E_NOMEM ((cinv_int32_t)ERROR_NOT_ENOUGH_MEMORY)
+#define CINV_S_NOMEM (GetWin32ErrMsg(ERROR_NOT_ENOUGH_MEMORY))
+#define CINV_NOMEM_NEEDSFREE 1
+#define CINV_E_INVAL ((cinv_int32_t)ERROR_INVALID_PARAMETER)
+
+// setting this to stdcall makes the win32 api work, but user-compiled
+// dlls break; you can't win
+#define CINV_CC_DEFAULT CINV_CC_CDECL
+#define CINV_T_2BYTE CINV_T_SHORT
+#define CINV_T_4BYTE CINV_T_INT
+#define CINV_T_8BYTE CINV_T_EXTRALONG
+
+/////////////////////////////////////
+// macros
+/////////////////////////////////////
+#define ARCH_SAVE_REGPARMS(regparms) \
+       __asm__("mov %%ecx, %0; \
+                       mov %%edx, %1" : \
+                               "=m"((regparms).first), \
+                               "=m"((regparms).second) \
+                       );
+
+#define ARCH_CALL(regparms, ep) \
+       __asm__("mov %0, %%ecx; \
+                       mov %1, %%edx; \
+                       call %2" : \
+                       : \
+                               "m"((regparms).first), \
+                               "m"((regparms).second), \
+                 "m"(ep));
+
+#define ARCH_SAVE_RETURN(archvalue, type) \
+       __asm__("mov %%eax, %0; \
+                       mov %%edx, %1" : \
+                               "=m"((archvalue).ivallow), \
+                               "=m"((archvalue).ivalhigh)); \
+       if (type == CINV_T_FLOAT || type == CINV_T_DOUBLE) { \
+               __asm__("fstp %0" : "=m"((archvalue).dval)); \
+       }
+
+#define ARCH_SET_RETURN(archvalue, type) \
+       if (type == CINV_T_FLOAT || type == CINV_T_DOUBLE) { \
+               __asm__("fld %0" : \
+                                               : \
+                                       "f"((archvalue).dval) \
+                               ); \
+       } \
+       __asm__("mov %0, %%eax; \
+                       mov %1, %%edx" : \
+                       : "m"((archvalue).ivallow), \
+                               "m"((archvalue).ivalhigh) \
+                       );
+
+#define ARCH_PUT_STACK_BYTES(bcount) \
+       __asm__("sub %0, %%esp" \
+                               : "=r"(bcount));
+
+#define ARCH_REMOVE_STACK_BYTES(bcount) \
+       __asm__("add %0, %%esp" \
+                               : "=r"(bcount));
+
+#define ARCH_GET_STACK(stackp) \
+       __asm__("mov %%esp, %0" \
+                               : "=r"(stackp));
+
+#define ARCH_GET_FRAME_PTR(framep) \
+       __asm__("mov %%ebp, %0" \
+                               : "=r"(framep));
+
+#define ARCH_CALLBACK_ARG_OFFSET (96)
+
+#define ARCH_BIG_ENDIAN 0
+
+#define ARCH_STACK_GROWS_DOWN 1
+
+#define ARCH_STACK_SKIPTOP 0
+
+#define ARCH_REGPARMS_IN_STACKSIZE 0
+
+#define ARCH_CLAMP_NONFIRST_STRUCTALIGN 0
+
+#endif

Modified: trunk/cinvoke/lib/cinvoke-arch.h
===================================================================
--- trunk/cinvoke/lib/cinvoke-arch.h    2007-09-01 18:59:08 UTC (rev 152)
+++ trunk/cinvoke/lib/cinvoke-arch.h    2008-07-29 03:29:39 UTC (rev 153)
@@ -76,6 +76,9 @@
 #ifdef ARCH_CL_X86_WIN
 #include "arch/cl_x86_win.h"
 #endif
+#ifdef ARCH_GCC_X86_WIN
+#include "arch/gcc_x86_win.h"
+#endif
 #ifdef ARCH_GCC_PPC_OSX
 #include "arch/gcc_ppc_osx.h"
 #endif





reply via email to

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