Blame sysdeps/unix/sysv/linux/x86_64/sigaction.c

Packit Service 82fcde
/* POSIX.1 `sigaction' call for Linux/x86-64.
Packit Service 82fcde
   Copyright (C) 2001-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#include <signal.h>
Packit Service 82fcde
#define SA_RESTORER 0x04000000
Packit Service 82fcde
#include <kernel_sigaction.h>
Packit Service 82fcde
Packit Service 82fcde
extern void restore_rt (void) asm ("__restore_rt") attribute_hidden;
Packit Service 82fcde
Packit Service 82fcde
#define SET_SA_RESTORER(kact, act)			\
Packit Service 82fcde
  (kact)->sa_flags = (act)->sa_flags | SA_RESTORER;	\
Packit Service 82fcde
  (kact)->sa_restorer = &restore_rt
Packit Service 82fcde
Packit Service 82fcde
#define RESET_SA_RESTORER(act, kact) 			\
Packit Service 82fcde
  (act)->sa_restorer = (kact)->sa_restorer
Packit Service 82fcde
Packit Service 82fcde
#include <sysdeps/unix/sysv/linux/sigaction.c>
Packit Service 82fcde
Packit Service 82fcde
/* NOTE: Please think twice before making any changes to the bits of
Packit Service 82fcde
   code below.  GDB needs some intimate knowledge about it to
Packit Service 82fcde
   recognize them as signal trampolines, and make backtraces through
Packit Service 82fcde
   signal handlers work right.  Important are both the names
Packit Service 82fcde
   (__restore_rt) and the exact instruction sequence.
Packit Service 82fcde
   If you ever feel the need to make any changes, please notify the
Packit Service 82fcde
   appropriate GDB maintainer.
Packit Service 82fcde
Packit Service 82fcde
   The unwind information starts a byte before __restore_rt, so that
Packit Service 82fcde
   it is found when unwinding, to get an address the unwinder assumes
Packit Service 82fcde
   will be in the middle of a call instruction.  See the Linux kernel
Packit Service 82fcde
   (the i386 vsyscall, in particular) for an explanation of the complex
Packit Service 82fcde
   unwind information used here in order to get the traditional CFA.
Packit Service 82fcde
   We do not restore cs - it's only stored as two bytes here so that's
Packit Service 82fcde
   a bit tricky.  We don't use the gas cfi directives, so that we can
Packit Service 82fcde
   reliably add .cfi_signal_frame.  */
Packit Service 82fcde
Packit Service 82fcde
#include "ucontext_i.h"
Packit Service 82fcde
Packit Service 82fcde
#define do_cfa_expr						\
Packit Service 82fcde
  "	.byte 0x0f\n"		/* DW_CFA_def_cfa_expression */	\
Packit Service 82fcde
  "	.uleb128 2f-1f\n"	/* length */			\
Packit Service 82fcde
  "1:	.byte 0x77\n"		/* DW_OP_breg7 */		\
Packit Service 82fcde
  "	.sleb128 " CFI_STRINGIFY (oRSP) "\n"			\
Packit Service 82fcde
  "	.byte 0x06\n"		/* DW_OP_deref */		\
Packit Service 82fcde
  "2:"
Packit Service 82fcde
Packit Service 82fcde
#define do_expr(regno, offset)					\
Packit Service 82fcde
  "	.byte 0x10\n"		/* DW_CFA_expression */		\
Packit Service 82fcde
  "	.uleb128 " CFI_STRINGIFY (regno) "\n"			\
Packit Service 82fcde
  "	.uleb128 2f-1f\n"	/* length */			\
Packit Service 82fcde
  "1:	.byte 0x77\n"		/* DW_OP_breg7 */		\
Packit Service 82fcde
  "	.sleb128 " CFI_STRINGIFY (offset) "\n"			\
Packit Service 82fcde
  "2:"
Packit Service 82fcde
Packit Service 82fcde
#define RESTORE(name, syscall) RESTORE2 (name, syscall)
Packit Service 82fcde
# define RESTORE2(name, syscall) \
Packit Service 82fcde
asm									\
Packit Service 82fcde
  (									\
Packit Service 82fcde
   /* `nop' for debuggers assuming `call' should not disalign the code.  */ \
Packit Service 82fcde
   "	nop\n"								\
Packit Service 82fcde
   ".align 16\n"							\
Packit Service 82fcde
   ".LSTART_" #name ":\n"						\
Packit Service 82fcde
   "	.type __" #name ",@function\n"					\
Packit Service 82fcde
   "__" #name ":\n"							\
Packit Service 82fcde
   "	movq $" #syscall ", %rax\n"					\
Packit Service 82fcde
   "	syscall\n"							\
Packit Service 82fcde
   ".LEND_" #name ":\n"							\
Packit Service 82fcde
   ".section .eh_frame,\"a\",@progbits\n"				\
Packit Service 82fcde
   ".LSTARTFRAME_" #name ":\n"						\
Packit Service 82fcde
   "	.long .LENDCIE_" #name "-.LSTARTCIE_" #name "\n"		\
Packit Service 82fcde
   ".LSTARTCIE_" #name ":\n"						\
Packit Service 82fcde
   "	.long 0\n"	/* CIE ID */					\
Packit Service 82fcde
   "	.byte 1\n"	/* Version number */				\
Packit Service 82fcde
   "	.string \"zRS\"\n" /* NUL-terminated augmentation string */	\
Packit Service 82fcde
   "	.uleb128 1\n"	/* Code alignment factor */			\
Packit Service 82fcde
   "	.sleb128 -8\n"	/* Data alignment factor */			\
Packit Service 82fcde
   "	.uleb128 16\n"	/* Return address register column (rip) */	\
Packit Service 82fcde
   /* Augmentation value length */					\
Packit Service 82fcde
   "	.uleb128 .LENDAUGMNT_" #name "-.LSTARTAUGMNT_" #name "\n"	\
Packit Service 82fcde
   ".LSTARTAUGMNT_" #name ":\n"						\
Packit Service 82fcde
   "	.byte 0x1b\n"	/* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */		\
Packit Service 82fcde
   ".LENDAUGMNT_" #name ":\n"						\
Packit Service 82fcde
   "	.align " LP_SIZE "\n"						\
Packit Service 82fcde
   ".LENDCIE_" #name ":\n"						\
Packit Service 82fcde
   "	.long .LENDFDE_" #name "-.LSTARTFDE_" #name "\n" /* FDE len */	\
Packit Service 82fcde
   ".LSTARTFDE_" #name ":\n"						\
Packit Service 82fcde
   "	.long .LSTARTFDE_" #name "-.LSTARTFRAME_" #name "\n" /* CIE */	\
Packit Service 82fcde
   /* `LSTART_' is subtracted 1 as debuggers assume a `call' here.  */	\
Packit Service 82fcde
   "	.long (.LSTART_" #name "-1)-.\n" /* PC-relative start addr.  */	\
Packit Service 82fcde
   "	.long .LEND_" #name "-(.LSTART_" #name "-1)\n"			\
Packit Service 82fcde
   "	.uleb128 0\n"			/* FDE augmentation length */	\
Packit Service 82fcde
   do_cfa_expr								\
Packit Service 82fcde
   do_expr (8 /* r8 */, oR8)						\
Packit Service 82fcde
   do_expr (9 /* r9 */, oR9)						\
Packit Service 82fcde
   do_expr (10 /* r10 */, oR10)						\
Packit Service 82fcde
   do_expr (11 /* r11 */, oR11)						\
Packit Service 82fcde
   do_expr (12 /* r12 */, oR12)						\
Packit Service 82fcde
   do_expr (13 /* r13 */, oR13)						\
Packit Service 82fcde
   do_expr (14 /* r14 */, oR14)						\
Packit Service 82fcde
   do_expr (15 /* r15 */, oR15)						\
Packit Service 82fcde
   do_expr (5 /* rdi */, oRDI)						\
Packit Service 82fcde
   do_expr (4 /* rsi */, oRSI)						\
Packit Service 82fcde
   do_expr (6 /* rbp */, oRBP)						\
Packit Service 82fcde
   do_expr (3 /* rbx */, oRBX)						\
Packit Service 82fcde
   do_expr (1 /* rdx */, oRDX)						\
Packit Service 82fcde
   do_expr (0 /* rax */, oRAX)						\
Packit Service 82fcde
   do_expr (2 /* rcx */, oRCX)						\
Packit Service 82fcde
   do_expr (7 /* rsp */, oRSP)						\
Packit Service 82fcde
   do_expr (16 /* rip */, oRIP)						\
Packit Service 82fcde
   /* libgcc-4.1.1 has only `DWARF_FRAME_REGISTERS == 17'.  */		\
Packit Service 82fcde
   /* do_expr (49 |* rflags *|, oEFL) */				\
Packit Service 82fcde
   /* `cs'/`ds'/`fs' are unaligned and a different size.  */		\
Packit Service 82fcde
   /* gas: Error: register save offset not a multiple of 8  */		\
Packit Service 82fcde
   "	.align " LP_SIZE "\n"						\
Packit Service 82fcde
   ".LENDFDE_" #name ":\n"						\
Packit Service 82fcde
   "	.previous\n"							\
Packit Service 82fcde
   );
Packit Service 82fcde
/* The return code for realtime-signals.  */
Packit Service 82fcde
RESTORE (restore_rt, __NR_rt_sigreturn)