return addr;
}
+#ifdef LEADING_UNDERSCORE
+#define UNDERSCORE "_"
+#else
+#define UNDERSCORE ""
+#endif
#if defined(i386_HOST_ARCH)
/*
Now here's something obscure for you:
returning in some static piece of memory and arrange
to return to it before tail jumping from the adjustor thunk.
*/
-__asm__ (
- ".globl obscure_ccall_ret_code\n"
- "obscure_ccall_ret_code:\n\t"
- "addl $0x4, %esp\n\t"
- "ret"
- );
+static void GNUC3_ATTRIBUTE(used) obscure_ccall_wrapper(void)
+{
+ __asm__ (
+ ".globl " UNDERSCORE "obscure_ccall_ret_code\n"
+ UNDERSCORE "obscure_ccall_ret_code:\n\t"
+ "addl $0x4, %esp\n\t"
+ "ret"
+ );
+}
extern void obscure_ccall_ret_code(void);
+
+#if defined(openbsd_HOST_OS)
+static unsigned char *obscure_ccall_ret_code_dyn;
#endif
-#if defined(x86_64_TARGET_ARCH)
-__asm__ (
- ".globl obscure_ccall_ret_code\n"
- "obscure_ccall_ret_code:\n\t"
+#endif
+
+#if defined(x86_64_HOST_ARCH)
+static void GNUC3_ATTRIBUTE(used) obscure_ccall_wrapper(void)
+{
+ __asm__ (
+ ".globl " UNDERSCORE "obscure_ccall_ret_code\n"
+ UNDERSCORE "obscure_ccall_ret_code:\n\t"
"addq $0x8, %rsp\n\t"
"ret"
);
+}
extern void obscure_ccall_ret_code(void);
#endif
*stable = getStablePtr((StgPtr)arr);
/* and return a ptr to the goods inside the array */
- return(BYTE_ARR_CTS(arr));
+ return(&(arr->payload));
}
#endif
createAdjustor(int cconv, StgStablePtr hptr,
StgFunPtr wptr,
char *typeString
-#if !defined(powerpc_HOST_ARCH) && !defined(powerpc64_HOST_ARCH) && !defined(x86_64_TARGET_ARCH)
+#if !defined(powerpc_HOST_ARCH) && !defined(powerpc64_HOST_ARCH) && !defined(x86_64_HOST_ARCH)
STG_UNUSED
#endif
)
*((StgFunPtr*)(adj_code + 0x06)) = (StgFunPtr)wptr;
adj_code[0x0a] = (unsigned char)0x68; /* pushl obscure_ccall_ret_code */
- *((StgFunPtr*)(adj_code + 0x0b)) = (StgFunPtr)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;
void
initAdjustor(void)
{
+#if defined(i386_HOST_ARCH) && defined(openbsd_HOST_OS)
+ obscure_ccall_ret_code_dyn = mallocBytesRWX(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
}