From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21610 invoked by alias); 22 Dec 2005 14:09:29 -0000 Received: (qmail 21599 invoked by uid 22791); 22 Dec 2005 14:09:27 -0000 X-Spam-Check-By: sourceware.org Received: from sibelius.xs4all.nl (HELO sibelius.xs4all.nl) (82.92.89.47) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 22 Dec 2005 14:09:24 +0000 Received: from elgar.sibelius.xs4all.nl (root@elgar.sibelius.xs4all.nl [192.168.0.2]) by sibelius.xs4all.nl (8.13.4/8.13.4) with ESMTP id jBME9Lrb030307 for ; Thu, 22 Dec 2005 15:09:21 +0100 (CET) Received: from elgar.sibelius.xs4all.nl (kettenis@localhost.sibelius.xs4all.nl [127.0.0.1]) by elgar.sibelius.xs4all.nl (8.13.4/8.13.3) with ESMTP id jBME9L9P005593 for ; Thu, 22 Dec 2005 15:09:21 +0100 (CET) Received: (from kettenis@localhost) by elgar.sibelius.xs4all.nl (8.13.4/8.13.4/Submit) id jBME9L7W005129; Thu, 22 Dec 2005 15:09:21 +0100 (CET) Date: Thu, 22 Dec 2005 17:07:00 -0000 Message-Id: <200512221409.jBME9L7W005129@elgar.sibelius.xs4all.nl> From: Mark Kettenis To: gdb-patches@sourceware.org Subject: [commit] Fix OpenBSD/i386 and OpenBSD/amd64 kernel trapframe unwinders Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2005-12/txt/msg00262.txt.bz2 Teach OpenBSD/i386 how to unwind from interrupt frames too. Plus a small fix for OpenBSD/amd64 for interrupts from user space. Mark Index: ChangeLog from Mark Kettenis * amd64obsd-tdep.c (amd64obsd_trapframe_cache): Fix detection of interrupts from user space. * i386obsd-tdep.c (i386obsd_trapframe_cache): Handle interrupt frames too. (i386obsd_trapframe_sniffer): Turn into a proper unwinder sniffer. (i386obsd_trapframe_unwind): Add sniffer. (i386obsd_init_abi): Prepend i386obsd_trapframe_unwind instead of appending i386obsd_trapframe_sniffer. Index: amd64obsd-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/amd64obsd-tdep.c,v retrieving revision 1.19 diff -u -p -r1.19 amd64obsd-tdep.c --- amd64obsd-tdep.c 22 Dec 2005 13:17:49 -0000 1.19 +++ amd64obsd-tdep.c 22 Dec 2005 14:06:28 -0000 @@ -370,7 +370,7 @@ amd64obsd_trapframe_cache(struct frame_i trad_frame_set_reg_addr (cache, i, addr + amd64obsd_tf_reg_offset[i]); /* Read %cs from trap frame. */ - addr = sp + amd64obsd_tf_reg_offset[AMD64_CS_REGNUM]; + addr += amd64obsd_tf_reg_offset[AMD64_CS_REGNUM]; cs = read_memory_unsigned_integer (addr, 8); if ((cs & I386_SEL_RPL) == I386_SEL_UPL) { Index: i386obsd-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/i386obsd-tdep.c,v retrieving revision 1.26 diff -u -p -r1.26 i386obsd-tdep.c --- i386obsd-tdep.c 19 Dec 2005 22:19:49 -0000 1.26 +++ i386obsd-tdep.c 22 Dec 2005 14:06:28 -0000 @@ -345,6 +345,7 @@ i386obsd_trapframe_cache(struct frame_in struct trad_frame_cache *cache; CORE_ADDR func, sp, addr; ULONGEST cs; + char *name; int i; if (*this_cache) @@ -355,12 +356,19 @@ i386obsd_trapframe_cache(struct frame_in func = frame_func_unwind (next_frame); sp = frame_unwind_register_unsigned (next_frame, I386_ESP_REGNUM); + + find_pc_partial_function (func, &name, NULL, NULL); + if (name && strncmp(name, "Xintr", 5) == 0) + addr = sp + 8; /* It's an interrupt frame. */ + else + addr = sp; + for (i = 0; i < ARRAY_SIZE (i386obsd_tf_reg_offset); i++) if (i386obsd_tf_reg_offset[i] != -1) - trad_frame_set_reg_addr (cache, i, sp + i386obsd_tf_reg_offset[i]); + trad_frame_set_reg_addr (cache, i, addr + i386obsd_tf_reg_offset[i]); /* Read %cs from trap frame. */ - addr = sp + i386obsd_tf_reg_offset[I386_CS_REGNUM]; + addr += i386obsd_tf_reg_offset[I386_CS_REGNUM]; cs = read_memory_unsigned_integer (addr, 4); if ((cs & I386_SEL_RPL) == I386_SEL_UPL) { @@ -400,17 +408,10 @@ i386obsd_trapframe_prev_register (struct optimizedp, lvalp, addrp, realnump, valuep); } -static const struct frame_unwind i386obsd_trapframe_unwind = { - /* FIXME: kettenis/20051219: This really is more like an interrupt - frame, but SIGTRAMP_FRAME would print , - which really is not what we want here. */ - NORMAL_FRAME, - i386obsd_trapframe_this_id, - i386obsd_trapframe_prev_register -}; - -static const struct frame_unwind * -i386obsd_trapframe_sniffer (struct frame_info *next_frame) +static int +i386obsd_trapframe_sniffer (const struct frame_unwind *self, + struct frame_info *next_frame, + void **this_prologue_cache) { ULONGEST cs; char *name; @@ -420,12 +421,21 @@ i386obsd_trapframe_sniffer (struct frame return NULL; find_pc_partial_function (frame_pc_unwind (next_frame), &name, NULL, NULL); - if (name && ((strcmp ("calltrap", name) == 0) - || (strcmp ("syscall1", name) == 0))) - return &i386obsd_trapframe_unwind; - - return NULL; + return (name && ((strcmp (name, "calltrap") == 0) + || (strcmp (name, "syscall1") == 0) + || (strncmp (name, "Xintr", 5) == 0))); } + +static const struct frame_unwind i386obsd_trapframe_unwind = { + /* FIXME: kettenis/20051219: This really is more like an interrupt + frame, but SIGTRAMP_FRAME would print , + which really is not what we want here. */ + NORMAL_FRAME, + i386obsd_trapframe_this_id, + i386obsd_trapframe_prev_register, + NULL, + i386obsd_trapframe_sniffer +}; static void @@ -459,7 +469,7 @@ i386obsd_init_abi (struct gdbarch_info i bsd_uthread_set_collect_uthread (gdbarch, i386obsd_collect_uthread); /* Unwind kernel trap frames correctly. */ - frame_unwind_append_sniffer (gdbarch, i386obsd_trapframe_sniffer); + frame_unwind_prepend_unwinder (gdbarch, &i386obsd_trapframe_unwind); } /* OpenBSD a.out. */