Changeset View
Changeset View
Standalone View
Standalone View
sys/compat/cloudabi64/cloudabi64_module.c
- This file was copied from sys/amd64/cloudabi64/cloudabi64_sysvec.c.
Show All 21 Lines | |||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD: head/sys/amd64/cloudabi64/cloudabi64_sysvec.c 286924 2015-08-19 15:18:32Z bapt $"); | __FBSDID("$FreeBSD: head/sys/amd64/cloudabi64/cloudabi64_sysvec.c 286924 2015-08-19 15:18:32Z bapt $"); | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/exec.h> | |||||
#include <sys/imgact.h> | #include <sys/imgact.h> | ||||
#include <sys/imgact_elf.h> | |||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/module.h> | #include <sys/module.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/smp.h> | #include <sys/smp.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/sysent.h> | #include <sys/sysent.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <vm/pmap.h> | |||||
#include <vm/vm.h> | |||||
#include <machine/frame.h> | |||||
#include <machine/pcb.h> | |||||
#include <machine/pmap.h> | |||||
#include <machine/psl.h> | |||||
#include <machine/vmparam.h> | |||||
#include <compat/cloudabi/cloudabi_util.h> | |||||
#include <compat/cloudabi64/cloudabi64_syscall.h> | |||||
#include <compat/cloudabi64/cloudabi64_syscalldefs.h> | #include <compat/cloudabi64/cloudabi64_syscalldefs.h> | ||||
#include <compat/cloudabi64/cloudabi64_util.h> | #include <compat/cloudabi64/cloudabi64_util.h> | ||||
extern const char *cloudabi64_syscallnames[]; | register_t * | ||||
extern struct sysent cloudabi64_sysent[]; | |||||
static register_t * | |||||
cloudabi64_copyout_strings(struct image_params *imgp) | cloudabi64_copyout_strings(struct image_params *imgp) | ||||
{ | { | ||||
struct image_args *args; | |||||
uintptr_t begin; | uintptr_t begin; | ||||
size_t len; | size_t len; | ||||
/* Copy out program arguments. */ | /* Copy out program arguments. */ | ||||
len = imgp->args->begin_envv - imgp->args->begin_argv; | args = imgp->args; | ||||
begin = rounddown2(USRSTACK - len, sizeof(register_t)); | len = args->begin_envv - args->begin_argv; | ||||
copyout(imgp->args->begin_argv, (void *)begin, len); | begin = rounddown2(imgp->sysent->sv_usrstack - len, sizeof(register_t)); | ||||
copyout(args->begin_argv, (void *)begin, len); | |||||
return ((register_t *)begin); | return ((register_t *)begin); | ||||
} | } | ||||
static int | int | ||||
cloudabi64_fixup(register_t **stack_base, struct image_params *imgp) | cloudabi64_fixup(register_t **stack_base, struct image_params *imgp) | ||||
{ | { | ||||
char canarybuf[64]; | char canarybuf[64]; | ||||
Elf64_Auxargs *args; | Elf64_Auxargs *args; | ||||
struct thread *td; | struct thread *td; | ||||
void *argdata, *canary; | void *argdata, *canary; | ||||
size_t argdatalen; | size_t argdatalen; | ||||
int error; | int error; | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | #define PTR(type, ptr) { .a_type = (type), .a_ptr = (uintptr_t)(ptr) } | ||||
VAL(CLOUDABI_AT_TID, td->td_tid), | VAL(CLOUDABI_AT_TID, td->td_tid), | ||||
#undef VAL | #undef VAL | ||||
#undef PTR | #undef PTR | ||||
{ .a_type = CLOUDABI_AT_NULL }, | { .a_type = CLOUDABI_AT_NULL }, | ||||
}; | }; | ||||
*stack_base -= howmany(sizeof(auxv), sizeof(register_t)); | *stack_base -= howmany(sizeof(auxv), sizeof(register_t)); | ||||
return (copyout(auxv, *stack_base, sizeof(auxv))); | return (copyout(auxv, *stack_base, sizeof(auxv))); | ||||
} | } | ||||
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 | static int | ||||
cloudabi64_modevent(module_t mod, int type, void *data) | cloudabi64_modevent(module_t mod, int type, void *data) | ||||
{ | { | ||||
switch (type) { | switch (type) { | ||||
case MOD_LOAD: | case MOD_LOAD: | ||||
if (elf64_insert_brand_entry(&cloudabi64_brand) < 0) { | if (elf64_insert_brand_entry(&cloudabi64_brand) < 0) { | ||||
Show All 26 Lines |