Implemented signals for x86_64.
This commit is contained in:
@@ -12,35 +12,108 @@
|
||||
|
||||
#if __x86_64__
|
||||
|
||||
struct vregs {
|
||||
unsigned long rax; /* gp regs */
|
||||
unsigned long rdx;
|
||||
unsigned long rcx;
|
||||
unsigned long rbx;
|
||||
unsigned long rsi;
|
||||
unsigned long rdi;
|
||||
unsigned long rbp;
|
||||
unsigned long rsp;
|
||||
|
||||
unsigned long r8; /* egp regs */
|
||||
unsigned long r9;
|
||||
unsigned long r10;
|
||||
unsigned long r11;
|
||||
unsigned long r12;
|
||||
unsigned long r13;
|
||||
unsigned long r14;
|
||||
unsigned long r15;
|
||||
|
||||
unsigned long rip;
|
||||
|
||||
/*TODO: add
|
||||
* Floatpoint
|
||||
* MMX
|
||||
* SSE
|
||||
*/
|
||||
|
||||
struct fp_stack {
|
||||
unsigned char st0[10];
|
||||
unsigned char _reserved_42_47[6];
|
||||
unsigned char st1[10];
|
||||
unsigned char _reserved_58_63[6];
|
||||
unsigned char st2[10];
|
||||
unsigned char _reserved_74_79[6];
|
||||
unsigned char st3[10];
|
||||
unsigned char _reserved_90_95[6];
|
||||
unsigned char st4[10];
|
||||
unsigned char _reserved_106_111[6];
|
||||
unsigned char st5[10];
|
||||
unsigned char _reserved_122_127[6];
|
||||
unsigned char st6[10];
|
||||
unsigned char _reserved_138_143[6];
|
||||
unsigned char st7[10];
|
||||
unsigned char _reserved_154_159[6];
|
||||
};
|
||||
|
||||
struct mmx_regs {
|
||||
unsigned char mm0[10];
|
||||
unsigned char _reserved_42_47[6];
|
||||
unsigned char mm1[10];
|
||||
unsigned char _reserved_58_63[6];
|
||||
unsigned char mm2[10];
|
||||
unsigned char _reserved_74_79[6];
|
||||
unsigned char mm3[10];
|
||||
unsigned char _reserved_90_95[6];
|
||||
unsigned char mm4[10];
|
||||
unsigned char _reserved_106_111[6];
|
||||
unsigned char mm5[10];
|
||||
unsigned char _reserved_122_127[6];
|
||||
unsigned char mm6[10];
|
||||
unsigned char _reserved_138_143[6];
|
||||
unsigned char mm7[10];
|
||||
unsigned char _reserved_154_159[6];
|
||||
};
|
||||
|
||||
struct xmm_regs {
|
||||
unsigned char xmm0[16];
|
||||
unsigned char xmm1[16];
|
||||
unsigned char xmm2[16];
|
||||
unsigned char xmm3[16];
|
||||
unsigned char xmm4[16];
|
||||
unsigned char xmm5[16];
|
||||
unsigned char xmm6[16];
|
||||
unsigned char xmm7[16];
|
||||
unsigned char xmm8[16];
|
||||
unsigned char xmm9[16];
|
||||
unsigned char xmm10[16];
|
||||
unsigned char xmm11[16];
|
||||
unsigned char xmm12[16];
|
||||
unsigned char xmm13[16];
|
||||
unsigned char xmm14[16];
|
||||
unsigned char xmm15[16];
|
||||
};
|
||||
|
||||
struct fpu_state {
|
||||
unsigned short control;
|
||||
unsigned short status;
|
||||
unsigned short tag;
|
||||
unsigned short opcode;
|
||||
unsigned long rip;
|
||||
unsigned long rdp;
|
||||
unsigned int mxcsr;
|
||||
unsigned int mscsr_mask;
|
||||
|
||||
union {
|
||||
struct fp_stack fp;
|
||||
struct mmx_regs mmx;
|
||||
};
|
||||
|
||||
struct xmm_regs xmm;
|
||||
unsigned char _reserved_416_511[96];
|
||||
};
|
||||
|
||||
struct vregs {
|
||||
unsigned long rax;
|
||||
unsigned long rbx;
|
||||
unsigned long rcx;
|
||||
unsigned long rdx;
|
||||
unsigned long rdi;
|
||||
unsigned long rsi;
|
||||
unsigned long rbp;
|
||||
unsigned long r8;
|
||||
unsigned long r9;
|
||||
unsigned long r10;
|
||||
unsigned long r11;
|
||||
unsigned long r12;
|
||||
unsigned long r13;
|
||||
unsigned long r14;
|
||||
unsigned long r15;
|
||||
|
||||
unsigned long rsp;
|
||||
unsigned long rip;
|
||||
unsigned long rflags;
|
||||
|
||||
struct fpu_state fpu;
|
||||
};
|
||||
|
||||
|
||||
#endif /* __x86_64__ */
|
||||
|
||||
#endif /* _ARCH_SIGNAL_H_ */
|
||||
|
||||
@@ -25,8 +25,6 @@ struct iframe* x86_get_thread_user_iframe(Thread* thread);
|
||||
|
||||
phys_addr_t x86_next_page_directory(Thread* from, Thread* to);
|
||||
void x86_initial_return_to_userland(Thread* thread, struct iframe* iframe);
|
||||
uint8* x86_get_signal_stack(Thread* thread, struct iframe* frame,
|
||||
struct sigaction* action);
|
||||
|
||||
void x86_restart_syscall(struct iframe* frame);
|
||||
void x86_set_tls_context(Thread* thread);
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
|
||||
#define COMMPAGE_ENTRY_X86_MEMCPY (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0)
|
||||
#define COMMPAGE_ENTRY_X86_MEMSET (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1)
|
||||
#define COMMPAGE_ENTRY_X86_SIGNAL_HANDLER \
|
||||
(COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 2)
|
||||
|
||||
#define ARCH_USER_COMMPAGE_ADDR (0xffffffffffff0000)
|
||||
#define ARCH_USER_COMMPAGE_ADDR (0xffffffffffff0000)
|
||||
|
||||
#endif /* _SYSTEM_ARCH_x86_64_COMMPAGE_DEFS_H */
|
||||
|
||||
@@ -107,6 +107,22 @@ x86_set_tls_context(Thread *thread)
|
||||
}
|
||||
|
||||
|
||||
static uint8*
|
||||
get_signal_stack(Thread* thread, struct iframe* frame, struct sigaction* action)
|
||||
{
|
||||
// use the alternate signal stack if we should and can
|
||||
if (thread->signal_stack_enabled
|
||||
&& (action->sa_flags & SA_ONSTACK) != 0
|
||||
&& (frame->user_sp < thread->signal_stack_base
|
||||
|| frame->user_sp >= thread->signal_stack_base
|
||||
+ thread->signal_stack_size)) {
|
||||
return (uint8*)(thread->signal_stack_base + thread->signal_stack_size);
|
||||
}
|
||||
|
||||
return (uint8*)frame->user_sp;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
@@ -290,7 +306,7 @@ arch_setup_signal_frame(Thread* thread, struct sigaction* action,
|
||||
signalFrameData->context.uc_mcontext.ebx = frame->bx;
|
||||
x86_fnsave((void *)(&signalFrameData->context.uc_mcontext.xregs));
|
||||
|
||||
// fill in signalFrameData->context.uc_stack
|
||||
// Fill in signalFrameData->context.uc_stack
|
||||
signal_get_user_stack(frame->user_sp, &signalFrameData->context.uc_stack);
|
||||
|
||||
// store orig_eax/orig_edx in syscall_restart_return_value
|
||||
@@ -299,7 +315,7 @@ arch_setup_signal_frame(Thread* thread, struct sigaction* action,
|
||||
|
||||
// get the stack to use -- that's either the current one or a special signal
|
||||
// stack
|
||||
uint8* userStack = x86_get_signal_stack(thread, frame, action);
|
||||
uint8* userStack = get_signal_stack(thread, frame, action);
|
||||
|
||||
// copy the signal frame data onto the stack
|
||||
userStack -= sizeof(*signalFrameData);
|
||||
|
||||
@@ -337,8 +337,9 @@ FUNCTION(x86_64_syscall_entry):
|
||||
// Get the system call table entry. Note I'm hardcoding the shift because
|
||||
// sizeof(syscall_info) is 16 and scale factors of 16 aren't supported,
|
||||
// so can't just do leaq kSyscallInfos(, %rax, SYSCALL_INFO_sizeof).
|
||||
shlq $4, %r14
|
||||
leaq kSyscallInfos(, %r14, 1), %rax
|
||||
movq %r14, %rax
|
||||
shlq $4, %rax
|
||||
leaq kSyscallInfos(, %rax, 1), %rax
|
||||
|
||||
// Check the number of call arguments, greater than 6 (6 * 8 = 48) requires
|
||||
// a stack copy.
|
||||
@@ -388,6 +389,10 @@ FUNCTION(x86_64_syscall_entry):
|
||||
|
||||
UPDATE_THREAD_KERNEL_TIME()
|
||||
|
||||
// If we've just restored a signal frame, use the IRET path.
|
||||
cmpq $SYSCALL_RESTORE_SIGNAL_FRAME, %r14
|
||||
je .Liret
|
||||
|
||||
// If the return address is not canonical, return using the IRET path.
|
||||
// On Intel's implementation of SYSRET, the canonical address check for the
|
||||
// return address is performed before the switch to user mode, so a fault
|
||||
|
||||
@@ -15,12 +15,25 @@
|
||||
#include <elf.h>
|
||||
#include <smp.h>
|
||||
|
||||
#include "syscall_numbers.h"
|
||||
|
||||
extern "C" void _user_signal_handler(void);
|
||||
extern int _user_signal_handler_end;
|
||||
|
||||
|
||||
void
|
||||
x86_initialize_commpage_signal_handler()
|
||||
{
|
||||
// TODO x86_64
|
||||
void* handlerCode = (void*)&_user_signal_handler;
|
||||
void* handlerCodeEnd = &_user_signal_handler_end;
|
||||
|
||||
// Copy the signal handler code to the commpage.
|
||||
size_t len = (size_t)((addr_t)handlerCodeEnd - (addr_t)handlerCode);
|
||||
fill_commpage_entry(COMMPAGE_ENTRY_X86_SIGNAL_HANDLER, handlerCode, len);
|
||||
|
||||
// Add symbol to the commpage image.
|
||||
image_id image = get_commpage_image();
|
||||
elf_add_memory_image_symbol(image, "commpage_signal_handler",
|
||||
((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER],
|
||||
len, B_SYMBOL_TYPE_TEXT);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <asm_defs.h>
|
||||
|
||||
#include "asm_offsets.h"
|
||||
#include "syscall_numbers.h"
|
||||
|
||||
|
||||
.text
|
||||
|
||||
|
||||
// Userspace signal handler wrapper, copied to the commpage.
|
||||
FUNCTION(_user_signal_handler):
|
||||
push %rbp
|
||||
movq %rsp, %rbp
|
||||
|
||||
// RDI points to the signal_frame_data structure, however we'll overwrite
|
||||
// that with the function arguments, so move it somewhere else. We can use
|
||||
// callee-save registers here without preserving them because the old value
|
||||
// will be restored when the frame is restored.
|
||||
movq %rdi, %r12
|
||||
|
||||
// Check the handler type.
|
||||
cmpb $0, SIGNAL_FRAME_DATA_siginfo_handler(%r12)
|
||||
jne .Lsiginfo_handler
|
||||
|
||||
.Lsimple_handler:
|
||||
// Fetch other arguments (user data, vregs).
|
||||
movq SIGNAL_FRAME_DATA_user_data(%r12), %rsi
|
||||
leaq SIGNAL_FRAME_DATA_context + UCONTEXT_T_uc_mcontext(%r12), %rdx
|
||||
|
||||
.Lcall_handler:
|
||||
// Get the handler address and the signal number first argument.
|
||||
movq SIGNAL_FRAME_DATA_handler(%r12), %rax
|
||||
movl SIGNAL_FRAME_DATA_info + SIGINFO_T_si_signo(%r12), %edi
|
||||
|
||||
// Call the handler.
|
||||
callq *%rax
|
||||
|
||||
// Perform the restore_signal_frame() syscall, should not return.
|
||||
movq $SYSCALL_RESTORE_SIGNAL_FRAME, %rax
|
||||
movq %r12, %rdi
|
||||
syscall
|
||||
|
||||
.Lsiginfo_handler:
|
||||
// Fetch other arguments (info pointer, context, user data).
|
||||
leaq SIGNAL_FRAME_DATA_info(%r12), %rsi
|
||||
leaq SIGNAL_FRAME_DATA_context(%r12), %rdx
|
||||
movq SIGNAL_FRAME_DATA_user_data(%r12), %rcx
|
||||
jmp .Lcall_handler
|
||||
FUNCTION_END(_user_signal_handler)
|
||||
SYMBOL(_user_signal_handler_end):
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <arch_cpu.h>
|
||||
#include <commpage.h>
|
||||
#include <cpu.h>
|
||||
#include <debug.h>
|
||||
#include <kernel.h>
|
||||
@@ -57,6 +57,26 @@ x86_set_tls_context(Thread* thread)
|
||||
}
|
||||
|
||||
|
||||
static uint8*
|
||||
get_signal_stack(Thread* thread, iframe* frame, struct sigaction* action)
|
||||
{
|
||||
// Use the alternate signal stack if we should and can.
|
||||
if (thread->signal_stack_enabled
|
||||
&& (action->sa_flags & SA_ONSTACK) != 0
|
||||
&& (frame->user_sp < thread->signal_stack_base
|
||||
|| frame->user_sp >= thread->signal_stack_base
|
||||
+ thread->signal_stack_size)) {
|
||||
return (uint8*)(thread->signal_stack_base + thread->signal_stack_size);
|
||||
}
|
||||
|
||||
// We are going to use the stack that we are already on. We must not touch
|
||||
// the red zone (128 byte area below the stack pointer, reserved for use
|
||||
// by functions to store temporary data and guaranteed not to be modified
|
||||
// by signal handlers).
|
||||
return (uint8*)(frame->user_sp - 128);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
@@ -203,8 +223,8 @@ arch_thread_enter_userspace(Thread* thread, addr_t entry, void* args1,
|
||||
filled in:
|
||||
- \c context.uc_stack: The stack currently used by the thread.
|
||||
- \c context.uc_mcontext: The current userland state of the registers.
|
||||
- \c syscall_restart_return_value: Architecture specific use. On x86 the
|
||||
value of eax and edx which are overwritten by the syscall return value.
|
||||
- \c syscall_restart_return_value: Architecture specific use. On x86_64 the
|
||||
value of rax which is overwritten by the syscall return value.
|
||||
|
||||
Furthermore the function needs to set \c thread->user_signal_context to the
|
||||
userland pointer to the \c ucontext_t on the user stack.
|
||||
@@ -219,14 +239,116 @@ status_t
|
||||
arch_setup_signal_frame(Thread* thread, struct sigaction* action,
|
||||
struct signal_frame_data* signalFrameData)
|
||||
{
|
||||
panic("arch_setup_signal_frame: TODO\n");
|
||||
return B_ERROR;
|
||||
iframe* frame = x86_get_current_iframe();
|
||||
if (!IFRAME_IS_USER(frame)) {
|
||||
panic("arch_setup_signal_frame(): No user iframe!");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
// Store the register state.
|
||||
signalFrameData->context.uc_mcontext.rax = frame->ax;
|
||||
signalFrameData->context.uc_mcontext.rbx = frame->bx;
|
||||
signalFrameData->context.uc_mcontext.rcx = frame->cx;
|
||||
signalFrameData->context.uc_mcontext.rdx = frame->dx;
|
||||
signalFrameData->context.uc_mcontext.rdi = frame->di;
|
||||
signalFrameData->context.uc_mcontext.rsi = frame->si;
|
||||
signalFrameData->context.uc_mcontext.rbp = frame->bp;
|
||||
signalFrameData->context.uc_mcontext.r8 = frame->r8;
|
||||
signalFrameData->context.uc_mcontext.r9 = frame->r9;
|
||||
signalFrameData->context.uc_mcontext.r10 = frame->r10;
|
||||
signalFrameData->context.uc_mcontext.r11 = frame->r11;
|
||||
signalFrameData->context.uc_mcontext.r12 = frame->r12;
|
||||
signalFrameData->context.uc_mcontext.r13 = frame->r13;
|
||||
signalFrameData->context.uc_mcontext.r14 = frame->r14;
|
||||
signalFrameData->context.uc_mcontext.r15 = frame->r15;
|
||||
signalFrameData->context.uc_mcontext.rsp = frame->user_sp;
|
||||
signalFrameData->context.uc_mcontext.rip = frame->ip;
|
||||
signalFrameData->context.uc_mcontext.rflags = frame->flags;
|
||||
|
||||
// Store the FPU state. There appears to be a bug in GCC where the aligned
|
||||
// attribute on a structure is being ignored when the structure is allocated
|
||||
// on the stack, so even if the fpu_state struct has aligned(16) it may not
|
||||
// get aligned correctly. Instead, use the current thread's FPU save area
|
||||
// and then memcpy() to the frame structure.
|
||||
x86_fxsave(thread->arch_info.fpu_state);
|
||||
memcpy((void*)&signalFrameData->context.uc_mcontext.fpu,
|
||||
thread->arch_info.fpu_state,
|
||||
sizeof(signalFrameData->context.uc_mcontext.fpu));
|
||||
|
||||
// Fill in signalFrameData->context.uc_stack.
|
||||
signal_get_user_stack(frame->user_sp, &signalFrameData->context.uc_stack);
|
||||
|
||||
// Store syscall_restart_return_value (TODO).
|
||||
//signalFrameData->syscall_restart_return_value = frame->orig_rax;
|
||||
|
||||
// Get the stack to use and copy the frame data to it.
|
||||
uint8* userStack = get_signal_stack(thread, frame, action);
|
||||
|
||||
userStack -= sizeof(*signalFrameData);
|
||||
signal_frame_data* userSignalFrameData = (signal_frame_data*)userStack;
|
||||
|
||||
if (user_memcpy(userSignalFrameData, signalFrameData,
|
||||
sizeof(*signalFrameData)) != B_OK) {
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
|
||||
// Copy a return address to the stack so that backtraces will be correct.
|
||||
userStack -= sizeof(frame->ip);
|
||||
if (user_memcpy(userStack, &frame->ip, sizeof(frame->ip)) != B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
// Update Thread::user_signal_context, now that everything seems to have
|
||||
// gone fine.
|
||||
thread->user_signal_context = &userSignalFrameData->context;
|
||||
|
||||
// Set up the iframe to execute the signal handler wrapper on our prepared
|
||||
// stack. First argument points to the frame data.
|
||||
frame->user_sp = (addr_t)userStack;
|
||||
frame->ip = ((addr_t*)USER_COMMPAGE_ADDR)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER];
|
||||
frame->di = (addr_t)userSignalFrameData;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
int64
|
||||
arch_restore_signal_frame(struct signal_frame_data* signalFrameData)
|
||||
{
|
||||
panic("arch_restore_signal_frame: TODO\n");
|
||||
return B_ERROR;
|
||||
iframe* frame = x86_get_current_iframe();
|
||||
|
||||
// TODO
|
||||
//frame->orig_rax = signalFrameData->syscall_restart_return_value;
|
||||
|
||||
frame->ax = signalFrameData->context.uc_mcontext.rax;
|
||||
frame->bx = signalFrameData->context.uc_mcontext.rbx;
|
||||
frame->cx = signalFrameData->context.uc_mcontext.rcx;
|
||||
frame->dx = signalFrameData->context.uc_mcontext.rdx;
|
||||
frame->di = signalFrameData->context.uc_mcontext.rdi;
|
||||
frame->si = signalFrameData->context.uc_mcontext.rsi;
|
||||
frame->bp = signalFrameData->context.uc_mcontext.rbp;
|
||||
frame->r8 = signalFrameData->context.uc_mcontext.r8;
|
||||
frame->r9 = signalFrameData->context.uc_mcontext.r9;
|
||||
frame->r10 = signalFrameData->context.uc_mcontext.r10;
|
||||
frame->r11 = signalFrameData->context.uc_mcontext.r11;
|
||||
frame->r12 = signalFrameData->context.uc_mcontext.r12;
|
||||
frame->r13 = signalFrameData->context.uc_mcontext.r13;
|
||||
frame->r14 = signalFrameData->context.uc_mcontext.r14;
|
||||
frame->r15 = signalFrameData->context.uc_mcontext.r15;
|
||||
frame->user_sp = signalFrameData->context.uc_mcontext.rsp;
|
||||
frame->ip = signalFrameData->context.uc_mcontext.rip;
|
||||
frame->flags = (frame->flags & ~(uint64)X86_EFLAGS_USER_FLAGS)
|
||||
| (signalFrameData->context.uc_mcontext.rflags & X86_EFLAGS_USER_FLAGS);
|
||||
|
||||
// Same as above, alignment may not be correct. Copy to thread and restore
|
||||
// from there.
|
||||
Thread* thread = thread_get_current_thread();
|
||||
memcpy(thread->arch_info.fpu_state,
|
||||
(void*)&signalFrameData->context.uc_mcontext.fpu,
|
||||
sizeof(thread->arch_info.fpu_state));
|
||||
x86_fxrstor(thread->arch_info.fpu_state);
|
||||
|
||||
// The syscall return code overwrites frame->ax with the return value of
|
||||
// the syscall, need to return it here to ensure the correct value is
|
||||
// restored.
|
||||
return frame->ax;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ if $(TARGET_ARCH) = x86_64 {
|
||||
interrupts.S
|
||||
stubs.cpp
|
||||
signals.cpp
|
||||
signals_asm.S
|
||||
syscalls.cpp
|
||||
thread.cpp
|
||||
|
||||
|
||||
@@ -172,23 +172,6 @@ x86_initial_return_to_userland(Thread* thread, iframe* frame)
|
||||
}
|
||||
|
||||
|
||||
uint8*
|
||||
x86_get_signal_stack(Thread* thread, struct iframe* frame,
|
||||
struct sigaction* action)
|
||||
{
|
||||
// use the alternate signal stack if we should and can
|
||||
if (thread->signal_stack_enabled
|
||||
&& (action->sa_flags & SA_ONSTACK) != 0
|
||||
&& (frame->user_sp < thread->signal_stack_base
|
||||
|| frame->user_sp >= thread->signal_stack_base
|
||||
+ thread->signal_stack_size)) {
|
||||
return (uint8*)(thread->signal_stack_base + thread->signal_stack_size);
|
||||
}
|
||||
|
||||
return (uint8*)frame->user_sp;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
|
||||
@@ -91,6 +91,7 @@ dummy()
|
||||
DEFINE_OFFSET_MACRO(SIGNAL_FRAME_DATA, signal_frame_data, context);
|
||||
DEFINE_OFFSET_MACRO(SIGNAL_FRAME_DATA, signal_frame_data, user_data);
|
||||
DEFINE_OFFSET_MACRO(SIGNAL_FRAME_DATA, signal_frame_data, handler);
|
||||
DEFINE_OFFSET_MACRO(SIGNAL_FRAME_DATA, signal_frame_data, siginfo_handler);
|
||||
|
||||
// struct ucontext_t
|
||||
DEFINE_OFFSET_MACRO(UCONTEXT_T, __ucontext_t, uc_mcontext);
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
|
||||
|
||||
void x86_initialize_commpage_signal_handler();
|
||||
#ifndef __x86_64__
|
||||
addr_t x86_get_user_signal_handler_wrapper(bool beosHandler);
|
||||
#endif
|
||||
|
||||
|
||||
#endif // _KERNEL_ARCH_X86_SIGNALS_H
|
||||
|
||||
Reference in New Issue
Block a user