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]

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


Hi!

DWARF4 inserts two new byte sized fields between augmentation
and code alignment factor.

The following patch adjusts output_call_frame_info, if we ever
choose to use dw_cie_version larger than 3, so that we don't
forget about that.

And the unwind* changes make us to be prepared for such .eh_frame
sections, at least if they say pointer size is the expected one
and no segment selectors are needed.

Ok for 4.6?

2010-04-02  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-01 21:42:26.000000000 +0200
+++ gcc/dwarf2out.c	2010-04-02 09:13:35.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-01-20 18:31:57.000000000 +0100
+++ gcc/unwind-dw2.c	2010-04-02 09:32:31.000000000 +0200
@@ -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;
+    }
   p = read_uleb128 (p, &utmp);
   fs->code_align = (_Unwind_Word)utmp;
   p = read_sleb128 (p, &stmp);
--- gcc/unwind-dw2-fde.c.jj	2009-09-21 17:50:45.000000000 +0200
+++ gcc/unwind-dw2-fde.c	2010-04-02 10:41:36.000000000 +0200
@@ -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 *);
+      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]