Commit 94af3abf authored by Rusty Russell's avatar Rusty Russell Committed by Benjamin Herrenschmidt

powerpc: ELF2 binaries launched directly.

No function descriptor, but we set r12 up and set TIF_RESTOREALL as it
normally isn't restored on return from syscall.
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
Signed-off-by: default avatarAnton Blanchard <anton@samba.org>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 918d0355
...@@ -1086,12 +1086,31 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) ...@@ -1086,12 +1086,31 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
regs->msr = MSR_USER; regs->msr = MSR_USER;
#else #else
if (!is_32bit_task()) { if (!is_32bit_task()) {
unsigned long entry, toc; unsigned long entry;
/* start is a relocated pointer to the function descriptor for if (is_elf2_task()) {
* the elf _start routine. The first entry in the function /* Look ma, no function descriptors! */
* descriptor is the entry address of _start and the second entry = start;
* entry is the TOC value we need to use.
/*
* Ulrich says:
* The latest iteration of the ABI requires that when
* calling a function (at its global entry point),
* the caller must ensure r12 holds the entry point
* address (so that the function can quickly
* establish addressability).
*/
regs->gpr[12] = start;
/* Make sure that's restored on entry to userspace. */
set_thread_flag(TIF_RESTOREALL);
} else {
unsigned long toc;
/* start is a relocated pointer to the function
* descriptor for the elf _start routine. The first
* entry in the function descriptor is the entry
* address of _start and the second entry is the TOC
* value we need to use.
*/ */
__get_user(entry, (unsigned long __user *)start); __get_user(entry, (unsigned long __user *)start);
__get_user(toc, (unsigned long __user *)start+1); __get_user(toc, (unsigned long __user *)start+1);
...@@ -1103,8 +1122,9 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) ...@@ -1103,8 +1122,9 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
entry += load_addr; entry += load_addr;
toc += load_addr; toc += load_addr;
} }
regs->nip = entry;
regs->gpr[2] = toc; regs->gpr[2] = toc;
}
regs->nip = entry;
regs->msr = MSR_USER64; regs->msr = MSR_USER64;
} else { } else {
regs->nip = start; regs->nip = start;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment