From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6329 invoked by alias); 4 May 2004 15:02:20 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 6305 invoked from network); 4 May 2004 15:02:17 -0000 Received: from unknown (HELO pippin.tausq.org) (64.81.244.94) by sources.redhat.com with SMTP; 4 May 2004 15:02:17 -0000 Received: by pippin.tausq.org (Postfix, from userid 1000) id 7815ECD28A; Tue, 4 May 2004 08:02:19 -0700 (PDT) Date: Tue, 04 May 2004 15:02:00 -0000 From: Randolph Chung To: gdb-patches@sources.redhat.com Subject: [patch] sigaltstack fixes for hppa-linux Message-ID: <20040504150219.GJ3965@tausq.org> Reply-To: Randolph Chung Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-GPG: for GPG key, see http://www.tausq.org/gpg.txt User-Agent: Mutt/1.5.5.1+cvs20040105i X-SW-Source: 2004-05/txt/msg00097.txt.bz2 This patch fixes sigaltstack handling on hppa. It requires one arch-indep change in frame.c: on hppa (stack-grows-up), the relationship of the sigaltstack can be that it is not "inner" to the signal frame, if the sigaltstack resides in a caller's stack frame (as is true in gdb's testcase.) ok to apply? 2004-05-03 Randolph Chung * frame.c (get_prev_frame_1): Relax frame_id_inner check for SIGTRAMP_FRAME. * hppa-linux-tdep.c (hppa_linux_sigtramp_find_sigcontext): Pass in pc instead of sp, handle sigaltstack case. (hppa_linux_sigtramp_frame_unwind_cache) (hppa_linux_sigtramp_unwind_sniffer): Adjust calls to hppa_linux_sigtramp_find_sigcontext. Index: frame.c =================================================================== RCS file: /cvs/src/src/gdb/frame.c,v retrieving revision 1.173 diff -u -p -r1.173 frame.c --- frame.c 26 Apr 2004 09:49:35 -0000 1.173 +++ frame.c 4 May 2004 14:43:32 -0000 @@ -1794,6 +1794,7 @@ get_prev_frame_1 (struct frame_info *thi Exclude signal trampolines (due to sigaltstack the frame ID can go backwards) and sentinel frames (the test is meaningless). */ if (this_frame->next->level >= 0 + && this_frame->type != SIGTRAMP_FRAME && this_frame->next->type != SIGTRAMP_FRAME && frame_id_inner (get_frame_id (this_frame), get_frame_id (this_frame->next))) Index: hppa-linux-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/hppa-linux-tdep.c,v retrieving revision 1.1 diff -u -p -r1.1 hppa-linux-tdep.c --- hppa-linux-tdep.c 29 Apr 2004 03:36:49 -0000 1.1 +++ hppa-linux-tdep.c 4 May 2004 14:43:32 -0000 @@ -282,7 +282,7 @@ hppa_linux_skip_trampoline_code (CORE_AD Note that with a 2.4 64-bit kernel, the signal context is not properly passed back to userspace so the unwind will not work correctly. */ static CORE_ADDR -hppa_linux_sigtramp_find_sigcontext (CORE_ADDR sp) +hppa_linux_sigtramp_find_sigcontext (CORE_ADDR pc) { unsigned int dummy[HPPA_MAX_INSN_PATTERN_LEN]; int offs = 0; @@ -291,6 +291,12 @@ hppa_linux_sigtramp_find_sigcontext (COR static int pcoffs[] = { 0, 4*4, 5*4 }; /* offsets to the rt_sigframe structure */ static int sfoffs[] = { 4*4, 10*4, 10*4 }; + CORE_ADDR sp; + + /* Most of the time, this will be correct. The one case when this will + fail is if the user defined an alternate stack, in which case the + beginning of the stack will not be pc & 63. */ + sp = (pc & ~63); /* rt_sigreturn trampoline: 3419000x ldi 0, %r25 or ldi 1, %r25 (x = 0 or 2) @@ -308,7 +314,18 @@ hppa_linux_sigtramp_find_sigcontext (COR } if (offs == 0) - return 0; + { + if (insns_match_pattern (pc, hppa_sigtramp, dummy)) + { + /* sigaltstack case: we have no way of knowing which offset to + use in this case; default to new kernel handling. If this is + wrong the unwinding will fail. */ + try = 2; + sp = pc - pcoffs[try]; + } + else + return 0; + } /* sp + sfoffs[try] points to a struct rt_sigframe, which contains a struct siginfo and a struct ucontext. struct ucontext contains @@ -331,7 +348,7 @@ hppa_linux_sigtramp_frame_unwind_cache ( { struct gdbarch *gdbarch = get_frame_arch (next_frame); struct hppa_linux_sigtramp_unwind_cache *info; - CORE_ADDR sp, pc, scptr; + CORE_ADDR pc, scptr; int i; if (*this_cache) @@ -342,8 +359,7 @@ hppa_linux_sigtramp_frame_unwind_cache ( info->saved_regs = trad_frame_alloc_saved_regs (next_frame); pc = frame_pc_unwind (next_frame); - sp = (pc & ~63); - scptr = hppa_linux_sigtramp_find_sigcontext (sp); + scptr = hppa_linux_sigtramp_find_sigcontext (pc); /* structure of struct sigcontext: @@ -448,14 +464,13 @@ static const struct frame_unwind * hppa_linux_sigtramp_unwind_sniffer (struct frame_info *next_frame) { CORE_ADDR pc = frame_pc_unwind (next_frame); - CORE_ADDR sp = (pc & ~63); - if (hppa_linux_sigtramp_find_sigcontext (sp)) + if (hppa_linux_sigtramp_find_sigcontext (pc)) return &hppa_linux_sigtramp_frame_unwind; return NULL; } /* Forward declarations. */ extern initialize_file_ftype _initialize_hppa_linux_tdep; -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/