Hurd: ____longjmp_chk
authorThomas Schwinge <thomas@schwinge.name>
Thu, 10 May 2012 19:47:31 +0000 (12:47 -0700)
committerRoland McGrath <roland@hack.frob.com>
Thu, 10 May 2012 22:57:22 +0000 (15:57 -0700)
ChangeLog
sysdeps/mach/hurd/i386/Makefile
sysdeps/mach/hurd/i386/____longjmp_chk.S [new file with mode: 0644]
sysdeps/mach/hurd/i386/signal-defines.sym [new file with mode: 0644]

index 976aa1e..9aa8753 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2012-05-10  Thomas Schwinge  <thomas@schwinge.name>
+
+       * sysdeps/mach/hurd/i386/____longjmp_chk.S: New file.
+       * sysdeps/mach/hurd/i386/signal-defines.sym: New file.
+       * sysdeps/mach/hurd/i386/Makefile (gen-as-const-headers): Add
+       signal-defines.sym.
+
 2012-05-10  Samuel Thibault  <samuel.thibault@ens-lyon.org>
 
         * bits/in.h (SOL_IP, SOL_IPV6, SOL_ICMPV6): New macros.
index 0eef17e..5f98809 100644 (file)
@@ -2,3 +2,7 @@ ifeq ($(subdir),misc)
 sysdep_routines += ioperm
 sysdep_headers += sys/io.h
 endif
+
+ifeq ($(subdir),debug)
+gen-as-const-headers += signal-defines.sym
+endif
diff --git a/sysdeps/mach/hurd/i386/____longjmp_chk.S b/sysdeps/mach/hurd/i386/____longjmp_chk.S
new file mode 100644 (file)
index 0000000..f499fbd
--- /dev/null
@@ -0,0 +1,107 @@
+/* Copyright (C) 2001-2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <jmpbuf-offsets.h>
+#include <asm-syntax.h>
+
+#include <signal-defines.h>
+/* #include <signal.h> */
+#define SS_ONSTACK 1
+
+
+       .section .rodata.str1.1,"aMS",@progbits,1
+       .type   longjmp_msg,@object
+longjmp_msg:
+       .string "longjmp causes uninitialized stack frame"
+       .size   longjmp_msg, .-longjmp_msg
+
+
+#ifdef PIC
+# define CALL_FAIL     movl    %ebx, %ecx; /* TODO: what's this mov good for? */ \
+                       cfi_register(%ebx,%ecx);                              \
+                       LOAD_PIC_REG (bx);                                    \
+                       leal    longjmp_msg@GOTOFF(%ebx), %eax;               \
+                       call    HIDDEN_JUMPTARGET(__fortify_fail)
+#else
+# define CALL_FAIL     movl    $longjmp_msg, %eax;                           \
+                       call    HIDDEN_JUMPTARGET(__fortify_fail)
+#endif
+
+
+       .text
+ENTRY (____longjmp_chk)
+       movl    4(%esp), %ecx   /* User's jmp_buf in %ecx.  */
+
+       /* Save the return address now.  */
+       movl    (JB_PC*4)(%ecx), %edx
+       /* Get the stack pointer.  */
+       movl    (JB_SP*4)(%ecx), %edi
+       cfi_undefined(%edi)
+       PTR_DEMANGLE (%edx)
+       PTR_DEMANGLE (%edi)
+
+       cmpl    %edi, %esp
+       /* Jumping to a higher-address frame is always allowed.  */
+       jbe     .Lok
+
+       /* Passing here, we're either about to do something invalid, or we're
+       executing on an alternative signal stack.  */
+
+       /* TODO: need locking?  */
+       /* struct hurd_sigstate * _hurd_self_sigstate (void) */
+       call    _hurd_self_sigstate
+       /* TODO: %eax and %eax->sigaltstack are always valid?  */
+
+       testl   $SS_ONSTACK, (HURD_SIGSTATE__SIGALTSTACK__OFFSET + SIGALTSTACK__SS_FLAGS__OFFSET)(%eax)
+       /* Fail if SS_ONSTACK is not set.  */
+       jz      .Lfail
+
+       movl    (HURD_SIGSTATE__SIGALTSTACK__OFFSET + SIGALTSTACK__SS_SP__OFFSET)(%eax), %ebx
+       addl    (HURD_SIGSTATE__SIGALTSTACK__OFFSET + SIGALTSTACK__SS_SIZE__OFFSET)(%eax), %ebx
+       subl    %edi, %ebx
+       cmpl    (HURD_SIGSTATE__SIGALTSTACK__OFFSET + SIGALTSTACK__SS_SIZE__OFFSET)(%eax), %ebx
+       /* TODO: comment this calculation.  */
+       jae     .Lok
+
+.Lfail:        CALL_FAIL
+
+.Lok:  /* We add unwind information for the target here.  */
+       cfi_def_cfa(%ecx, 0)
+       cfi_register(%eip, %edx)
+       cfi_register(%esp, %edi)
+       cfi_offset(%ebx, JB_BX*4)
+       cfi_offset(%esi, JB_SI*4)
+       cfi_offset(%edi, JB_DI*4)
+       cfi_offset(%ebp, JB_BP*4)
+
+       movl    8(%esp), %eax   /* Second argument is return value.  */
+       movl    %edi, %esp
+
+       /* Restore registers.  */
+       movl    (JB_BX*4)(%ecx), %ebx
+       movl    (JB_SI*4)(%ecx), %esi
+       movl    (JB_DI*4)(%ecx), %edi
+       movl    (JB_BP*4)(%ecx), %ebp
+       cfi_restore(%ebx)
+       cfi_restore(%esi)
+       cfi_restore(%edi)
+       cfi_restore(%ebp)
+
+       /* Jump to saved PC.  */
+       jmp     *%edx
+END (____longjmp_chk)
diff --git a/sysdeps/mach/hurd/i386/signal-defines.sym b/sysdeps/mach/hurd/i386/signal-defines.sym
new file mode 100644 (file)
index 0000000..9521bd7
--- /dev/null
@@ -0,0 +1,10 @@
+#include <hurd/signal.h>
+#include <signal.h>
+
+--
+
+HURD_SIGSTATE__SIGALTSTACK__OFFSET     offsetof(struct hurd_sigstate, sigaltstack)
+
+SIGALTSTACK__SS_SP__OFFSET             offsetof(struct sigaltstack, ss_sp)
+SIGALTSTACK__SS_SIZE__OFFSET           offsetof(struct sigaltstack, ss_size)
+SIGALTSTACK__SS_FLAGS__OFFSET          offsetof(struct sigaltstack, ss_flags)