~ubuntu-branches/ubuntu/precise/eglibc/precise

« back to all changes in this revision

Viewing changes to ports/sysdeps/unix/sysv/linux/generic/____longjmp_chk.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2011-10-04 17:48:26 UTC
  • mfrom: (216.1.23 oneiric)
  • Revision ID: package-import@ubuntu.com-20111004174826-2cyb9ewn3ucymlsx
Tags: 2.13-20ubuntu5
libc6-dev: Don't break the current {gnat,gcj}-4.4-base versons. LP: #853688.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2011 Free Software Foundation, Inc.
2
 
   This file is part of the GNU C Library.
3
 
   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
4
 
 
5
 
   The GNU C Library is free software; you can redistribute it and/or
6
 
   modify it under the terms of the GNU Lesser General Public
7
 
   License as published by the Free Software Foundation; either
8
 
   version 2.1 of the License, or (at your option) any later version.
9
 
 
10
 
   The GNU C Library is distributed in the hope that it will be useful,
11
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 
   Lesser General Public License for more details.
14
 
 
15
 
   You should have received a copy of the GNU Lesser General Public
16
 
   License along with the GNU C Library; if not, write to the Free
17
 
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18
 
   02111-1307 USA.  */
19
 
 
20
 
#include <jmpbuf-offsets.h>
21
 
#include <sysdep.h>
22
 
#include <setjmp.h>
23
 
#include <signal.h>
24
 
#include <stdio.h>
25
 
#include <stackinfo.h>
26
 
 
27
 
#ifdef _STACK_GROWS_DOWN
28
 
#define called_from(this, saved) ((this) < (saved))
29
 
#else
30
 
#define called_from(this, saved) ((this) > (saved))
31
 
#endif
32
 
 
33
 
extern void ____longjmp_chk (__jmp_buf __env, int __val)
34
 
  __attribute__ ((__noreturn__));
35
 
 
36
 
void ____longjmp_chk (__jmp_buf env, int val)
37
 
{
38
 
  void *this_frame = __builtin_frame_address (0);
39
 
  void *saved_frame = JB_FRAME_ADDRESS (env);
40
 
  INTERNAL_SYSCALL_DECL (err);
41
 
  stack_t ss;
42
 
 
43
 
  /* If "env" is from a frame that called us, we're all set.  */
44
 
  if (called_from(this_frame, saved_frame))
45
 
    __longjmp (env, val);
46
 
 
47
 
  /* If we can't get the current stack state, give up and do the longjmp. */
48
 
  if (INTERNAL_SYSCALL (sigaltstack, err, 2, NULL, &ss) != 0)
49
 
    __longjmp (env, val);
50
 
 
51
 
  /* If we we are executing on the alternate stack and within the
52
 
     bounds, do the longjmp.  */
53
 
  if (ss.ss_flags == SS_ONSTACK &&
54
 
      (this_frame >= ss.ss_sp && this_frame < (ss.ss_sp + ss.ss_size)))
55
 
    __longjmp (env, val);
56
 
 
57
 
  __fortify_fail ("longjmp causes uninitialized stack frame");
58
 
}