Skip to content

Commit

Permalink
syscalls/mprotect04: Fix for ia64
Browse files Browse the repository at this point in the history
IA64 ABI calls functions by function descriptors and because of that we
cannot simply copy function address since the address we get in C is
addres of the function descriptor and not the function itself.

Instead of that we copy a code for a minimal function to the mmaped page
and create a function descriptor for it.

Signed-off-by: Cyril Hrubis <[email protected]>
  • Loading branch information
metan-ucw committed Sep 2, 2015
1 parent 98d8d3a commit beea06f
Showing 1 changed file with 38 additions and 3 deletions.
41 changes: 38 additions & 3 deletions testcases/kernel/syscalls/mprotect/mprotect04.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ static void cleanup(void);

static void testfunc_protnone(void);

static void exec_func(void);
static void testfunc_protexec(void);

static void (*testfunc[])(void) = { testfunc_protnone, testfunc_protexec };
Expand Down Expand Up @@ -127,14 +126,51 @@ static void testfunc_protnone(void)
SAFE_MUNMAP(cleanup, addr, page_sz);
}

#ifdef __ia64__

static char exec_func[] = {
0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* nop.m 0x0 */
0x00, 0x00, 0x00, 0x02, 0x00, 0x80, /* nop.i 0x0 */
0x08, 0x00, 0x84, 0x00, /* br.ret.sptk.many b0;; */
};

struct func_desc {
uint64_t func_addr;
uint64_t glob_pointer;
};

static __attribute__((noinline)) void *get_func(void *mem)
{
static struct func_desc fdesc;

memcpy(mem, exec_func, sizeof(exec_func));

fdesc.func_addr = (uint64_t)mem;
fdesc.glob_pointer = 0;

return &fdesc;
}

#else

static void exec_func(void)
{
return;
}

static void *get_func(void *mem)
{
memcpy(mem, exec_func, getpagesize());

return mem;
}

#endif

static void testfunc_protexec(void)
{
int page_sz;
void (*func)(void);
void *p;

sig_caught = 0;
Expand All @@ -144,15 +180,14 @@ static void testfunc_protexec(void)
p = SAFE_MMAP(cleanup, 0, page_sz, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

memcpy(p, exec_func, page_sz);
func = get_func(p);

/* Change the protection to PROT_EXEC. */
TEST(mprotect(p, page_sz, PROT_EXEC));

if (TEST_RETURN == -1) {
tst_resm(TFAIL | TTERRNO, "mprotect failed");
} else {
int (*func)(void) = p;
if (sigsetjmp(env, 1) == 0)
(*func)();

Expand Down

0 comments on commit beea06f

Please sign in to comment.