#include "PosixSource.h"
#include "Rts.h"
-#include "RtsExternal.h"
+
#include "RtsUtils.h"
-#include <stdlib.h>
+#include "Stable.h"
#if defined(USE_LIBFFI_FOR_ADJUSTORS)
-
#include "ffi.h"
#include <string.h>
+#endif
+#if defined(i386_HOST_ARCH) && defined(darwin_HOST_OS)
+extern void adjustorCode(void);
+#elif defined(powerpc_HOST_ARCH) || defined(powerpc64_HOST_ARCH)
+// from AdjustorAsm.s
+// not declared as a function so that AIX-style
+// fundescs can never get in the way.
+extern void *adjustorCode;
+#endif
+
+#if defined(USE_LIBFFI_FOR_ADJUSTORS)
void
freeHaskellFunctionPtr(void* ptr)
{
ffi_type *result_type;
ffi_closure *cl;
int r, abi;
+ void *code;
n_args = strlen(typeString) - 1;
cif = stgMallocBytes(sizeof(ffi_cif), "createAdjustor");
arg_types[i] = char_to_ffi_type(typeString[i+1]);
}
switch (cconv) {
-#ifdef mingw32_TARGET_OS
+#ifdef mingw32_HOST_OS
case 0: /* stdcall */
abi = FFI_STDCALL;
break;
r = ffi_prep_cif(cif, abi, n_args, result_type, arg_types);
if (r != FFI_OK) barf("ffi_prep_cif failed: %d", r);
- // ToDo: use ffi_closure_alloc()
- cl = allocateExec(sizeof(ffi_closure));
+ cl = allocateExec(sizeof(ffi_closure), &code);
+ if (cl == NULL) {
+ barf("createAdjustor: failed to allocate memory");
+ }
r = ffi_prep_closure(cl, cif, (void*)wptr, hptr/*userdata*/);
if (r != FFI_OK) barf("ffi_prep_closure failed: %d", r);
- return (void*)cl;
+ return (void*)code;
}
#else // To end of file...
nat data_size_in_words, total_size_in_words;
/* round up to a whole number of words */
- data_size_in_words = (size_in_bytes + sizeof(W_) + 1) / sizeof(W_);
+ data_size_in_words = ROUNDUP_BYTES_TO_WDS(size_in_bytes);
total_size_in_words = sizeofW(StgArrWords) + data_size_in_words;
/* allocate and fill it in */
arr = (StgArrWords *)allocate(total_size_in_words);
- SET_ARR_HDR(arr, &stg_ARR_WORDS_info, CCCS, data_size_in_words);
+ SET_ARR_HDR(arr, &stg_ARR_WORDS_info, CCCS, size_in_bytes);
/* obtain a stable ptr */
*stable = getStablePtr((StgPtr)arr);
} AdjustorStub;
#endif
-#if defined(darwin_HOST_OS) || defined(powerpc_HOST_ARCH) || defined(powerpc64_HOST_ARCH)
+#if (defined(i386_HOST_ARCH) && defined(darwin_HOST_OS)) || defined(powerpc_HOST_ARCH) || defined(powerpc64_HOST_ARCH)
static int totalArgumentSize(char *typeString)
{
int sz = 0;
)
{
void *adjustor = NULL;
+ void *code;
switch (cconv)
{
<c>: ff e0 jmp %eax # and jump to it.
# the callee cleans up the stack
*/
- adjustor = allocateExec(14);
+ adjustor = allocateExec(14,&code);
{
unsigned char *const adj_code = (unsigned char *)adjustor;
adj_code[0x00] = (unsigned char)0x58; /* popl %eax */
That's (thankfully) the case here with the restricted set of
return types that we support.
*/
- adjustor = allocateExec(17);
+ adjustor = allocateExec(17,&code);
{
unsigned char *const adj_code = (unsigned char *)adjustor;
We offload most of the work to AdjustorAsm.S.
*/
- AdjustorStub *adjustorStub = allocateExec(sizeof(AdjustorStub));
+ AdjustorStub *adjustorStub = allocateExec(sizeof(AdjustorStub),&code);
adjustor = adjustorStub;
- extern void adjustorCode(void);
int sz = totalArgumentSize(typeString);
adjustorStub->call[0] = 0xe8;
{
int i = 0;
char *c;
+ StgWord8 *adj_code;
// determine whether we have 6 or more integer arguments,
// and therefore need to flush one to the stack.
}
if (i < 6) {
- adjustor = allocateExec(0x30);
-
- *(StgInt32 *)adjustor = 0x49c1894d;
- *(StgInt32 *)(adjustor+0x4) = 0x8948c889;
- *(StgInt32 *)(adjustor+0x8) = 0xf28948d1;
- *(StgInt32 *)(adjustor+0xc) = 0x48fe8948;
- *(StgInt32 *)(adjustor+0x10) = 0x000a3d8b;
- *(StgInt32 *)(adjustor+0x14) = 0x25ff0000;
- *(StgInt32 *)(adjustor+0x18) = 0x0000000c;
- *(StgInt64 *)(adjustor+0x20) = (StgInt64)hptr;
- *(StgInt64 *)(adjustor+0x28) = (StgInt64)wptr;
+ adjustor = allocateExec(0x30,&code);
+ adj_code = (StgWord8*)adjustor;
+
+ *(StgInt32 *)adj_code = 0x49c1894d;
+ *(StgInt32 *)(adj_code+0x4) = 0x8948c889;
+ *(StgInt32 *)(adj_code+0x8) = 0xf28948d1;
+ *(StgInt32 *)(adj_code+0xc) = 0x48fe8948;
+ *(StgInt32 *)(adj_code+0x10) = 0x000a3d8b;
+ *(StgInt32 *)(adj_code+0x14) = 0x25ff0000;
+ *(StgInt32 *)(adj_code+0x18) = 0x0000000c;
+ *(StgInt64 *)(adj_code+0x20) = (StgInt64)hptr;
+ *(StgInt64 *)(adj_code+0x28) = (StgInt64)wptr;
}
else
{
- adjustor = allocateExec(0x40);
-
- *(StgInt32 *)adjustor = 0x35ff5141;
- *(StgInt32 *)(adjustor+0x4) = 0x00000020;
- *(StgInt32 *)(adjustor+0x8) = 0x49c1894d;
- *(StgInt32 *)(adjustor+0xc) = 0x8948c889;
- *(StgInt32 *)(adjustor+0x10) = 0xf28948d1;
- *(StgInt32 *)(adjustor+0x14) = 0x48fe8948;
- *(StgInt32 *)(adjustor+0x18) = 0x00123d8b;
- *(StgInt32 *)(adjustor+0x1c) = 0x25ff0000;
- *(StgInt32 *)(adjustor+0x20) = 0x00000014;
+ adjustor = allocateExec(0x40,&code);
+ adj_code = (StgWord8*)adjustor;
+
+ *(StgInt32 *)adj_code = 0x35ff5141;
+ *(StgInt32 *)(adj_code+0x4) = 0x00000020;
+ *(StgInt32 *)(adj_code+0x8) = 0x49c1894d;
+ *(StgInt32 *)(adj_code+0xc) = 0x8948c889;
+ *(StgInt32 *)(adj_code+0x10) = 0xf28948d1;
+ *(StgInt32 *)(adj_code+0x14) = 0x48fe8948;
+ *(StgInt32 *)(adj_code+0x18) = 0x00123d8b;
+ *(StgInt32 *)(adj_code+0x1c) = 0x25ff0000;
+ *(StgInt32 *)(adj_code+0x20) = 0x00000014;
- *(StgInt64 *)(adjustor+0x28) = (StgInt64)obscure_ccall_ret_code;
- *(StgInt64 *)(adjustor+0x30) = (StgInt64)hptr;
- *(StgInt64 *)(adjustor+0x38) = (StgInt64)wptr;
+ *(StgInt64 *)(adj_code+0x28) = (StgInt64)obscure_ccall_ret_code;
+ *(StgInt64 *)(adj_code+0x30) = (StgInt64)hptr;
+ *(StgInt64 *)(adj_code+0x38) = (StgInt64)wptr;
}
}
#elif defined(sparc_HOST_ARCH)
similarly, and local variables should be accessed via %fp, not %sp. In a
nutshell: This should work! (Famous last words! :-)
*/
- adjustor = allocateExec(4*(11+1));
+ adjustor = allocateExec(4*(11+1),&code);
{
unsigned long *const adj_code = (unsigned long *)adjustor;
4 bytes (getting rid of the nop), hence saving memory. [ccshan]
*/
ASSERT(((StgWord64)wptr & 3) == 0);
- adjustor = allocateExec(48);
+ adjustor = allocateExec(48,&code);
{
StgWord64 *const code = (StgWord64 *)adjustor;
}
else
{
- if((t == 'l' || t == 'L' || t == 'd')
+ if(t == 'l' || t == 'L' || t == 'd')
{
if(src_offset % 8)
src_offset += 4;
*/
// allocate space for at most 4 insns per parameter
// plus 14 more instructions.
- adjustor = allocateExec(4 * (4*n + 14));
+ adjustor = allocateExec(4 * (4*n + 14),&code);
code = (unsigned*)adjustor;
*code++ = 0x48000008; // b *+8
AdjustorStub *adjustorStub;
int sz = 0, extra_sz, total_sz;
- // from AdjustorAsm.s
- // not declared as a function so that AIX-style
- // fundescs can never get in the way.
- extern void *adjustorCode;
-
#ifdef FUNDESCS
adjustorStub = stgMallocBytes(sizeof(AdjustorStub), "createAdjustor");
#else
- adjustorStub = allocateExec(sizeof(AdjustorStub));
+ adjustorStub = allocateExec(sizeof(AdjustorStub),&code);
#endif
adjustor = adjustorStub;
}
/* Have fun! */
- return adjustor;
+ return code;
}
freeStablePtr(((AdjustorStub*)ptr)->hptr);
#elif defined(x86_64_HOST_ARCH)
if ( *(StgWord16 *)ptr == 0x894d ) {
- freeStablePtr(*(StgStablePtr*)(ptr+0x20));
+ freeStablePtr(*(StgStablePtr*)((StgWord8*)ptr+0x20));
} else if ( *(StgWord16 *)ptr == 0x5141 ) {
- freeStablePtr(*(StgStablePtr*)(ptr+0x30));
+ freeStablePtr(*(StgStablePtr*)((StgWord8*)ptr+0x30));
} else {
errorBelch("freeHaskellFunctionPtr: not for me, guv! %p\n", ptr);
return;
}
freeStablePtr(((StgStablePtr*)ptr)[1]);
#elif defined(powerpc_HOST_ARCH) || defined(powerpc64_HOST_ARCH)
- extern void* adjustorCode;
if ( ((AdjustorStub*)ptr)->code != (StgFunPtr) &adjustorCode ) {
errorBelch("freeHaskellFunctionPtr: not for me, guv! %p\n", ptr);
return;
#else
ASSERT(0);
#endif
- *((unsigned char*)ptr) = '\0';
+ // Can't write to this memory, it is only executable:
+ // *((unsigned char*)ptr) = '\0';
freeExec(ptr);
}