Add 469782 to NEWS
[valgrind.git] / coregrind / m_sigframe / sigframe-common.c
blob3812c22f83c0b8f55c9f8b43caeefb665b9aee80
1 /* -*- mode: C; c-basic-offset: 3; -*- */
3 /*--------------------------------------------------------------------*/
4 /*--- Signal frames handling: stuff common to most/all platforms ---*/
5 /*--- ---*/
6 /*--- sigframe-common.c ---*/
7 /*--------------------------------------------------------------------*/
9 /*
10 This file is part of Valgrind, a dynamic binary instrumentation
11 framework.
13 Copyright (C) 2000-2017 Nicholas Nethercote
14 njn@valgrind.org
15 Copyright (C) 2006-2017 OpenWorks Ltd
16 info@open-works.co.uk
18 This program is free software; you can redistribute it and/or
19 modify it under the terms of the GNU General Public License as
20 published by the Free Software Foundation; either version 2 of the
21 License, or (at your option) any later version.
23 This program is distributed in the hope that it will be useful, but
24 WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 General Public License for more details.
28 You should have received a copy of the GNU General Public License
29 along with this program; if not, see <http://www.gnu.org/licenses/>.
31 The GNU General Public License is contained in the file COPYING.
34 #include "pub_core_aspacemgr.h" // VG_(am_find_nsegment)
35 #include "pub_core_signals.h" // VG_(extend_stack)
36 #include "pub_core_libcprint.h" // VG_(umsg)
37 #include "pub_core_tooliface.h" // VG_TRACK
38 #include "pub_core_machine.h" // VG_STACK_REDZONE_SZB
39 #include "priv_sigframe.h" // self
42 /* For tracking memory events, indicate the entire frame has been
43 allocated. Except, don't mess with the area which
44 overlaps the previous frame's redzone. */
45 static void track_frame_memory ( Addr addr, SizeT size, ThreadId tid )
47 VG_TRACK( new_mem_stack_signal, addr - VG_STACK_REDZONE_SZB, size, tid );
50 #if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
52 /* Extend the stack segment downwards if needed so as to ensure the
53 new signal frames are mapped to something. Return a Bool
54 indicating whether or not the operation was successful. */
55 Bool ML_(sf_maybe_extend_stack) ( const ThreadState *tst, Addr addr,
56 SizeT size, UInt flags )
58 ThreadId tid = tst->tid;
59 const NSegment *stackseg = NULL;
61 if (flags & VKI_SA_ONSTACK) {
62 /* If the sigframe is allocated on an alternate stack, then we cannot
63 extend that stack. Nothing to do here. */
64 stackseg = VG_(am_find_nsegment)(addr);
65 } else if (VG_(am_addr_is_in_extensible_client_stack)(addr)) {
66 if (VG_(extend_stack)(tid, addr)) {
67 stackseg = VG_(am_find_nsegment)(addr);
68 if (0 && stackseg)
69 VG_(printf)("frame=%#lx seg=%#lx-%#lx\n",
70 addr, stackseg->start, stackseg->end);
72 } else if ((stackseg = VG_(am_find_nsegment)(addr)) &&
73 VG_(am_is_valid_for_client)(addr, 1,
74 VKI_PROT_READ | VKI_PROT_WRITE)) {
75 /* We come here for explicitly defined pthread-stacks which can be
76 located in any client segment. */
77 } else {
78 /* Something unexpected */
79 stackseg = NULL;
82 if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) {
83 VG_(umsg)("Can't extend stack to %#lx during signal delivery for "
84 "thread %u:\n", addr, tid);
85 if (stackseg == NULL)
86 VG_(umsg)(" no stack segment\n");
87 else
88 VG_(umsg)(" too small or bad protection modes\n");
90 /* set SIGSEGV to default handler */
91 VG_(set_default_handler)(VKI_SIGSEGV);
92 VG_(synth_fault_mapping)(tid, addr);
94 /* The whole process should be about to die, since the default
95 action of SIGSEGV to kill the whole process. */
96 return False;
99 /* Tell the tool about the new memory */
100 track_frame_memory(addr, size, tid);
102 return True;
105 #elif defined(VGO_darwin)
107 /* Extend the stack segment downwards if needed so as to ensure the
108 new signal frames are mapped to something. Return a Bool
109 indicating whether or not the operation was successful. */
110 Bool ML_(sf_maybe_extend_stack) ( const ThreadState *tst, Addr addr,
111 SizeT size, UInt flags )
113 /* Tell the tool about the new memory */
114 track_frame_memory(addr, size, tst->tid);
115 return True;
118 #else
119 #error unknown OS
120 #endif
122 /*--------------------------------------------------------------------*/
123 /*--- end ---*/
124 /*--------------------------------------------------------------------*/