From 95ed3b4432d5b477c5f1508a9b392758f4a29b1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Tue, 15 May 2018 18:50:40 +0200 Subject: [PATCH] kernel/x86_64: add signal handler compat code. * x86_64_signal_handler_compat is a dump of x86 x86_signal_frame_function(). * the x86 compiler should be used to produce this code, which ends up in the commpage. Change-Id: I03da02c376f67ff83dbaba9bcb144da726463996 --- .../kernel/arch/x86/64/signals_compat.cpp | 40 +++++++++++++++ .../kernel/arch/x86/64/signals_compat_asm.S | 49 +++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 src/system/kernel/arch/x86/64/signals_compat.cpp create mode 100644 src/system/kernel/arch/x86/64/signals_compat_asm.S diff --git a/src/system/kernel/arch/x86/64/signals_compat.cpp b/src/system/kernel/arch/x86/64/signals_compat.cpp new file mode 100644 index 0000000000..990658bbb1 --- /dev/null +++ b/src/system/kernel/arch/x86/64/signals_compat.cpp @@ -0,0 +1,40 @@ +/* + * Copyright 2018, Jérôme Duval, jerome.duval@gmail.com. + * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. + * Distributed under the terms of the MIT License. + */ + + +#include "x86_signals.h" + +#include + +#include + +#include +#include +#include +#include + + +extern "C" void x86_64_signal_handler_compat(void); +extern int x86_64_signal_handler_compat_end; + + +void +x86_compat_initialize_commpage_signal_handler() +{ + void* handlerCode = (void*)&x86_64_signal_handler_compat; + void* handlerCodeEnd = &x86_64_signal_handler_compat_end; + + // Copy the signal handler code to the commpage. + size_t len = (size_t)((addr_t)handlerCodeEnd - (addr_t)handlerCode); + addr_t position = fill_commpage_compat_entry( + COMMPAGE_ENTRY_X86_SIGNAL_HANDLER, handlerCode, len); + + // Add symbol to the commpage image. + image_id image = get_commpage_compat_image(); + elf_add_memory_image_symbol(image, "commpage_compat_signal_handler", + position, len, B_SYMBOL_TYPE_TEXT); +} + diff --git a/src/system/kernel/arch/x86/64/signals_compat_asm.S b/src/system/kernel/arch/x86/64/signals_compat_asm.S new file mode 100644 index 0000000000..7b3b76caa8 --- /dev/null +++ b/src/system/kernel/arch/x86/64/signals_compat_asm.S @@ -0,0 +1,49 @@ +/* + * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + * + * Dump of x86_signal_frame_function() in arch/x86/32/signals.cpp + */ + + +#include + + +// TODO: build from arch/x86/32/signals.cpp with the x86 compiler +FUNCTION(x86_64_signal_handler_compat): + .byte 0x55 // push %ebp + .byte 0x89,0xe5 // mov %esp,%ebp + .byte 0x83,0xec,0x14 // sub $0x14,%esp + .byte 0x53 // push %ebx + .byte 0x8b,0x5d,0x08 // mov 0x8(%ebp),%ebx + .byte 0x80,0xbb,0x74,0x2,0x0,0x0,0x0 // cmpb $0x0,0x274(%ebx) + .byte 0x74,0x19 // je + .byte 0x8b,0x93,0x70,0x2,0x0,0x0 // mov 0x270(%ebx),%edx + .byte 0x8b,0x83,0x6c,0x2,0x0,0x0 // mov 0x26c(%ebx),%eax + .byte 0x50 // push %eax + .byte 0x8d,0x43,0x24 // lea 0x24(%ebx),%eax + .byte 0x50 // push %eax + .byte 0x53 // push %ebx + .byte 0x8b,0x3 // mov (%ebx),%eax + .byte 0x50 // push %eax + .byte 0xff,0xd2 // call *%edx + .byte 0xeb,0x19 // jmp + .byte 0x8b,0x93,0x70,0x2,0x0,0x0 // mov 0x270(%ebx),%edx + .byte 0x83,0xc4,0xfc // add $0xfffffffc,%esp + .byte 0x8d,0x43,0x3c // lea 0x3c(%ebx),%eax + .byte 0x50 // push %eax + .byte 0x8b,0x83,0x6c,0x2,0x0,0x0 // mov 0x26c(%ebx),%eax + .byte 0x50 // push %eax + .byte 0x8b,0x03 // mov (%ebx),%eax + .byte 0x50 // push %eax + .byte 0xff,0xd2 // call *%edx + .byte 0x53 // push %ebx + .byte 0x6a,0x0 // push $0 + .byte 0xb8,0x3f,0x0,0x0,0x0 // movl $ TO_STRING_LITERAL(SYSCALL_RESTORE_SIGNAL_FRAME) , %%eax; + .byte 0xcd,0x63 // int $99 + .byte 0x8b,0x5d,0xe8 // mov -0x18(%ebp),%ebx + .byte 0x89,0xec // mov %ebp,%esp + .byte 0x5d // pop %ebp + .byte 0xc3 // ret +FUNCTION_END(x86_64_signal_handler_compat) +SYMBOL(x86_64_signal_handler_compat_end):