Skip to content

Commit d606b92

Browse files
rustyrussellozbenh
authored andcommitted
powerpc: ELF2 binaries signal handling
For the ELFv2 ABI, the hander is the entry point, not a function descriptor. We also need to set up r12, and fortunately the fast_exception_return exit path restores r12 for us so nothing else is required. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Anton Blanchard <anton@samba.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
1 parent 94af3ab commit d606b92

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

arch/powerpc/kernel/signal_64.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -701,12 +701,6 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
701701
int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
702702
sigset_t *set, struct pt_regs *regs)
703703
{
704-
/* Handler is *really* a pointer to the function descriptor for
705-
* the signal routine. The first entry in the function
706-
* descriptor is the entry address of signal and the second
707-
* entry is the TOC value we need to use.
708-
*/
709-
func_descr_t __user *funct_desc_ptr;
710704
struct rt_sigframe __user *frame;
711705
unsigned long newsp = 0;
712706
long err = 0;
@@ -766,19 +760,32 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
766760
goto badframe;
767761
regs->link = (unsigned long) &frame->tramp[0];
768762
}
769-
funct_desc_ptr = (func_descr_t __user *) ka->sa.sa_handler;
770763

771764
/* Allocate a dummy caller frame for the signal handler. */
772765
newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE;
773766
err |= put_user(regs->gpr[1], (unsigned long __user *)newsp);
774767

775768
/* Set up "regs" so we "return" to the signal handler. */
776-
err |= get_user(regs->nip, &funct_desc_ptr->entry);
769+
if (is_elf2_task()) {
770+
regs->nip = (unsigned long) ka->sa.sa_handler;
771+
regs->gpr[12] = regs->nip;
772+
} else {
773+
/* Handler is *really* a pointer to the function descriptor for
774+
* the signal routine. The first entry in the function
775+
* descriptor is the entry address of signal and the second
776+
* entry is the TOC value we need to use.
777+
*/
778+
func_descr_t __user *funct_desc_ptr =
779+
(func_descr_t __user *) ka->sa.sa_handler;
780+
781+
err |= get_user(regs->nip, &funct_desc_ptr->entry);
782+
err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
783+
}
784+
777785
/* enter the signal handler in native-endian mode */
778786
regs->msr &= ~MSR_LE;
779787
regs->msr |= (MSR_KERNEL & MSR_LE);
780788
regs->gpr[1] = newsp;
781-
err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
782789
regs->gpr[3] = signr;
783790
regs->result = 0;
784791
if (ka->sa.sa_flags & SA_SIGINFO) {

0 commit comments

Comments
 (0)