Fix the generation of unnecesaary CIE stack unwinding frames.
Resolves: #2121123
This commit is contained in:
parent
09c1fb65b9
commit
cbd5319db8
|
@ -0,0 +1,155 @@
|
|||
--- binutils.orig/gas/dw2gencfi.c 2022-09-08 13:54:05.539276706 +0100
|
||||
+++ binutils-2.35.2/gas/dw2gencfi.c 2022-09-08 14:05:56.128016840 +0100
|
||||
@@ -2054,6 +2054,64 @@ output_fde (struct fde_entry *fde, struc
|
||||
symbol_set_value_now (end_address);
|
||||
}
|
||||
|
||||
+/* Allow these insns to be put in the initial sequence of a CIE.
|
||||
+ If J is non-NULL, then compare I and J insns for a match. */
|
||||
+
|
||||
+static inline bfd_boolean
|
||||
+initial_cie_insn (const struct cfi_insn_data *i, const struct cfi_insn_data *j)
|
||||
+{
|
||||
+ if (j && i->insn != j->insn)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ switch (i->insn)
|
||||
+ {
|
||||
+ case DW_CFA_offset:
|
||||
+ case DW_CFA_def_cfa:
|
||||
+ case DW_CFA_val_offset:
|
||||
+ if (j)
|
||||
+ {
|
||||
+ if (i->u.ri.reg != j->u.ri.reg)
|
||||
+ return FALSE;
|
||||
+ if (i->u.ri.offset != j->u.ri.offset)
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_register:
|
||||
+ if (j)
|
||||
+ {
|
||||
+ if (i->u.rr.reg1 != j->u.rr.reg1)
|
||||
+ return FALSE;
|
||||
+ if (i->u.rr.reg2 != j->u.rr.reg2)
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_def_cfa_register:
|
||||
+ case DW_CFA_restore:
|
||||
+ case DW_CFA_undefined:
|
||||
+ case DW_CFA_same_value:
|
||||
+ if (j)
|
||||
+ {
|
||||
+ if (i->u.r != j->u.r)
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_def_cfa_offset:
|
||||
+ if (j)
|
||||
+ {
|
||||
+ if (i->u.i != j->u.i)
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
static struct cie_entry *
|
||||
select_cie_for_fde (struct fde_entry *fde, bfd_boolean eh_frame,
|
||||
struct cfi_insn_data **pfirst, int align)
|
||||
@@ -2099,71 +2157,15 @@ select_cie_for_fde (struct fde_entry *fd
|
||||
i != cie->last && j != NULL;
|
||||
i = i->next, j = j->next)
|
||||
{
|
||||
- if (i->insn != j->insn)
|
||||
- goto fail;
|
||||
- switch (i->insn)
|
||||
- {
|
||||
- case DW_CFA_advance_loc:
|
||||
- case DW_CFA_remember_state:
|
||||
- /* We reached the first advance/remember in the FDE,
|
||||
- but did not reach the end of the CIE list. */
|
||||
- goto fail;
|
||||
-
|
||||
- case DW_CFA_offset:
|
||||
- case DW_CFA_def_cfa:
|
||||
- if (i->u.ri.reg != j->u.ri.reg)
|
||||
- goto fail;
|
||||
- if (i->u.ri.offset != j->u.ri.offset)
|
||||
- goto fail;
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_register:
|
||||
- if (i->u.rr.reg1 != j->u.rr.reg1)
|
||||
- goto fail;
|
||||
- if (i->u.rr.reg2 != j->u.rr.reg2)
|
||||
- goto fail;
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_def_cfa_register:
|
||||
- case DW_CFA_restore:
|
||||
- case DW_CFA_undefined:
|
||||
- case DW_CFA_same_value:
|
||||
- if (i->u.r != j->u.r)
|
||||
- goto fail;
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_def_cfa_offset:
|
||||
- if (i->u.i != j->u.i)
|
||||
- goto fail;
|
||||
- break;
|
||||
-
|
||||
- case CFI_escape:
|
||||
- case CFI_val_encoded_addr:
|
||||
- case CFI_label:
|
||||
- /* Don't bother matching these for now. */
|
||||
- goto fail;
|
||||
-
|
||||
- default:
|
||||
- abort ();
|
||||
- }
|
||||
+ if (!initial_cie_insn (i, j))
|
||||
+ break;
|
||||
}
|
||||
|
||||
- /* Success if we reached the end of the CIE list, and we've either
|
||||
- run out of FDE entries or we've encountered an advance,
|
||||
- remember, or escape. */
|
||||
- if (i == cie->last
|
||||
- && (!j
|
||||
- || j->insn == DW_CFA_advance_loc
|
||||
- || j->insn == DW_CFA_remember_state
|
||||
- || j->insn == CFI_escape
|
||||
- || j->insn == CFI_val_encoded_addr
|
||||
- || j->insn == CFI_label))
|
||||
+ if (i == cie->last)
|
||||
{
|
||||
*pfirst = j;
|
||||
return cie;
|
||||
}
|
||||
-
|
||||
- fail:;
|
||||
}
|
||||
|
||||
cie = XNEW (struct cie_entry);
|
||||
@@ -2181,11 +2183,7 @@ select_cie_for_fde (struct fde_entry *fd
|
||||
#endif
|
||||
|
||||
for (i = cie->first; i ; i = i->next)
|
||||
- if (i->insn == DW_CFA_advance_loc
|
||||
- || i->insn == DW_CFA_remember_state
|
||||
- || i->insn == CFI_escape
|
||||
- || i->insn == CFI_val_encoded_addr
|
||||
- || i->insn == CFI_label)
|
||||
+ if (!initial_cie_insn (i, NULL))
|
||||
break;
|
||||
|
||||
cie->last = i;
|
|
@ -39,7 +39,7 @@
|
|||
Summary: A GNU collection of binary utilities
|
||||
Name: binutils%{?name_cross}%{?_with_debug:-debug}
|
||||
Version: 2.35.2
|
||||
Release: 24%{?dist}
|
||||
Release: 25%{?dist}
|
||||
License: GPLv3+
|
||||
URL: https://sourceware.org/binutils
|
||||
|
||||
|
@ -424,10 +424,14 @@ Patch55: binutils-s390-z16.patch
|
|||
# Lifetime: Fixed in 2.37
|
||||
Patch56: binutils-s390x-static-PIE.patch
|
||||
|
||||
# Purpose: Fix bogis linker warnings about references to undefined symbols.
|
||||
# Purpose: Fix bogus linker warnings about references to undefined symbols.
|
||||
# Lifetime: Fixed in 2.36
|
||||
Patch57: binutils-undefined-ref-to-sym.patch
|
||||
|
||||
# Purpose: Fix unnecessary generation of CIE debug frames.
|
||||
# Lifetime: Fixed in 2.40
|
||||
Patch58: binutils-CIE-generation.patch
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
Provides: bundled(libiberty)
|
||||
|
@ -1021,6 +1025,9 @@ exit 0
|
|||
|
||||
#----------------------------------------------------------------------------
|
||||
%changelog
|
||||
* Thu Sep 08 2022 Nick Clifton <nickc@redhat.com> - 2.35.2-25
|
||||
- Fix the generation of unnecesaary CIE stack unwinding frames. (#2121123)
|
||||
|
||||
* Mon Jun 13 2022 Nick Clifton <nickc@redhat.com> - 2.35.2-24
|
||||
- Fix bogus linker warnings about references to undefined symbols. (#2095926)
|
||||
|
||||
|
|
Loading…
Reference in New Issue