kernel/x86_64: compatibility syscalls for signal.cpp.

* handle 32-bit types in _user_send_signal(), _user_sigaction(), _user_sigwait(),
_user_set_signal_stack(), _user_restore_signal_frame(), other syscalls are
compatible as is.

Change-Id: I4c8dc47bfa80f36e363d444d2a5a7be6c621606d
This commit is contained in:
Jérôme Duval
2018-06-12 17:56:55 +02:00
parent c70cba914a
commit aac8d4c317
3 changed files with 132 additions and 26 deletions
@@ -39,6 +39,7 @@ typedef struct __compat_siginfo_t {
union compat_sigval si_value; /* signal value */
} compat_siginfo_t;
struct compat_signal_frame_data {
compat_siginfo_t info;
compat_ucontext_t context;
@@ -19,4 +19,52 @@ struct compat_sigaction {
} _PACKED;
inline status_t
copy_ref_var_from_user(struct sigaction* userAction, struct sigaction &action)
{
if (!IS_USER_ADDRESS(userAction))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
struct compat_sigaction compat_action;
if (user_memcpy(&compat_action, userAction, sizeof(compat_sigaction))
< B_OK) {
return B_BAD_ADDRESS;
}
action.sa_handler = (__sighandler_t)(addr_t)compat_action.sa_handler;
action.sa_mask = compat_action.sa_mask;
action.sa_flags = compat_action.sa_flags;
action.sa_userdata = (void*)(addr_t)compat_action.sa_userdata;
} else if (user_memcpy(&action, userAction, sizeof(action)) < B_OK) {
return B_BAD_ADDRESS;
}
return B_OK;
}
inline status_t
copy_ref_var_to_user(struct sigaction &action, struct sigaction* userAction)
{
if (!IS_USER_ADDRESS(userAction))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
struct compat_sigaction compat_action;
compat_action.sa_handler = (addr_t)action.sa_handler;
compat_action.sa_mask = action.sa_mask;
compat_action.sa_flags = action.sa_flags;
compat_action.sa_userdata = (addr_t)action.sa_userdata;
if (user_memcpy(userAction, &compat_action, sizeof(compat_action))
< B_OK) {
return B_BAD_ADDRESS;
}
} else if (user_memcpy(userAction, &action, sizeof(action)) < B_OK) {
return B_BAD_ADDRESS;
}
return B_OK;
}
#endif // _KERNEL_COMPAT_SIGNAL_H