Index: sys/amd64/cloudabi64/cloudabi64_sysvec.c =================================================================== --- sys/amd64/cloudabi64/cloudabi64_sysvec.c +++ sys/amd64/cloudabi64/cloudabi64_sysvec.c @@ -27,107 +27,26 @@ __FBSDID("$FreeBSD$"); #include -#include -#include -#include #include -#include #include -#include -#include #include -#include -#include #include +#include #include #include #include -#include #include #include #include -#include #include extern const char *cloudabi64_syscallnames[]; extern struct sysent cloudabi64_sysent[]; -static register_t * -cloudabi64_copyout_strings(struct image_params *imgp) -{ - uintptr_t begin; - size_t len; - - /* Copy out program arguments. */ - len = imgp->args->begin_envv - imgp->args->begin_argv; - begin = rounddown2(USRSTACK - len, sizeof(register_t)); - copyout(imgp->args->begin_argv, (void *)begin, len); - return ((register_t *)begin); -} - -static int -cloudabi64_fixup(register_t **stack_base, struct image_params *imgp) -{ - char canarybuf[64]; - Elf64_Auxargs *args; - struct thread *td; - void *argdata, *canary; - size_t argdatalen; - int error; - - /* - * CloudABI executables do not store the FreeBSD OS release - * number in their header. Set the OS release number to the - * latest version of FreeBSD, so that system calls behave as if - * called natively. - */ - td = curthread; - td->td_proc->p_osrel = __FreeBSD_version; - - /* Store canary for stack smashing protection. */ - argdata = *stack_base; - arc4rand(canarybuf, sizeof(canarybuf), 0); - *stack_base -= howmany(sizeof(canarybuf), sizeof(register_t)); - canary = *stack_base; - error = copyout(canarybuf, canary, sizeof(canarybuf)); - if (error != 0) - return (error); - - /* - * Compute length of program arguments. As the argument data is - * binary safe, we had to add a trailing null byte in - * exec_copyin_data_fds(). Undo this by reducing the length. - */ - args = (Elf64_Auxargs *)imgp->auxargs; - argdatalen = imgp->args->begin_envv - imgp->args->begin_argv; - if (argdatalen > 0) - --argdatalen; - - /* Write out an auxiliary vector. */ - cloudabi64_auxv_t auxv[] = { -#define VAL(type, val) { .a_type = (type), .a_val = (val) } -#define PTR(type, ptr) { .a_type = (type), .a_ptr = (uintptr_t)(ptr) } - PTR(CLOUDABI_AT_ARGDATA, argdata), - VAL(CLOUDABI_AT_ARGDATALEN, argdatalen), - PTR(CLOUDABI_AT_CANARY, canary), - VAL(CLOUDABI_AT_CANARYLEN, sizeof(canarybuf)), - VAL(CLOUDABI_AT_NCPUS, mp_ncpus), - VAL(CLOUDABI_AT_PAGESZ, args->pagesz), - PTR(CLOUDABI_AT_PHDR, args->phdr), - VAL(CLOUDABI_AT_PHNUM, args->phnum), - VAL(CLOUDABI_AT_TID, td->td_tid), -#undef VAL -#undef PTR - { .a_type = CLOUDABI_AT_NULL }, - }; - *stack_base -= howmany(sizeof(auxv), sizeof(register_t)); - return (copyout(auxv, *stack_base, sizeof(auxv))); -} - static int cloudabi64_fetch_syscall_args(struct thread *td, struct syscall_args *sa) { @@ -234,43 +153,9 @@ INIT_SYSENTVEC(elf_sysvec, &cloudabi64_elf_sysvec); -static Elf64_Brandinfo cloudabi64_brand = { +Elf64_Brandinfo cloudabi64_brand = { .brand = ELFOSABI_CLOUDABI, .machine = EM_X86_64, .sysvec = &cloudabi64_elf_sysvec, .compat_3_brand = "CloudABI", }; - -static int -cloudabi64_modevent(module_t mod, int type, void *data) -{ - - switch (type) { - case MOD_LOAD: - if (elf64_insert_brand_entry(&cloudabi64_brand) < 0) { - printf("Failed to add CloudABI ELF brand handler\n"); - return (EINVAL); - } - return (0); - case MOD_UNLOAD: - if (elf64_brand_inuse(&cloudabi64_brand)) - return (EBUSY); - if (elf64_remove_brand_entry(&cloudabi64_brand) < 0) { - printf("Failed to remove CloudABI ELF brand handler\n"); - return (EINVAL); - } - return (0); - default: - return (EOPNOTSUPP); - } -} - -static moduledata_t cloudabi64_module = { - "cloudabi64", - cloudabi64_modevent, - NULL -}; - -DECLARE_MODULE_TIED(cloudabi64, cloudabi64_module, SI_SUB_EXEC, SI_ORDER_ANY); -MODULE_DEPEND(cloudabi64, cloudabi, 1, 1, 1); -FEATURE(cloudabi64, "CloudABI 64bit support"); Index: sys/compat/cloudabi64/cloudabi64_module.c =================================================================== --- sys/compat/cloudabi64/cloudabi64_module.c +++ sys/compat/cloudabi64/cloudabi64_module.c @@ -27,9 +27,7 @@ __FBSDID("$FreeBSD: head/sys/amd64/cloudabi64/cloudabi64_sysvec.c 286924 2015-08-19 15:18:32Z bapt $"); #include -#include #include -#include #include #include #include @@ -38,38 +36,25 @@ #include #include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include #include #include -extern const char *cloudabi64_syscallnames[]; -extern struct sysent cloudabi64_sysent[]; - -static register_t * +register_t * cloudabi64_copyout_strings(struct image_params *imgp) { + struct image_args *args; uintptr_t begin; size_t len; /* Copy out program arguments. */ - len = imgp->args->begin_envv - imgp->args->begin_argv; - begin = rounddown2(USRSTACK - len, sizeof(register_t)); - copyout(imgp->args->begin_argv, (void *)begin, len); + args = imgp->args; + len = args->begin_envv - args->begin_argv; + begin = rounddown2(imgp->sysent->sv_usrstack - len, sizeof(register_t)); + copyout(args->begin_argv, (void *)begin, len); return ((register_t *)begin); } -static int +int cloudabi64_fixup(register_t **stack_base, struct image_params *imgp) { char canarybuf[64]; @@ -129,119 +114,6 @@ } static int -cloudabi64_fetch_syscall_args(struct thread *td, struct syscall_args *sa) -{ - struct trapframe *frame = td->td_frame; - - /* Obtain system call number. */ - sa->code = frame->tf_rax; - if (sa->code >= CLOUDABI64_SYS_MAXSYSCALL) - return (ENOSYS); - sa->callp = &cloudabi64_sysent[sa->code]; - - /* Fetch system call arguments. */ - sa->args[0] = frame->tf_rdi; - sa->args[1] = frame->tf_rsi; - sa->args[2] = frame->tf_rdx; - sa->args[3] = frame->tf_rcx; /* Actually %r10. */ - sa->args[4] = frame->tf_r8; - sa->args[5] = frame->tf_r9; - - /* Default system call return values. */ - td->td_retval[0] = 0; - td->td_retval[1] = frame->tf_rdx; - return (0); -} - -static void -cloudabi64_set_syscall_retval(struct thread *td, int error) -{ - struct trapframe *frame = td->td_frame; - - switch (error) { - case 0: - /* System call succeeded. */ - frame->tf_rax = td->td_retval[0]; - frame->tf_rdx = td->td_retval[1]; - frame->tf_rflags &= ~PSL_C; - break; - case ERESTART: - /* Restart system call. */ - frame->tf_rip -= frame->tf_err; - frame->tf_r10 = frame->tf_rcx; - set_pcb_flags(td->td_pcb, PCB_FULL_IRET); - break; - case EJUSTRETURN: - break; - default: - /* System call returned an error. */ - frame->tf_rax = cloudabi_convert_errno(error); - frame->tf_rflags |= PSL_C; - break; - } -} - -static void -cloudabi64_schedtail(struct thread *td) -{ - struct trapframe *frame = td->td_frame; - - /* Initial register values for processes returning from fork. */ - frame->tf_rax = CLOUDABI_PROCESS_CHILD; - frame->tf_rdx = td->td_tid; -} - -void -cloudabi64_thread_setregs(struct thread *td, - const cloudabi64_threadattr_t *attr) -{ - struct trapframe *frame; - stack_t stack; - - /* Perform standard register initialization. */ - stack.ss_sp = (void *)attr->stack; - stack.ss_size = attr->stack_size; - cpu_set_upcall_kse(td, (void *)attr->entry_point, NULL, &stack); - - /* - * Pass in the thread ID of the new thread and the argument - * pointer provided by the parent thread in as arguments to the - * entry point. - */ - frame = td->td_frame; - frame->tf_rdi = td->td_tid; - frame->tf_rsi = attr->argument; -} - -static struct sysentvec cloudabi64_elf_sysvec = { - .sv_size = CLOUDABI64_SYS_MAXSYSCALL, - .sv_table = cloudabi64_sysent, - .sv_fixup = cloudabi64_fixup, - .sv_name = "CloudABI ELF64", - .sv_coredump = elf64_coredump, - .sv_pagesize = PAGE_SIZE, - .sv_minuser = VM_MIN_ADDRESS, - .sv_maxuser = VM_MAXUSER_ADDRESS, - .sv_usrstack = USRSTACK, - .sv_stackprot = VM_PROT_READ | VM_PROT_WRITE, - .sv_copyout_strings = cloudabi64_copyout_strings, - .sv_flags = SV_ABI_CLOUDABI | SV_CAPSICUM, - .sv_set_syscall_retval = cloudabi64_set_syscall_retval, - .sv_fetch_syscall_args = cloudabi64_fetch_syscall_args, - .sv_syscallnames = cloudabi64_syscallnames, - .sv_schedtail = cloudabi64_schedtail, -}; - -INIT_SYSENTVEC(elf_sysvec, &cloudabi64_elf_sysvec); - -static Elf64_Brandinfo cloudabi64_brand = { - .brand = ELFOSABI_CLOUDABI, - .machine = EM_X86_64, - .sysvec = &cloudabi64_elf_sysvec, - .compat_3_brand = "CloudABI", -}; - -static int cloudabi64_modevent(module_t mod, int type, void *data) { Index: sys/compat/cloudabi64/cloudabi64_util.h =================================================================== --- sys/compat/cloudabi64/cloudabi64_util.h +++ sys/compat/cloudabi64/cloudabi64_util.h @@ -28,10 +28,20 @@ #ifndef _CLOUDABI64_UTIL_H_ #define _CLOUDABI64_UTIL_H_ +#include +#include + #include +struct image_params; struct thread; +extern Elf64_Brandinfo cloudabi64_brand; + +/* Stack initialization during process execution. */ +register_t *cloudabi64_copyout_strings(struct image_params *); +int cloudabi64_fixup(register_t **, struct image_params *); + void cloudabi64_thread_setregs(struct thread *, const cloudabi64_threadattr_t *); Index: sys/conf/files =================================================================== --- sys/conf/files +++ sys/conf/files @@ -266,6 +266,7 @@ compat/cloudabi/cloudabi_sock.c optional compat_cloudabi64 compat/cloudabi/cloudabi_thread.c optional compat_cloudabi64 compat/cloudabi64/cloudabi64_fd.c optional compat_cloudabi64 +compat/cloudabi64/cloudabi64_module.c optional compat_cloudabi64 compat/cloudabi64/cloudabi64_poll.c optional compat_cloudabi64 compat/cloudabi64/cloudabi64_sock.c optional compat_cloudabi64 compat/cloudabi64/cloudabi64_syscalls.c optional compat_cloudabi64 Index: sys/modules/cloudabi64/Makefile =================================================================== --- sys/modules/cloudabi64/Makefile +++ sys/modules/cloudabi64/Makefile @@ -4,8 +4,8 @@ .PATH: ${.CURDIR}/../../${MACHINE}/cloudabi64 KMOD= cloudabi64 -SRCS= cloudabi64_fd.c cloudabi64_poll.c cloudabi64_sock.c \ - cloudabi64_syscalls.c cloudabi64_sysent.c cloudabi64_sysvec.c \ - cloudabi64_thread.c +SRCS= cloudabi64_fd.c cloudabi64_module.c cloudabi64_poll.c \ + cloudabi64_sock.c cloudabi64_syscalls.c cloudabi64_sysent.c \ + cloudabi64_sysvec.c cloudabi64_thread.c .include