#include <sys/proc.h>
#include <c2/audit.h>
#include <sys/procfs.h>
#include <sys/core.h>
void
upanic(void *addr, size_t len)
{
kthread_t *t = curthread;
proc_t *p = curproc;
klwp_t *lwp = ttolwp(t);
uint32_t auditing = AU_AUDITING();
uint32_t upflag = P_UPF_PANICKED;
void *buf;
int code;
mutex_enter(&p->p_lock);
lwp->lwp_cursig = SIGABRT;
mutex_exit(&p->p_lock);
proc_is_exiting(p);
if (exitlwps(1) != 0) {
mutex_enter(&p->p_lock);
lwp_exit();
}
if (addr != NULL && len > 0) {
size_t copylen;
upflag |= P_UPF_HAVEMSG;
if (len >= PRUPANIC_BUFLEN) {
copylen = PRUPANIC_BUFLEN;
upflag |= P_UPF_TRUNCMSG;
} else {
copylen = len;
}
buf = kmem_zalloc(PRUPANIC_BUFLEN, KM_SLEEP);
if (copyin(addr, buf, copylen) != 0) {
upflag |= P_UPF_INVALMSG;
upflag &= ~P_UPF_HAVEMSG;
} else {
mutex_enter(&p->p_lock);
ASSERT3P(p->p_upanic, ==, NULL);
p->p_upanic = buf;
mutex_exit(&p->p_lock);
}
}
mutex_enter(&p->p_lock);
p->p_upanicflag = upflag;
mutex_exit(&p->p_lock);
if (auditing) {
audit_finish(0, SYS_upanic, 0, NULL);
audit_core_start(SIGABRT);
}
code = core(SIGABRT, B_FALSE);
if (auditing)
audit_core_finish(code ? CLD_KILLED : CLD_DUMPED);
exit(code ? CLD_KILLED : CLD_DUMPED, SIGABRT);
}