Changeset View
Changeset View
Standalone View
Standalone View
head/sys/compat/cloudabi32/cloudabi32_module.c
Show All 40 Lines | |||||
#include <compat/cloudabi/cloudabi_util.h> | #include <compat/cloudabi/cloudabi_util.h> | ||||
#include <compat/cloudabi32/cloudabi32_util.h> | #include <compat/cloudabi32/cloudabi32_util.h> | ||||
extern char _binary_cloudabi32_vdso_o_start[]; | extern char _binary_cloudabi32_vdso_o_start[]; | ||||
extern char _binary_cloudabi32_vdso_o_end[]; | extern char _binary_cloudabi32_vdso_o_end[]; | ||||
int | int | ||||
cloudabi32_copyout_strings(struct image_params *imgp, register_t **stack_base) | cloudabi32_copyout_strings(struct image_params *imgp, uintptr_t *stack_base) | ||||
{ | { | ||||
struct image_args *args; | struct image_args *args; | ||||
uintptr_t begin; | uintptr_t begin; | ||||
size_t len; | size_t len; | ||||
/* Copy out program arguments. */ | /* Copy out program arguments. */ | ||||
args = imgp->args; | args = imgp->args; | ||||
len = exec_args_get_begin_envv(args) - args->begin_argv; | len = exec_args_get_begin_envv(args) - args->begin_argv; | ||||
begin = rounddown2(imgp->sysent->sv_usrstack - len, sizeof(register_t)); | begin = rounddown2(imgp->sysent->sv_usrstack - len, sizeof(register_t)); | ||||
*stack_base = (register_t *)begin; | *stack_base = begin; | ||||
return (copyout(args->begin_argv, (void *)begin, len)); | return (copyout(args->begin_argv, (void *)begin, len)); | ||||
} | } | ||||
int | int | ||||
cloudabi32_fixup(register_t **stack_base, struct image_params *imgp) | cloudabi32_fixup(uintptr_t *stack_base, struct image_params *imgp) | ||||
{ | { | ||||
char canarybuf[64], pidbuf[16]; | char canarybuf[64], pidbuf[16]; | ||||
Elf32_Auxargs *args; | Elf32_Auxargs *args; | ||||
struct thread *td; | struct thread *td; | ||||
void *argdata, *canary, *pid; | void *argdata, *canary, *pid; | ||||
size_t argdatalen; | size_t argdatalen; | ||||
int error; | int error; | ||||
/* | /* | ||||
* CloudABI executables do not store the FreeBSD OS release | * CloudABI executables do not store the FreeBSD OS release | ||||
* number in their header. Set the OS release number to the | * number in their header. Set the OS release number to the | ||||
* latest version of FreeBSD, so that system calls behave as if | * latest version of FreeBSD, so that system calls behave as if | ||||
* called natively. | * called natively. | ||||
*/ | */ | ||||
td = curthread; | td = curthread; | ||||
td->td_proc->p_osrel = __FreeBSD_version; | td->td_proc->p_osrel = __FreeBSD_version; | ||||
argdata = *stack_base; | argdata = (void *)*stack_base; | ||||
/* Store canary for stack smashing protection. */ | /* Store canary for stack smashing protection. */ | ||||
arc4rand(canarybuf, sizeof(canarybuf), 0); | arc4rand(canarybuf, sizeof(canarybuf), 0); | ||||
*stack_base -= howmany(sizeof(canarybuf), sizeof(register_t)); | *stack_base -= roundup(sizeof(canarybuf), sizeof(register_t)); | ||||
canary = *stack_base; | canary = (void *)*stack_base; | ||||
error = copyout(canarybuf, canary, sizeof(canarybuf)); | error = copyout(canarybuf, canary, sizeof(canarybuf)); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
/* | /* | ||||
* Generate a random UUID that identifies the process. Right now | * Generate a random UUID that identifies the process. Right now | ||||
* we don't store this UUID in the kernel. Ideally, it should be | * we don't store this UUID in the kernel. Ideally, it should be | ||||
* exposed through ps(1). | * exposed through ps(1). | ||||
*/ | */ | ||||
arc4rand(pidbuf, sizeof(pidbuf), 0); | arc4rand(pidbuf, sizeof(pidbuf), 0); | ||||
pidbuf[6] = (pidbuf[6] & 0x0f) | 0x40; | pidbuf[6] = (pidbuf[6] & 0x0f) | 0x40; | ||||
pidbuf[8] = (pidbuf[8] & 0x3f) | 0x80; | pidbuf[8] = (pidbuf[8] & 0x3f) | 0x80; | ||||
*stack_base -= howmany(sizeof(pidbuf), sizeof(register_t)); | *stack_base -= roundup(sizeof(pidbuf), sizeof(register_t)); | ||||
pid = *stack_base; | pid = (void *)*stack_base; | ||||
error = copyout(pidbuf, pid, sizeof(pidbuf)); | error = copyout(pidbuf, pid, sizeof(pidbuf)); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
/* | /* | ||||
* Compute length of program arguments. As the argument data is | * Compute length of program arguments. As the argument data is | ||||
* binary safe, we had to add a trailing null byte in | * binary safe, we had to add a trailing null byte in | ||||
* exec_copyin_data_fds(). Undo this by reducing the length. | * exec_copyin_data_fds(). Undo this by reducing the length. | ||||
Show All 20 Lines | #define PTR(type, ptr) { .a_type = (type), .a_ptr = (uintptr_t)(ptr) } | ||||
PTR(CLOUDABI_AT_PID, pid), | PTR(CLOUDABI_AT_PID, pid), | ||||
PTR(CLOUDABI_AT_SYSINFO_EHDR, | PTR(CLOUDABI_AT_SYSINFO_EHDR, | ||||
imgp->proc->p_sysent->sv_shared_page_base), | imgp->proc->p_sysent->sv_shared_page_base), | ||||
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 -= roundup(sizeof(auxv), sizeof(register_t)); | ||||
error = copyout(auxv, *stack_base, sizeof(auxv)); | error = copyout(auxv, (void *)*stack_base, sizeof(auxv)); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
/* Reserve space for storing the TCB. */ | /* Reserve space for storing the TCB. */ | ||||
*stack_base -= howmany(sizeof(cloudabi32_tcb_t), sizeof(register_t)); | *stack_base -= roundup(sizeof(cloudabi32_tcb_t), sizeof(register_t)); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
cloudabi32_modevent(module_t mod, int type, void *data) | cloudabi32_modevent(module_t mod, int type, void *data) | ||||
{ | { | ||||
switch (type) { | switch (type) { | ||||
Show All 32 Lines |