Date: Fri, 1 Apr 2011 11:44:59 +0000 From: Alexander Best <arundel@freebsd.org> To: Konstantin Belousov <kib@FreeBSD.org> Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r220238 - in head/sys: amd64/ia32 compat/freebsd32 compat/ia32 ia64/ia32 kern modules sys Message-ID: <20110401114459.GA13612@freebsd.org> In-Reply-To: <201104011116.p31BGTx4042314@svn.freebsd.org> References: <201104011116.p31BGTx4042314@svn.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Fri Apr 1 11, Konstantin Belousov wrote: > Author: kib > Date: Fri Apr 1 11:16:29 2011 > New Revision: 220238 > URL: http://svn.freebsd.org/changeset/base/220238 > > Log: > Add support for executing the FreeBSD 1/i386 a.out binaries on amd64. > > In particular: > - implement compat shims for old stat(2) variants and ogetdirentries(2); > - implement delivery of signals with ancient stack frame layout and > corresponding sigreturn(2); > - implement old getpagesize(2); > - provide a user-mode trampoline and LDT call gate for lcall $7,$0; > - port a.out image activator and connect it to the build as a module > on amd64. > > The changes are hidden under COMPAT_43. hmm...for i386 there's # Enable i386 a.out binary support options COMPAT_AOUT why not make this feature dependant upon the same option and not COMPAT_43? ...also i noticed sys/amd/conf/NOTES says: # Enable 32-bit Linux ABI emulation (requires COMPAT_43 and COMPAT_FREEBSD32) options COMPAT_LINUX32 ...i don't think COMPAT_43 is actually necessary to use COMPAT_FREEBSD32, is it? cheers. alex > > MFC after: 1 month > > Modified: > head/sys/amd64/ia32/ia32_misc.c > head/sys/amd64/ia32/ia32_signal.c > head/sys/amd64/ia32/ia32_sigtramp.S > head/sys/amd64/ia32/ia32_syscall.c > head/sys/compat/freebsd32/freebsd32_misc.c > head/sys/compat/freebsd32/syscalls.master > head/sys/compat/ia32/ia32_genassym.c > head/sys/compat/ia32/ia32_signal.h > head/sys/compat/ia32/ia32_sysvec.c > head/sys/compat/ia32/ia32_util.h > head/sys/ia64/ia32/ia32_misc.c > head/sys/ia64/ia32/ia32_signal.c > head/sys/kern/imgact_aout.c > head/sys/kern/vfs_syscalls.c > head/sys/modules/Makefile > head/sys/sys/syscallsubr.h > > Modified: head/sys/amd64/ia32/ia32_misc.c > ============================================================================== > --- head/sys/amd64/ia32/ia32_misc.c Fri Apr 1 06:28:21 2011 (r220237) > +++ head/sys/amd64/ia32/ia32_misc.c Fri Apr 1 11:16:29 2011 (r220238) > @@ -69,3 +69,14 @@ freebsd32_sysarch(struct thread *td, str > return (sysarch(td, &uap1)); > } > } > + > +#ifdef COMPAT_43 > +int > +ofreebsd32_getpagesize(struct thread *td, > + struct ofreebsd32_getpagesize_args *uap) > +{ > + > + td->td_retval[0] = IA32_PAGE_SIZE; > + return (0); > +} > +#endif > > Modified: head/sys/amd64/ia32/ia32_signal.c > ============================================================================== > --- head/sys/amd64/ia32/ia32_signal.c Fri Apr 1 06:28:21 2011 (r220237) > +++ head/sys/amd64/ia32/ia32_signal.c Fri Apr 1 11:16:29 2011 (r220238) > @@ -300,6 +300,109 @@ freebsd32_swapcontext(struct thread *td, > * frame pointer, it returns to the user > * specified pc, psl. > */ > + > +#ifdef COMPAT_43 > +static void > +ia32_osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) > +{ > + struct ia32_sigframe3 sf, *fp; > + struct proc *p; > + struct thread *td; > + struct sigacts *psp; > + struct trapframe *regs; > + int sig; > + int oonstack; > + > + td = curthread; > + p = td->td_proc; > + PROC_LOCK_ASSERT(p, MA_OWNED); > + sig = ksi->ksi_signo; > + psp = p->p_sigacts; > + mtx_assert(&psp->ps_mtx, MA_OWNED); > + regs = td->td_frame; > + oonstack = sigonstack(regs->tf_rsp); > + > + /* Allocate space for the signal handler context. */ > + if ((td->td_pflags & TDP_ALTSTACK) && !oonstack && > + SIGISMEMBER(psp->ps_sigonstack, sig)) { > + fp = (struct ia32_sigframe3 *)(td->td_sigstk.ss_sp + > + td->td_sigstk.ss_size - sizeof(sf)); > + td->td_sigstk.ss_flags |= SS_ONSTACK; > + } else > + fp = (struct ia32_sigframe3 *)regs->tf_rsp - 1; > + > + /* Translate the signal if appropriate. */ > + if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) > + sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; > + > + /* Build the argument list for the signal handler. */ > + sf.sf_signum = sig; > + sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc; > + if (SIGISMEMBER(psp->ps_siginfo, sig)) { > + /* Signal handler installed with SA_SIGINFO. */ > + sf.sf_arg2 = (register_t)&fp->sf_siginfo; > + sf.sf_siginfo.si_signo = sig; > + sf.sf_siginfo.si_code = ksi->ksi_code; > + sf.sf_ah = (uintptr_t)catcher; > + } else { > + /* Old FreeBSD-style arguments. */ > + sf.sf_arg2 = ksi->ksi_code; > + sf.sf_addr = (register_t)ksi->ksi_addr; > + sf.sf_ah = (uintptr_t)catcher; > + } > + mtx_unlock(&psp->ps_mtx); > + PROC_UNLOCK(p); > + > + /* Save most if not all of trap frame. */ > + sf.sf_siginfo.si_sc.sc_eax = regs->tf_rax; > + sf.sf_siginfo.si_sc.sc_ebx = regs->tf_rbx; > + sf.sf_siginfo.si_sc.sc_ecx = regs->tf_rcx; > + sf.sf_siginfo.si_sc.sc_edx = regs->tf_rdx; > + sf.sf_siginfo.si_sc.sc_esi = regs->tf_rsi; > + sf.sf_siginfo.si_sc.sc_edi = regs->tf_rdi; > + sf.sf_siginfo.si_sc.sc_cs = regs->tf_cs; > + sf.sf_siginfo.si_sc.sc_ds = regs->tf_ds; > + sf.sf_siginfo.si_sc.sc_ss = regs->tf_ss; > + sf.sf_siginfo.si_sc.sc_es = regs->tf_es; > + sf.sf_siginfo.si_sc.sc_fs = regs->tf_fs; > + sf.sf_siginfo.si_sc.sc_gs = regs->tf_gs; > + sf.sf_siginfo.si_sc.sc_isp = regs->tf_rsp; > + > + /* Build the signal context to be used by osigreturn(). */ > + sf.sf_siginfo.si_sc.sc_onstack = (oonstack) ? 1 : 0; > + SIG2OSIG(*mask, sf.sf_siginfo.si_sc.sc_mask); > + sf.sf_siginfo.si_sc.sc_esp = regs->tf_rsp; > + sf.sf_siginfo.si_sc.sc_ebp = regs->tf_rbp; > + sf.sf_siginfo.si_sc.sc_eip = regs->tf_rip; > + sf.sf_siginfo.si_sc.sc_eflags = regs->tf_rflags; > + sf.sf_siginfo.si_sc.sc_trapno = regs->tf_trapno; > + sf.sf_siginfo.si_sc.sc_err = regs->tf_err; > + > + /* > + * Copy the sigframe out to the user's stack. > + */ > + if (copyout(&sf, fp, sizeof(*fp)) != 0) { > +#ifdef DEBUG > + printf("process %ld has trashed its stack\n", (long)p->p_pid); > +#endif > + PROC_LOCK(p); > + sigexit(td, SIGILL); > + } > + > + regs->tf_rsp = (uintptr_t)fp; > + regs->tf_rip = p->p_sysent->sv_psstrings - sz_ia32_osigcode; > + regs->tf_rflags &= ~(PSL_T | PSL_D); > + regs->tf_cs = _ucode32sel; > + regs->tf_ds = _udatasel; > + regs->tf_es = _udatasel; > + regs->tf_fs = _udatasel; > + regs->tf_ss = _udatasel; > + set_pcb_flags(td->td_pcb, PCB_FULL_IRET); > + PROC_LOCK(p); > + mtx_lock(&psp->ps_mtx); > +} > +#endif > + > #ifdef COMPAT_FREEBSD4 > static void > freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) > @@ -441,6 +544,12 @@ ia32_sendsig(sig_t catcher, ksiginfo_t * > return; > } > #endif > +#ifdef COMPAT_43 > + if (SIGISMEMBER(psp->ps_osigset, sig)) { > + ia32_osendsig(catcher, ksi, mask); > + return; > + } > +#endif > mtx_assert(&psp->ps_mtx, MA_OWNED); > regs = td->td_frame; > oonstack = sigonstack(regs->tf_rsp); > @@ -547,6 +656,64 @@ ia32_sendsig(sig_t catcher, ksiginfo_t * > * make sure that the user has not modified the > * state to gain improper privileges. > */ > + > +#ifdef COMPAT_43 > +int > +ofreebsd32_sigreturn(struct thread *td, struct ofreebsd32_sigreturn_args *uap) > +{ > + struct ia32_sigcontext3 sc, *scp; > + struct trapframe *regs; > + int eflags, error; > + ksiginfo_t ksi; > + > + regs = td->td_frame; > + error = copyin(uap->sigcntxp, &sc, sizeof(sc)); > + if (error != 0) > + return (error); > + scp = ≻ > + eflags = scp->sc_eflags; > + if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) { > + return (EINVAL); > + } > + if (!CS_SECURE(scp->sc_cs)) { > + ksiginfo_init_trap(&ksi); > + ksi.ksi_signo = SIGBUS; > + ksi.ksi_code = BUS_OBJERR; > + ksi.ksi_trapno = T_PROTFLT; > + ksi.ksi_addr = (void *)regs->tf_rip; > + trapsignal(td, &ksi); > + return (EINVAL); > + } > + regs->tf_ds = scp->sc_ds; > + regs->tf_es = scp->sc_es; > + regs->tf_fs = scp->sc_fs; > + regs->tf_gs = scp->sc_gs; > + > + regs->tf_rax = scp->sc_eax; > + regs->tf_rbx = scp->sc_ebx; > + regs->tf_rcx = scp->sc_ecx; > + regs->tf_rdx = scp->sc_edx; > + regs->tf_rsi = scp->sc_esi; > + regs->tf_rdi = scp->sc_edi; > + regs->tf_cs = scp->sc_cs; > + regs->tf_ss = scp->sc_ss; > + regs->tf_rbp = scp->sc_ebp; > + regs->tf_rsp = scp->sc_esp; > + regs->tf_rip = scp->sc_eip; > + regs->tf_rflags = eflags; > + > + if (scp->sc_onstack & 1) > + td->td_sigstk.ss_flags |= SS_ONSTACK; > + else > + td->td_sigstk.ss_flags &= ~SS_ONSTACK; > + > + kern_sigprocmask(td, SIG_SETMASK, (sigset_t *)&scp->sc_mask, NULL, > + SIGPROCMASK_OLD); > + set_pcb_flags(td->td_pcb, PCB_FULL_IRET); > + return (EJUSTRETURN); > +} > +#endif > + > #ifdef COMPAT_FREEBSD4 > /* > * MPSAFE > @@ -734,6 +901,9 @@ ia32_setregs(struct thread *td, struct i > user_ldt_free(td); > else > mtx_unlock(&dt_lock); > +#ifdef COMPAT_43 > + setup_lcall_gate(); > +#endif > > pcb->pcb_fsbase = 0; > pcb->pcb_gsbase = 0; > > Modified: head/sys/amd64/ia32/ia32_sigtramp.S > ============================================================================== > --- head/sys/amd64/ia32/ia32_sigtramp.S Fri Apr 1 06:28:21 2011 (r220237) > +++ head/sys/amd64/ia32/ia32_sigtramp.S Fri Apr 1 11:16:29 2011 (r220238) > @@ -66,6 +66,35 @@ freebsd4_ia32_sigcode: > jmp 1b > #endif > > +#ifdef COMPAT_43 > + ALIGN_TEXT > +ia32_osigcode: > + calll *IA32_SIGF_HANDLER(%esp)/* call signal handler */ > + leal IA32_SIGF_SC(%esp),%eax /* get sigcontext */ > + pushl %eax > + movl $103,%eax /* 3.x SYS_sigreturn */ > + pushl %eax /* junk to fake return addr. */ > + int $0x80 /* enter kernel with args */ > +1: > + jmp 1b > + > + > + ALIGN_TEXT > +lcall_tramp: > + pushl %ebp > + movl %esp,%ebp > + pushl 0x24(%ebp) /* arg 6 */ > + pushl 0x20(%ebp) > + pushl 0x1c(%ebp) > + pushl 0x18(%ebp) > + pushl 0x14(%ebp) > + pushl 0x10(%ebp) /* arg 1 */ > + pushl 0xc(%ebp) /* gap */ > + int $0x80 > + leave > + lretl > +#endif > + > ALIGN_TEXT > esigcode: > > @@ -78,3 +107,11 @@ sz_ia32_sigcode: > sz_freebsd4_ia32_sigcode: > .long esigcode-freebsd4_ia32_sigcode > #endif > +#ifdef COMPAT_43 > + .globl sz_ia32_osigcode > +sz_ia32_osigcode: > + .long esigcode-ia32_osigcode > + .globl sz_lcall_tramp > +sz_lcall_tramp: > + .long esigcode-lcall_tramp > +#endif > > Modified: head/sys/amd64/ia32/ia32_syscall.c > ============================================================================== > --- head/sys/amd64/ia32/ia32_syscall.c Fri Apr 1 06:28:21 2011 (r220237) > +++ head/sys/amd64/ia32/ia32_syscall.c Fri Apr 1 11:16:29 2011 (r220238) > @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); > */ > > #include "opt_clock.h" > +#include "opt_compat.h" > #include "opt_cpu.h" > #include "opt_isa.h" > > @@ -78,7 +79,17 @@ __FBSDID("$FreeBSD$"); > #include <machine/intr_machdep.h> > #include <machine/md_var.h> > > +#include <compat/freebsd32/freebsd32_signal.h> > #include <compat/freebsd32/freebsd32_util.h> > +#include <compat/ia32/ia32_signal.h> > +#include <machine/psl.h> > +#include <machine/segments.h> > +#include <machine/specialreg.h> > +#include <machine/sysarch.h> > +#include <machine/frame.h> > +#include <machine/md_var.h> > +#include <machine/pcb.h> > +#include <machine/cpufunc.h> > > #define IDTVEC(name) __CONCAT(X,name) > > @@ -198,3 +209,45 @@ ia32_syscall_disable(void *dummy) > > SYSINIT(ia32_syscall, SI_SUB_EXEC, SI_ORDER_ANY, ia32_syscall_enable, NULL); > SYSUNINIT(ia32_syscall, SI_SUB_EXEC, SI_ORDER_ANY, ia32_syscall_disable, NULL); > + > +#ifdef COMPAT_43 > +int > +setup_lcall_gate(void) > +{ > + struct i386_ldt_args uap; > + struct user_segment_descriptor descs[2]; > + struct gate_descriptor *ssd; > + uint32_t lcall_addr; > + int error; > + > + bzero(&uap, sizeof(uap)); > + uap.start = 0; > + uap.num = 2; > + > + /* > + * This is the easiest way to cut the space for system > + * descriptor in ldt. Manually adjust the descriptor type to > + * the call gate later. > + */ > + bzero(&descs[0], sizeof(descs)); > + descs[0].sd_type = SDT_SYSNULL; > + descs[1].sd_type = SDT_SYSNULL; > + error = amd64_set_ldt(curthread, &uap, descs); > + if (error != 0) > + return (error); > + > + lcall_addr = curproc->p_sysent->sv_psstrings - sz_lcall_tramp; > + mtx_lock(&dt_lock); > + ssd = (struct gate_descriptor *)(curproc->p_md.md_ldt->ldt_base); > + bzero(ssd, sizeof(*ssd)); > + ssd->gd_looffset = lcall_addr; > + ssd->gd_hioffset = lcall_addr >> 16; > + ssd->gd_selector = _ucode32sel; > + ssd->gd_type = SDT_SYSCGT; > + ssd->gd_dpl = SEL_UPL; > + ssd->gd_p = 1; > + mtx_unlock(&dt_lock); > + > + return (0); > +} > +#endif > > Modified: head/sys/compat/freebsd32/freebsd32_misc.c > ============================================================================== > --- head/sys/compat/freebsd32/freebsd32_misc.c Fri Apr 1 06:28:21 2011 (r220237) > +++ head/sys/compat/freebsd32/freebsd32_misc.c Fri Apr 1 11:16:29 2011 (r220238) > @@ -1454,6 +1454,29 @@ freebsd32_ftruncate(struct thread *td, s > return (ftruncate(td, &ap)); > } > > +#ifdef COMPAT_43 > +int > +ofreebsd32_getdirentries(struct thread *td, > + struct ofreebsd32_getdirentries_args *uap) > +{ > + struct ogetdirentries_args ap; > + int error; > + long loff; > + int32_t loff_cut; > + > + ap.fd = uap->fd; > + ap.buf = uap->buf; > + ap.count = uap->count; > + ap.basep = NULL; > + error = kern_ogetdirentries(td, &ap, &loff); > + if (error == 0) { > + loff_cut = loff; > + error = copyout(&loff_cut, uap->basep, sizeof(int32_t)); > + } > + return (error); > +} > +#endif > + > int > freebsd32_getdirentries(struct thread *td, > struct freebsd32_getdirentries_args *uap) > @@ -1638,6 +1661,29 @@ copy_stat(struct stat *in, struct stat32 > TS_CP(*in, *out, st_birthtim); > } > > +#ifdef COMPAT_43 > +static void > +copy_ostat(struct stat *in, struct ostat32 *out) > +{ > + > + CP(*in, *out, st_dev); > + CP(*in, *out, st_ino); > + CP(*in, *out, st_mode); > + CP(*in, *out, st_nlink); > + CP(*in, *out, st_uid); > + CP(*in, *out, st_gid); > + CP(*in, *out, st_rdev); > + CP(*in, *out, st_size); > + TS_CP(*in, *out, st_atim); > + TS_CP(*in, *out, st_mtim); > + TS_CP(*in, *out, st_ctim); > + CP(*in, *out, st_blksize); > + CP(*in, *out, st_blocks); > + CP(*in, *out, st_flags); > + CP(*in, *out, st_gen); > +} > +#endif > + > int > freebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap) > { > @@ -1653,6 +1699,23 @@ freebsd32_stat(struct thread *td, struct > return (error); > } > > +#ifdef COMPAT_43 > +int > +ofreebsd32_stat(struct thread *td, struct ofreebsd32_stat_args *uap) > +{ > + struct stat sb; > + struct ostat32 sb32; > + int error; > + > + error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); > + if (error) > + return (error); > + copy_ostat(&sb, &sb32); > + error = copyout(&sb32, uap->ub, sizeof (sb32)); > + return (error); > +} > +#endif > + > int > freebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap) > { > @@ -1668,6 +1731,23 @@ freebsd32_fstat(struct thread *td, struc > return (error); > } > > +#ifdef COMPAT_43 > +int > +ofreebsd32_fstat(struct thread *td, struct ofreebsd32_fstat_args *uap) > +{ > + struct stat ub; > + struct ostat32 ub32; > + int error; > + > + error = kern_fstat(td, uap->fd, &ub); > + if (error) > + return (error); > + copy_ostat(&ub, &ub32); > + error = copyout(&ub32, uap->ub, sizeof(ub32)); > + return (error); > +} > +#endif > + > int > freebsd32_fstatat(struct thread *td, struct freebsd32_fstatat_args *uap) > { > @@ -1698,9 +1778,23 @@ freebsd32_lstat(struct thread *td, struc > return (error); > } > > -/* > - * MPSAFE > - */ > +#ifdef COMPAT_43 > +int > +ofreebsd32_lstat(struct thread *td, struct ofreebsd32_lstat_args *uap) > +{ > + struct stat sb; > + struct ostat32 sb32; > + int error; > + > + error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); > + if (error) > + return (error); > + copy_ostat(&sb, &sb32); > + error = copyout(&sb32, uap->ub, sizeof (sb32)); > + return (error); > +} > +#endif > + > int > freebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap) > { > > Modified: head/sys/compat/freebsd32/syscalls.master > ============================================================================== > --- head/sys/compat/freebsd32/syscalls.master Fri Apr 1 06:28:21 2011 (r220237) > +++ head/sys/compat/freebsd32/syscalls.master Fri Apr 1 11:16:29 2011 (r220238) > @@ -117,9 +117,11 @@ > 35 AUE_FCHFLAGS NOPROTO { int fchflags(int fd, int flags); } > 36 AUE_SYNC NOPROTO { int sync(void); } > 37 AUE_KILL NOPROTO { int kill(int pid, int signum); } > -38 AUE_STAT UNIMPL ostat > +38 AUE_STAT COMPAT { int freebsd32_stat(char *path, \ > + struct ostat32 *ub); } > 39 AUE_GETPPID NOPROTO { pid_t getppid(void); } > -40 AUE_LSTAT UNIMPL olstat > +40 AUE_LSTAT COMPAT { int freebsd32_lstat(char *path, \ > + struct ostat *ub); } > 41 AUE_DUP NOPROTO { int dup(u_int fd); } > 42 AUE_PIPE NOPROTO { int pipe(void); } > 43 AUE_GETEGID NOPROTO { gid_t getegid(void); } > @@ -153,9 +155,11 @@ > 60 AUE_UMASK NOPROTO { int umask(int newmask); } umask \ > umask_args int > 61 AUE_CHROOT NOPROTO { int chroot(char *path); } > -62 AUE_FSTAT OBSOL ofstat > +62 AUE_FSTAT COMPAT { int freebsd32_fstat(int fd, \ > + struct ostat32 *ub); } > 63 AUE_NULL OBSOL ogetkerninfo > -64 AUE_NULL OBSOL ogetpagesize > +64 AUE_NULL COMPAT { int freebsd32_getpagesize( \ > + int32_t dummy); } > 65 AUE_MSYNC NOPROTO { int msync(void *addr, size_t len, \ > int flags); } > 66 AUE_VFORK NOPROTO { int vfork(void); } > @@ -210,7 +214,8 @@ > 100 AUE_GETPRIORITY NOPROTO { int getpriority(int which, int who); } > 101 AUE_NULL OBSOL osend > 102 AUE_NULL OBSOL orecv > -103 AUE_NULL OBSOL osigreturn > +103 AUE_NULL COMPAT { int freebsd32_sigreturn( \ > + struct ia32_sigcontext3 *sigcntxp); } > 104 AUE_BIND NOPROTO { int bind(int s, caddr_t name, \ > int namelen); } > 105 AUE_SETSOCKOPT NOPROTO { int setsockopt(int s, int level, \ > @@ -292,7 +297,8 @@ > ; 155 is initialized by the NFS code, if present. > ; XXX this is a problem!!! > 155 AUE_NFS_SVC UNIMPL nfssvc > -156 AUE_GETDIRENTRIES OBSOL ogetdirentries > +156 AUE_GETDIRENTRIES COMPAT { int freebsd32_getdirentries(int fd, \ > + char *buf, u_int count, uint32_t *basep); } > 157 AUE_STATFS COMPAT4 { int freebsd32_statfs(char *path, \ > struct statfs32 *buf); } > 158 AUE_FSTATFS COMPAT4 { int freebsd32_fstatfs(int fd, \ > > Modified: head/sys/compat/ia32/ia32_genassym.c > ============================================================================== > --- head/sys/compat/ia32/ia32_genassym.c Fri Apr 1 06:28:21 2011 (r220237) > +++ head/sys/compat/ia32/ia32_genassym.c Fri Apr 1 11:16:29 2011 (r220238) > @@ -13,6 +13,9 @@ __FBSDID("$FreeBSD$"); > > ASSYM(IA32_SIGF_HANDLER, offsetof(struct ia32_sigframe, sf_ah)); > ASSYM(IA32_SIGF_UC, offsetof(struct ia32_sigframe, sf_uc)); > +#ifdef COMPAT_43 > +ASSYM(IA32_SIGF_SC, offsetof(struct ia32_sigframe3, sf_siginfo.si_sc)); > +#endif > ASSYM(IA32_UC_GS, offsetof(struct ia32_ucontext, uc_mcontext.mc_gs)); > ASSYM(IA32_UC_FS, offsetof(struct ia32_ucontext, uc_mcontext.mc_fs)); > ASSYM(IA32_UC_ES, offsetof(struct ia32_ucontext, uc_mcontext.mc_es)); > > Modified: head/sys/compat/ia32/ia32_signal.h > ============================================================================== > --- head/sys/compat/ia32/ia32_signal.h Fri Apr 1 06:28:21 2011 (r220237) > +++ head/sys/compat/ia32/ia32_signal.h Fri Apr 1 11:16:29 2011 (r220238) > @@ -112,7 +112,7 @@ struct ia32_ucontext4 { > }; > #endif > > -#ifdef COMPAT_FREEBSD3 > +#ifdef COMPAT_43 > struct ia32_sigcontext3 { > u_int32_t sc_onstack; > u_int32_t sc_mask; > @@ -165,7 +165,7 @@ struct ia32_sigframe { > struct siginfo32 sf_si; /* = *sf_siginfo (SA_SIGINFO case) */ > }; > > -#ifdef COMPAT_FREEBSD3 > +#ifdef COMPAT_43 > struct ia32_siginfo3 { > struct ia32_sigcontext3 si_sc; > int si_signo; > @@ -186,10 +186,15 @@ struct ksiginfo; > struct image_params; > extern char ia32_sigcode[]; > extern char freebsd4_ia32_sigcode[]; > +extern char ia32_osigcode[]; > +extern char lcall_tramp; > extern int sz_ia32_sigcode; > extern int sz_freebsd4_ia32_sigcode; > -extern void ia32_sendsig(sig_t, struct ksiginfo *, sigset_t *); > -extern void ia32_setregs(struct thread *td, struct image_params *imgp, > +extern int sz_ia32_osigcode; > +extern int sz_lcall_tramp; > +void ia32_sendsig(sig_t, struct ksiginfo *, sigset_t *); > +void ia32_setregs(struct thread *td, struct image_params *imgp, > u_long stack); > +int setup_lcall_gate(void); > > #endif > > Modified: head/sys/compat/ia32/ia32_sysvec.c > ============================================================================== > --- head/sys/compat/ia32/ia32_sysvec.c Fri Apr 1 06:28:21 2011 (r220237) > +++ head/sys/compat/ia32/ia32_sysvec.c Fri Apr 1 11:16:29 2011 (r220238) > @@ -95,14 +95,12 @@ CTASSERT(sizeof(struct ia32_sigframe4) = > > extern const char *freebsd32_syscallnames[]; > > -static void ia32_fixlimit(struct rlimit *rl, int which); > - > SYSCTL_NODE(_compat, OID_AUTO, ia32, CTLFLAG_RW, 0, "ia32 mode"); > > static u_long ia32_maxdsiz = IA32_MAXDSIZ; > SYSCTL_ULONG(_compat_ia32, OID_AUTO, maxdsiz, CTLFLAG_RW, &ia32_maxdsiz, 0, ""); > TUNABLE_ULONG("compat.ia32.maxdsiz", &ia32_maxdsiz); > -static u_long ia32_maxssiz = IA32_MAXSSIZ; > +u_long ia32_maxssiz = IA32_MAXSSIZ; > SYSCTL_ULONG(_compat_ia32, OID_AUTO, maxssiz, CTLFLAG_RW, &ia32_maxssiz, 0, ""); > TUNABLE_ULONG("compat.ia32.maxssiz", &ia32_maxssiz); > static u_long ia32_maxvmem = IA32_MAXVMEM; > @@ -206,7 +204,7 @@ elf32_dump_thread(struct thread *td __un > { > } > > -static void > +void > ia32_fixlimit(struct rlimit *rl, int which) > { > > > Modified: head/sys/compat/ia32/ia32_util.h > ============================================================================== > --- head/sys/compat/ia32/ia32_util.h Fri Apr 1 06:28:21 2011 (r220237) > +++ head/sys/compat/ia32/ia32_util.h Fri Apr 1 11:16:29 2011 (r220238) > @@ -58,5 +58,6 @@ > struct syscall_args; > int ia32_fetch_syscall_args(struct thread *td, struct syscall_args *sa); > void ia32_set_syscall_retval(struct thread *, int); > +void ia32_fixlimit(struct rlimit *rl, int which); > > #endif > > Modified: head/sys/ia64/ia32/ia32_misc.c > ============================================================================== > --- head/sys/ia64/ia32/ia32_misc.c Fri Apr 1 06:28:21 2011 (r220237) > +++ head/sys/ia64/ia32/ia32_misc.c Fri Apr 1 11:16:29 2011 (r220238) > @@ -48,3 +48,14 @@ freebsd32_sysarch(struct thread *td, str > > return (EOPNOTSUPP); > } > + > +#ifdef COMPAT_43 > +int > +ofreebsd32_getpagesize(struct thread *td, > + struct ofreebsd32_getpagesize_args *uap) > +{ > + > + td->td_retval[0] = IA32_PAGE_SIZE; > + return (0); > +} > +#endif > > Modified: head/sys/ia64/ia32/ia32_signal.c > ============================================================================== > --- head/sys/ia64/ia32/ia32_signal.c Fri Apr 1 06:28:21 2011 (r220237) > +++ head/sys/ia64/ia32/ia32_signal.c Fri Apr 1 11:16:29 2011 (r220238) > @@ -92,6 +92,15 @@ x) */ > }; > int sz_ia32_sigcode = sizeof(ia32_sigcode); > > +#ifdef COMPAT_43 > +int > +ofreebsd32_sigreturn(struct thread *td, struct ofreebsd32_sigreturn_args *uap) > +{ > + > + return (EOPNOTSUPP); > +} > +#endif > + > /* > * Signal sending has not been implemented on ia64. This causes > * the sigtramp code to not understand the arguments and the application > > Modified: head/sys/kern/imgact_aout.c > ============================================================================== > --- head/sys/kern/imgact_aout.c Fri Apr 1 06:28:21 2011 (r220237) > +++ head/sys/kern/imgact_aout.c Fri Apr 1 11:16:29 2011 (r220238) > @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); > #include <sys/imgact.h> > #include <sys/imgact_aout.h> > #include <sys/kernel.h> > +#include <sys/limits.h> > #include <sys/lock.h> > #include <sys/malloc.h> > #include <sys/mutex.h> > @@ -52,9 +53,18 @@ __FBSDID("$FreeBSD$"); > #include <vm/vm_object.h> > #include <vm/vm_param.h> > > +#ifdef __amd64__ > +#include <compat/freebsd32/freebsd32_signal.h> > +#include <compat/freebsd32/freebsd32_util.h> > +#include <compat/freebsd32/freebsd32_proto.h> > +#include <compat/freebsd32/freebsd32_syscall.h> > +#include <compat/ia32/ia32_signal.h> > +#endif > + > static int exec_aout_imgact(struct image_params *imgp); > static int aout_fixup(register_t **stack_base, struct image_params *imgp); > > +#if defined(__i386__) > struct sysentvec aout_sysvec = { > .sv_size = SYS_MAXSYSCALL, > .sv_table = sysent, > @@ -83,31 +93,69 @@ struct sysentvec aout_sysvec = { > .sv_setregs = exec_setregs, > .sv_fixlimit = NULL, > .sv_maxssiz = NULL, > - .sv_flags = SV_ABI_FREEBSD | SV_AOUT | > -#if defined(__i386__) > - SV_IA32 | SV_ILP32 > -#else > -#error Choose SV_XXX flags for the platform > -#endif > - , > + .sv_flags = SV_ABI_FREEBSD | SV_AOUT | SV_IA32 | SV_ILP32, > .sv_set_syscall_retval = cpu_set_syscall_retval, > .sv_fetch_syscall_args = cpu_fetch_syscall_args, > .sv_syscallnames = syscallnames, > .sv_schedtail = NULL, > }; > > +#elif defined(__amd64__) > + > +#define AOUT32_USRSTACK 0xbfc0000 > +#define AOUT32_PS_STRINGS \ > + (AOUT32_USRSTACK - sizeof(struct freebsd32_ps_strings)) > + > +extern const char *freebsd32_syscallnames[]; > +extern u_long ia32_maxssiz; > + > +struct sysentvec aout_sysvec = { > + .sv_size = FREEBSD32_SYS_MAXSYSCALL, > + .sv_table = freebsd32_sysent, > + .sv_mask = 0, > + .sv_sigsize = 0, > + .sv_sigtbl = NULL, > + .sv_errsize = 0, > + .sv_errtbl = NULL, > + .sv_transtrap = NULL, > + .sv_fixup = aout_fixup, > + .sv_sendsig = ia32_sendsig, > + .sv_sigcode = ia32_sigcode, > + .sv_szsigcode = &sz_ia32_sigcode, > + .sv_prepsyscall = NULL, > + .sv_name = "FreeBSD a.out", > + .sv_coredump = NULL, > + .sv_imgact_try = NULL, > + .sv_minsigstksz = MINSIGSTKSZ, > + .sv_pagesize = IA32_PAGE_SIZE, > + .sv_minuser = 0, > + .sv_maxuser = AOUT32_USRSTACK, > + .sv_usrstack = AOUT32_USRSTACK, > + .sv_psstrings = AOUT32_PS_STRINGS, > + .sv_stackprot = VM_PROT_ALL, > + .sv_copyout_strings = freebsd32_copyout_strings, > + .sv_setregs = ia32_setregs, > + .sv_fixlimit = ia32_fixlimit, > + .sv_maxssiz = &ia32_maxssiz, > + .sv_flags = SV_ABI_FREEBSD | SV_AOUT | SV_IA32 | SV_ILP32, > + .sv_set_syscall_retval = ia32_set_syscall_retval, > + .sv_fetch_syscall_args = ia32_fetch_syscall_args, > + .sv_syscallnames = freebsd32_syscallnames, > +}; > +#else > +#error "Port me" > +#endif > + > static int > -aout_fixup(stack_base, imgp) > - register_t **stack_base; > - struct image_params *imgp; > +aout_fixup(register_t **stack_base, struct image_params *imgp) > { > > - return (suword(--(*stack_base), imgp->args->argc)); > + *(char **)stack_base -= sizeof(uint32_t); > + return (suword(*stack_base, imgp->args->argc)); > } > > static int > -exec_aout_imgact(imgp) > - struct image_params *imgp; > +exec_aout_imgact(struct image_params *imgp) > { > const struct exec *a_out = (const struct exec *) imgp->image_header; > struct vmspace *vmspace; > @@ -175,7 +223,14 @@ exec_aout_imgact(imgp) > a_out->a_entry >= virtual_offset + a_out->a_text || > > /* text and data size must each be page rounded */ > - a_out->a_text & PAGE_MASK || a_out->a_data & PAGE_MASK) > + a_out->a_text & PAGE_MASK || a_out->a_data & PAGE_MASK > + > +#ifdef __amd64__ > + || > + /* overflows */ > + virtual_offset + a_out->a_text + a_out->a_data + bss_size > UINT_MAX > +#endif > + ) > return (-1); > > /* text + data can't exceed file size */ > > Modified: head/sys/kern/vfs_syscalls.c > ============================================================================== > --- head/sys/kern/vfs_syscalls.c Fri Apr 1 06:28:21 2011 (r220237) > +++ head/sys/kern/vfs_syscalls.c Fri Apr 1 11:16:29 2011 (r220238) > @@ -3898,14 +3898,20 @@ struct ogetdirentries_args { > }; > #endif > int > -ogetdirentries(td, uap) > - struct thread *td; > - register struct ogetdirentries_args /* { > - int fd; > - char *buf; > - u_int count; > - long *basep; > - } */ *uap; > +ogetdirentries(struct thread *td, struct ogetdirentries_args *uap) > +{ > + long loff; > + int error; > + > + error = kern_ogetdirentries(td, uap, &loff); > + if (error == 0) > + error = copyout(&loff, uap->basep, sizeof(long)); > + return (error); > +} > + > +int > +kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap, > + long *ploff) > { > struct vnode *vp; > struct file *fp; > @@ -4024,9 +4030,10 @@ unionread: > } > VOP_UNLOCK(vp, 0); > VFS_UNLOCK_GIANT(vfslocked); > - error = copyout(&loff, uap->basep, sizeof(long)); > fdrop(fp, td); > td->td_retval[0] = uap->count - auio.uio_resid; > + if (error == 0) > + *ploff = loff; > return (error); > } > #endif /* COMPAT_43 */ > > Modified: head/sys/modules/Makefile > ============================================================================== > --- head/sys/modules/Makefile Fri Apr 1 06:28:21 2011 (r220237) > +++ head/sys/modules/Makefile Fri Apr 1 11:16:29 2011 (r220238) > @@ -518,6 +518,7 @@ _snc= snc > > .if ${MACHINE_CPUARCH} == "amd64" > _aac= aac > +_aout= aout > _acpi= acpi > .if ${MK_CRYPT} != "no" || defined(ALL_MODULES) > _aesni= aesni > > Modified: head/sys/sys/syscallsubr.h > ============================================================================== > --- head/sys/sys/syscallsubr.h Fri Apr 1 06:28:21 2011 (r220237) > +++ head/sys/sys/syscallsubr.h Fri Apr 1 11:16:29 2011 (r220238) > @@ -52,6 +52,7 @@ struct kld_file_stat; > struct ksiginfo; > struct sendfile_args; > struct thr_param; > +struct ogetdirentries_args; > > int kern___getcwd(struct thread *td, u_char *buf, enum uio_seg bufseg, > u_int buflen); > @@ -143,6 +144,8 @@ int kern_msgsnd(struct thread *, int, co > int kern_msgrcv(struct thread *, int, void *, size_t, long, int, long *); > int kern_nanosleep(struct thread *td, struct timespec *rqt, > struct timespec *rmt); > +int kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap, > + long *ploff); > int kern_open(struct thread *td, char *path, enum uio_seg pathseg, > int flags, int mode); > int kern_openat(struct thread *td, int fd, char *path, -- a13x
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20110401114459.GA13612>