This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils 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]

fix cfi sharing in dw2gencfi.c


I've been writing some unwinder info for powerpc and powerpc64 signal
return trampolines today.  I chose to use the new .cfi support in gas,
which actually doesn't help all that much with sigreturn since you need
to make heavy use of .cfi_escape, and gas doesn't have a uleb128 or
sleb128 operator for expressions.  Maybe I'll add that some day, but for
now, this fixes a cie inefficiency.

	* dw2gencfi.c (select_cie_for_fde): When separating cie out
	from fde, treat a CFI_escape as we do a DW_CFA_advance_loc.

Before: Two CIEs, no sharing.
$ readelf -wf tramp32.o
The section .eh_frame contains:

00000000 0000014c 00000000 CIE
  Version:               1
  Augmentation:          "zR"
  Code alignment factor: 4
  Data alignment factor: -4
  Return address column: 67
  Augmentation data:     1b

  DW_CFA_def_cfa: r1 ofs 0
  DW_CFA_def_cfa_expression (DW_OP_breg1: 92; DW_OP_deref; DW_OP_plus_uconst: 4; DW_OP_deref)
  DW_CFA_expression: r0 (DW_OP_breg1: 92; DW_OP_deref)
  DW_CFA_expression: r2 (DW_OP_breg1: 92; DW_OP_deref; DW_OP_plus_uconst: 8)
[snip]

00000150 00000010 00000154 FDE cie=00000000 pc=00000000..00000008
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop

00000164 0000014c 00000000 CIE
  Version:               1
  Augmentation:          "zR"
  Code alignment factor: 4
  Data alignment factor: -4
  Return address column: 67
  Augmentation data:     1b

  DW_CFA_def_cfa: r1 ofs 0
  DW_CFA_def_cfa_expression (DW_OP_breg1: 256; DW_OP_deref; DW_OP_plus_uconst: 4; DW_OP_deref)
  DW_CFA_expression: r0 (DW_OP_breg1: 256; DW_OP_deref)
[snip]

000002b4 00000010 00000154 FDE cie=00000164 pc=00000008..00000010
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop


After:  One CIE shared by the FDEs.
$ readelf -wf tramp32.o
The section .eh_frame contains:

00000000 00000010 00000000 CIE
  Version:               1
  Augmentation:          "zR"
  Code alignment factor: 4
  Data alignment factor: -4
  Return address column: 67
  Augmentation data:     1b

  DW_CFA_def_cfa: r1 ofs 0

00000014 0000014c 00000018 FDE cie=00000000 pc=00000000..00000008
  DW_CFA_def_cfa_expression (DW_OP_breg1: 92; DW_OP_deref; DW_OP_plus_uconst: 4; DW_OP_deref)
  DW_CFA_expression: r0 (DW_OP_breg1: 92; DW_OP_deref)
  DW_CFA_expression: r2 (DW_OP_breg1: 92; DW_OP_deref; DW_OP_plus_uconst: 8)
[snip]

00000164 0000014c 00000168 FDE cie=00000000 pc=00000008..00000010
  DW_CFA_def_cfa_expression (DW_OP_breg1: 256; DW_OP_deref; DW_OP_plus_uconst: 4; DW_OP_deref)
  DW_CFA_expression: r0 (DW_OP_breg1: 256; DW_OP_deref)
[snip]


Index: gas/dw2gencfi.c
===================================================================
RCS file: /cvs/src/src/gas/dw2gencfi.c,v
retrieving revision 1.17
diff -u -p -r1.17 dw2gencfi.c
--- gas/dw2gencfi.c	13 May 2004 14:41:18 -0000	1.17
+++ gas/dw2gencfi.c	9 Sep 2004 12:56:08 -0000
@@ -975,8 +975,12 @@ select_cie_for_fde (struct fde_entry *fd
 	}
 
       /* 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.  */
-      if (i == cie->last && (!j || j->insn == DW_CFA_advance_loc))
+	 run out of FDE entries or we've encountered an advance or
+	 escape.  */
+      if (i == cie->last
+	  && (!j
+	      || j->insn == DW_CFA_advance_loc
+	      || j->insn == CFI_escape))
 	{
 	  *pfirst = j;
 	  return cie;
@@ -992,7 +996,8 @@ select_cie_for_fde (struct fde_entry *fd
   cie->first = fde->data;
 
   for (i = cie->first; i ; i = i->next)
-    if (i->insn == DW_CFA_advance_loc)
+    if (i->insn == DW_CFA_advance_loc
+	|| i->insn == CFI_escape)
       break;
 
   cie->last = i;

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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