This is the mail archive of the libffi-discuss@sourceware.org mailing list for the libffi 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]

PATCH: Add Linux/x32 support


This patch adds support for Linux/x32:

https://sites.google.com/site/x32abi/

Linux/x32 has 32bit pointers and long with x86-64 instruction set.  We
have to use long long to update 64bit address and integer registes.
Tested on Linux/x32.


H.J.
---
2012-03-03  H.J. Lu  <hongjiu.lu@intel.com>
    
	* src/x86/ffi64.c (ffi_call): Cast the return value to unsigned
	long.
	(ffi_prep_closure_loc): Cast to 64bit address in trampoline.
	(ffi_closure_unix64_inner): Cast return pointer to unsigned long
	first.

	* src/x86/ffitarget.h (FFI_SIZEOF_ARG): Defined to 8 for x32.
	(ffi_arg): Set to unsigned long long for x32.
	(ffi_sarg): Set to long long for x32.
diff --git a/src/x86/ffi64.c b/src/x86/ffi64.c
index c8eb455..defd774 100644
--- a/src/x86/ffi64.c
+++ b/src/x86/ffi64.c
@@ -427,7 +427,7 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
   /* If the return value is passed in memory, add the pointer as the
      first integer argument.  */
   if (ret_in_memory)
-    reg_args->gpr[gprcount++] = (long) rvalue;
+    reg_args->gpr[gprcount++] = (unsigned long) rvalue;
 
   avn = cif->nargs;
   arg_types = cif->arg_types;
@@ -509,9 +509,11 @@ ffi_prep_closure_loc (ffi_closure* closure,
   tramp = (volatile unsigned short *) &closure->tramp[0];
 
   tramp[0] = 0xbb49;		/* mov <code>, %r11	*/
-  *(void * volatile *) &tramp[1] = ffi_closure_unix64;
+  *((unsigned long long * volatile) &tramp[1])
+    = (unsigned long) ffi_closure_unix64;
   tramp[5] = 0xba49;		/* mov <data>, %r10	*/
-  *(void * volatile *) &tramp[6] = codeloc;
+  *((unsigned long long * volatile) &tramp[6])
+    = (unsigned long) codeloc;
 
   /* Set the carry bit iff the function uses any sse registers.
      This is clc or stc, together with the first byte of the jmp.  */
@@ -550,7 +552,7 @@ ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue,
 	{
 	  /* The return value goes in memory.  Arrange for the closure
 	     return value to go directly back to the original caller.  */
-	  rvalue = (void *) reg_args->gpr[gprcount++];
+	  rvalue = (void *) (unsigned long) reg_args->gpr[gprcount++];
 	  /* We don't have to do anything in asm for the return.  */
 	  ret = FFI_TYPE_VOID;
 	}
diff --git a/src/x86/ffitarget.h b/src/x86/ffitarget.h
index 17f60bc..54a6121 100644
--- a/src/x86/ffitarget.h
+++ b/src/x86/ffitarget.h
@@ -61,9 +61,15 @@ typedef unsigned long long     ffi_arg;
 typedef long long              ffi_sarg;
 #endif
 #else
+#if defined __x86_64__ && !defined __LP64__
+#define FFI_SIZEOF_ARG 8
+typedef unsigned long long     ffi_arg;
+typedef long long              ffi_sarg;
+#else
 typedef unsigned long          ffi_arg;
 typedef signed long            ffi_sarg;
 #endif
+#endif
 
 typedef enum ffi_abi {
   FFI_FIRST_ABI = 0,


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