| 155 | } |
| 156 | |
| 157 | int |
| 158 | cloudabi64_thread_setregs(struct thread *td, |
| 159 | const cloudabi64_threadattr_t *attr, uint64_t tcb) |
| 160 | { |
| 161 | struct trapframe *frame; |
| 162 | stack_t stack; |
| 163 | uint64_t tcbptr; |
| 164 | int error; |
| 165 | |
| 166 | /* |
| 167 | * On x86-64, the TCB is referred to by %fs:0. Take some space |
| 168 | * from the top of the stack to store a single element array, |
| 169 | * containing a pointer to the TCB. %fs base will point to this. |
| 170 | */ |
| 171 | tcbptr = rounddown(attr->stack + attr->stack_len - sizeof(tcbptr), |
| 172 | _Alignof(tcbptr)); |
| 173 | error = copyout(&tcb, (void *)tcbptr, sizeof(tcb)); |
| 174 | if (error != 0) |
| 175 | return (error); |
| 176 | |
| 177 | /* Perform standard register initialization. */ |
| 178 | stack.ss_sp = TO_PTR(attr->stack); |
| 179 | stack.ss_size = tcbptr - attr->stack; |
| 180 | cpu_set_upcall(td, TO_PTR(attr->entry_point), NULL, &stack); |
| 181 | |
| 182 | /* |
| 183 | * Pass in the thread ID of the new thread and the argument |
| 184 | * pointer provided by the parent thread in as arguments to the |
| 185 | * entry point. |
| 186 | */ |
| 187 | frame = td->td_frame; |
| 188 | frame->tf_rdi = td->td_tid; |
| 189 | frame->tf_rsi = attr->argument; |
| 190 | |
| 191 | return (cpu_set_user_tls(td, TO_PTR(tcbptr))); |
| 192 | } |
| 193 | |
| 194 | static struct sysentvec cloudabi64_elf_sysvec = { |
| 195 | .sv_size = CLOUDABI64_SYS_MAXSYSCALL, |
nothing calls this directly
no test coverage detected