This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Be prepared for DWARF4 .debug_frame (and .eh_frame) format
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>
- Cc: Richard Henderson <rth at redhat dot com>, Cary Coutant <ccoutant at google dot com>, gcc-patches at gcc dot gnu dot org
- Date: Tue, 20 Apr 2010 08:04:33 +0200
- Subject: Re: [PATCH] Be prepared for DWARF4 .debug_frame (and .eh_frame) format
- References: <20100402093249.GD2817@tyan-ft48-01.lab.bos.redhat.com> <4BCD397B.2000706@redhat.com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Tue, Apr 20, 2010 at 01:19:55AM -0400, Jason Merrill wrote:
> On 04/02/2010 05:32 AM, Jakub Jelinek wrote:
> >@@ -358,6 +358,12 @@ extract_cie_info (const struct dwarf_cie
> >
> > /* Immediately following the augmentation are the code and
> > data alignment and return address column. */
> >+ if (__builtin_expect (cie->version>= 4, 0))
> >+ {
> >+ if (p[0] != sizeof (void *) || p[1] != 0)
> >+ return NULL;
> >+ p += 2;
> >+ }
>
> The comment needs an update.
>
> >+ if (aug[0] != 'z')
> >+ p += sizeof (void *);
>
> This also needs a comment.
Like this?
2010-04-20 Jakub Jelinek <jakub@redhat.com>
* dwarf2out.c (output_call_frame_info): For dw_cie_version
>= 4 add also address size and segment size fields into CIE
header.
* unwind-dw2.c (extract_cie_info): Handle CIE version 4, as
long as address size is the same as sizeof (void *) and
segment size is 0.
* unwind-dw2-fde.c (get_cie_encoding): Likewise. If
address size or segment size is unexpected, return DW_EH_PE_omit.
(classify_object_over_fdes): If get_cie_encoding returned
DW_EH_PE_omit, return -1.
(init_object): If classify_object_over_fdes returned -1,
pretend there were no FDEs at all.
--- gcc/dwarf2out.c.jj 2010-04-19 23:52:19.000000000 +0200
+++ gcc/dwarf2out.c 2010-04-20 07:57:43.000000000 +0200
@@ -3771,6 +3771,11 @@ output_call_frame_info (int for_eh)
}
dw2_asm_output_nstring (augmentation, -1, "CIE Augmentation");
+ if (dw_cie_version >= 4)
+ {
+ dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "CIE Address Size");
+ dw2_asm_output_data (1, 0, "CIE Segment Size");
+ }
dw2_asm_output_data_uleb128 (1, "CIE Code Alignment Factor");
dw2_asm_output_data_sleb128 (DWARF_CIE_DATA_ALIGNMENT,
"CIE Data Alignment Factor");
--- gcc/unwind-dw2.c.jj 2010-04-19 23:52:19.000000000 +0200
+++ gcc/unwind-dw2.c 2010-04-20 08:00:31.000000000 +0200
@@ -356,7 +356,16 @@ extract_cie_info (const struct dwarf_cie
aug += 2;
}
- /* Immediately following the augmentation are the code and
+ /* After the augmentation resp. pointer for "eh" augmentation
+ follows for CIE version >= 4 address size byte and
+ segment size byte. */
+ if (__builtin_expect (cie->version >= 4, 0))
+ {
+ if (p[0] != sizeof (void *) || p[1] != 0)
+ return NULL;
+ p += 2;
+ }
+ /* Immediately following this are the code and
data alignment and return address column. */
p = read_uleb128 (p, &utmp);
fs->code_align = (_Unwind_Word)utmp;
--- gcc/unwind-dw2-fde.c.jj 2010-04-19 23:52:19.000000000 +0200
+++ gcc/unwind-dw2-fde.c 2010-04-20 08:02:14.000000000 +0200
@@ -1,6 +1,6 @@
/* Subroutines needed for unwinding stack frames for exception handling. */
/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008,
- 2009 Free Software Foundation, Inc.
+ 2009, 2010 Free Software Foundation, Inc.
Contributed by Jason Merrill <jason@cygnus.com>.
This file is part of GCC.
@@ -265,10 +265,20 @@ get_cie_encoding (const struct dwarf_cie
_sleb128_t stmp;
aug = cie->augmentation;
+ p = aug + strlen ((const char *)aug) + 1; /* Skip the augmentation string. */
+ if (__builtin_expect (cie->version >= 4, 0))
+ {
+ if (aug[0] != 'z')
+ p += sizeof (void *); /* Skip g++ v2 pointer. */
+ if (p[0] != sizeof (void *) || p[1] != 0)
+ return DW_EH_PE_omit; /* We are not prepared to handle unexpected
+ address sizes or segment selectors. */
+ p += 2; /* Skip address size and segment size. */
+ }
+
if (aug[0] != 'z')
return DW_EH_PE_absptr;
- p = aug + strlen ((const char *)aug) + 1; /* Skip the augmentation string. */
p = read_uleb128 (p, &utmp); /* Skip code alignment. */
p = read_sleb128 (p, &stmp); /* Skip data alignment. */
if (cie->version == 1) /* Skip return address column. */
@@ -614,6 +624,8 @@ classify_object_over_fdes (struct object
{
last_cie = this_cie;
encoding = get_cie_encoding (this_cie);
+ if (encoding == DW_EH_PE_omit)
+ return -1;
base = base_from_object (encoding, ob);
if (ob->s.b.encoding == DW_EH_PE_omit)
ob->s.b.encoding = encoding;
@@ -723,10 +735,26 @@ init_object (struct object* ob)
{
fde **p = ob->u.array;
for (count = 0; *p; ++p)
- count += classify_object_over_fdes (ob, *p);
+ {
+ size_t cur_count = classify_object_over_fdes (ob, *p);
+ if (cur_count == (size_t) -1)
+ goto unhandled_fdes;
+ count += cur_count;
+ }
}
else
- count = classify_object_over_fdes (ob, ob->u.single);
+ {
+ count = classify_object_over_fdes (ob, ob->u.single);
+ if (count == (size_t) -1)
+ {
+ static const fde terminator;
+ unhandled_fdes:
+ ob->s.i = 0;
+ ob->s.b.encoding = DW_EH_PE_omit;
+ ob->u.single = &terminator;
+ return;
+ }
+ }
/* The count field we have in the main struct object is somewhat
limited, but should suffice for virtually all cases. If the
Jakub