From e00902b5b1f22c689428be8416ce74c369744367 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Sun, 29 Mar 2020 14:27:40 +0000 Subject: [PATCH] x86_64: modernize implementation --- arch/x86_64/defs.h | 36 +++++++++++++++++ arch/x86_64/getcontext.S | 48 +++++++++++----------- arch/x86_64/makecontext.c | 1 + arch/x86_64/setcontext.S | 49 ++++++++++++----------- arch/x86_64/startcontext.S | 8 ++-- arch/x86_64/swapcontext.S | 82 +++++++++++++++++++------------------- 6 files changed, 132 insertions(+), 92 deletions(-) create mode 100644 arch/x86_64/defs.h diff --git a/arch/x86_64/defs.h b/arch/x86_64/defs.h new file mode 100644 index 0000000..dbbc1d6 --- /dev/null +++ b/arch/x86_64/defs.h @@ -0,0 +1,36 @@ +#ifndef __ARCH_X86_64_DEFS_H +#define __ARCH_X86_64_DEFS_H + +#ifndef _GNU_SOURCE +# define REG_R8 (0) +# define REG_R9 (1) +# define REG_R10 (2) +# define REG_R11 (3) +# define REG_R12 (4) +# define REG_R13 (5) +# define REG_R14 (6) +# define REG_R15 (7) +# define REG_RDI (8) +# define REG_RSI (9) +# define REG_RBP (10) +# define REG_RBX (11) +# define REG_RDX (12) +# define REG_RAX (13) +# define REG_RCX (14) +# define REG_RSP (15) +# define REG_RIP (16) +# define REG_EFL (17) +# define REG_CSGSFS (18) +# define REG_ERR (19) +# define REG_TRAPNO (20) +# define REG_OLDMASK (21) +# define REG_CR2 (22) +#endif + +#define MCONTEXT_GREGS (40) + +#define SZ_REG (8) + +#include "common-defs.h" + +#endif diff --git a/arch/x86_64/getcontext.S b/arch/x86_64/getcontext.S index 76c43b1..5b3a05d 100644 --- a/arch/x86_64/getcontext.S +++ b/arch/x86_64/getcontext.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Ariadne Conill + * Copyright (c) 2018, 2020 Ariadne Conill * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -10,39 +10,39 @@ * from the use of this software. */ -.globl __getcontext; -__getcontext: +#include "defs.h" + +ALIAS(getcontext, __getcontext) + +FUNC(__getcontext) /* copy all of the current registers into the ucontext structure */ - movq %r8, 40(%rdi) - movq %r9, 48(%rdi) - movq %r10, 56(%rdi) - movq %r11, 64(%rdi) - movq %r12, 72(%rdi) - movq %r13, 80(%rdi) - movq %r14, 88(%rdi) - movq %r15, 96(%rdi) - movq %rdi, 104(%rdi) - movq %rsi, 112(%rdi) - movq %rbp, 120(%rdi) - movq %rbx, 128(%rdi) - movq %rdx, 136(%rdi) - movq $1, 144(%rdi) /* $1 is %rax */ - movq %rcx, 152(%rdi) + movq %r8, REG_OFFSET(REG_R8)(%rdi) + movq %r9, REG_OFFSET(REG_R9)(%rdi) + movq %r10, REG_OFFSET(REG_R10)(%rdi) + movq %r11, REG_OFFSET(REG_R11)(%rdi) + movq %r12, REG_OFFSET(REG_R12)(%rdi) + movq %r13, REG_OFFSET(REG_R13)(%rdi) + movq %r14, REG_OFFSET(REG_R14)(%rdi) + movq %r15, REG_OFFSET(REG_R15)(%rdi) + movq %rdi, REG_OFFSET(REG_RDI)(%rdi) + movq %rsi, REG_OFFSET(REG_RSI)(%rdi) + movq %rbp, REG_OFFSET(REG_RBP)(%rdi) + movq %rbx, REG_OFFSET(REG_RBX)(%rdi) + movq %rdx, REG_OFFSET(REG_RDX)(%rdi) + movq %rax, REG_OFFSET(REG_RAX)(%rdi) + movq %rcx, REG_OFFSET(REG_RCX)(%rdi) /* the first argument on the stack is the jump target (%rip), so we store it in the RIP register in the ucontext structure. */ movq (%rsp), %rcx - movq %rcx, 168(%rdi) + movq %rcx, REG_OFFSET(REG_RIP)(%rdi) /* finally take the stack pointer address (%rsp) offsetting by 8 to skip over the jump target. */ leaq 8(%rsp), %rcx - movq %rcx, 160(%rdi) + movq %rcx, REG_OFFSET(REG_RSP)(%rdi) /* we're all done here, return 0 */ xorl %eax, %eax ret - - -.weak getcontext; -getcontext = __getcontext; +END(__getcontext) diff --git a/arch/x86_64/makecontext.c b/arch/x86_64/makecontext.c index 76942c9..3a7fff7 100644 --- a/arch/x86_64/makecontext.c +++ b/arch/x86_64/makecontext.c @@ -17,6 +17,7 @@ #include #include +#include "defs.h" extern void __start_context(void); diff --git a/arch/x86_64/setcontext.S b/arch/x86_64/setcontext.S index d934613..22098fc 100644 --- a/arch/x86_64/setcontext.S +++ b/arch/x86_64/setcontext.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Ariadne Conill + * Copyright (c) 2018, 2020 Ariadne Conill * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -10,35 +10,36 @@ * from the use of this software. */ -.globl __setcontext; -__setcontext: +#include "defs.h" + +ALIAS(setcontext, __setcontext) + +FUNC(__setcontext) /* set all of the registers */ - movq 40(%rdi), %r8 - movq 48(%rdi), %r9 - movq 56(%rdi), %r10 - movq 64(%rdi), %r11 - movq 72(%rdi), %r12 - movq 80(%rdi), %r13 - movq 88(%rdi), %r14 - movq 96(%rdi), %r15 - movq 112(%rdi), %rsi - movq 120(%rdi), %rbp - movq 128(%rdi), %rbx - movq 136(%rdi), %rdx - movq 144(%rdi), %rax - movq 152(%rdi), %rcx - movq 160(%rdi), %rsp + movq REG_OFFSET(REG_R8)(%rdi), %r8 + movq REG_OFFSET(REG_R9)(%rdi), %r9 + movq REG_OFFSET(REG_R10)(%rdi), %r10 + movq REG_OFFSET(REG_R11)(%rdi), %r11 + movq REG_OFFSET(REG_R12)(%rdi), %r12 + movq REG_OFFSET(REG_R13)(%rdi), %r13 + movq REG_OFFSET(REG_R14)(%rdi), %r14 + movq REG_OFFSET(REG_R15)(%rdi), %r15 + movq REG_OFFSET(REG_RSI)(%rdi), %rsi + movq REG_OFFSET(REG_RBP)(%rdi), %rbp + movq REG_OFFSET(REG_RBX)(%rdi), %rbx + movq REG_OFFSET(REG_RDX)(%rdi), %rdx + movq REG_OFFSET(REG_RAX)(%rdi), %rax + movq REG_OFFSET(REG_RCX)(%rdi), %rcx + movq REG_OFFSET(REG_RSP)(%rdi), %rsp /* set the jump target by pushing it to the stack. ret will pop the new %rip from the stack, causing us to jump there. */ - pushq 168(%rdi) + pushq REG_OFFSET(REG_RIP)(%rdi) /* finally, set %rdi correctly. */ - movq 104(%rdi), %rdi + movq REG_OFFSET(REG_RDI)(%rdi), %rdi /* we're all done here, return 0 */ - xorl %eax, %eax + xorl %eax, %eax ret - -.weak setcontext; -setcontext = __setcontext; +END(__setcontext) diff --git a/arch/x86_64/startcontext.S b/arch/x86_64/startcontext.S index a249573..4d39b2f 100644 --- a/arch/x86_64/startcontext.S +++ b/arch/x86_64/startcontext.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Ariadne Conill + * Copyright (c) 2018, 2020 Ariadne Conill * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -10,8 +10,9 @@ * from the use of this software. */ -.globl __start_context; -__start_context: +#include "defs.h" + +FUNC(__start_context) /* get the proper context into position and test for NULL */ movq %rbx, %rsp movq (%rsp), %rdi @@ -30,3 +31,4 @@ no_linked_context: /* something is really hosed, call hlt to force termination */ hlt +END(__start_context) diff --git a/arch/x86_64/swapcontext.S b/arch/x86_64/swapcontext.S index 4e4c983..5d3b4b0 100644 --- a/arch/x86_64/swapcontext.S +++ b/arch/x86_64/swapcontext.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Ariadne Conill + * Copyright (c) 2018, 2020 Ariadne Conill * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -10,65 +10,65 @@ * from the use of this software. */ -.globl __swapcontext; -__swapcontext: +#include "defs.h" + +ALIAS(swapcontext, __swapcontext) + +FUNC(__swapcontext) /* copy all of the current registers into the ucontext structure pointed by the first argument */ - movq %r8, 40(%rdi) - movq %r9, 48(%rdi) - movq %r10, 56(%rdi) - movq %r11, 64(%rdi) - movq %r12, 72(%rdi) - movq %r13, 80(%rdi) - movq %r14, 88(%rdi) - movq %r15, 96(%rdi) - movq %rdi, 104(%rdi) - movq %rsi, 112(%rdi) - movq %rbp, 120(%rdi) - movq %rbx, 128(%rdi) - movq %rdx, 136(%rdi) - movq $1, 144(%rdi) /* $1 is %rax */ - movq %rcx, 152(%rdi) + movq %r8, REG_OFFSET(REG_R8)(%rdi) + movq %r9, REG_OFFSET(REG_R9)(%rdi) + movq %r10, REG_OFFSET(REG_R10)(%rdi) + movq %r11, REG_OFFSET(REG_R11)(%rdi) + movq %r12, REG_OFFSET(REG_R12)(%rdi) + movq %r13, REG_OFFSET(REG_R13)(%rdi) + movq %r14, REG_OFFSET(REG_R14)(%rdi) + movq %r15, REG_OFFSET(REG_R15)(%rdi) + movq %rdi, REG_OFFSET(REG_RDI)(%rdi) + movq %rsi, REG_OFFSET(REG_RSI)(%rdi) + movq %rbp, REG_OFFSET(REG_RBP)(%rdi) + movq %rbx, REG_OFFSET(REG_RBX)(%rdi) + movq %rdx, REG_OFFSET(REG_RDX)(%rdi) + movq %rax, REG_OFFSET(REG_RAX)(%rdi) + movq %rcx, REG_OFFSET(REG_RCX)(%rdi) /* the first argument on the stack is the jump target (%rip), so we store it in the RIP register in the ucontext structure. */ movq (%rsp), %rcx - movq %rcx, 168(%rdi) + movq %rcx, REG_OFFSET(REG_RIP)(%rdi) /* finally take the stack pointer address (%rsp) offsetting by 8 to skip over the jump target. */ leaq 8(%rsp), %rcx - movq %rcx, 160(%rdi) + movq %rcx, REG_OFFSET(REG_RSP)(%rdi) /* set all of the registers to their new states, stored in the second ucontext structure */ - movq 40(%rsi), %r8 - movq 48(%rsi), %r9 - movq 56(%rsi), %r10 - movq 64(%rsi), %r11 - movq 72(%rsi), %r12 - movq 80(%rsi), %r13 - movq 88(%rsi), %r14 - movq 96(%rsi), %r15 - movq 104(%rsi), %rdi - movq 120(%rsi), %rbp - movq 128(%rsi), %rbx - movq 136(%rsi), %rdx - movq 144(%rsi), %rax - movq 152(%rsi), %rcx - movq 160(%rsi), %rsp + movq REG_OFFSET(REG_R8)(%rsi), %r8 + movq REG_OFFSET(REG_R9)(%rsi), %r9 + movq REG_OFFSET(REG_R10)(%rsi), %r10 + movq REG_OFFSET(REG_R11)(%rsi), %r11 + movq REG_OFFSET(REG_R12)(%rsi), %r12 + movq REG_OFFSET(REG_R13)(%rsi), %r13 + movq REG_OFFSET(REG_R14)(%rsi), %r14 + movq REG_OFFSET(REG_R15)(%rsi), %r15 + movq REG_OFFSET(REG_RDI)(%rsi), %rdi + movq REG_OFFSET(REG_RBP)(%rsi), %rbp + movq REG_OFFSET(REG_RBX)(%rsi), %rbx + movq REG_OFFSET(REG_RDX)(%rsi), %rdx + movq REG_OFFSET(REG_RAX)(%rsi), %rax + movq REG_OFFSET(REG_RCX)(%rsi), %rcx + movq REG_OFFSET(REG_RSP)(%rsi), %rsp /* set the jump target by pushing it to the stack. ret will pop the new %rip from the stack, causing us to jump there. */ - pushq 168(%rsi) + pushq REG_OFFSET(REG_RIP)(%rsi) /* finally, set %rsi correctly since we do not need it anymore. */ - movq 112(%rsi), %rsi + movq REG_OFFSET(REG_RSI)(%rsi), %rsi /* we're all done here, return 0 */ xorl %eax, %eax ret - - -.weak swapcontext; -swapcontext = __swapcontext; +END(__swapcontext)