SH: ____longjmp_chk for GNU/Linux with sigaltstack support
Thomas Schwinge
thomas@codesourcery.com
Wed Jun 13 10:28:00 GMT 2012
Hi!
This one is based on Joseph's suggestions as posted in
<http://sourceware.org/ml/libc-ports/2009-08/msg00002.html>; a part of
the following assembler bits are what »gcc -O2 -S« produced for Joseph's
C code. No regressions and debug/tst-longjmp_chk2 now passes -- Kaz,
would you please review this patch?
* 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.
diff --git a/sysdeps/unix/sysv/linux/sh/Makefile b/sysdeps/unix/sysv/linux/sh/Makefile
index 1ead8f2..dd3b382 100644
--- a/sysdeps/unix/sysv/linux/sh/Makefile
+++ b/sysdeps/unix/sysv/linux/sh/Makefile
@@ -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/sh/____longjmp_chk.S b/sysdeps/unix/sysv/linux/sh/____longjmp_chk.S
similarity index 59%
copy from sysdeps/sh/____longjmp_chk.S
copy to sysdeps/unix/sysv/linux/sh/____longjmp_chk.S
index 5d17f3a..8e83112 100644
--- a/sysdeps/sh/____longjmp_chk.S
+++ b/sysdeps/unix/sysv/linux/sh/____longjmp_chk.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2009 Free Software Foundation, Inc.
+/* 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
@@ -15,6 +15,10 @@
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:
@@ -61,9 +65,39 @@ longjmp_msg:
#endif
#define CHECK_SP(reg) \
- cmp/hs r15, reg; \
- bt .Lok; \
- CALL_FAIL \
+ /* 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. */ \
+ mov.l r1, @-r15; /* PTR_DEMANGLE helper. */ \
+ mov.l r2, @-r15; /* The new SP value is already in here. */ \
+ mov.l r4, @-r15; /* We'll still need this one. */ \
+ add #-sizeSS, r15; \
+ 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; \
+ mov.l @r15+, r4; \
+ mov.l @r15+, r2; \
+ mov.l @r15+, r1; \
+ mov.l @r15+, r0; \
.Lok:
#include <__longjmp.S>
diff --git a/sysdeps/unix/sysv/linux/x86_64/sigaltstack-offsets.sym b/sysdeps/unix/sysv/linux/sh/sigaltstack-offsets.sym
similarity index 80%
copy from sysdeps/unix/sysv/linux/x86_64/sigaltstack-offsets.sym
copy to sysdeps/unix/sysv/linux/sh/sigaltstack-offsets.sym
index 5ff3af4..f734469 100644
--- a/sysdeps/unix/sysv/linux/x86_64/sigaltstack-offsets.sym
+++ b/sysdeps/unix/sysv/linux/sh/sigaltstack-offsets.sym
@@ -1,7 +1,3 @@
-#ifndef _XOPEN_EXTENDED
-# define _XOPEN_EXTENDED
-#endif
-
#include <stddef.h>
#include <signal.h>
@@ -11,5 +7,7 @@
sizeSS sizeof (stack_t)
oSS_SP sigaltstack (ss_sp)
-oSS_SIZE sigaltstack (ss_size)
oSS_FLAGS sigaltstack (ss_flags)
+oSS_SIZE sigaltstack (ss_size)
+
+SS_ONSTACK
Grüße,
Thomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/libc-alpha/attachments/20120613/723212d9/attachment.sig>
More information about the Libc-alpha
mailing list