Changeset View
Changeset View
Standalone View
Standalone View
sys/arm64/linux/linux_sysvec.c
Show First 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | |||||
extern char _binary_linux_locore_o_start; | extern char _binary_linux_locore_o_start; | ||||
extern char _binary_linux_locore_o_end; | extern char _binary_linux_locore_o_end; | ||||
extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL]; | extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL]; | ||||
SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler); | SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler); | ||||
static int linux_copyout_strings(struct image_params *imgp, | static int linux_copyout_strings(struct image_params *imgp, | ||||
register_t **stack_base); | uintptr_t *stack_base); | ||||
static int linux_elf_fixup(register_t **stack_base, | static int linux_elf_fixup(uintptr_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(const void *param); | static void linux_vdso_install(const void *param); | ||||
static void linux_vdso_deinstall(const void *param); | static void linux_vdso_deinstall(const 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 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); | uintptr_t stack); | ||||
static int linux_vsyscall(struct thread *td); | static int linux_vsyscall(struct thread *td); | ||||
/* DTrace init */ | /* DTrace init */ | ||||
LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE); | LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE); | ||||
/* DTrace probes */ | /* DTrace probes */ | ||||
LIN_SDT_PROBE_DEFINE2(sysvec, linux_translate_traps, todo, "int", "int"); | LIN_SDT_PROBE_DEFINE2(sysvec, linux_translate_traps, todo, "int", "int"); | ||||
LIN_SDT_PROBE_DEFINE0(sysvec, linux_exec_setregs, todo); | LIN_SDT_PROBE_DEFINE0(sysvec, linux_exec_setregs, todo); | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | |||||
linux_set_syscall_retval(struct thread *td, int error) | linux_set_syscall_retval(struct thread *td, int error) | ||||
{ | { | ||||
td->td_retval[1] = td->td_frame->tf_x[1]; | td->td_retval[1] = td->td_frame->tf_x[1]; | ||||
cpu_set_syscall_retval(td, error); | cpu_set_syscall_retval(td, error); | ||||
} | } | ||||
static int | static int | ||||
linux_copyout_auxargs(struct image_params *imgp, u_long *base) | linux_copyout_auxargs(struct image_params *imgp, uintptr_t *base) | ||||
{ | { | ||||
Elf_Auxargs *args; | Elf_Auxargs *args; | ||||
Elf_Auxinfo *argarray, *pos; | Elf_Auxinfo *argarray, *pos; | ||||
u_long auxlen; | u_long auxlen; | ||||
struct proc *p; | struct proc *p; | ||||
int error, issetugid; | int error, issetugid; | ||||
LIN_SDT_PROBE0(sysvec, linux_copyout_auxargs, todo); | LIN_SDT_PROBE0(sysvec, linux_copyout_auxargs, todo); | ||||
Show All 38 Lines | #endif | ||||
auxlen = sizeof(*argarray) * (pos - argarray); | auxlen = sizeof(*argarray) * (pos - argarray); | ||||
*base -= auxlen; | *base -= auxlen; | ||||
error = copyout(argarray, (void *)*base, auxlen); | error = copyout(argarray, (void *)*base, auxlen); | ||||
free(argarray, M_TEMP); | free(argarray, M_TEMP); | ||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
linux_elf_fixup(register_t **stack_base, struct image_params *imgp) | linux_elf_fixup(uintptr_t *stack_base, struct image_params *imgp) | ||||
{ | { | ||||
LIN_SDT_PROBE0(sysvec, linux_elf_fixup, todo); | LIN_SDT_PROBE0(sysvec, linux_elf_fixup, todo); | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Copy strings out to the new process address space, constructing new arg | * Copy strings out to the new process address space, constructing new arg | ||||
* and env vector tables. Return a pointer to the base so that it can be used | * and env vector tables. Return a pointer to the base so that it can be used | ||||
* as the initial stack pointer. | * as the initial stack pointer. | ||||
* LINUXTODO: deduplicate against other linuxulator archs | * LINUXTODO: deduplicate against other linuxulator archs | ||||
*/ | */ | ||||
static int | static int | ||||
linux_copyout_strings(struct image_params *imgp, register_t **stack_base) | linux_copyout_strings(struct image_params *imgp, uintptr_t *stack_base) | ||||
{ | { | ||||
char **vectp; | char **vectp; | ||||
char *stringp, *destp; | char *stringp, *destp; | ||||
struct ps_strings *arginfo; | struct ps_strings *arginfo; | ||||
char canary[LINUX_AT_RANDOM_LEN]; | char canary[LINUX_AT_RANDOM_LEN]; | ||||
size_t execpath_len; | size_t execpath_len; | ||||
struct proc *p; | struct proc *p; | ||||
int argc, envc, error; | int argc, envc, error; | ||||
Show All 26 Lines | imgp->canary = (uintptr_t)arginfo - | ||||
roundup(sizeof(canary), sizeof(char *)); | roundup(sizeof(canary), sizeof(char *)); | ||||
error = copyout(canary, (void *)imgp->canary, sizeof(canary)); | error = copyout(canary, (void *)imgp->canary, sizeof(canary)); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
vectp = (char **)destp; | vectp = (char **)destp; | ||||
if (imgp->auxargs) { | if (imgp->auxargs) { | ||||
error = imgp->sysent->sv_copyout_auxargs(imgp, | error = imgp->sysent->sv_copyout_auxargs(imgp, | ||||
(u_long *)&vectp); | (uintptr_t *)&vectp); | ||||
kib: Same. | |||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Allocate room for argc and the argv[] and env vectors including the | * Allocate room for argc and the argv[] and env vectors including the | ||||
* terminating NULL pointers. | * terminating NULL pointers. | ||||
*/ | */ | ||||
vectp -= 1 + imgp->args->argc + 1 + imgp->args->envc + 1; | vectp -= 1 + imgp->args->argc + 1 + imgp->args->envc + 1; | ||||
vectp = (char **)STACKALIGN(vectp); | vectp = (char **)STACKALIGN(vectp); | ||||
/* vectp also becomes our initial stack base. */ | /* vectp also becomes our initial stack base. */ | ||||
*stack_base = (register_t *)vectp; | *stack_base = (uintptr_t)vectp; | ||||
stringp = imgp->args->begin_argv; | stringp = imgp->args->begin_argv; | ||||
argc = imgp->args->argc; | argc = imgp->args->argc; | ||||
envc = imgp->args->envc; | envc = imgp->args->envc; | ||||
/* Copy out strings - arguments and environment. */ | /* Copy out strings - arguments and environment. */ | ||||
error = copyout(stringp, destp, ARG_MAX - imgp->args->stringspace); | error = copyout(stringp, destp, ARG_MAX - imgp->args->stringspace); | ||||
if (error != 0) | if (error != 0) | ||||
Show All 39 Lines | linux_copyout_strings(struct image_params *imgp, uintptr_t *stack_base) | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Reset registers to default values on exec. | * Reset registers to default values on exec. | ||||
*/ | */ | ||||
static void | static void | ||||
linux_exec_setregs(struct thread *td, struct image_params *imgp, u_long stack) | linux_exec_setregs(struct thread *td, struct image_params *imgp, | ||||
uintptr_t stack) | |||||
{ | { | ||||
struct trapframe *regs = td->td_frame; | struct trapframe *regs = td->td_frame; | ||||
/* LINUXTODO: validate */ | /* LINUXTODO: validate */ | ||||
LIN_SDT_PROBE0(sysvec, linux_exec_setregs, todo); | LIN_SDT_PROBE0(sysvec, linux_exec_setregs, todo); | ||||
memset(regs, 0, sizeof(*regs)); | memset(regs, 0, sizeof(*regs)); | ||||
/* glibc start.S registers function pointer in x0 with atexit. */ | /* glibc start.S registers function pointer in x0 with atexit. */ | ||||
▲ Show 20 Lines • Show All 215 Lines • Show Last 20 Lines |
Same.