1/* @title: Kernel Panic Interface */
2#pragma once
3#include <compiler/core.h>
4#include <compiler/intrinsic.h>
5#include <console/crash.h>
6
7cc_noreturn cc_cold cc_printf_like(4, 5) cc_nonnull(1, 3, 4) void
8panic_impl_msg(const char *file, int line, const char *func, const char *fmt,
9 ...);
10cc_noreturn cc_cold cc_printf_like(5, 6) cc_nonnull(1, 3, 5) void
11panic_impl_code(const char *file, int line, const char *func,
12 const struct crash_code *code, const char *fmt, ...);
13cc_noreturn cc_cold cc_nonnull(1, 3) void
14panic_impl_code_only(const char *file, int line, const char *func,
15 const struct crash_code *code);
16
17#define _panic_pick(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, \
18 _13, _14, _15, _16, NAME, ...) \
19 NAME
20
21#define _panic_arity(...) \
22 _panic_pick(_, ##__VA_ARGS__, _panic_n, _panic_n, _panic_n, _panic_n, \
23 _panic_n, _panic_n, _panic_n, _panic_n, _panic_n, _panic_n, \
24 _panic_n, _panic_n, _panic_n, _panic_n, _panic_n, _panic_1, \
25 _panic_0)
26
27#define _panic_fn(a, code_fn) \
28 cc_generic((a), char * : panic_impl_msg, const char * : panic_impl_msg, \
29 default : code_fn)
30
31/* panic() */
32#define _panic_0() panic_impl_code_only(__FILE__, __LINE__, __func__, NULL)
33
34/*
35 * panic("msg")
36 * panic(INVALID_STATE)
37 * panic((asan, RUNTIME))
38 *
39 * more about CRASH_CODE_ARG in console/crash.h
40 */
41#define _panic_1(a) \
42 CRASH_CODE_SCOPED(a, _panic_fn(CRASH_CODE_ARG(a), panic_impl_code_only)( \
43 __FILE__, __LINE__, __func__, CRASH_CODE_ARG(a)))
44
45/*
46 * panic("msg %d", 12)
47 * panic(INVALID_STATE, "msg %d", 12)
48 * panic((asan, RUNTIME), "msg %d", 12)
49 */
50#define _panic_n(a, ...) \
51 CRASH_CODE_SCOPED( \
52 a, _panic_fn(CRASH_CODE_ARG(a), panic_impl_code)( \
53 __FILE__, __LINE__, __func__, CRASH_CODE_ARG(a), __VA_ARGS__))
54
55#define panic(...) _panic_arity(__VA_ARGS__)(__VA_ARGS__)
56