| 208 | } |
| 209 | |
| 210 | static inline void |
| 211 | syscallret(struct thread *td) |
| 212 | { |
| 213 | struct proc *p; |
| 214 | struct syscall_args *sa; |
| 215 | ksiginfo_t ksi; |
| 216 | int traced; |
| 217 | |
| 218 | KASSERT((td->td_pflags & TDP_FORKING) == 0, |
| 219 | ("fork() did not clear TDP_FORKING upon completion")); |
| 220 | KASSERT(td->td_errno != ERELOOKUP, |
| 221 | ("ERELOOKUP not consumed syscall %d", td->td_sa.code)); |
| 222 | |
| 223 | p = td->td_proc; |
| 224 | sa = &td->td_sa; |
| 225 | if (__predict_false(td->td_errno == ENOTCAPABLE || |
| 226 | td->td_errno == ECAPMODE)) { |
| 227 | if ((trap_enotcap || |
| 228 | (p->p_flag2 & P2_TRAPCAP) != 0) && IN_CAPABILITY_MODE(td)) { |
| 229 | ksiginfo_init_trap(&ksi); |
| 230 | ksi.ksi_signo = SIGTRAP; |
| 231 | ksi.ksi_errno = td->td_errno; |
| 232 | ksi.ksi_code = TRAP_CAP; |
| 233 | trapsignal(td, &ksi); |
| 234 | } |
| 235 | } |
| 236 | |
| 237 | /* |
| 238 | * Handle reschedule and other end-of-syscall issues |
| 239 | */ |
| 240 | userret(td, td->td_frame); |
| 241 | |
| 242 | #ifdef KTRACE |
| 243 | if (KTRPOINT(td, KTR_SYSRET)) { |
| 244 | ktrsysret(sa->code, td->td_errno, td->td_retval[0]); |
| 245 | } |
| 246 | #endif |
| 247 | |
| 248 | traced = 0; |
| 249 | if (__predict_false(p->p_flag & P_TRACED)) { |
| 250 | traced = 1; |
| 251 | PROC_LOCK(p); |
| 252 | td->td_dbgflags |= TDB_SCX; |
| 253 | PROC_UNLOCK(p); |
| 254 | } |
| 255 | if (__predict_false(traced || |
| 256 | (td->td_dbgflags & (TDB_EXEC | TDB_FORK)) != 0)) { |
| 257 | PROC_LOCK(p); |
| 258 | /* |
| 259 | * If tracing the execed process, trap to the debugger |
| 260 | * so that breakpoints can be set before the program |
| 261 | * executes. If debugger requested tracing of syscall |
| 262 | * returns, do it now too. |
| 263 | */ |
| 264 | if (traced && |
| 265 | ((td->td_dbgflags & (TDB_FORK | TDB_EXEC)) != 0 || |
| 266 | (p->p_ptevents & PTRACE_SCX) != 0)) |
| 267 | ptracestop(td, SIGTRAP, NULL); |
no test coverage detected