Commit 47f81bc1 authored by Todd Inglett's avatar Todd Inglett

64bit dynamic app fix (still needs binfmt_elf.c patch to work)

parent 6af6a189
...@@ -236,22 +236,30 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, ...@@ -236,22 +236,30 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
/* /*
* Set up a thread for executing a new program * Set up a thread for executing a new program
*/ */
void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp) void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp)
{ {
/* NIP is *really* a pointer to the function descriptor for unsigned long entry, toc, load_addr = regs->gpr[2];
/* fdptr is a relocated pointer to the function descriptor for
* the elf _start routine. The first entry in the function * the elf _start routine. The first entry in the function
* descriptor is the entry address of _start and the second * descriptor is the entry address of _start and the second
* entry is the TOC value we need to use. * entry is the TOC value we need to use.
*/ */
unsigned long *entry = (unsigned long *)nip;
unsigned long *toc = entry + 1;
set_fs(USER_DS); set_fs(USER_DS);
memset(regs->gpr, 0, sizeof(regs->gpr)); __get_user(entry, (unsigned long *)fdptr);
memset(&regs->ctr, 0, 4 * sizeof(regs->ctr)); __get_user(toc, (unsigned long *)fdptr+1);
__get_user(regs->nip, entry);
/* 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->nip = entry;
regs->gpr[1] = sp; regs->gpr[1] = sp;
__get_user(regs->gpr[2], toc); regs->gpr[2] = toc;
regs->msr = MSR_USER64; regs->msr = MSR_USER64;
if (last_task_used_math == current) if (last_task_used_math == current)
last_task_used_math = 0; last_task_used_math = 0;
......
...@@ -599,7 +599,7 @@ GLUE(GLUE(.LT,NAME),_procname_end): ...@@ -599,7 +599,7 @@ GLUE(GLUE(.LT,NAME),_procname_end):
extern int have_of; extern int have_of;
struct task_struct; struct task_struct;
void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp); void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp);
void release_thread(struct task_struct *); void release_thread(struct task_struct *);
/* /*
......
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