#ifdef FUNCPTR_POINTS_TO_CODE
/* A function pointer points directly to the code. */
# define COPY_FUNCPTR(funcptr) funcptr
-# define CODE(funcptr) (funcptr)
+/* On arm, bit 0 of a function pointer tells which instruction set the function
+ uses. */
+# if defined __arm__ || defined __armhf__
+# define CODE(funcptr) ((void *) ((uintptr_t) (funcptr) & ~(intptr_t)1))
+# define SET_CODE(funcptr,code_addr) \
+ ((void) ((funcptr) = \
+ (void *) (((uintptr_t) (funcptr) & (intptr_t)1) \
+ | (uintptr_t) (code_addr))))
+# define IS(funcptr) ((uintptr_t) (funcptr) & 1)
+# define SET_IS(funcptr,is) \
+ ((void) ((funcptr) = \
+ (void *) (((uintptr_t) (funcptr) & ~(intptr_t)1) | (is))))
+# else
+# define CODE(funcptr) (funcptr)
+# define SET_CODE(funcptr,code_addr) \
+ ((void) ((funcptr) = (void *) (code_addr)))
+# define IS(funcptr) ((void) (funcptr), 0)
+# define SET_IS(funcptr,is) ((void) (funcptr), (void) (is))
+# endif
#else
/* A function pointer points to a 'struct func'. */
# if FUNCPTR_BIAS
structptr_to_funcptr (xcopy_structptr (funcptr_to_structptr (funcptr)))
# define CODE(funcptr) \
((funcptr_to_structptr (funcptr))->code_address)
+# define SET_CODE(funcptr,code_addr) \
+ ((void) (CODE (funcptr) = (code_addr)))
+# define IS(funcptr) ((void) (funcptr), 0)
+# define SET_IS(funcptr,is) ((void) (funcptr), (void) (is))
#endif
/* This test assumes that the code generated by the compiler for the
void const *code_of_return2;
size_t size_of_return1;
size_t size_of_return2;
+ int is_of_return1;
+ int is_of_return2;
#if defined __OpenBSD__ || defined _RET_PROTECTOR
/* OpenBSD maps code with PROT_EXEC (as opposed to PROT_READ | PROT_EXEC).
We need to use predetermined code for 'return1' and 'return2'. */
code_of_return2 = return2_code;
size_of_return1 = sizeof (return1_code);
size_of_return2 = sizeof (return2_code);
+ /* On arm, return1_code and return2_code use the "ARM" instruction set. */
+ is_of_return1 = 0;
+ is_of_return2 = 0;
#else
code_of_return1 = CODE (return1);
code_of_return2 = CODE (return2);
/* We assume that the code is not longer than 64 bytes. */
size_of_return1 = 64;
size_of_return2 = 64;
+ is_of_return1 = IS (return1);
+ is_of_return2 = IS (return2);
#endif
int const pagesize = getpagesize ();
}
int (*f) (void) = COPY_FUNCPTR (return1);
- CODE (f) = start;
+ SET_CODE (f, start);
memcpy (start_rw, code_of_return1, size_of_return1);
+ SET_IS (f, is_of_return1);
clear_cache (start, end);
ASSERT (f () == 1);
memcpy (start_rw, code_of_return2, size_of_return2);
+ SET_IS (f, is_of_return2);
clear_cache (start, end);
ASSERT (f () == 2);