1 /**
2  * \file
3  * Low-level assert implementation.
4  */
5 /*
6  * (c) 2015 Adam Lackorzynski <adam@l4re.org>
7  *
8  * This file is part of L4Re and distributed under the terms of the
9  * GNU General Public License 2.
10  * Please see the COPYING-GPL-2 file for details.
11  *
12  * As a special exception, you may use this file as part of a free software
13  * library without restriction.  Specifically, if other files instantiate
14  * templates or use macros or inline functions from this file, or you compile
15  * this file and link it with other files to produce an executable, this
16  * file does not by itself cause the resulting executable to be covered by
17  * the GNU General Public License.  This exception does not however
18  * invalidate any other reasons why the executable file might be covered by
19  * the GNU General Public License.
20  */
21 #pragma once
22 
23 #ifdef NDEBUG
24 
25 #define l4_assert(x) do { } while (0)
26 #define l4_check(x) do { (void)(x); } while (0)
27 
28 #else
29 
30 #include <l4/sys/compiler.h>
31 #include <l4/sys/thread.h>
32 #include <l4/sys/vcon.h>
33 
34 /**
35  * Low-level assert.
36  *
37  * \param expr  Expression to be evaluate for the assertion.
38  *
39  * This assertion is a low-level implementation that directly uses
40  * kernel primitives. Only use l4_assert() when the standard assert()
41  * functionality is not available.
42  */
43 #define l4_assert(expr) \
44   l4_assert_fn(expr, __FILE__ ":" L4_stringify(__LINE__) ": Assertion \"" \
45                      L4_stringify(expr) "\" failed.\n")
46 
47 #define l4_check(expr) l4_assert(expr)
48 
49 /**
50  * \internal
51  */
52 L4_ALWAYS_INLINE
53 void l4_assert_fn(bool expr, const char *text) L4_NOTHROW;
54 
55 /**
56  * \internal
57  */
58 L4_INLINE L4_NORETURN
59 void l4_assert_abort(const char *text) L4_NOTHROW;
60 
61 
62 /* IMPLEMENTATION -----------------------------------------------------------*/
63 
64 L4_INLINE L4_NORETURN
l4_assert_abort(const char * text)65 void l4_assert_abort(const char *text) L4_NOTHROW
66 {
67   l4_vcon_write(L4_BASE_LOG_CAP, text, __builtin_strlen(text));
68   for (;;)
69     l4_thread_ex_regs(L4_INVALID_CAP, ~0UL, ~0UL,
70                       L4_THREAD_EX_REGS_TRIGGER_EXCEPTION);
71 }
72 
73 L4_ALWAYS_INLINE
l4_assert_fn(bool expr,const char * text)74 void l4_assert_fn(bool expr, const char *text) L4_NOTHROW
75 {
76   if (L4_LIKELY(expr))
77     return;
78 
79   l4_assert_abort(text);
80 }
81 
82 #endif /* NDEBUG */
83