1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120 | #include "gate/functions.h"
#include "gate/results.h"
#include "gate/console.h"
#include "gate/debugging.h"
static gate_result_t GATE_CALL no_fault_entry(void* arg)
{
GATE_UNUSED_ARG(arg);
return GATE_RESULT_OK;
}
static gate_result_t GATE_CALL seg_fault_entry(void* arg)
{
int volatile* volatile ptr = (int volatile*)arg;
volatile int n = *ptr;
*ptr = n;
return GATE_RESULT_OK;
}
static volatile int zero = 0;
static gate_result_t GATE_CALL div_fault_entry(void* arg)
{
int volatile value = 42;
int volatile result;
(void)arg;
result = value / zero; // cppcheck-suppress zerodiv<--- Division by zero
value = result * zero; // cppcheck-suppress unreadVariable<--- Variable 'value' is assigned a value that is never used.<--- Unmatched suppression: zerodiv
return GATE_RESULT_OK;<--- Unmatched suppression: unreadVariable
}
static volatile float zerof = 0.0f;
static gate_result_t GATE_CALL float_fault_entry(void* arg)
{
float value = 42.0f;
float result;
(void)arg;
result = value / zerof;
value = result * zerof; // cppcheck-suppress unreadVariable<--- Variable 'value' is assigned a value that is never used.
return GATE_RESULT_OK;<--- Unmatched suppression: unreadVariable
}
static gate_result_t GATE_CALL fault_handler(unsigned fault_code, void* fault_arg)
{
if (fault_arg)
{
unsigned* volatile ptr = (unsigned* volatile)fault_arg; // cppcheck-suppress unreadVariable<--- Variable 'ptr' is not assigned a value.<--- Uninitialized variable: ptr
*ptr = fault_code; // cppcheck-suppress uninitvar<--- Uninitialized variable: ptr<--- Unmatched suppression: unreadVariable
}<--- Unmatched suppression: uninitvar
else
{
GATE_DEBUG_TRACE("Missing fault_arg");
}
return GATE_RESULT_OK;
}
static gate_bool_t test_function_fault_succeed(gate_entrypoint_t entry, void* arg)
{
gate_result_t ret = true;
gate_result_t result;
unsigned fault_code = 0;
result = gate_function_invoke_guarded(entry, arg, &fault_handler, &fault_code);
if (GATE_FAILED(result))
{
GATE_DEBUG_TRACE("correct function failed to executed with fault guard");
ret = false;
}
if (fault_code != 0)
{
GATE_DEBUG_TRACE_MSG_VALUE("unexpected fault code", fault_code);
ret = false;
}
return ret;
}
static gate_bool_t test_function_fault_fail(gate_entrypoint_t entry, void* arg, unsigned expected_fault_code)
{
gate_bool_t ret = true;
gate_result_t result;
unsigned fault_code = 0;
result = gate_function_invoke_guarded(entry, arg, &fault_handler, &fault_code);
if (result != GATE_RESULT_BADINSTRUCTION)
{
GATE_DEBUG_TRACE_MSG_VALUE("unexpected result of bad-instruction function", result);
ret = false;
}
if (fault_code != expected_fault_code)
{
GATE_DEBUG_TRACE_MSG_VALUE("unexpected result of bad-instruction function", fault_code);
ret = false;
}
return ret;
}
gate_bool_t test_fault_guard()
{
gate_bool_t succeeded = true;
#if !defined(GATE_SYS_BSD)
GATE_DEBUG_TRACE("Test correct function with fault guard");
succeeded &= test_function_fault_succeed(&no_fault_entry, NULL);
#if !defined(GATE_SYS_DOS)
GATE_DEBUG_TRACE("Test bad segfault function with fault guard");
succeeded &= test_function_fault_fail(&seg_fault_entry, NULL, GATE_FUNCTION_FAULT_ADDRESS);
GATE_DEBUG_TRACE("Test bad integer-error function with fault guard");
succeeded &= test_function_fault_fail(&div_fault_entry, NULL, GATE_FUNCTION_FAULT_ARITHMETIC);
#endif
#if defined(GATE_SYS_WIN)
// floating-point errors are not raised on
GATE_DEBUG_TRACE("Test bad floating-point-error function with fault guard");
succeeded &= test_function_fault_fail(&float_fault_entry, NULL, GATE_FUNCTION_FAULT_FLOAT);
#endif
#endif
return succeeded;
}
|