1
0
Fork 0

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: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
hifive-unleashed-5.1
Rusty Russell 2013-11-20 22:15:02 +11:00 committed by Benjamin Herrenschmidt
parent 918d03552e
commit 94af3abf99
1 changed files with 35 additions and 15 deletions

View File

@ -1086,25 +1086,45 @@ 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.
*/
__get_user(entry, (unsigned long __user *)start);
__get_user(toc, (unsigned long __user *)start+1);
/* Check whether the e_entry function descriptor entries /*
* need to be relocated before we can use them. * Ulrich says:
*/ * The latest iteration of the ABI requires that when
if (load_addr != 0) { * calling a function (at its global entry point),
entry += load_addr; * the caller must ensure r12 holds the entry point
toc += load_addr; * 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(toc, (unsigned long __user *)start+1);
/* Check whether the e_entry function descriptor entries
* need to be relocated before we can use them.
*/
if (load_addr != 0) {
entry += load_addr;
toc += load_addr;
}
regs->gpr[2] = toc;
} }
regs->nip = entry; regs->nip = entry;
regs->gpr[2] = toc;
regs->msr = MSR_USER64; regs->msr = MSR_USER64;
} else { } else {
regs->nip = start; regs->nip = start;