ChangeLog:

2009-06-30  Paul Pluzhnikov  <ppluzhnikov@google.com>

	gdb/10275
	* dwarf2-frame.c (dwarf2_frame_state): Move cfa_offset, cfa_reg,
	cfa_how and cfa_exp into regs and adjust users.

testsuite/ChangeLog:

2009-06-30  Paul Pluzhnikov  <ppluzhnikov@google.com>

	gdb/10275
	* gdb.dwarf2/dw2-restore.{S,exp}: New test.
This commit is contained in:
Paul Pluzhnikov 2009-06-30 16:22:59 +00:00
parent c38f313db7
commit 2fd481e1ea
5 changed files with 133 additions and 32 deletions

View File

@ -1,3 +1,9 @@
2009-06-30 Paul Pluzhnikov <ppluzhnikov@google.com>
gdb/10275
* dwarf2-frame.c (dwarf2_frame_state): Move cfa_offset, cfa_reg,
cfa_how and cfa_exp into regs and adjust users.
2009-06-30 Daniel Jacobowitz <dan@codesourcery.com>
* dwarf2read.c (inherit_abstract_dies): Work around GCC PR 40573.

View File

@ -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,22 @@ bad CFI data; mismatched DW_CFA_restore_state at 0x%s"), paddr (fs->pc));
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 +526,7 @@ bad CFI data; mismatched DW_CFA_restore_state at 0x%s"), paddr (fs->pc));
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 +534,11 @@ bad CFI data; mismatched DW_CFA_restore_state at 0x%s"), paddr (fs->pc));
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 +591,18 @@ bad CFI data; mismatched DW_CFA_restore_state at 0x%s"), paddr (fs->pc));
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 +935,19 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
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;

View File

@ -1,3 +1,8 @@
2009-06-30 Paul Pluzhnikov <ppluzhnikov@google.com>
gdb/10275
* gdb.dwarf2/dw2-restore.{S,exp}: New test.
2009-06-30 Daniel Jacobowitz <dan@codesourcery.com>
* gdb.opt/inline-locals.exp: Remove XFAIL with duplicated arg1.

View File

@ -0,0 +1,50 @@
/*
Copyright 2009 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Compile with "gcc -nostdlib dw2-restore.S" */
.text
.globl _start
.func _start
_start: call foo
mov $0,%rax
ret
.endfunc
.func foo
foo: .cfi_startproc
push %rbp
.cfi_adjust_cfa_offset 8
mov %rsp,%rbp
.cfi_def_cfa_register %rbp
.cfi_remember_state
jmp 2f
1: mov %rbp,%rsp
.cfi_restore %rbp
pop %rbp
.cfi_adjust_cfa_offset -8
.cfi_def_cfa_register %rsp
ret
.cfi_restore_state
2: movq $0,%rax
movq $0,(%rax) /* crash here */
jmp 1b
.cfi_endproc
.endfunc

View File

@ -0,0 +1,37 @@
# Copyright 2009 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Test handling of DW_CFA_restore_state.
# This test can only be run on x86_64 targets.
if {![istarget x86_64-*]} {
return 0
}
set testfile "dw2-restore"
set srcfile ${testfile}.S
set binfile ${objdir}/${subdir}/${testfile}.x
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \
[list {additional_flags=-nostdlib}]] != "" } {
return -1
}
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
gdb_test "run" ""
gdb_test "where" ".*$hex in foo ().+$hex in _start ().*"