forked from Minki/linux
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>
This commit is contained in:
parent
918d03552e
commit
94af3abf99
@ -1086,25 +1086,45 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
|
||||
regs->msr = MSR_USER;
|
||||
#else
|
||||
if (!is_32bit_task()) {
|
||||
unsigned long entry, toc;
|
||||
unsigned long entry;
|
||||
|
||||
/* 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);
|
||||
if (is_elf2_task()) {
|
||||
/* Look ma, no function descriptors! */
|
||||
entry = start;
|
||||
|
||||
/* 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;
|
||||
/*
|
||||
* 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(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->gpr[2] = toc;
|
||||
regs->msr = MSR_USER64;
|
||||
} else {
|
||||
regs->nip = start;
|
||||
|
Loading…
Reference in New Issue
Block a user