diff options
author | Younes Manton <ymanton@ca.ibm.com> | 2022-08-30 18:18:21 +0300 |
---|---|---|
committer | Andrei Vagin <avagin@gmail.com> | 2022-10-02 08:42:48 +0300 |
commit | 615763ec2d9777167f934f9e6a6830140a94b4ff (patch) | |
tree | e2852d97254d3948e2d682129a140920f6a61c62 | |
parent | a7cbdcb0382cd3d0dea27f8e5bfed3b0fbf30b8b (diff) |
compel: Fix ppc64le parasite stack layout
The ppc64le ABI allows functions to store data in caller frames.
When initializing the stack pointer prior to executing parasite code
we need to pre-allocating the minimum sized stack frame before
jumping to the parasite code.
Signed-off-by: Younes Manton <ymanton@ca.ibm.com>
-rw-r--r-- | compel/arch/ppc64/src/lib/include/uapi/asm/sigframe.h | 5 | ||||
-rw-r--r-- | compel/arch/ppc64/src/lib/infect.c | 4 |
2 files changed, 7 insertions, 2 deletions
diff --git a/compel/arch/ppc64/src/lib/include/uapi/asm/sigframe.h b/compel/arch/ppc64/src/lib/include/uapi/asm/sigframe.h index eb12c9f7c..8cc94ba74 100644 --- a/compel/arch/ppc64/src/lib/include/uapi/asm/sigframe.h +++ b/compel/arch/ppc64/src/lib/include/uapi/asm/sigframe.h @@ -23,6 +23,11 @@ /* Copied from the Linux kernel header arch/powerpc/include/asm/ptrace.h */ #define USER_REDZONE_SIZE 512 +#if _CALL_ELF != 2 +#error Only supporting ABIv2. +#else +#define STACK_FRAME_MIN_SIZE 32 +#endif /* Copied from the Linux kernel source file arch/powerpc/kernel/signal_64.c */ #define TRAMP_SIZE 6 diff --git a/compel/arch/ppc64/src/lib/infect.c b/compel/arch/ppc64/src/lib/infect.c index 61cd6e985..db999ce37 100644 --- a/compel/arch/ppc64/src/lib/infect.c +++ b/compel/arch/ppc64/src/lib/infect.c @@ -441,13 +441,13 @@ void *remote_mmap(struct parasite_ctl *ctl, void *addr, size_t length, int prot, void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs) { /* - * OpenPOWER ABI requires that r12 is set to the calling function addressi + * OpenPOWER ABI requires that r12 is set to the calling function address * to compute the TOC pointer. */ regs->gpr[12] = new_ip; regs->nip = new_ip; if (stack) - regs->gpr[1] = (unsigned long)stack; + regs->gpr[1] = (unsigned long)stack - STACK_FRAME_MIN_SIZE; regs->trap = 0; } |