2 * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
7 #include "x86_signals.h"
11 #include <KernelExport.h>
18 #include "syscall_numbers.h"
21 // implemented in assembly
22 extern "C" void x86_signal_frame_function_beos(signal_frame_data
* frameData
);
26 x86_signal_frame_function(signal_frame_data
* frameData
)
28 // Note: This function is copied to the commpage. Hence it needs to be
29 // position independent. We don't build this source file with the respective
30 // flags, but the code the compiler generates for this function is position
31 // independent anyway. It simply doesn't contain constructs that could
32 // result in position dependent code. The potentially problematic jumps
33 // needed due to the "if" statement are all harmless relative jumps.
35 if (frameData
->siginfo_handler
) {
36 // SA_SIGINFO style handler function -- we additionally pass the user
38 void (*handler
)(int, siginfo_t
*, void*, void*)
39 = (void (*)(int, siginfo_t
*, void*, void*))frameData
->handler
;
40 handler(frameData
->info
.si_signo
, &frameData
->info
,
41 &frameData
->context
, frameData
->user_data
);
43 // Simple handler function -- we call it with additional user data
44 // pointer and vregs parameters. Note that unlike in BeOS the last
45 // parameter is a pointer to a vregs structure, while in BeOS the
46 // structure was passed be value. For setting up a BeOS binary
47 // compatible signal handler call x86_signal_frame_function_beos() is
49 void (*handler
)(int, void*, vregs
*)
50 = (void (*)(int, void*, vregs
*))frameData
->handler
;
51 handler(frameData
->info
.si_signo
, frameData
->user_data
,
52 &frameData
->context
.uc_mcontext
);
55 #define TO_STRING_LITERAL_HELPER(number) #number
56 #define TO_STRING_LITERAL(number) TO_STRING_LITERAL_HELPER(number)
58 // call the restore_signal_frame() syscall -- does not return (here)
60 // push frameData -- the parameter to restore_signal_frame()
62 // push a dummy return value
64 // syscall number to eax
65 "movl $" TO_STRING_LITERAL(SYSCALL_RESTORE_SIGNAL_FRAME
) ", %%eax;"
71 #undef TO_STRING_LITERAL_HELPER
72 #undef TO_STRING_LITERAL
77 register_signal_handler_function(const char* functionName
, int32 commpageIndex
,
78 const char* commpageSymbolName
, addr_t expectedAddress
)
80 // look up the x86_signal_frame_function() symbol -- we have its address,
81 // but also need its size
82 elf_symbol_info symbolInfo
;
83 if (elf_lookup_kernel_symbol(functionName
, &symbolInfo
)
85 panic("x86_initialize_commpage_signal_handler(): Failed to find "
86 "signal frame function \"%s\"!", functionName
);
89 ASSERT(expectedAddress
== symbolInfo
.address
);
91 // fill in the commpage table entry
92 addr_t position
= fill_commpage_entry(commpageIndex
,
93 (void*)symbolInfo
.address
, symbolInfo
.size
);
95 // add symbol to the commpage image
96 image_id image
= get_commpage_image();
97 elf_add_memory_image_symbol(image
, commpageSymbolName
, position
,
98 symbolInfo
.size
, B_SYMBOL_TYPE_TEXT
);
103 x86_initialize_commpage_signal_handler()
106 register_signal_handler_function("x86_signal_frame_function",
107 COMMPAGE_ENTRY_X86_SIGNAL_HANDLER
, "commpage_signal_handler",
108 (addr_t
)&x86_signal_frame_function
);
110 // handler for BeOS backwards compatibility
111 register_signal_handler_function("x86_signal_frame_function_beos",
112 COMMPAGE_ENTRY_X86_SIGNAL_HANDLER_BEOS
, "commpage_signal_handler_beos",
113 (addr_t
)&x86_signal_frame_function_beos
);
118 x86_get_user_signal_handler_wrapper(bool beosHandler
, void* commPageAdddress
)
120 int32 index
= beosHandler
121 ? COMMPAGE_ENTRY_X86_SIGNAL_HANDLER_BEOS
122 : COMMPAGE_ENTRY_X86_SIGNAL_HANDLER
;
123 return ((addr_t
*)commPageAdddress
)[index
] + (addr_t
)commPageAdddress
;