xref: /minix3/minix/lib/libvassert/vassert.h (revision 65f76edb8f568553a5b4386b0c4917803d47e97d)
1433d6423SLionel Sambuc #ifndef _VASSERT_H_
2433d6423SLionel Sambuc #define _VASSERT_H_
3433d6423SLionel Sambuc 
4433d6423SLionel Sambuc #ifdef __cplusplus
5433d6423SLionel Sambuc extern "C"
6433d6423SLionel Sambuc {
7433d6423SLionel Sambuc #endif /*__cplusplus*/
8433d6423SLionel Sambuc 
9433d6423SLionel Sambuc #define ALIGNED(n) __attribute__((__aligned__(n)))
10433d6423SLionel Sambuc #define VASSERT_TRIGGER_OFFSET 1221
11433d6423SLionel Sambuc #define VASSERT_PAGE_SIZE      4096
12433d6423SLionel Sambuc 
13433d6423SLionel Sambuc /* Need to align at 4K. */
14433d6423SLionel Sambuc /* Ensure the inReplay flag is on its own page. */
15433d6423SLionel Sambuc #pragma pack(1)
16433d6423SLionel Sambuc typedef struct VAssert_StateWrapper {
17433d6423SLionel Sambuc    char space1[VASSERT_TRIGGER_OFFSET];
18433d6423SLionel Sambuc    volatile char inReplay;
19433d6423SLionel Sambuc    char space[VASSERT_PAGE_SIZE - VASSERT_TRIGGER_OFFSET - sizeof(char)];
20433d6423SLionel Sambuc } VAssert_StateWrapper;
21433d6423SLionel Sambuc #pragma pack()
22433d6423SLionel Sambuc 
23433d6423SLionel Sambuc extern VAssert_StateWrapper vassert_state;
24433d6423SLionel Sambuc 
25433d6423SLionel Sambuc /*
26433d6423SLionel Sambuc  * User-selectable standard functions.
27433d6423SLionel Sambuc  * XXX: Document these, in coordination with the SDK docs.
28433d6423SLionel Sambuc  */
29433d6423SLionel Sambuc 
30433d6423SLionel Sambuc #if defined(__KERNEL__)
31433d6423SLionel Sambuc #  define KERNEL_VASSERT
32433d6423SLionel Sambuc #endif
33433d6423SLionel Sambuc 
34433d6423SLionel Sambuc #ifdef KERNEL_VASSERT
35433d6423SLionel Sambuc 
36433d6423SLionel Sambuc #  ifndef VASSERT_CUSTOM_ASSERT
37433d6423SLionel Sambuc #     define VASSERT_CUSTOM_ASSERT(expr)
38433d6423SLionel Sambuc #  endif
39433d6423SLionel Sambuc 
40433d6423SLionel Sambuc #  ifndef VASSERT_CUSTOM_ABORT
41433d6423SLionel Sambuc #     include <linux/kernel.h>
42433d6423SLionel Sambuc #     define VASSERT_CUSTOM_ABORT() ((void)0) // printk(KERN_ALERT"VAssert abort at %s: %d", __FILE__, __LINE__)
43433d6423SLionel Sambuc #  endif
44433d6423SLionel Sambuc 
45433d6423SLionel Sambuc #  ifndef VASSERT_CUSTOM_LOG
46433d6423SLionel Sambuc #     include <linux/kernel.h>
47433d6423SLionel Sambuc #     define VASSERT_CUSTOM_LOG printk
48433d6423SLionel Sambuc #  endif
49433d6423SLionel Sambuc 
50433d6423SLionel Sambuc #else
51433d6423SLionel Sambuc #  ifndef VASSERT_CUSTOM_ASSERT
52433d6423SLionel Sambuc #     include <assert.h>
53433d6423SLionel Sambuc #     define VASSERT_CUSTOM_ASSERT assert
54433d6423SLionel Sambuc #  endif
55433d6423SLionel Sambuc 
56433d6423SLionel Sambuc #  ifndef VASSERT_CUSTOM_ABORT
57433d6423SLionel Sambuc #     include <stdlib.h>
58433d6423SLionel Sambuc #     define VASSERT_CUSTOM_ABORT abort
59433d6423SLionel Sambuc #  endif
60433d6423SLionel Sambuc 
61433d6423SLionel Sambuc #  ifndef VASSERT_CUSTOM_LOG
62433d6423SLionel Sambuc #     include <stdio.h>
63433d6423SLionel Sambuc #     define VASSERT_CUSTOM_LOG printf
64433d6423SLionel Sambuc #  endif
65433d6423SLionel Sambuc #endif
66433d6423SLionel Sambuc 
67433d6423SLionel Sambuc /* Results: 0 if successful, -1 if not. */
68433d6423SLionel Sambuc // XXX need to automatic de-register trigger page when the program quits
69433d6423SLionel Sambuc extern char VAssert_Init(void);
70433d6423SLionel Sambuc extern char VAssert_Uninit(void);
71433d6423SLionel Sambuc 
72433d6423SLionel Sambuc /*
73433d6423SLionel Sambuc  * These functions should not be called directly; they need to be wrapped.
74433d6423SLionel Sambuc  */
75*65f76edbSDavid van Moolenbroek extern void VAssert_LogMain(const char *format, ...)
76*65f76edbSDavid van Moolenbroek 	__attribute__((__format__(__printf__, 1, 2)));
77433d6423SLionel Sambuc extern void VAssert_GoLiveMain(void);
78433d6423SLionel Sambuc extern void VAssert_ReturnToReplayMain(void);
79433d6423SLionel Sambuc extern char VAssert_Trace(size_t max_size);
80433d6423SLionel Sambuc 
81433d6423SLionel Sambuc #ifdef VASSERT_ALWAYS_EXECUTE
82433d6423SLionel Sambuc 
83433d6423SLionel Sambuc #define VAssert_Assert(expr)              \
84433d6423SLionel Sambuc do {                                      \
85433d6423SLionel Sambuc    VASSERT_CUSTOM_ASSERT(expr);           \
86433d6423SLionel Sambuc } while (0)
87433d6423SLionel Sambuc 
88433d6423SLionel Sambuc #define VAssert_Log(args)                 \
89433d6423SLionel Sambuc do {                                      \
90433d6423SLionel Sambuc    VASSERT_CUSTOM_LOG args;               \
91433d6423SLionel Sambuc } while (0)
92433d6423SLionel Sambuc 
93433d6423SLionel Sambuc #define VAssert_BeginBlock
94433d6423SLionel Sambuc #define VAssert_EndBlock
95433d6423SLionel Sambuc 
96433d6423SLionel Sambuc #else /* VASSERT_ALWAYS_EXECUTE */
97433d6423SLionel Sambuc 
98433d6423SLionel Sambuc #define VAssert_Assert(expr)              \
99433d6423SLionel Sambuc do {                                      \
100433d6423SLionel Sambuc    if (vassert_state.inReplay) {          \
101433d6423SLionel Sambuc       if (!(expr)) {                      \
102433d6423SLionel Sambuc          VAssert_GoLiveMain();            \
103433d6423SLionel Sambuc          VASSERT_CUSTOM_ABORT();          \
104433d6423SLionel Sambuc       } else {                            \
105433d6423SLionel Sambuc          VAssert_ReturnToReplayMain();    \
106433d6423SLionel Sambuc       }                                   \
107433d6423SLionel Sambuc    }                                      \
108433d6423SLionel Sambuc } while (0)
109433d6423SLionel Sambuc 
110433d6423SLionel Sambuc #define VAssert_Log(args)                 \
111433d6423SLionel Sambuc do {                                      \
112433d6423SLionel Sambuc    if (vassert_state.inReplay) {          \
113433d6423SLionel Sambuc       VAssert_LogMain args;               \
114433d6423SLionel Sambuc       VAssert_ReturnToReplayMain();       \
115433d6423SLionel Sambuc    }                                      \
116433d6423SLionel Sambuc } while (0)
117433d6423SLionel Sambuc 
118433d6423SLionel Sambuc #define VAssert_BeginBlock if (vassert_state.inReplay)
119433d6423SLionel Sambuc #define VAssert_EndBlock VAssert_ReturnToReplayMain()
120433d6423SLionel Sambuc 
121433d6423SLionel Sambuc #endif /* VASSERT_ALWAYS_EXECUTE */
122433d6423SLionel Sambuc 
123433d6423SLionel Sambuc /*
124433d6423SLionel Sambuc  * Record/Replay functionality
125433d6423SLionel Sambuc  */
126433d6423SLionel Sambuc /*
127433d6423SLionel Sambuc  * Results: True if successful, false if not.
128433d6423SLionel Sambuc  * Input: True to start recording, false to stop.
129433d6423SLionel Sambuc  */
130433d6423SLionel Sambuc extern char VAssert_SetRecordingMain(char start);
131433d6423SLionel Sambuc 
132433d6423SLionel Sambuc #define VAssert_StartRecording() VAssert_SetRecordingMain(1)
133433d6423SLionel Sambuc #define VAssert_StopRecording() VAssert_SetRecordingMain(0)
134433d6423SLionel Sambuc 
135433d6423SLionel Sambuc #ifdef __cplusplus
136433d6423SLionel Sambuc }
137433d6423SLionel Sambuc #endif /*__cplusplus*/
138433d6423SLionel Sambuc 
139433d6423SLionel Sambuc #endif /*_VASSERT_H_*/
140