This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Be prepared for DWARF4 .debug_frame (and .eh_frame) format


On Tue, Apr 20, 2010 at 05:54:57PM -0400, Jason Merrill wrote:
> Ah.  When/where is such an augmentation generated?  Is this just a
> backwards compatibility thing?  In any case handling of this case

Before 3.0.  Yes, it is a backwards compatibility thing.

> should check for an augmentation string of "eh", not assume that
> anything that doesn't start with 'z' is "eh".

You're right.  In fact, 2.9* even generated "" augmentation in .eh_frame
if no eh_ptr was needed.

So this updated patch skips the eh_ptr only if augmentation starts with
"eh".

2010-04-21  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-20 19:07:50.000000000 +0200
+++ gcc/dwarf2out.c	2010-04-21 00:18:39.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-20 17:38:33.000000000 +0200
+++ gcc/unwind-dw2.c	2010-04-21 00:18:39.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-20 17:38:33.000000000 +0200
+++ gcc/unwind-dw2-fde.c	2010-04-21 00:21:04.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] == 'e' && aug[1] == 'h')
+	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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]