X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2FAdjustor.c;h=e2815d0d04e64c5631f23ade76b99a18b165d763;hb=0b9530245a33b8206ca38b9de6dfb01e056fd8dc;hp=fc4182e7312861eeccb0bfa8b801aabe307c82d7;hpb=b05302725141dd9f422c918bec6d02e1572448a1;p=ghc-hetmet.git diff --git a/rts/Adjustor.c b/rts/Adjustor.c index fc4182e..e2815d0 100644 --- a/rts/Adjustor.c +++ b/rts/Adjustor.c @@ -84,10 +84,6 @@ static void GNUC3_ATTRIBUTE(used) obscure_ccall_wrapper(void) } extern void obscure_ccall_ret_code(void); -#if defined(openbsd_HOST_OS) -static unsigned char *obscure_ccall_ret_code_dyn; -#endif - #endif #if defined(x86_64_HOST_ARCH) @@ -113,7 +109,6 @@ extern void obscure_ccall_ret_code(void); #endif #if defined(ia64_HOST_ARCH) -#include "Storage.h" /* Layout of a function descriptor */ typedef struct _IA64FunDesc { @@ -266,7 +261,7 @@ createAdjustor(int cconv, StgStablePtr hptr, : ff e0 jmp %eax # and jump to it. # the callee cleans up the stack */ - adjustor = stgMallocBytesRWX(14); + adjustor = allocateExec(14); { unsigned char *const adj_code = (unsigned char *)adjustor; adj_code[0x00] = (unsigned char)0x58; /* popl %eax */ @@ -311,7 +306,7 @@ createAdjustor(int cconv, StgStablePtr hptr, That's (thankfully) the case here with the restricted set of return types that we support. */ - adjustor = stgMallocBytesRWX(17); + adjustor = allocateExec(17); { unsigned char *const adj_code = (unsigned char *)adjustor; @@ -323,11 +318,7 @@ createAdjustor(int cconv, StgStablePtr hptr, adj_code[0x0a] = (unsigned char)0x68; /* pushl obscure_ccall_ret_code */ *((StgFunPtr*)(adj_code + 0x0b)) = -#if !defined(openbsd_HOST_OS) (StgFunPtr)obscure_ccall_ret_code; -#else - (StgFunPtr)obscure_ccall_ret_code_dyn; -#endif adj_code[0x0f] = (unsigned char)0xff; /* jmp *%eax */ adj_code[0x10] = (unsigned char)0xe0; @@ -340,7 +331,7 @@ createAdjustor(int cconv, StgStablePtr hptr, We offload most of the work to AdjustorAsm.S. */ - AdjustorStub *adjustorStub = stgMallocBytesRWX(sizeof(AdjustorStub)); + AdjustorStub *adjustorStub = allocateExec(sizeof(AdjustorStub)); adjustor = adjustorStub; extern void adjustorCode(void); @@ -443,7 +434,7 @@ createAdjustor(int cconv, StgStablePtr hptr, } if (i < 6) { - adjustor = stgMallocBytesRWX(0x30); + adjustor = allocateExec(0x30); *(StgInt32 *)adjustor = 0x49c1894d; *(StgInt32 *)(adjustor+0x4) = 0x8948c889; @@ -457,7 +448,7 @@ createAdjustor(int cconv, StgStablePtr hptr, } else { - adjustor = stgMallocBytesRWX(0x40); + adjustor = allocateExec(0x40); *(StgInt32 *)adjustor = 0x35ff5141; *(StgInt32 *)(adjustor+0x4) = 0x00000020; @@ -504,7 +495,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 = stgMallocBytesRWX(4*(11+1)); + adjustor = allocateExec(4*(11+1)); { unsigned long *const adj_code = (unsigned long *)adjustor; @@ -581,7 +572,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 = stgMallocBytesRWX(48); + adjustor = allocateExec(48); { StgWord64 *const code = (StgWord64 *)adjustor; @@ -686,7 +677,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 = stgMallocBytesRWX(4 * (4*n + 14)); + adjustor = allocateExec(4 * (4*n + 14)); code = (unsigned*)adjustor; *code++ = 0x48000008; // b *+8 @@ -845,7 +836,7 @@ TODO: Depending on how much allocation overhead stgMallocBytes uses for #ifdef FUNDESCS adjustorStub = stgMallocBytes(sizeof(AdjustorStub), "createAdjustor"); #else - adjustorStub = stgMallocBytesRWX(sizeof(AdjustorStub)); + adjustorStub = allocateExec(sizeof(AdjustorStub)); #endif adjustor = adjustorStub; @@ -958,8 +949,12 @@ TODO: Depending on how much allocation overhead stgMallocBytes uses for /* These macros distribute a long constant into the two words of an MLX bundle */ #define BITS(val,start,count) (((val) >> (start)) & ((1 << (count))-1)) #define MOVL_LOWORD(val) (BITS(val,22,18) << 46) -#define MOVL_HIWORD(val) (BITS(val,40,23) | (BITS(val,0,7) << 36) | (BITS(val,7,9) << 50) \ - | (BITS(val,16,5) << 55) | (BITS(val,21,1) << 44) | BITS(val,63,1) << 59) +#define MOVL_HIWORD(val) ( (BITS(val,0,7) << 36) \ + | (BITS(val,7,9) << 50) \ + | (BITS(val,16,5) << 45) \ + | (BITS(val,21,1) << 44) \ + | (BITS(val,40,23)) \ + | (BITS(val,63,1) << 59)) { StgStablePtr stable; @@ -968,11 +963,17 @@ TODO: Depending on how much allocation overhead stgMallocBytes uses for IA64FunDesc *fdesc; StgWord64 *code; - /* we allocate on the Haskell heap since malloc'd memory isn't executable - argh */ - adjustor = stgAllocStable(sizeof(IA64FunDesc)+18*8, &stable); + /* we allocate on the Haskell heap since malloc'd memory isn't + * executable - argh */ + /* Allocated memory is word-aligned (8 bytes) but functions on ia64 + * must be aligned to 16 bytes. We allocate an extra 8 bytes of + * wiggle room so that we can put the code on a 16 byte boundary. */ + adjustor = stgAllocStable(sizeof(IA64FunDesc)+18*8+8, &stable); fdesc = (IA64FunDesc *)adjustor; code = (StgWord64 *)(fdesc + 1); + /* add 8 bytes to code if needed to align to a 16-byte boundary */ + if ((StgWord64)code & 15) code++; fdesc->ip = (StgWord64)code; fdesc->gp = wdesc->gp; @@ -1088,23 +1089,5 @@ if ( *(unsigned char*)ptr != 0xe8 ) { #endif *((unsigned char*)ptr) = '\0'; - stgFree(ptr); -} - - -/* - * Function: initAdjustor() - * - * Perform initialisation of adjustor thunk layer (if needed.) - */ -void -initAdjustor(void) -{ -#if defined(i386_HOST_ARCH) && defined(openbsd_HOST_OS) - obscure_ccall_ret_code_dyn = stgMallocBytesRWX(4); - obscure_ccall_ret_code_dyn[0] = ((unsigned char *)obscure_ccall_ret_code)[0]; - obscure_ccall_ret_code_dyn[1] = ((unsigned char *)obscure_ccall_ret_code)[1]; - obscure_ccall_ret_code_dyn[2] = ((unsigned char *)obscure_ccall_ret_code)[2]; - obscure_ccall_ret_code_dyn[3] = ((unsigned char *)obscure_ccall_ret_code)[3]; -#endif + freeExec(ptr); }