GCC Code Coverage Report


Directory: src/gate/
File: src/gate/platform/posix/posixcallstack.c
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 2 10 20.0%
Functions: 1 3 33.3%
Branches: 1 8 12.5%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/platform/posix/posixcallstack.h"
30
31 #if defined(GATE_SYS_POSIX) || defined(GATE_SYS_EFI)
32
33 typedef void* (*gate_posix_callstack_create_native_t)(void*, gate_callstack_context_t*, void*, void*);
34 typedef void* (*gate_posix_callstack_switch_native_t)(gate_callstack_context_t*, gate_callstack_context_t*);
35
36
37 #if defined(GATE_COMPILE_ASM_SUPPORT)
38 # if (GATE_ARCH == GATE_ARCH_X86IA32)
39 extern void* gate_posix_callstack_create_x86(void*, gate_callstack_context_t*, void*, void*);
40 extern void* gate_posix_callstack_switch_x86(gate_callstack_context_t*, gate_callstack_context_t*);
41 # define NATIVE_CALLSTACK_CREATE_FUNC gate_posix_callstack_create_x86
42 # define NATIVE_CALLSTACK_SWITCH_FUNC gate_posix_callstack_switch_x86
43 # elif (GATE_ARCH == GATE_ARCH_X86X64)
44 extern void* gate_posix_callstack_create_x64(void*, gate_callstack_context_t*, void*, void*);
45 extern void* gate_posix_callstack_switch_x64(gate_callstack_context_t*, gate_callstack_context_t*);
46 # define NATIVE_CALLSTACK_CREATE_FUNC gate_posix_callstack_create_x64
47 # define NATIVE_CALLSTACK_SWITCH_FUNC gate_posix_callstack_switch_x64
48 # elif (GATE_ARCH == GATE_ARCH_ARM32)
49 extern void* gate_posix_callstack_create_arm32(void*, gate_callstack_context_t*, void*, void*);
50 extern void* gate_posix_callstack_switch_arm32(gate_callstack_context_t*, gate_callstack_context_t*);
51 # define NATIVE_CALLSTACK_CREATE_FUNC gate_posix_callstack_create_arm32
52 # define NATIVE_CALLSTACK_SWITCH_FUNC gate_posix_callstack_switch_arm32
53 # elif (GATE_ARCH == GATE_ARCH_ARM64)
54 extern void* gate_posix_callstack_create_arm64(void*, gate_callstack_context_t*, void*, void*);
55 extern void* gate_posix_callstack_switch_arm64(gate_callstack_context_t*, gate_callstack_context_t*);
56 # define NATIVE_CALLSTACK_CREATE_FUNC gate_posix_callstack_create_arm64
57 # define NATIVE_CALLSTACK_SWITCH_FUNC gate_posix_callstack_switch_arm64
58 # else
59 # define NATIVE_CALLSTACK_CREATE_FUNC NULL
60 # define NATIVE_CALLSTACK_SWITCH_FUNC NULL
61 # endif
62 #else
63 # define NATIVE_CALLSTACK_CREATE_FUNC NULL
64 # define NATIVE_CALLSTACK_SWITCH_FUNC NULL
65
66 #endif
67
68 /*
69 NOTICE:
70 Use function pointers to native ASM routines to try to ensure that
71 LTO/WPO does not apply any kind of inlining which bypasses CDECL/ABI function calls.
72 We want that the compiler saves all auxiliary data registers (e.g. x87/mmx/xmm
73 before the native code switches stacks and mandatory CPU registers.
74 */
75
76 static gate_posix_callstack_create_native_t native_callstack_create = NATIVE_CALLSTACK_CREATE_FUNC;
77 static gate_posix_callstack_switch_native_t native_callstack_switch = NATIVE_CALLSTACK_SWITCH_FUNC;
78
79 3 gate_bool_t gate_posix_callstack_supported()
80 {
81
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 return native_callstack_create && native_callstack_switch;
82 }
83
84 void* gate_posix_callstack_create(
85 void* stack_ptr_top,
86 gate_callstack_context_t* store_old_stack,
87 void* func_ptr, void* func_param)
88 {
89 if (native_callstack_create)
90 {
91 return native_callstack_create(stack_ptr_top, store_old_stack, func_ptr, func_param);
92 }
93 return NULL;
94 }
95
96 void* gate_posix_callstack_switch(
97 gate_callstack_context_t* store_current_context,
98 gate_callstack_context_t* load_next_context)
99 {
100 if (native_callstack_switch)
101 {
102 return native_callstack_switch(store_current_context, load_next_context);
103 }
104 return NULL;
105 }
106
107 #endif
108