aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2008-05-19 00:40:12 -0400
committerPaul Mundt <lethal@linux-sh.org>2008-07-28 05:10:28 -0400
commit3bc24a1a5441ef621daf737ec93b0a10e8999d59 (patch)
tree09e3e2e8eda617de72f643aa22ba86490b16cd17 /arch/sh
parent9b14ec35f03d89c88cba225add8b6eca15203964 (diff)
sh: Initial ELF FDPIC support.
This adds initial support for ELF FDPIC on MMU-less SH, as per version 0.2 of the ABI definition at: http://www.codesourcery.com/public/docs/sh-fdpic/sh-fdpic-abi.txt Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/kernel/ptrace_32.c23
-rw-r--r--arch/sh/kernel/signal_32.c25
2 files changed, 46 insertions, 2 deletions
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index fddb547f3c2b..2bc72def5cf8 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -241,6 +241,29 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
241 break; 241 break;
242 } 242 }
243#endif 243#endif
244#ifdef CONFIG_BINFMT_ELF_FDPIC
245 case PTRACE_GETFDPIC: {
246 unsigned long tmp = 0;
247
248 switch (addr) {
249 case PTRACE_GETFDPIC_EXEC:
250 tmp = child->mm->context.exec_fdpic_loadmap;
251 break;
252 case PTRACE_GETFDPIC_INTERP:
253 tmp = child->mm->context.interp_fdpic_loadmap;
254 break;
255 default:
256 break;
257 }
258
259 ret = 0;
260 if (put_user(tmp, (unsigned long *) data)) {
261 ret = -EFAULT;
262 break;
263 }
264 break;
265 }
266#endif
244 default: 267 default:
245 ret = ptrace_request(child, request, addr, data); 268 ret = ptrace_request(child, request, addr, data);
246 break; 269 break;
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index f311551d9a05..46170a9a7221 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -33,6 +33,11 @@
33 33
34#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 34#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
35 35
36struct fdpic_func_descriptor {
37 unsigned long text;
38 unsigned long GOT;
39};
40
36/* 41/*
37 * Atomically swap in the new signal mask, and wait for a signal. 42 * Atomically swap in the new signal mask, and wait for a signal.
38 */ 43 */
@@ -378,7 +383,15 @@ static int setup_frame(int sig, struct k_sigaction *ka,
378 regs->regs[4] = signal; /* Arg for signal handler */ 383 regs->regs[4] = signal; /* Arg for signal handler */
379 regs->regs[5] = 0; 384 regs->regs[5] = 0;
380 regs->regs[6] = (unsigned long) &frame->sc; 385 regs->regs[6] = (unsigned long) &frame->sc;
381 regs->pc = (unsigned long) ka->sa.sa_handler; 386
387 if (current->personality & FDPIC_FUNCPTRS) {
388 struct fdpic_func_descriptor __user *funcptr =
389 (struct fdpic_func_descriptor __user *)ka->sa.sa_handler;
390
391 __get_user(regs->pc, &funcptr->text);
392 __get_user(regs->regs[12], &funcptr->GOT);
393 } else
394 regs->pc = (unsigned long)ka->sa.sa_handler;
382 395
383 set_fs(USER_DS); 396 set_fs(USER_DS);
384 397
@@ -458,7 +471,15 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
458 regs->regs[4] = signal; /* Arg for signal handler */ 471 regs->regs[4] = signal; /* Arg for signal handler */
459 regs->regs[5] = (unsigned long) &frame->info; 472 regs->regs[5] = (unsigned long) &frame->info;
460 regs->regs[6] = (unsigned long) &frame->uc; 473 regs->regs[6] = (unsigned long) &frame->uc;
461 regs->pc = (unsigned long) ka->sa.sa_handler; 474
475 if (current->personality & FDPIC_FUNCPTRS) {
476 struct fdpic_func_descriptor __user *funcptr =
477 (struct fdpic_func_descriptor __user *)ka->sa.sa_handler;
478
479 __get_user(regs->pc, &funcptr->text);
480 __get_user(regs->regs[12], &funcptr->GOT);
481 } else
482 regs->pc = (unsigned long)ka->sa.sa_handler;
462 483
463 set_fs(USER_DS); 484 set_fs(USER_DS);
464 485