X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2FAdjustor.c;h=607c0b8abebacba0b6338c29eecb4d68267afc76;hb=8625c675de45bdb8bcfa795572ce7c47687c147c;hp=a4c6abeddbb3eff0b6b1963a75de9940e7b4a27b;hpb=72cd126afbeae4fb60f4b5ef10e21133611cbafa;p=ghc-hetmet.git diff --git a/rts/Adjustor.c b/rts/Adjustor.c index a4c6abe..607c0b8 100644 --- a/rts/Adjustor.c +++ b/rts/Adjustor.c @@ -38,15 +38,25 @@ Haskell side. #include "PosixSource.h" #include "Rts.h" -#include "RtsExternal.h" + #include "RtsUtils.h" -#include +#include "Stable.h" #if defined(USE_LIBFFI_FOR_ADJUSTORS) - #include "ffi.h" #include +#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) { @@ -90,6 +100,7 @@ createAdjustor (int cconv, ffi_type *result_type; ffi_closure *cl; int r, abi; + void *code; n_args = strlen(typeString) - 1; cif = stgMallocBytes(sizeof(ffi_cif), "createAdjustor"); @@ -100,7 +111,7 @@ createAdjustor (int cconv, 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; @@ -115,13 +126,15 @@ createAdjustor (int cconv, 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... @@ -207,12 +220,12 @@ stgAllocStable(size_t size_in_bytes, StgStablePtr *stable) 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); @@ -291,7 +304,7 @@ typedef struct AdjustorStub { } 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; @@ -329,6 +342,7 @@ createAdjustor(int cconv, StgStablePtr hptr, ) { void *adjustor = NULL; + void *code; switch (cconv) { @@ -346,7 +360,7 @@ createAdjustor(int cconv, StgStablePtr hptr, : 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 */ @@ -391,7 +405,7 @@ createAdjustor(int cconv, StgStablePtr hptr, 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; @@ -416,10 +430,9 @@ createAdjustor(int cconv, StgStablePtr hptr, 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; @@ -505,6 +518,7 @@ createAdjustor(int cconv, StgStablePtr hptr, { 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. @@ -514,35 +528,37 @@ createAdjustor(int cconv, StgStablePtr hptr, } 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) @@ -575,7 +591,7 @@ createAdjustor(int cconv, StgStablePtr hptr, 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; @@ -652,7 +668,7 @@ TODO: Depending on how much allocation overhead stgMallocBytes uses for 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; @@ -757,7 +773,7 @@ TODO: Depending on how much allocation overhead stgMallocBytes uses for */ // 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 @@ -908,15 +924,10 @@ TODO: Depending on how much allocation overhead stgMallocBytes uses for 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; @@ -1089,7 +1100,7 @@ TODO: Depending on how much allocation overhead stgMallocBytes uses for } /* Have fun! */ - return adjustor; + return code; } @@ -1117,9 +1128,9 @@ if ( *(unsigned char*)ptr != 0xe8 ) { 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; @@ -1147,7 +1158,6 @@ if ( *(unsigned char*)ptr != 0xe8 ) { } 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; @@ -1167,7 +1177,8 @@ if ( *(unsigned char*)ptr != 0xe8 ) { #else ASSERT(0); #endif - *((unsigned char*)ptr) = '\0'; + // Can't write to this memory, it is only executable: + // *((unsigned char*)ptr) = '\0'; freeExec(ptr); }