This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH libffi: darwin_closure.S dylib/shared library safe
- From: Andreas Tobler <toa at pop dot agri dot ch>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>, David Edelsohn <dje at watson dot ibm dot com>
- Date: Mon, 03 Mar 2003 16:20:02 +0100
- Subject: PATCH libffi: darwin_closure.S dylib/shared library safe
Hi,
this patch makes the libffi port of darwin dylib/shared library safe. I
took the ppc_closure.S as example and added the necessary part. (stub call)
I tested the libffi on darwin6.3 for gcc 3.4 and 3.3. Both builds, a
static one and a dylib one work. (also the ffitest)
For those not familar with, dylibs are the apple variant of shared
libraries.
I would like to get some feedback from apple people as well, since I
have taken the stub call from generated sample assembly. Is this done
the right way?
Thank you in advance.
Andreas
Changelog:
2003-03-03 Andreas Tobler <a dot tobler at schweiz dot ch>
* src/powerpc/darwin_closure.S: Recode to fit dynamic libraries.
Index: src/powerpc/darwin_closure.S
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/powerpc/darwin_closure.S,v
retrieving revision 1.1.32.2
diff -u -r1.1.32.2 darwin_closure.S
--- src/powerpc/darwin_closure.S 7 Feb 2003 04:33:43 -0000 1.1.32.2
+++ src/powerpc/darwin_closure.S 3 Mar 2003 15:04:49 -0000
@@ -25,21 +25,19 @@
----------------------------------------------------------------------- */
#define LIBFFI_ASM
-#define JUMPTARGET(name) name
#define L(x) x
-.text
-.globl _ffi_closure_helper_DARWIN
+ .file "darwin_closure.S"
.text
- .align 2
+ .align 2
.globl _ffi_closure_ASM
-
+
.text
.align 2
_ffi_closure_ASM:
LFB1:
- mflr r0 /* extract return address */
- stw r0, 8(r1) /* save the return address */
+ mflr r0 /* extract return address */
+ stw r0, 8(r1) /* save the return address */
LCFI0:
/* 24 Bytes (Linkage Area)
32 Bytes (outgoing parameter area, always reserved)
@@ -47,7 +45,7 @@
8 Bytes (result)
168 Bytes */
- stwu r1,-176(r1) /* skip over caller save area
+ stwu r1,-176(r1) /* skip over caller save area
keep stack aligned to 16 */
LCFI1:
/* we want to build up an area for the parameters passed
@@ -64,7 +62,7 @@
stw r9, 224(r1)
stw r10, 228(r1)
- /* we save fpr 1 to fpr 13 (aligned to 8) */
+ /* we save fpr 1 to fpr 13 (aligned to 8) */
stfd f1, 56(r1)
stfd f2, 64(r1)
stfd f3, 72(r1)
@@ -97,98 +95,147 @@
addi r7,r1,232
/* make the call */
- bl L(_ffi_closure_helper_DARWIN)
-
+ bl Lffi_closure_helper_DARWIN$stub
+
/* now r3 contains the return type */
/* so use it to look up in a table */
/* so we know how to deal with each type */
/* look up the proper starting point in table */
- /* by using return type as offset */
- addi r5,r1,160 /* get pointer to results area */
- addis r4,0,ha16(.L60) /* get address of jump table */
- addi r4,r4,lo16(.L60)
- slwi r3,r3,2 /* now multiply return type by 4 */
- lwzx r3,r4,r3 /* get the contents of that table value */
- add r3,r3,r4 /* add contents of table to table address */
+ /* by using return type as offset */
+ addi r5,r1,160 /* get pointer to results area */
+ bl Lget_ret_type0_addr /* get pointer to Lret_type0 into LR */
+ mflr r4 /* move to r4 */
+ slwi r3,r3,4 /* now multiply return type by 16 */
+ add r3,r3,r4 /* add contents of table to table address */
mtctr r3
- bctr /* jump to it */
+ bctr /* jump to it */
LFE1:
- .align 2
+/* Each of the ret_typeX code fragments has to be exactly 16 bytes long */
+/* (4 instructions). For cache effectiveness we align to a 16 byte boundary */
+/* first. */
+
+ .align 4
-.L60:
- .long .L44-.L60 /* FFI_TYPE_VOID */
- .long .L50-.L60 /* FFI_TYPE_INT */
- .long .L47-.L60 /* FFI_TYPE_FLOAT */
- .long .L46-.L60 /* FFI_TYPE_DOUBLE */
- .long .L46-.L60 /* FFI_TYPE_LONGDOUBLE */
- .long .L56-.L60 /* FFI_TYPE_UINT8 */
- .long .L55-.L60 /* FFI_TYPE_SINT8 */
- .long .L58-.L60 /* FFI_TYPE_UINT16 */
- .long .L57-.L60 /* FFI_TYPE_SINT16 */
- .long .L50-.L60 /* FFI_TYPE_UINT32 */
- .long .L50-.L60 /* FFI_TYPE_SINT32 */
- .long .L48-.L60 /* FFI_TYPE_UINT64 */
- .long .L48-.L60 /* FFI_TYPE_SINT64 */
- .long .L44-.L60 /* FFI_TYPE_STRUCT */
- .long .L50-.L60 /* FFI_TYPE_POINTER */
-
-
-/* case double */
-.L46:
- lfd f1,0(r5)
- b .L44
-
-/* case float */
-.L47:
- lfs f1,0(r5)
- b .L44
-
-/* case long long */
-.L48:
- lwz r3,0(r5)
- lwz r4,4(r5)
- b .L44
-
-/* case default / int32 / pointer */
-.L50:
- lwz r3,0(r5)
- b .L44
-
-/* case signed int8 */
-.L55:
- addi r5,r5,3
- lbz r3,0(r5)
- extsb r3,r3
- b .L44
-
-/* case unsigned int8 */
-.L56:
- addi r5,r5,3
- lbz r3,0(r5)
- b .L44
-
-/* case signed int16 */
-.L57:
- addi r5,r5,2
- lhz r3,0(r5)
- extsh r3,r3
- b .L44
-
-/* case unsigned int16 */
-.L58:
- addi r5,r5,2
- lhz r3,0(r5)
-
-/* case void / done */
-.L44:
-
- addi r1,r1,176 /* restore stack pointer */
- lwz r0,8(r1) /* get return address */
- mtlr r0 /* reset link register */
+ nop
+ nop
+ nop
+Lget_ret_type0_addr:
+ blrl
+
+/* case FFI_TYPE_VOID */
+Lret_type0:
+ b Lfinish
+ nop
+ nop
+ nop
+
+/* case FFI_TYPE_INT */
+Lret_type1:
+ lwz r3,0(r5)
+ b Lfinish
+ nop
+ nop
+
+/* case FFI_TYPE_FLOAT */
+Lret_type2:
+ lfs f1,0(r5)
+ b Lfinish
+ nop
+ nop
+
+/* case FFI_TYPE_DOUBLE */
+Lret_type3:
+ lfd f1,0(r5)
+ b Lfinish
+ nop
+ nop
+
+/* case FFI_TYPE_LONGDOUBLE */
+Lret_type4:
+ lfd f1,0(r5)
+ b Lfinish
+ nop
+ nop
+
+/* case FFI_TYPE_UINT8 */
+Lret_type5:
+ lbz r3,3(r5)
+ b Lfinish
+ nop
+ nop
+
+/* case FFI_TYPE_SINT8 */
+Lret_type6:
+ lbz r3,3(r5)
+ extsb r3,r3
+ b Lfinish
+ nop
+
+/* case FFI_TYPE_UINT16 */
+Lret_type7:
+ lhz r3,2(r5)
+ b Lfinish
+ nop
+ nop
+
+/* case FFI_TYPE_SINT16 */
+Lret_type8:
+ lha r3,2(r5)
+ b Lfinish
+ nop
+ nop
+
+/* case FFI_TYPE_UINT32 */
+Lret_type9:
+ lwz r3,0(r5)
+ b Lfinish
+ nop
+ nop
+
+/* case FFI_TYPE_SINT32 */
+Lret_type10:
+ lwz r3,0(r5)
+ b Lfinish
+ nop
+ nop
+
+/* case FFI_TYPE_UINT64 */
+Lret_type11:
+ lwz r3,0(r5)
+ lwz r4,4(r5)
+ b Lfinish
+ nop
+
+/* case FFI_TYPE_SINT64 */
+Lret_type12:
+ lwz r3,0(r5)
+ lwz r4,4(r5)
+ b Lfinish
+ nop
+
+/* case FFI_TYPE_STRUCT */
+Lret_type13:
+ b Lfinish
+ nop
+ nop
+ nop
+
+/* case FFI_TYPE_POINTER */
+Lret_type14:
+ lwz r3,0(r5)
+ b Lfinish
+ nop
+ nop
+
+/* case done */
+Lfinish:
+ addi r1,r1,176 /* restore stack pointer */
+ lwz r0,8(r1) /* get return address */
+ mtlr r0 /* reset link register */
blr
-
-/* END(ffi_closure_ASM) */
+
+/* END(ffi_closure_ASM) */
.data
.section __TEXT,__eh_frame
@@ -233,4 +280,24 @@
.byte 0x7e ; sleb128 -2
.align 2
LEFDE1:
-
+.data
+ .align 2
+LDFCM0:
+.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
+ .align 2
+Lffi_closure_helper_DARWIN$stub:
+ .indirect_symbol _ffi_closure_helper_DARWIN
+ mflr r0
+ bcl 20,31,LO$ffi_closure_helper_DARWIN
+LO$ffi_closure_helper_DARWIN:
+ mflr r11
+ addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN)
+ mtlr r0
+ lwzu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN)(r11)
+ mtctr r12
+ bctr
+.data
+.lazy_symbol_pointer
+L_ffi_closure_helper_DARWIN$lazy_ptr:
+ .indirect_symbol _ffi_closure_helper_DARWIN
+ .long dyld_stub_binding_helper