From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28568 invoked by alias); 12 Jun 2011 20:57:49 -0000 Received: (qmail 28560 invoked by uid 22791); 12 Jun 2011 20:57:48 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL,BAYES_00,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from sibelius.xs4all.nl (HELO glazunov.sibelius.xs4all.nl) (83.163.83.176) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 12 Jun 2011 20:57:34 +0000 Received: from glazunov.sibelius.xs4all.nl (kettenis@localhost [127.0.0.1]) by glazunov.sibelius.xs4all.nl (8.14.3/8.14.3) with ESMTP id p5CKvVT3028376 for ; Sun, 12 Jun 2011 22:57:31 +0200 (CEST) Received: (from kettenis@localhost) by glazunov.sibelius.xs4all.nl (8.14.3/8.14.3/Submit) id p5CKvUEa030437; Sun, 12 Jun 2011 22:57:30 +0200 (CEST) Date: Sun, 12 Jun 2011 20:57:00 -0000 Message-Id: <201106122057.p5CKvUEa030437@glazunov.sibelius.xs4all.nl> From: Mark Kettenis To: gdb-patches@sourceware.org Subject: [PATCH] Fix some i386 unwinder inconcistencies Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-06/txt/msg00153.txt.bz2 This diff fixes a few issues with the epilogue and stack tramp unwinders. Committed. 2011-06-12 Mark Kettenis * i386-tdep.c (i386_epilogue_frame_cache): Simplify code. Call get_frame_func instead of get_frame_pc to determine the code address used to construct the frame ID. (i386_epilogue_frame_unwind_stop_reason): Fix coding style. (i386_epilogue_frame_this_id): Likewise. (i386_epilogue_frame_prev_register): New function. (i386_epilogue_frame_unwind): Use i386_epilogue_frame_prev_register. (i386_stack_tramp_frame_sniffer): Fix coding style. (i386_stack_tramp_frame_unwind): Use i386_epilogue_frame_prev_register. (i386_gdbarch_init): Fix comments. Index: i386-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/i386-tdep.c,v retrieving revision 1.333 diff -u -p -r1.333 i386-tdep.c --- i386-tdep.c 12 Jun 2011 18:21:55 -0000 1.333 +++ i386-tdep.c 12 Jun 2011 20:39:01 -0000 @@ -1910,11 +1910,9 @@ i386_epilogue_frame_sniffer (const struc static struct i386_frame_cache * i386_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache) { - struct gdbarch *gdbarch = get_frame_arch (this_frame); - enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); volatile struct gdb_exception ex; struct i386_frame_cache *cache; - gdb_byte buf[4]; + CORE_ADDR sp; if (*this_cache) return *this_cache; @@ -1924,18 +1922,14 @@ i386_epilogue_frame_cache (struct frame_ TRY_CATCH (ex, RETURN_MASK_ERROR) { - /* Cache base will be %esp plus cache->sp_offset (-4). */ - get_frame_register (this_frame, I386_ESP_REGNUM, buf); - cache->base = extract_unsigned_integer (buf, 4, - byte_order) + cache->sp_offset; + cache->pc = get_frame_func (this_frame); - /* Cache pc will be the frame func. */ - cache->pc = get_frame_pc (this_frame); - - /* The saved %esp will be at cache->base plus 8. */ + /* At this point the stack looks as if we just entered the + function, with the return address at the top of the + stack. */ + sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM); + cache->base = sp + cache->sp_offset; cache->saved_sp = cache->base + 8; - - /* The saved %eip will be at cache->base plus 4. */ cache->saved_regs[I386_EIP_REGNUM] = cache->base + 4; cache->base_p = 1; @@ -1950,8 +1944,8 @@ static enum unwind_stop_reason i386_epilogue_frame_unwind_stop_reason (struct frame_info *this_frame, void **this_cache) { - struct i386_frame_cache *cache - = i386_epilogue_frame_cache (this_frame, this_cache); + struct i386_frame_cache *cache = + i386_epilogue_frame_cache (this_frame, this_cache); if (!cache->base_p) return UNWIND_UNAVAILABLE; @@ -1964,8 +1958,8 @@ i386_epilogue_frame_this_id (struct fram void **this_cache, struct frame_id *this_id) { - struct i386_frame_cache *cache = i386_epilogue_frame_cache (this_frame, - this_cache); + struct i386_frame_cache *cache = + i386_epilogue_frame_cache (this_frame, this_cache); if (!cache->base_p) return; @@ -1973,12 +1967,22 @@ i386_epilogue_frame_this_id (struct fram (*this_id) = frame_id_build (cache->base + 8, cache->pc); } +static struct value * +i386_epilogue_frame_prev_register (struct frame_info *this_frame, + void **this_cache, int regnum) +{ + /* Make sure we've initialized the cache. */ + i386_epilogue_frame_cache (this_frame, this_cache); + + return i386_frame_prev_register (this_frame, this_cache, regnum); +} + static const struct frame_unwind i386_epilogue_frame_unwind = { NORMAL_FRAME, i386_epilogue_frame_unwind_stop_reason, i386_epilogue_frame_this_id, - i386_frame_prev_register, + i386_epilogue_frame_prev_register, NULL, i386_epilogue_frame_sniffer }; @@ -2045,8 +2049,8 @@ i386_in_stack_tramp_p (struct gdbarch *g static int i386_stack_tramp_frame_sniffer (const struct frame_unwind *self, - struct frame_info *this_frame, - void **this_prologue_cache) + struct frame_info *this_frame, + void **this_cache) { if (frame_relative_level (this_frame) == 0) return i386_in_stack_tramp_p (get_frame_arch (this_frame), @@ -2060,7 +2064,7 @@ static const struct frame_unwind i386_st NORMAL_FRAME, i386_epilogue_frame_unwind_stop_reason, i386_epilogue_frame_this_id, - i386_frame_prev_register, + i386_epilogue_frame_prev_register, NULL, i386_stack_tramp_frame_sniffer }; @@ -7311,13 +7315,13 @@ i386_gdbarch_init (struct gdbarch_info i set_gdbarch_fetch_pointer_argument (gdbarch, i386_fetch_pointer_argument); /* Hook the function epilogue frame unwinder. This unwinder is - appended to the list first, so that it supercedes the Dwarf - unwinder in function epilogues (where the Dwarf unwinder + appended to the list first, so that it supercedes the DWARF + unwinder in function epilogues (where the DWARF unwinder currently fails). */ frame_unwind_append_unwinder (gdbarch, &i386_epilogue_frame_unwind); /* Hook in the DWARF CFI frame unwinder. This unwinder is appended - to the list before the prologue-based unwinders, so that Dwarf + to the list before the prologue-based unwinders, so that DWARF CFI info will be used if it is available. */ dwarf2_append_unwinders (gdbarch);