]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
SH: ____longjmp_chk for GNU/Linux with sigaltstack support.
authorThomas Schwinge <thomas@codesourcery.com>
Sat, 23 Jun 2012 09:56:02 +0000 (11:56 +0200)
committerThomas Schwinge <thomas@codesourcery.com>
Sat, 23 Jun 2012 09:56:02 +0000 (11:56 +0200)
debug/tst-longjmp_chk2 now passes.

ChangeLog
sysdeps/unix/sysv/linux/sh/Makefile
sysdeps/unix/sysv/linux/sh/____longjmp_chk.S [new file with mode: 0644]
sysdeps/unix/sysv/linux/sh/sigaltstack-offsets.sym [new file with mode: 0644]

index 1ec2e00a7d204153d86b0760f2467450df849609..0653538cc1fe14d260cb06535b226a0d6c379280 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2012-06-23  Thomas Schwinge  <thomas@codesourcery.com>
 
+       * sysdeps/unix/sysv/linux/sh/____longjmp_chk.S: New file, based on
+       sysdeps/sh/____longjmp_chk.S.
+       * sysdeps/unix/sysv/linux/sh/sigaltstack-offsets.sym: New file, based
+       on sysdeps/unix/sysv/linux/x86_64/sigaltstack-offsets.sym.
+       * sysdeps/unix/sysv/linux/sh/Makefile [subdir=misc]
+       (gen-as-const-headers): Append sigaltstack-offsets.sym.
+
        * sysdeps/sh/abort-instr.h: New file.
        * sysdeps/unix/sysv/linux/sh/makecontext.S (.Lexitcode): Terminate the
        process in case exit returns.
index 1ead8f2ae3760eafc57f0d8eefff8fec1603d89a..dd3b382ac108e716c71685b239698c055c7c94e8 100644 (file)
@@ -6,6 +6,10 @@ ifeq ($(subdir),stdlib)
 gen-as-const-headers += ucontext_i.sym
 endif
 
+ifeq ($(subdir),misc)
+gen-as-const-headers += sigaltstack-offsets.sym
+endif
+
 ifeq ($(subdir),math)
 # The libm.so link can't find __fpscr_values
 libm.so-no-z-defs = yes
diff --git a/sysdeps/unix/sysv/linux/sh/____longjmp_chk.S b/sysdeps/unix/sysv/linux/sh/____longjmp_chk.S
new file mode 100644 (file)
index 0000000..d034afc
--- /dev/null
@@ -0,0 +1,113 @@
+/* Copyright (C) 2009-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 <sigaltstack-offsets.h>
+
+       .section .rodata.str1.1,"aMS",@progbits,1
+       .type   longjmp_msg,@object
+longjmp_msg:
+       .string "longjmp causes uninitialized stack frame"
+       .size   longjmp_msg, .-longjmp_msg
+       .text
+
+#define __longjmp ____longjmp_chk
+
+#ifdef PIC
+# define CALL_FAIL \
+       mov.l   .Lfail, r1;                             \
+       mov.l   .Lstr, r4;                              \
+       mova    .Lgot, r0;                              \
+       mov.l   .Lgot, r12;                             \
+       add     r0, r12;                                \
+       bsrf    r1;                                     \
+        add    r12, r4;                                \
+.Lfail0:                                               \
+       bra     0f;                                     \
+        nop;                                           \
+       .align  2;                                      \
+.Lgot:                                                 \
+       .long   _GLOBAL_OFFSET_TABLE_;                  \
+.Lstr:                                                 \
+       .long   longjmp_msg@GOTOFF;                     \
+.Lfail:                                                        \
+       .long   __GI___fortify_fail@PLT-(.Lfail0-.);    \
+0:
+#else
+# define CALL_FAIL \
+       mov.l   .Lfail, r1;                             \
+       mov.l   .Lstr, r4;                              \
+       jsr     @r1;                                    \
+        nop;                                           \
+       bra     0f;                                     \
+        nop;                                           \
+       .align  2;                                      \
+.Lstr:                                                 \
+       .long   longjmp_msg;                            \
+.Lfail:                                                        \
+       .long   __fortify_fail;                         \
+0:
+#endif
+
+#define CHECK_SP(reg) \
+       /* Jumping to a higher-address frame is always allowed.  */     \
+       cmp/hs  r15, reg;                                               \
+       bt      .Lok;                                                   \
+                                                                       \
+       mov.l   r0, @-r15; /* The return value is already in here.  */  \
+       cfi_adjust_cfa_offset (4);                                      \
+       mov.l   r1, @-r15; /* PTR_DEMANGLE helper.  */                  \
+       cfi_adjust_cfa_offset (4);                                      \
+       mov.l   r2, @-r15; /* The new SP value is already in here.  */  \
+       cfi_adjust_cfa_offset (4);                                      \
+       mov.l   r4, @-r15; /* We'll still need this one.  */            \
+       cfi_adjust_cfa_offset (4);                                      \
+       add     #-sizeSS, r15;                                          \
+       cfi_adjust_cfa_offset (sizeSS);                                 \
+       mov     #0, r4;                                                 \
+       mov     r15, r5;                                                \
+       DO_CALL (sigaltstack, 2);                                       \
+       /* Without working sigaltstack we cannot perform the test.  */  \
+       tst     r0, r0;                                                 \
+       bf      .Lok2;                                                  \
+       mov.l   @(oSS_FLAGS, r15), r0;                                  \
+       tst     #SS_ONSTACK, r0;                                        \
+       bt      .Lcall_fail;                                            \
+       mov.l   @(oSS_SIZE, r15), r2;                                   \
+       mov.l   @(oSS_SP, r15), r1;                                     \
+       add     r2, r1;                                                 \
+       sub     r8, r1;                                                 \
+       cmp/hi  r1, r2;                                                 \
+       bf      .Lok2;                                                  \
+.Lcall_fail:                                                           \
+       CALL_FAIL                                                       \
+                                                                       \
+.Lok2:                                                                 \
+       add     #sizeSS, r15;                                           \
+       cfi_adjust_cfa_offset (-sizeSS);                                \
+       mov.l   @r15+, r4;                                              \
+       cfi_adjust_cfa_offset (-4);                                     \
+       mov.l   @r15+, r2;                                              \
+       cfi_adjust_cfa_offset (-4);                                     \
+       mov.l   @r15+, r1;                                              \
+       cfi_adjust_cfa_offset (-4);                                     \
+       mov.l   @r15+, r0;                                              \
+       cfi_adjust_cfa_offset (-4);                                     \
+.Lok:
+
+#include <__longjmp.S>
diff --git a/sysdeps/unix/sysv/linux/sh/sigaltstack-offsets.sym b/sysdeps/unix/sysv/linux/sh/sigaltstack-offsets.sym
new file mode 100644 (file)
index 0000000..f734469
--- /dev/null
@@ -0,0 +1,13 @@
+#include <stddef.h>
+#include <signal.h>
+
+--
+
+#define sigaltstack(member)    offsetof (stack_t, member)
+
+sizeSS                         sizeof (stack_t)
+oSS_SP                         sigaltstack (ss_sp)
+oSS_FLAGS                      sigaltstack (ss_flags)
+oSS_SIZE                       sigaltstack (ss_size)
+
+SS_ONSTACK