diff options
author | Carlos O'Donell <carlos@systemhalted.org> | 2012-11-19 00:36:08 -0500 |
---|---|---|
committer | Carlos O'Donell <carlos@systemhalted.org> | 2012-11-19 00:36:08 -0500 |
commit | 0d6bed71502f053fa702ccbb7dd4fa6741b2a0ed (patch) | |
tree | 8d7f0a7cac0ce6b02d69dcd643a0d6d9faa6fdd7 | |
parent | 320194d5b958156a9ad21e8c4e07e8033b405ccd (diff) | |
download | glibc-0d6bed71502f053fa702ccbb7dd4fa6741b2a0ed.zip glibc-0d6bed71502f053fa702ccbb7dd4fa6741b2a0ed.tar.gz glibc-0d6bed71502f053fa702ccbb7dd4fa6741b2a0ed.tar.bz2 |
hppa: Add ____longjmp_check C implementation.
-rw-r--r-- | ports/sysdeps/unix/sysv/linux/hppa/____longjmp_chk.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/ports/sysdeps/unix/sysv/linux/hppa/____longjmp_chk.c b/ports/sysdeps/unix/sysv/linux/hppa/____longjmp_chk.c new file mode 100644 index 0000000..46357dd --- /dev/null +++ b/ports/sysdeps/unix/sysv/linux/hppa/____longjmp_chk.c @@ -0,0 +1,47 @@ +/* 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 General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include <stdio.h> +#include <signal.h> +#include <sysdep.h> +#define __longjmp ____longjmp_chk +#define CHECK_SP(sp) \ + do { \ + register unsigned long this_sp asm ("r30"); \ + /* The stack grows up, therefore frames that were created and then \ + destroyed must all have stack values higher than ours. */ \ + if ((unsigned long) (sp) > this_sp) \ + { \ + struct sigaltstack oss; \ + INTERNAL_SYSCALL_DECL (err); \ + int result = INTERNAL_SYSCALL (sigaltstack, err, 2, NULL, &oss);\ + /* If we aren't using an alternate stack then we have already \ + shown that we are jumping to a frame that doesn't exist so \ + error out. If we are using an alternate stack we must prove \ + that we are jumping *out* of the alternate stack. Note that \ + the check for that is the same as that for _STACK_GROWS_UP \ + as for _STACK_GROWS_DOWN. */ \ + if (!INTERNAL_SYSCALL_ERROR_P (result, err) \ + && ((oss.ss_flags & SS_ONSTACK) == 0 \ + || ((unsigned long) oss.ss_sp + oss.ss_size \ + - (unsigned long) (sp)) < oss.ss_size)) \ + __fortify_fail ("longjmp causes uninitialized stack frame"); \ + } \ + } while (0) + +#include <__longjmp.c> |