| 174 | } |
| 175 | |
| 176 | int |
| 177 | cloudabi32_thread_setregs(struct thread *td, |
| 178 | const cloudabi32_threadattr_t *attr, uint32_t tcb) |
| 179 | { |
| 180 | stack_t stack; |
| 181 | uint32_t args[3]; |
| 182 | void *frameptr; |
| 183 | int error; |
| 184 | |
| 185 | /* Perform standard register initialization. */ |
| 186 | stack.ss_sp = TO_PTR(attr->stack); |
| 187 | stack.ss_size = attr->stack_len - sizeof(args); |
| 188 | cpu_set_upcall(td, TO_PTR(attr->entry_point), NULL, &stack); |
| 189 | |
| 190 | /* |
| 191 | * Copy the arguments for the thread entry point onto the stack |
| 192 | * (args[1] and args[2]). Similar to process startup, use the |
| 193 | * otherwise unused return address (args[0]) for TLS. |
| 194 | */ |
| 195 | args[0] = tcb; |
| 196 | args[1] = td->td_tid; |
| 197 | args[2] = attr->argument; |
| 198 | frameptr = (void *)td->td_frame->tf_rsp; |
| 199 | error = copyout(args, frameptr, sizeof(args)); |
| 200 | if (error != 0) |
| 201 | return (error); |
| 202 | |
| 203 | return (cpu_set_user_tls(td, frameptr)); |
| 204 | } |
| 205 | |
| 206 | static struct sysentvec cloudabi32_elf_sysvec = { |
| 207 | .sv_size = CLOUDABI32_SYS_MAXSYSCALL, |
nothing calls this directly
no test coverage detected