From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18795 invoked by alias); 13 Jun 2009 01:28:18 -0000 Received: (qmail 18785 invoked by uid 22791); 13 Jun 2009 01:28:17 -0000 X-SWARE-Spam-Status: No, hits=-2.1 required=5.0 tests=AWL,BAYES_00,SPF_PASS X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (216.239.33.17) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 13 Jun 2009 01:28:12 +0000 Received: from spaceape23.eur.corp.google.com (spaceape23.eur.corp.google.com [172.28.16.75]) by smtp-out.google.com with ESMTP id n5D1S8EZ002396 for ; Sat, 13 Jun 2009 02:28:08 +0100 Received: from localhost (ppluzhnikov.mtv.corp.google.com [172.18.118.92]) by spaceape23.eur.corp.google.com with ESMTP id n5D1S5D1011781; Fri, 12 Jun 2009 18:28:05 -0700 Received: by localhost (Postfix, from userid 74925) id BD89576BC4; Fri, 12 Jun 2009 18:28:04 -0700 (PDT) To: gdb-patches@sourceware.org CC: ppluzhnikov@google.com Subject: [rfc][patch] Fix for gdb/10275 (mis-handling of DW_CFA_restore_state) Message-Id: <20090613012804.BD89576BC4@localhost> Date: Sat, 13 Jun 2009 01:28:00 -0000 From: ppluzhnikov@google.com (Paul Pluzhnikov) X-IsSubscribed: yes 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: 2009-06/txt/msg00347.txt.bz2 Greetings, Fixing this looks easier than I expected :-) Regtested on Linux/x86_64 (no regressions). I also verified that I get correct stack for my reduced test case in gdb/10275, and in my real gcc-4.5 compiled optimized code. If this looks correct, I'll add a test case. Thanks, -- Paul Pluzhnikov 2009-06-12 Paul Pluzhnikov gdb/10275 * dwarf2-frame.c (dwarf2_frame_state): Move cfa_offset, cfa_reg, cfa_how and cfa_exp into regs and adjust users. Index: dwarf2-frame.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2-frame.c,v retrieving revision 1.87 diff -u -p -u -r1.87 dwarf2-frame.c --- dwarf2-frame.c 3 Jan 2009 05:57:51 -0000 1.87 +++ dwarf2-frame.c 13 Jun 2009 01:20:54 -0000 @@ -164,19 +164,19 @@ struct dwarf2_frame_state struct dwarf2_frame_state_reg *reg; int num_regs; + LONGEST cfa_offset; + ULONGEST cfa_reg; + enum { + CFA_UNSET, + CFA_REG_OFFSET, + CFA_EXP + } cfa_how; + gdb_byte *cfa_exp; + /* Used to implement DW_CFA_remember_state. */ struct dwarf2_frame_state_reg_info *prev; } regs; - LONGEST cfa_offset; - ULONGEST cfa_reg; - gdb_byte *cfa_exp; - enum { - CFA_UNSET, - CFA_REG_OFFSET, - CFA_EXP - } cfa_how; - /* The PC described by the current frame state. */ CORE_ADDR pc; @@ -502,21 +502,21 @@ bad CFI data; mismatched DW_CFA_restore_ break; case DW_CFA_def_cfa: - insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->cfa_reg); + insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->regs.cfa_reg); insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp); if (fs->armcc_cfa_offsets_sf) utmp *= fs->data_align; - fs->cfa_offset = utmp; - fs->cfa_how = CFA_REG_OFFSET; + fs->regs.cfa_offset = utmp; + fs->regs.cfa_how = CFA_REG_OFFSET; break; case DW_CFA_def_cfa_register: - insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->cfa_reg); - fs->cfa_reg = dwarf2_frame_adjust_regnum (gdbarch, fs->cfa_reg, - eh_frame_p); - fs->cfa_how = CFA_REG_OFFSET; + insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->regs.cfa_reg); + fs->regs.cfa_reg = dwarf2_frame_adjust_regnum (gdbarch, fs->regs.cfa_reg, + eh_frame_p); + fs->regs.cfa_how = CFA_REG_OFFSET; break; case DW_CFA_def_cfa_offset: @@ -525,7 +525,7 @@ bad CFI data; mismatched DW_CFA_restore_ if (fs->armcc_cfa_offsets_sf) utmp *= fs->data_align; - fs->cfa_offset = utmp; + fs->regs.cfa_offset = utmp; /* cfa_how deliberately not set. */ break; @@ -533,10 +533,10 @@ bad CFI data; mismatched DW_CFA_restore_ break; case DW_CFA_def_cfa_expression: - insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->cfa_exp_len); - fs->cfa_exp = insn_ptr; - fs->cfa_how = CFA_EXP; - insn_ptr += fs->cfa_exp_len; + insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->regs.cfa_exp_len); + fs->regs.cfa_exp = insn_ptr; + fs->regs.cfa_how = CFA_EXP; + insn_ptr += fs->regs.cfa_exp_len; break; case DW_CFA_expression: @@ -589,17 +589,18 @@ bad CFI data; mismatched DW_CFA_restore_ break; case DW_CFA_def_cfa_sf: - insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->cfa_reg); - fs->cfa_reg = dwarf2_frame_adjust_regnum (gdbarch, fs->cfa_reg, - eh_frame_p); + insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->regs.cfa_reg); + fs->regs.cfa_reg = dwarf2_frame_adjust_regnum (gdbarch, + fs->regs.cfa_reg, + eh_frame_p); insn_ptr = read_sleb128 (insn_ptr, insn_end, &offset); - fs->cfa_offset = offset * fs->data_align; - fs->cfa_how = CFA_REG_OFFSET; + fs->regs.cfa_offset = offset * fs->data_align; + fs->regs.cfa_how = CFA_REG_OFFSET; break; case DW_CFA_def_cfa_offset_sf: insn_ptr = read_sleb128 (insn_ptr, insn_end, &offset); - fs->cfa_offset = offset * fs->data_align; + fs->regs.cfa_offset = offset * fs->data_align; /* cfa_how deliberately not set. */ break; @@ -932,19 +933,19 @@ dwarf2_frame_cache (struct frame_info *t execute_cfa_program (fde, fde->instructions, fde->end, this_frame, fs); /* Calculate the CFA. */ - switch (fs->cfa_how) + switch (fs->regs.cfa_how) { case CFA_REG_OFFSET: - cache->cfa = read_reg (this_frame, fs->cfa_reg); + cache->cfa = read_reg (this_frame, fs->regs.cfa_reg); if (fs->armcc_cfa_offsets_reversed) - cache->cfa -= fs->cfa_offset; + cache->cfa -= fs->regs.cfa_offset; else - cache->cfa += fs->cfa_offset; + cache->cfa += fs->regs.cfa_offset; break; case CFA_EXP: cache->cfa = - execute_stack_op (fs->cfa_exp, fs->cfa_exp_len, + execute_stack_op (fs->regs.cfa_exp, fs->regs.cfa_exp_len, cache->addr_size, this_frame, 0); break;