1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2025 The FreeBSD Foundation 5 * All rights reserved. 6 * 7 * This software were developed by Konstantin Belousov <kib@FreeBSD.org> 8 * under sponsorship from the FreeBSD Foundation. 9 */ 10 11 #ifndef _SYS_EXTERRVAR_H_ 12 #define _SYS_EXTERRVAR_H_ 13 14 #include <sys/_exterr.h> 15 #include <sys/_uexterror.h> 16 #include <sys/exterr_cat.h> 17 #ifdef EXTERR_CATEGORY_DYNAMIC 18 #include <sys/linker_set.h> 19 #endif 20 21 #define UEXTERROR_MAXLEN 256 22 23 #define UEXTERROR_VER 0x10010002 24 25 #define EXTERRCTL_ENABLE 1 26 #define EXTERRCTL_DISABLE 2 27 #define EXTERRCTL_UD 3 28 29 #define EXTERRCTLF_FORCE 0x00000001 30 31 #ifdef _KERNEL 32 33 struct exterr_cat { 34 unsigned int cat; 35 const char *file; 36 }; 37 38 struct thread; 39 40 #ifdef EXTERR_CATEGORY_DYNAMIC 41 #ifdef EXTERR_STRINGS 42 static struct exterr_cat __dynamic_cat = { .file = EXTERR_CATEGORY_DYNAMIC }; 43 DATA_WSET(exterr_cats, __dynamic_cat); 44 #define EXTERR_CATEGORY (__dynamic_cat.cat | EXTERR_CAT_SRC_KERN_DYNAMIC) 45 #else 46 #define EXTERR_CATEGORY EXTERR_CAT_NONE 47 #endif 48 #endif 49 50 #ifndef EXTERR_CATEGORY 51 #error "Specify error category before including sys/exterrvar.h" 52 #endif 53 54 #ifdef EXTERR_STRINGS 55 #define SET_ERROR_MSG(mmsg) (mmsg) 56 #else 57 #define SET_ERROR_MSG(mmsg) NULL 58 #endif 59 60 #define _SET_ERROR2_KE(kep, eerror, mmsg, pp1, pp2) ({ \ 61 (kep)->error = (eerror); \ 62 (kep)->cat = EXTERR_CATEGORY; \ 63 (kep)->msg = SET_ERROR_MSG(mmsg); \ 64 (kep)->p1 = (pp1); \ 65 (kep)->p2 = (pp2); \ 66 (kep)->src_line = __LINE__; \ 67 (kep)->error; \ 68 }) 69 #define _SET_ERROR0_KE(kep, eerror, mmsg) \ 70 _SET_ERROR2_KE(kep, eerror, mmsg, 0, 0) 71 #define _SET_ERROR1_KE(kep, eerror, mmsg, pp1) \ 72 _SET_ERROR2_KE(kep, eerror, mmsg, pp1, 0) 73 74 #define _EXTERROR_MACRO_KE(kep, eerror, mmsg, _1, _2, NAME, ...) \ 75 NAME 76 #define EXTERROR_KE(...) \ 77 _EXTERROR_MACRO_KE(__VA_ARGS__, _SET_ERROR2_KE, _SET_ERROR1_KE, \ 78 _SET_ERROR0_KE)(__VA_ARGS__) 79 80 #define _SET_ERROR2(eerror, mmsg, pp1, pp2) \ 81 exterr_set(eerror, EXTERR_CATEGORY, SET_ERROR_MSG(mmsg), \ 82 (uint64ptr_t)(pp1), (uint64ptr_t)(pp2), __LINE__) 83 #define _SET_ERROR0(eerror, mmsg) _SET_ERROR2(eerror, mmsg, 0, 0) 84 #define _SET_ERROR1(eerror, mmsg, pp1) _SET_ERROR2(eerror, mmsg, pp1, 0) 85 86 #define _EXTERROR_MACRO(eerror, mmsg, _1, _2, NAME, ...) \ 87 NAME 88 #define EXTERROR(...) \ 89 _EXTERROR_MACRO(__VA_ARGS__, _SET_ERROR2, _SET_ERROR1, \ 90 _SET_ERROR0)(__VA_ARGS__) 91 92 void exterr_clear(struct kexterr *ke); 93 void exterr_db_print(struct kexterr *ke); 94 int exterr_set_from(const struct kexterr *ke); 95 int exterr_set(int eerror, int category, const char *mmsg, uint64ptr_t pp1, 96 uint64ptr_t pp2, int line); 97 int exterr_to_ue(struct thread *td, struct uexterror *ue); 98 void ktrexterr(struct thread *td); 99 void exterr_cat_register_module(struct exterr_cat **start, 100 struct exterr_cat **stop); 101 void exterr_cat_unregister_module(struct exterr_cat **start, 102 struct exterr_cat **stop); 103 104 #else /* !_KERNEL */ 105 106 #include <sys/types.h> 107 108 __BEGIN_DECLS 109 int exterrctl(u_int op, u_int flags, void *ptr); 110 __END_DECLS 111 112 #endif /* _KERNEL */ 113 114 #endif 115