From: Alexandre Oliva Date: Sun, 28 May 2006 05:56:20 +0000 (+0000) Subject: * dwarf2-frame.c (struct dwarf2_cie): Add signal_frame field. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=56c987f6063485c5c588dc27dbf1b3ddce3b0200;p=binutils-gdb.git * dwarf2-frame.c (struct dwarf2_cie): Add signal_frame field. (dwarf2_frame_sniffer): Use it. (decode_frame_entry_1): Set it according to augmentation "S". --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 1cc0b6f6fc8..d1fbeb6b7cf 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2006-05-28 Alexandre Oliva + + * dwarf2-frame.c (struct dwarf2_cie): Add signal_frame field. + (dwarf2_frame_sniffer): Use it. + (decode_frame_entry_1): Set it according to augmentation "S". + 2006-05-27 Joel Brobecker From Peter Schauer diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index a11aac9ce40..6b81dff7999 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -70,6 +70,9 @@ struct dwarf2_cie /* True if a 'z' augmentation existed. */ unsigned char saw_z_augmentation; + /* True if an 'S' augmentation existed. */ + unsigned char signal_frame; + struct dwarf2_cie *next; }; @@ -1053,15 +1056,17 @@ dwarf2_frame_sniffer (struct frame_info *next_frame) function. frame_pc_unwind(), for a no-return next function, can end up returning something past the end of this function's body. */ CORE_ADDR block_addr = frame_unwind_address_in_block (next_frame); - if (!dwarf2_frame_find_fde (&block_addr)) + struct dwarf2_fde *fde = dwarf2_frame_find_fde (&block_addr); + if (!fde) return NULL; /* On some targets, signal trampolines may have unwind information. We need to recognize them so that we set the frame type correctly. */ - if (dwarf2_frame_signal_frame_p (get_frame_arch (next_frame), - next_frame)) + if (fde->cie->signal_frame + || dwarf2_frame_signal_frame_p (get_frame_arch (next_frame), + next_frame)) return &dwarf2_signal_frame_unwind; return &dwarf2_frame_unwind; @@ -1521,6 +1526,10 @@ decode_frame_entry_1 (struct comp_unit *unit, gdb_byte *start, int eh_frame_p) depends on the target address size. */ cie->encoding = DW_EH_PE_absptr; + /* We'll determine the final value later, but we need to + initialize it conservatively. */ + cie->signal_frame = 0; + /* Check version number. */ cie_version = read_1_byte (unit->abfd, buf); if (cie_version != 1 && cie_version != 3) @@ -1604,6 +1613,17 @@ decode_frame_entry_1 (struct comp_unit *unit, gdb_byte *start, int eh_frame_p) augmentation++; } + /* "S" indicates a signal frame, such that the return + address must not be decremented to locate the call frame + info for the previous frame; it might even be the first + instruction of a function, so decrementing it would take + us to a different function. */ + else if (*augmentation == 'S') + { + cie->signal_frame = 1; + augmentation++; + } + /* Otherwise we have an unknown augmentation. Bail out unless we saw a 'z' prefix. */ else