Changeset View
Changeset View
Standalone View
Standalone View
head/sys/amd64/linux/linux_sysvec.c
Show First 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | |||||
#include <compat/linux/linux_misc.h> | #include <compat/linux/linux_misc.h> | ||||
#include <compat/linux/linux_signal.h> | #include <compat/linux/linux_signal.h> | ||||
#include <compat/linux/linux_sysproto.h> | #include <compat/linux/linux_sysproto.h> | ||||
#include <compat/linux/linux_util.h> | #include <compat/linux/linux_util.h> | ||||
#include <compat/linux/linux_vdso.h> | #include <compat/linux/linux_vdso.h> | ||||
MODULE_VERSION(linux64, 1); | MODULE_VERSION(linux64, 1); | ||||
#if BYTE_ORDER == LITTLE_ENDIAN | |||||
#define SHELLMAGIC 0x2123 /* #! */ | |||||
#else | |||||
#define SHELLMAGIC 0x2321 | |||||
#endif | |||||
#if defined(DEBUG) | #if defined(DEBUG) | ||||
SYSCTL_PROC(_compat_linux, OID_AUTO, debug, | SYSCTL_PROC(_compat_linux, OID_AUTO, debug, | ||||
CTLTYPE_STRING | CTLFLAG_RW, | CTLTYPE_STRING | CTLFLAG_RW, | ||||
0, 0, linux_sysctl_debug, "A", | 0, 0, linux_sysctl_debug, "A", | ||||
"Linux 64 debugging control"); | "Linux 64 debugging control"); | ||||
#endif | #endif | ||||
/* | /* | ||||
Show All 17 Lines | |||||
static register_t * linux_copyout_strings(struct image_params *imgp); | static register_t * linux_copyout_strings(struct image_params *imgp); | ||||
static int linux_fixup_elf(register_t **stack_base, | static int linux_fixup_elf(register_t **stack_base, | ||||
struct image_params *iparams); | struct image_params *iparams); | ||||
static bool linux_trans_osrel(const Elf_Note *note, int32_t *osrel); | static bool linux_trans_osrel(const Elf_Note *note, int32_t *osrel); | ||||
static void linux_vdso_install(void *param); | static void linux_vdso_install(void *param); | ||||
static void linux_vdso_deinstall(void *param); | static void linux_vdso_deinstall(void *param); | ||||
static void linux_set_syscall_retval(struct thread *td, int error); | static void linux_set_syscall_retval(struct thread *td, int error); | ||||
static int linux_fetch_syscall_args(struct thread *td); | static int linux_fetch_syscall_args(struct thread *td); | ||||
static int linux_exec_imgact_try(struct image_params *iparams); | |||||
static void linux_exec_setregs(struct thread *td, struct image_params *imgp, | static void linux_exec_setregs(struct thread *td, struct image_params *imgp, | ||||
u_long stack); | u_long stack); | ||||
static int linux_vsyscall(struct thread *td); | static int linux_vsyscall(struct thread *td); | ||||
#define LINUX_T_UNKNOWN 255 | #define LINUX_T_UNKNOWN 255 | ||||
static int _bsd_to_linux_trapcode[] = { | static int _bsd_to_linux_trapcode[] = { | ||||
LINUX_T_UNKNOWN, /* 0 */ | LINUX_T_UNKNOWN, /* 0 */ | ||||
6, /* 1 T_PRIVINFLT */ | 6, /* 1 T_PRIVINFLT */ | ||||
▲ Show 20 Lines • Show All 519 Lines • ▼ Show 20 Lines | #endif | ||||
regs->tf_rsp = (long)sfp; | regs->tf_rsp = (long)sfp; | ||||
regs->tf_rip = linux_rt_sigcode; | regs->tf_rip = linux_rt_sigcode; | ||||
regs->tf_rflags &= ~(PSL_T | PSL_D); | regs->tf_rflags &= ~(PSL_T | PSL_D); | ||||
regs->tf_cs = _ucodesel; | regs->tf_cs = _ucodesel; | ||||
set_pcb_flags(td->td_pcb, PCB_FULL_IRET); | set_pcb_flags(td->td_pcb, PCB_FULL_IRET); | ||||
PROC_LOCK(p); | PROC_LOCK(p); | ||||
mtx_lock(&psp->ps_mtx); | mtx_lock(&psp->ps_mtx); | ||||
} | |||||
/* | |||||
* If a Linux binary is exec'ing something, try this image activator | |||||
* first. We override standard shell script execution in order to | |||||
* be able to modify the interpreter path. We only do this if a Linux | |||||
* binary is doing the exec, so we do not create an EXEC module for it. | |||||
*/ | |||||
static int | |||||
linux_exec_imgact_try(struct image_params *imgp) | |||||
{ | |||||
const char *head = (const char *)imgp->image_header; | |||||
char *rpath; | |||||
int error = -1; | |||||
/* | |||||
* The interpreter for shell scripts run from a Linux binary needs | |||||
* to be located in /compat/linux if possible in order to recursively | |||||
* maintain Linux path emulation. | |||||
*/ | |||||
if (((const short *)head)[0] == SHELLMAGIC) { | |||||
/* | |||||
* Run our normal shell image activator. If it succeeds then | |||||
* attempt to use the alternate path for the interpreter. If | |||||
* an alternate path is found, use our stringspace to store it. | |||||
*/ | |||||
if ((error = exec_shell_imgact(imgp)) == 0) { | |||||
linux_emul_convpath(FIRST_THREAD_IN_PROC(imgp->proc), | |||||
imgp->interpreter_name, UIO_SYSSPACE, &rpath, 0, | |||||
AT_FDCWD); | |||||
if (rpath != NULL) | |||||
imgp->args->fname_buf = | |||||
imgp->interpreter_name = rpath; | |||||
} | |||||
} | |||||
return (error); | |||||
} | } | ||||
#define LINUX_VSYSCALL_START (-10UL << 20) | #define LINUX_VSYSCALL_START (-10UL << 20) | ||||
#define LINUX_VSYSCALL_SZ 1024 | #define LINUX_VSYSCALL_SZ 1024 | ||||
const unsigned long linux_vsyscall_vector[] = { | const unsigned long linux_vsyscall_vector[] = { | ||||
LINUX_SYS_gettimeofday, | LINUX_SYS_gettimeofday, | ||||
LINUX_SYS_linux_time, | LINUX_SYS_linux_time, | ||||
▲ Show 20 Lines • Show All 253 Lines • Show Last 20 Lines |