OSDN Git Service

* dwarf2out.c (output_call_frame_info): For dw_cie_version
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 21 Apr 2010 06:57:37 +0000 (06:57 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 21 Apr 2010 06:57:37 +0000 (06:57 +0000)
>= 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158589 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/dwarf2out.c
gcc/unwind-dw2-fde.c
gcc/unwind-dw2.c

index 4348d3d..6f875d4 100644 (file)
@@ -1,3 +1,19 @@
+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.
+
 2010-04-21  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386.md (bswap<mode>2): Macroize expander from
index cfacf96..21a3f75 100644 (file)
@@ -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");
index 60535cf..93d4271 100644 (file)
@@ -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,18 @@ get_cie_encoding (const struct dwarf_cie *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 (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 +622,8 @@ classify_object_over_fdes (struct object *ob, const fde *this_fde)
        {
          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 +733,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
index 3cf3189..65d639d 100644 (file)
@@ -356,7 +356,16 @@ extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
       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;