You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gentoo-overlay/dev-libs/libffi/files/libffi-3.4.4-hppa-closure-f...

171 lines
5.8 KiB

https://github.com/libffi/libffi/commit/e58e22b22386ed0e0a95e97eb8eed016e3f01b02
From e58e22b22386ed0e0a95e97eb8eed016e3f01b02 Mon Sep 17 00:00:00 2001
From: Anthony Green <green@moxielogic.com>
Date: Thu, 2 Feb 2023 07:02:53 -0500
Subject: [PATCH] From Dave Anglin:
A couple of years ago the 32-bit hppa targets were converted from using a trampoline executed on the stack to the function descriptor technique used by ia64. This is more efficient and avoids having to have an executable stack. However, function pointers on 32-bit need the PLABEL bit set in the pointer. It distinguishes between pointers that point directly to the executable code and pointer that point to a function descriptor. We need the later for libffi. But as a result, it is not possible to convert using casts data pointers to function pointers.
The solution at the time was to set the PLABEL bit in hppa closure pointers using FFI_CLOSURE_PTR. However, I realized recently that this was a bad choice. Packages like python-cffi allocate their own closure pointers, so this isn't going to work well there.
A better solution is to leave closure pointers unchanged and only set the PLABEL bit in pointers used to point to executable code.
The attached patch drops the FFI_CLOSURE_PTR and FFI_RESTORE_PTR defines. This allows some cleanup in the hppa closure routines. The FFI_FN define is now used to set the PLABEL bit on hppa. ffi_closure_alloc is modified to set the PLABEL bit in the value set in *code.
I also added a FFI_CL define to convert a function pointer to a closure pointer. It is only used in one test case.
--- a/include/ffi.h.in
+++ b/include/ffi.h.in
@@ -361,14 +361,6 @@ typedef struct {
FFI_API void *ffi_closure_alloc (size_t size, void **code);
FFI_API void ffi_closure_free (void *);
-#if defined(PA_LINUX) || defined(PA_HPUX)
-#define FFI_CLOSURE_PTR(X) ((void *)((unsigned int)(X) | 2))
-#define FFI_RESTORE_PTR(X) ((void *)((unsigned int)(X) & ~3))
-#else
-#define FFI_CLOSURE_PTR(X) (X)
-#define FFI_RESTORE_PTR(X) (X)
-#endif
-
FFI_API ffi_status
ffi_prep_closure (ffi_closure*,
ffi_cif *,
@@ -515,8 +507,14 @@ FFI_API
ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type,
size_t *offsets);
-/* Useful for eliminating compiler warnings. */
+/* Convert between closure and function pointers. */
+#if defined(PA_LINUX) || defined(PA_HPUX)
+#define FFI_FN(f) ((void (*)(void))((unsigned int)(f) | 2))
+#define FFI_CL(f) ((void *)((unsigned int)(f) & ~3))
+#else
#define FFI_FN(f) ((void (*)(void))f)
+#define FFI_CL(f) ((void *)(f))
+#endif
/* ---- Definitions shared with assembly code ---------------------------- */
--- a/src/closures.c
+++ b/src/closures.c
@@ -993,23 +993,23 @@ ffi_closure_alloc (size_t size, void **code)
if (!code)
return NULL;
- ptr = FFI_CLOSURE_PTR (dlmalloc (size));
+ ptr = dlmalloc (size);
if (ptr)
{
msegmentptr seg = segment_holding (gm, ptr);
- *code = add_segment_exec_offset (ptr, seg);
+ *code = FFI_FN (add_segment_exec_offset (ptr, seg));
if (!ffi_tramp_is_supported ())
return ptr;
ftramp = ffi_tramp_alloc (0);
if (ftramp == NULL)
{
- dlfree (FFI_RESTORE_PTR (ptr));
+ dlfree (ptr);
return NULL;
}
- *code = ffi_tramp_get_addr (ftramp);
+ *code = FFI_FN (ffi_tramp_get_addr (ftramp));
((ffi_closure *) ptr)->ftramp = ftramp;
}
@@ -1050,7 +1050,7 @@ ffi_closure_free (void *ptr)
if (ffi_tramp_is_supported ())
ffi_tramp_free (((ffi_closure *) ptr)->ftramp);
- dlfree (FFI_RESTORE_PTR (ptr));
+ dlfree (ptr);
}
int
@@ -1070,16 +1070,20 @@ ffi_tramp_is_present (void *ptr)
void *
ffi_closure_alloc (size_t size, void **code)
{
+ void *c;
+
if (!code)
return NULL;
- return *code = FFI_CLOSURE_PTR (malloc (size));
+ c = malloc (size);
+ *code = FFI_FN (c);
+ return c;
}
void
ffi_closure_free (void *ptr)
{
- free (FFI_RESTORE_PTR (ptr));
+ free (ptr);
}
void *
--- a/src/pa/ffi.c
+++ b/src/pa/ffi.c
@@ -445,7 +445,6 @@ ffi_status ffi_closure_inner_pa32(ffi_closure *closure, UINT32 *stack)
int i, avn;
unsigned int slot = FIRST_ARG_SLOT;
register UINT32 r28 asm("r28");
- ffi_closure *c = (ffi_closure *)FFI_RESTORE_PTR (closure);
cif = closure->cif;
@@ -548,7 +547,7 @@ ffi_status ffi_closure_inner_pa32(ffi_closure *closure, UINT32 *stack)
}
/* Invoke the closure. */
- (c->fun) (cif, rvalue, avalue, c->user_data);
+ (closure->fun) (cif, rvalue, avalue, closure->user_data);
debug(3, "after calling function, ret[0] = %08x, ret[1] = %08x\n", u.ret[0],
u.ret[1]);
@@ -649,8 +648,6 @@ ffi_prep_closure_loc (ffi_closure* closure,
void *user_data,
void *codeloc)
{
- ffi_closure *c = (ffi_closure *)FFI_RESTORE_PTR (closure);
-
/* The layout of a function descriptor. A function pointer with the PLABEL
bit set points to a function descriptor. */
struct pa32_fd
@@ -676,14 +673,14 @@ ffi_prep_closure_loc (ffi_closure* closure,
fd = (struct pa32_fd *)((UINT32)ffi_closure_pa32 & ~3);
/* Setup trampoline. */
- tramp = (struct ffi_pa32_trampoline_struct *)c->tramp;
+ tramp = (struct ffi_pa32_trampoline_struct *)closure->tramp;
tramp->code_pointer = fd->code_pointer;
tramp->fake_gp = (UINT32)codeloc & ~3;
tramp->real_gp = fd->gp;
- c->cif = cif;
- c->user_data = user_data;
- c->fun = fun;
+ closure->cif = cif;
+ closure->user_data = user_data;
+ closure->fun = fun;
return FFI_OK;
}
--- a/testsuite/libffi.closures/closure_loc_fn0.c
+++ b/testsuite/libffi.closures/closure_loc_fn0.c
@@ -85,7 +85,7 @@ int main (void)
#ifndef FFI_EXEC_STATIC_TRAMP
/* With static trampolines, the codeloc does not point to closure */
- CHECK(memcmp(pcl, codeloc, sizeof(*pcl)) == 0);
+ CHECK(memcmp(pcl, FFI_CL(codeloc), sizeof(*pcl)) == 0);
#endif
res = (*((closure_loc_test_type0)codeloc))