diff options
author | mdodd <mdodd@FreeBSD.org> | 2003-05-11 21:51:11 +0000 |
---|---|---|
committer | mdodd <mdodd@FreeBSD.org> | 2003-05-11 21:51:11 +0000 |
commit | 232af61924775739828ef91d56d57624fdebe2fd (patch) | |
tree | 2b3f9415d22c816190167feb195bd2ff9c5b787b /sys/i386/linux/linux_sysvec.c | |
parent | fac5c1185550eb79eaf647644070d47c7a5ced8f (diff) | |
download | FreeBSD-src-232af61924775739828ef91d56d57624fdebe2fd.zip FreeBSD-src-232af61924775739828ef91d56d57624fdebe2fd.tar.gz |
Provide exec_linux_setregs() to override exec_setregs().
Linux initializes %gs to 0. Mimic this behavior.
Submitted by: Christian Zander <zander@minion.de>
Reviewed by: jake
Approved by: re
Diffstat (limited to 'sys/i386/linux/linux_sysvec.c')
-rw-r--r-- | sys/i386/linux/linux_sysvec.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index 940c238..27105bc 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -111,6 +111,8 @@ static void linux_prepsyscall(struct trapframe *tf, int *args, u_int *code, caddr_t *params); static void linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code); +static void exec_linux_setregs(struct thread *td, u_long entry, + u_long stack, u_long ps_strings); /* * Linux syscalls return negative errno's, we do positive and map them @@ -805,6 +807,23 @@ exec_linux_imgact_try(struct image_params *imgp) return(error); } +/* + * exec_setregs may initialize some registers differently than Linux + * does, thus potentially confusing Linux binaries. If necessary, we + * override the exec_setregs default(s) here. + */ +static void +exec_linux_setregs(struct thread *td, u_long entry, + u_long stack, u_long ps_strings) +{ + struct pcb *pcb = td->td_pcb; + + exec_setregs(td, entry, stack, ps_strings); + + /* Linux sets %gs to 0, we default to _udatasel */ + pcb->pcb_gs = 0; load_gs(0); +} + struct sysentvec linux_sysvec = { LINUX_SYS_MAXSYSCALL, linux_sysent, @@ -830,7 +849,7 @@ struct sysentvec linux_sysvec = { PS_STRINGS, VM_PROT_ALL, exec_copyout_strings, - exec_setregs + exec_linux_setregs }; struct sysentvec elf_linux_sysvec = { @@ -858,7 +877,7 @@ struct sysentvec elf_linux_sysvec = { PS_STRINGS, VM_PROT_ALL, exec_copyout_strings, - exec_setregs + exec_linux_setregs }; static Elf32_Brandinfo linux_brand = { |