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;
|
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;
|
||||||
|
|
Loading…
Reference in a new issue