diff --git a/ircd/Makefile.am b/ircd/Makefile.am index 96ea1a8f0..1a629ed34 100644 --- a/ircd/Makefile.am +++ b/ircd/Makefile.am @@ -129,6 +129,7 @@ libircd_la_SOURCES += prof_linux.cc endif libircd_la_SOURCES += fs.cc libircd_la_SOURCES += ios.cc +libircd_la_SOURCES += ctx_x86_64.S libircd_la_SOURCES += ctx.cc libircd_la_SOURCES += ctx_eh.cc libircd_la_SOURCES += ctx_ole.cc @@ -164,6 +165,7 @@ libircd_la_SOURCES += ircd.cc base.lo: AM_CPPFLAGS := @BOOST_CPPFLAGS@ ${AM_CPPFLAGS} client.lo: AM_CPPFLAGS := ${ASIO_UNIT_CPPFLAGS} ${AM_CPPFLAGS} +ctx_x86_64.lo: AM_CPPFLAGS := -I$(top_srcdir)/include ctx.lo: AM_CPPFLAGS := ${ASIO_UNIT_CPPFLAGS} ${AM_CPPFLAGS} ctx_ole.lo: AM_CPPFLAGS := ${ASIO_UNIT_CPPFLAGS} ${AM_CPPFLAGS} ctx_eh.lo: AM_CPPFLAGS := ${ASIO_UNIT_CPPFLAGS} ${AM_CPPFLAGS} diff --git a/ircd/ctx_x86_64.S b/ircd/ctx_x86_64.S new file mode 100644 index 000000000..41c4b4e48 --- /dev/null +++ b/ircd/ctx_x86_64.S @@ -0,0 +1,61 @@ +// Matrix Construct +// +// Copyright (C) Matrix Construct Developers, Authors & Contributors +// Copyright (C) 2016-2019 Jason Volk +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice is present in all copies. The +// full license for this software is available in the LICENSE file. + +// This unit contains customization and experimentation for the core context +// switching routines. First note that everything here is platform-specific +// and not implemented on all platforms. Furthermore, boost::context functions +// overriden here are also overriden for the entire address space; if other +// libraries use boost::context our code will hook their context switches +// which we might not want. All of this must be considered to build or change +// any functionality from here. + +#include +#if defined(__x86_64__) && defined(__ELF__) + +.file "ctx_x86_64.S" +.globl jump_fcontext + +.text +.type jump_fcontext, @function + +.align 16 +// returns struct transfer_t { void *fctx, *data; }; +// param DI = void *to +// param SI = void *vp +jump_fcontext: + push %rbp // store rbp 0x30 + push %rbx // store rbx 0x28 + push %r15 // store r15 0x20 + push %r14 // store r14 0x18 + push %r13 // store r13 0x10 + push %r12 // store r12 0x08 + subq $0x08, %rsp // alloc fc_mxcsr | fc_x87_cw +// fnstcw 0x04(%rsp) // store x87 control-word +// stmxcsr 0x00(%rsp) // store MMX control- and status-word + xchgq %rsp, %rdi // swap stack + movq %rsi, %rdx // store transfer_t.data (retval) + movq %rdi, %rax // store transfer_t.fctx (retval) +// ldmxcsr 0x00(%rsp) // load MMX control- and status-word +// fldcw 0x04(%rsp) // load x87 control-word + subq $-0x08, %rsp // free fc_mxcsr | fc_x87_cw + pop %r12 // load r12 + pop %r13 // load r13 + pop %r14 // load r14 + pop %r15 // load r15 + pop %rbx // load rbx + pop %rbp // load rbp + retq // enter context + +// mark the size of jump_fcontext +.size jump_fcontext, .-jump_fcontext + +// Mark that we don't need executable stack. +.section .note.GNU-stack, "", %progbits +#endif