aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2010-04-21 08:57:37 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2010-04-21 08:57:37 +0200
commit8f65940dd1ba4a5d305a9efa4d44a5af15518af1 (patch)
tree17be69b1e08b391d9bba647e830f604c506db243 /gcc
parentd64427ff33f0521b2af8636a74422d52392141e3 (diff)
downloadgcc-8f65940dd1ba4a5d305a9efa4d44a5af15518af1.zip
gcc-8f65940dd1ba4a5d305a9efa4d44a5af15518af1.tar.gz
gcc-8f65940dd1ba4a5d305a9efa4d44a5af15518af1.tar.bz2
dwarf2out.c (output_call_frame_info): For dw_cie_version >= 4 add also address size and segment size fields into CIE...
* 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. From-SVN: r158589
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/dwarf2out.c5
-rw-r--r--gcc/unwind-dw2-fde.c34
-rw-r--r--gcc/unwind-dw2.c11
4 files changed, 61 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4348d3d..6f875d4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index cfacf96..21a3f75 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -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");
diff --git a/gcc/unwind-dw2-fde.c b/gcc/unwind-dw2-fde.c
index 60535cf..93d4271 100644
--- a/gcc/unwind-dw2-fde.c
+++ b/gcc/unwind-dw2-fde.c
@@ -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
diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c
index 3cf3189..65d639d 100644
--- a/gcc/unwind-dw2.c
+++ b/gcc/unwind-dw2.c
@@ -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;