Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+35 −15
Original line number Diff line number Diff line
@@ -1086,12 +1086,31 @@ 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.
		if (is_elf2_task()) {
			/* Look ma, no function descriptors! */
			entry = start;

			/*
			 * 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);
@@ -1103,8 +1122,9 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
				entry += load_addr;
				toc   += load_addr;
			}
		regs->nip = entry;
			regs->gpr[2] = toc;
		}
		regs->nip = entry;
		regs->msr = MSR_USER64;
	} else {
		regs->nip = start;