Skip to content

Commit beea06f

Browse files
committed
syscalls/mprotect04: Fix for ia64
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]>
1 parent 98d8d3a commit beea06f

File tree

1 file changed

+38
-3
lines changed

1 file changed

+38
-3
lines changed

testcases/kernel/syscalls/mprotect/mprotect04.c

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ static void cleanup(void);
4545

4646
static void testfunc_protnone(void);
4747

48-
static void exec_func(void);
4948
static void testfunc_protexec(void);
5049

5150
static void (*testfunc[])(void) = { testfunc_protnone, testfunc_protexec };
@@ -127,14 +126,51 @@ static void testfunc_protnone(void)
127126
SAFE_MUNMAP(cleanup, addr, page_sz);
128127
}
129128

129+
#ifdef __ia64__
130+
131+
static char exec_func[] = {
132+
0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* nop.m 0x0 */
133+
0x00, 0x00, 0x00, 0x02, 0x00, 0x80, /* nop.i 0x0 */
134+
0x08, 0x00, 0x84, 0x00, /* br.ret.sptk.many b0;; */
135+
};
136+
137+
struct func_desc {
138+
uint64_t func_addr;
139+
uint64_t glob_pointer;
140+
};
141+
142+
static __attribute__((noinline)) void *get_func(void *mem)
143+
{
144+
static struct func_desc fdesc;
145+
146+
memcpy(mem, exec_func, sizeof(exec_func));
147+
148+
fdesc.func_addr = (uint64_t)mem;
149+
fdesc.glob_pointer = 0;
150+
151+
return &fdesc;
152+
}
153+
154+
#else
155+
130156
static void exec_func(void)
131157
{
132158
return;
133159
}
134160

161+
static void *get_func(void *mem)
162+
{
163+
memcpy(mem, exec_func, getpagesize());
164+
165+
return mem;
166+
}
167+
168+
#endif
169+
135170
static void testfunc_protexec(void)
136171
{
137172
int page_sz;
173+
void (*func)(void);
138174
void *p;
139175

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

147-
memcpy(p, exec_func, page_sz);
183+
func = get_func(p);
148184

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

152188
if (TEST_RETURN == -1) {
153189
tst_resm(TFAIL | TTERRNO, "mprotect failed");
154190
} else {
155-
int (*func)(void) = p;
156191
if (sigsetjmp(env, 1) == 0)
157192
(*func)();
158193

0 commit comments

Comments
 (0)