1/*- 2 * Copyright (c) 1994-1996 S��ren Schmidt 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 13 unchanged lines hidden (view full) --- 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: stable/10/sys/i386/linux/linux_sysvec.c 293514 2016-01-09 15:44:38Z dchagin $"); |
31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/exec.h> 35#include <sys/fcntl.h> 36#include <sys/imgact.h> 37#include <sys/imgact_aout.h> 38#include <sys/imgact_elf.h> --- 27 unchanged lines hidden (view full) --- 66#include <i386/linux/linux_proto.h> 67#include <compat/linux/linux_emul.h> 68#include <compat/linux/linux_futex.h> 69#include <compat/linux/linux_ioctl.h> 70#include <compat/linux/linux_mib.h> 71#include <compat/linux/linux_misc.h> 72#include <compat/linux/linux_signal.h> 73#include <compat/linux/linux_util.h> |
74#include <compat/linux/linux_vdso.h> |
75 76MODULE_VERSION(linux, 1); 77 78MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures"); 79 80#if BYTE_ORDER == LITTLE_ENDIAN 81#define SHELLMAGIC 0x2123 /* #! */ 82#else --- 6 unchanged lines hidden (view full) --- 89 * to syscall 0. This is slightly less bogus than using 90 * ldebug(sigreturn). 91 */ 92#define LINUX_SYS_linux_rt_sendsig 0 93#define LINUX_SYS_linux_sendsig 0 94 95#define LINUX_PS_STRINGS (LINUX_USRSTACK - sizeof(struct ps_strings)) 96 |
97static int linux_szsigcode; 98static vm_object_t linux_shared_page_obj; 99static char *linux_shared_page_mapping; 100extern char _binary_linux_locore_o_start; 101extern char _binary_linux_locore_o_end; |
102 103extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL]; 104 105SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler); 106SET_DECLARE(linux_device_handler_set, struct linux_device_handler); 107 108static int linux_fixup(register_t **stack_base, 109 struct image_params *iparams); 110static int elf_linux_fixup(register_t **stack_base, 111 struct image_params *iparams); 112static void linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask); 113static void exec_linux_setregs(struct thread *td, 114 struct image_params *imgp, u_long stack); 115static register_t *linux_copyout_strings(struct image_params *imgp); 116static boolean_t linux_trans_osrel(const Elf_Note *note, int32_t *osrel); |
117static void linux_vdso_install(void *param); 118static void linux_vdso_deinstall(void *param); |
119 120static int linux_szplatform; 121const char *linux_platform; 122 123static eventhandler_tag linux_exit_tag; 124static eventhandler_tag linux_exec_tag; 125static eventhandler_tag linux_thread_dtor_tag; 126 --- 73 unchanged lines hidden (view full) --- 200 19, /* 29 T_XMMFLT */ 201 15 /* 30 T_RESERVED */ 202}; 203#define bsd_to_linux_trapcode(code) \ 204 ((code)<sizeof(_bsd_to_linux_trapcode)/sizeof(*_bsd_to_linux_trapcode)? \ 205 _bsd_to_linux_trapcode[(code)]: \ 206 LINUX_T_UNKNOWN) 207 |
208LINUX_VDSO_SYM_INTPTR(linux_sigcode); 209LINUX_VDSO_SYM_INTPTR(linux_rt_sigcode); 210LINUX_VDSO_SYM_INTPTR(linux_vsyscall); 211 |
212/* 213 * If FreeBSD & Linux have a difference of opinion about what a trap 214 * means, deal with it here. 215 * 216 * MPSAFE 217 */ 218static int 219translate_traps(int signal, int trap_code) --- 40 unchanged lines hidden (view full) --- 260 ("unsafe elf_linux_fixup(), should be curproc")); 261 262 p = imgp->proc; 263 arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings; 264 uplatform = (Elf32_Addr *)((caddr_t)arginfo - linux_szplatform); 265 args = (Elf32_Auxargs *)imgp->auxargs; 266 pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2); 267 |
268 AUXARGS_ENTRY(pos, LINUX_AT_SYSINFO_EHDR, 269 imgp->proc->p_sysent->sv_shared_page_base); 270 AUXARGS_ENTRY(pos, LINUX_AT_SYSINFO, linux_vsyscall); |
271 AUXARGS_ENTRY(pos, LINUX_AT_HWCAP, cpu_feature); 272 273 /* 274 * Do not export AT_CLKTCK when emulating Linux kernel prior to 2.4.0, 275 * as it has appeared in the 2.4.0-rc7 first time. 276 * Being exported, AT_CLKTCK is returned by sysconf(_SC_CLK_TCK), 277 * glibc falls back to the hard-coded CLK_TCK value when aux entry 278 * is not present. --- 128 unchanged lines hidden (view full) --- 407 } 408 409 /* end of vector table is a null pointer */ 410 suword(vectp, 0); 411 412 return (stack_base); 413} 414 |
415static void 416linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) 417{ 418 struct thread *td = curthread; 419 struct proc *p = td->td_proc; 420 struct sigacts *psp; 421 struct trapframe *regs; 422 struct l_rt_sigframe *fp, frame; --- 59 unchanged lines hidden (view full) --- 482 frame.sf_sc.uc_mcontext.sc_gs = rgs(); 483 frame.sf_sc.uc_mcontext.sc_fs = regs->tf_fs; 484 frame.sf_sc.uc_mcontext.sc_es = regs->tf_es; 485 frame.sf_sc.uc_mcontext.sc_ds = regs->tf_ds; 486 frame.sf_sc.uc_mcontext.sc_edi = regs->tf_edi; 487 frame.sf_sc.uc_mcontext.sc_esi = regs->tf_esi; 488 frame.sf_sc.uc_mcontext.sc_ebp = regs->tf_ebp; 489 frame.sf_sc.uc_mcontext.sc_ebx = regs->tf_ebx; |
490 frame.sf_sc.uc_mcontext.sc_esp = regs->tf_esp; |
491 frame.sf_sc.uc_mcontext.sc_edx = regs->tf_edx; 492 frame.sf_sc.uc_mcontext.sc_ecx = regs->tf_ecx; 493 frame.sf_sc.uc_mcontext.sc_eax = regs->tf_eax; 494 frame.sf_sc.uc_mcontext.sc_eip = regs->tf_eip; 495 frame.sf_sc.uc_mcontext.sc_cs = regs->tf_cs; 496 frame.sf_sc.uc_mcontext.sc_eflags = regs->tf_eflags; 497 frame.sf_sc.uc_mcontext.sc_esp_at_signal = regs->tf_esp; 498 frame.sf_sc.uc_mcontext.sc_ss = regs->tf_ss; --- 21 unchanged lines hidden (view full) --- 520 PROC_LOCK(p); 521 sigexit(td, SIGILL); 522 } 523 524 /* 525 * Build context to run handler in. 526 */ 527 regs->tf_esp = (int)fp; |
528 regs->tf_eip = linux_rt_sigcode; |
529 regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D); 530 regs->tf_cs = _ucodesel; 531 regs->tf_ds = _udatasel; 532 regs->tf_es = _udatasel; 533 regs->tf_fs = _udatasel; 534 regs->tf_ss = _udatasel; 535 PROC_LOCK(p); 536 mtx_lock(&psp->ps_mtx); --- 74 unchanged lines hidden (view full) --- 611 frame.sf_sc.sc_gs = rgs(); 612 frame.sf_sc.sc_fs = regs->tf_fs; 613 frame.sf_sc.sc_es = regs->tf_es; 614 frame.sf_sc.sc_ds = regs->tf_ds; 615 frame.sf_sc.sc_edi = regs->tf_edi; 616 frame.sf_sc.sc_esi = regs->tf_esi; 617 frame.sf_sc.sc_ebp = regs->tf_ebp; 618 frame.sf_sc.sc_ebx = regs->tf_ebx; |
619 frame.sf_sc.sc_esp = regs->tf_esp; |
620 frame.sf_sc.sc_edx = regs->tf_edx; 621 frame.sf_sc.sc_ecx = regs->tf_ecx; 622 frame.sf_sc.sc_eax = regs->tf_eax; 623 frame.sf_sc.sc_eip = regs->tf_eip; 624 frame.sf_sc.sc_cs = regs->tf_cs; 625 frame.sf_sc.sc_eflags = regs->tf_eflags; 626 frame.sf_sc.sc_esp_at_signal = regs->tf_esp; 627 frame.sf_sc.sc_ss = regs->tf_ss; --- 12 unchanged lines hidden (view full) --- 640 PROC_LOCK(p); 641 sigexit(td, SIGILL); 642 } 643 644 /* 645 * Build context to run handler in. 646 */ 647 regs->tf_esp = (int)fp; |
648 regs->tf_eip = linux_sigcode; |
649 regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D); 650 regs->tf_cs = _ucodesel; 651 regs->tf_ds = _udatasel; 652 regs->tf_es = _udatasel; 653 regs->tf_fs = _udatasel; 654 regs->tf_ss = _udatasel; 655 PROC_LOCK(p); 656 mtx_lock(&psp->ps_mtx); --- 299 unchanged lines hidden (view full) --- 956 .sv_mask = 0, 957 .sv_sigsize = LINUX_SIGTBLSZ, 958 .sv_sigtbl = bsd_to_linux_signal, 959 .sv_errsize = ELAST + 1, 960 .sv_errtbl = bsd_to_linux_errno, 961 .sv_transtrap = translate_traps, 962 .sv_fixup = linux_fixup, 963 .sv_sendsig = linux_sendsig, |
964 .sv_sigcode = &_binary_linux_locore_o_start, |
965 .sv_szsigcode = &linux_szsigcode, 966 .sv_prepsyscall = NULL, 967 .sv_name = "Linux a.out", 968 .sv_coredump = NULL, 969 .sv_imgact_try = exec_linux_imgact_try, 970 .sv_minsigstksz = LINUX_MINSIGSTKSZ, 971 .sv_pagesize = PAGE_SIZE, 972 .sv_minuser = VM_MIN_ADDRESS, --- 22 unchanged lines hidden (view full) --- 995 .sv_mask = 0, 996 .sv_sigsize = LINUX_SIGTBLSZ, 997 .sv_sigtbl = bsd_to_linux_signal, 998 .sv_errsize = ELAST + 1, 999 .sv_errtbl = bsd_to_linux_errno, 1000 .sv_transtrap = translate_traps, 1001 .sv_fixup = elf_linux_fixup, 1002 .sv_sendsig = linux_sendsig, |
1003 .sv_sigcode = &_binary_linux_locore_o_start, |
1004 .sv_szsigcode = &linux_szsigcode, 1005 .sv_prepsyscall = NULL, 1006 .sv_name = "Linux ELF", 1007 .sv_coredump = elf32_coredump, 1008 .sv_imgact_try = exec_linux_imgact_try, 1009 .sv_minsigstksz = LINUX_MINSIGSTKSZ, 1010 .sv_pagesize = PAGE_SIZE, 1011 .sv_minuser = VM_MIN_ADDRESS, --- 9 unchanged lines hidden (view full) --- 1021 .sv_set_syscall_retval = cpu_set_syscall_retval, 1022 .sv_fetch_syscall_args = linux_fetch_syscall_args, 1023 .sv_syscallnames = NULL, 1024 .sv_shared_page_base = LINUX_SHAREDPAGE, 1025 .sv_shared_page_len = PAGE_SIZE, 1026 .sv_schedtail = linux_schedtail, 1027 .sv_thread_detach = linux_thread_detach, 1028}; |
1029 |
1030static void 1031linux_vdso_install(void *param) 1032{ 1033 1034 linux_szsigcode = (&_binary_linux_locore_o_end - 1035 &_binary_linux_locore_o_start); 1036 1037 if (linux_szsigcode > elf_linux_sysvec.sv_shared_page_len) 1038 panic("Linux invalid vdso size\n"); 1039 1040 __elfN(linux_vdso_fixup)(&elf_linux_sysvec); 1041 1042 linux_shared_page_obj = __elfN(linux_shared_page_init) 1043 (&linux_shared_page_mapping); 1044 1045 __elfN(linux_vdso_reloc)(&elf_linux_sysvec, LINUX_SHAREDPAGE); 1046 1047 bcopy(elf_linux_sysvec.sv_sigcode, linux_shared_page_mapping, 1048 linux_szsigcode); 1049 elf_linux_sysvec.sv_shared_page_obj = linux_shared_page_obj; 1050} 1051SYSINIT(elf_linux_vdso_init, SI_SUB_EXEC, SI_ORDER_ANY, 1052 (sysinit_cfunc_t)linux_vdso_install, NULL); 1053 1054static void 1055linux_vdso_deinstall(void *param) 1056{ 1057 1058 __elfN(linux_shared_page_fini)(linux_shared_page_obj); 1059}; 1060SYSUNINIT(elf_linux_vdso_uninit, SI_SUB_EXEC, SI_ORDER_FIRST, 1061 (sysinit_cfunc_t)linux_vdso_deinstall, NULL); 1062 |
1063static char GNU_ABI_VENDOR[] = "GNU"; 1064static int GNULINUX_ABI_DESC = 0; 1065 1066static boolean_t 1067linux_trans_osrel(const Elf_Note *note, int32_t *osrel) 1068{ 1069 const Elf32_Word *desc; 1070 uintptr_t p; --- 134 unchanged lines hidden --- |