This is the mail archive of the binutils@sourceware.org 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]

Patch ping: Scale DW_CFA_advance_loc[124] output values


Hi!

Ping, this is quite urgent bug that GCC needs to check for in
its configury and apply workarounds.
Below is the final version of both patches (only the (offsetT)
cast has been added) together.

2008-11-28  Jakub Jelinek  <jakub@redhat.com>

	* Makefile.am (ehopt.o): Add struc-symbol.h.
	* Makefile.in: Regenerated.
	* ehopt.c: Include struc-symbol.h.
	(check_eh_frame): For very small O_constant DW_CFA_advance_loc4
	create correct DW_CFA_advance_loc.  Handle O_subtract only
	for code alignment factor 1, otherwise handle O_divide or
	O_right_shift of O_subtract and O_constant.
	(eh_frame_estimate_size_before_relax): Always divide by ca.
	(eh_frame_convert_frag): Likewise.

2008-11-28  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>

	* dw2gencfi.c (output_cfi_insn): Scale DW_CFA_advance_loc1,
	DW_CFA_advance_loc2 and DW_CFA_advance_loc4 outputs.

--- gas/Makefile.am.jj	2008-11-19 15:50:40.000000000 +0100
+++ gas/Makefile.am	2008-11-19 16:57:49.000000000 +0100
@@ -2159,7 +2159,8 @@ dwarf2dbg.o: dwarf2dbg.c $(INCDIR)/safe-
 dw2gencfi.o: dw2gencfi.c dw2gencfi.h $(INCDIR)/elf/dwarf2.h \
   subsegs.h $(INCDIR)/obstack.h
 ecoff.o: ecoff.c ecoff.h
-ehopt.o: ehopt.c subsegs.h $(INCDIR)/obstack.h $(INCDIR)/elf/dwarf2.h
+ehopt.o: ehopt.c subsegs.h $(INCDIR)/obstack.h $(INCDIR)/elf/dwarf2.h \
+  struc-symbol.h
 expr.o: expr.c $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h
 flonum-copy.o: flonum-copy.c
 flonum-konst.o: flonum-konst.c
--- gas/Makefile.in.jj	2008-11-19 15:50:40.000000000 +0100
+++ gas/Makefile.in	2008-11-19 16:58:03.000000000 +0100
@@ -3015,7 +3015,8 @@ dwarf2dbg.o: dwarf2dbg.c $(INCDIR)/safe-
 dw2gencfi.o: dw2gencfi.c dw2gencfi.h $(INCDIR)/elf/dwarf2.h \
   subsegs.h $(INCDIR)/obstack.h
 ecoff.o: ecoff.c ecoff.h
-ehopt.o: ehopt.c subsegs.h $(INCDIR)/obstack.h $(INCDIR)/elf/dwarf2.h
+ehopt.o: ehopt.c subsegs.h $(INCDIR)/obstack.h $(INCDIR)/elf/dwarf2.h \
+  struc-symbol.h
 expr.o: expr.c $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h
 flonum-copy.o: flonum-copy.c
 flonum-konst.o: flonum-konst.c
--- gas/ehopt.c.jj	2007-12-28 09:31:47.000000000 +0100
+++ gas/ehopt.c	2008-11-19 17:03:48.000000000 +0100
@@ -1,5 +1,6 @@
 /* ehopt.c--optimize gcc exception frame information.
-   Copyright 1998, 2000, 2001, 2003, 2005, 2007 Free Software Foundation, Inc.
+   Copyright 1998, 2000, 2001, 2003, 2005, 2007, 2008
+   Free Software Foundation, Inc.
    Written by Ian Lance Taylor <ian@cygnus.com>.
 
    This file is part of GAS, the GNU Assembler.
@@ -21,6 +22,7 @@
 
 #include "as.h"
 #include "subsegs.h"
+#include "struc-symbol.h"
 
 /* We include this ELF file, even though we may not be assembling for
    ELF, since the exception frame information is always in a format
@@ -398,13 +400,10 @@ check_eh_frame (expressionS *exp, unsign
 	     subtracted were in the same frag and the expression was
 	     reduced to a constant.  We can do the optimization entirely
 	     in this function.  */
-	  if (d->cie_info.code_alignment > 0
-	      && exp->X_add_number % d->cie_info.code_alignment == 0
-	      && exp->X_add_number / d->cie_info.code_alignment < 0x40)
+	  if (exp->X_add_number < 0x40)
 	    {
 	      d->loc4_frag->fr_literal[d->loc4_fix]
-		= DW_CFA_advance_loc
-		  | (exp->X_add_number / d->cie_info.code_alignment);
+		= DW_CFA_advance_loc | exp->X_add_number;
 	      /* No more bytes needed.  */
 	      return 1;
 	    }
@@ -419,23 +418,39 @@ check_eh_frame (expressionS *exp, unsign
 	      *pnbytes = 2;
 	    }
 	}
-      else if (exp->X_op == O_subtract)
+      else if (exp->X_op == O_subtract && d->cie_info.code_alignment == 1)
 	{
 	  /* This is a case we can optimize.  The expression was not
 	     reduced, so we can not finish the optimization until the end
 	     of the assembly.  We set up a variant frag which we handle
 	     later.  */
-	  int fr_subtype;
-
-	  if (d->cie_info.code_alignment > 0)
-	    fr_subtype = d->cie_info.code_alignment << 3;
-	  else
-	    fr_subtype = 0;
-
-	  frag_var (rs_cfa, 4, 0, fr_subtype, make_expr_symbol (exp),
+	  frag_var (rs_cfa, 4, 0, 1 << 3, make_expr_symbol (exp),
 		    d->loc4_fix, (char *) d->loc4_frag);
 	  return 1;
 	}
+      else if ((exp->X_op == O_divide
+		|| exp->X_op == O_right_shift)
+	       && d->cie_info.code_alignment > 1)
+	{
+	  if (exp->X_add_symbol->bsym
+	      && exp->X_op_symbol->bsym
+	      && exp->X_add_symbol->sy_value.X_op == O_subtract
+	      && exp->X_op_symbol->sy_value.X_op == O_constant
+	      && ((exp->X_op == O_divide
+		   ? exp->X_op_symbol->sy_value.X_add_number
+		   : (offsetT) 1 << exp->X_op_symbol->sy_value.X_add_number)
+		  == (offsetT) d->cie_info.code_alignment))
+	    {
+	      /* This is a case we can optimize as well.  The expression was
+		 not reduced, so we can not finish the optimization until the
+		 end of the assembly.  We set up a variant frag which we
+		 handle later.  */
+	      frag_var (rs_cfa, 4, 0, d->cie_info.code_alignment << 3,
+			make_expr_symbol (&exp->X_add_symbol->sy_value),
+			d->loc4_fix, (char *) d->loc4_frag);
+	      return 1;
+	    }
+	}
       break;
 
     case state_error:
@@ -459,7 +474,9 @@ eh_frame_estimate_size_before_relax (fra
 
   diff = resolve_symbol_value (frag->fr_symbol);
 
-  if (ca > 0 && diff % ca == 0 && diff / ca < 0x40)
+  assert (ca > 0);
+  diff /= ca;
+  if (diff < 0x40)
     ret = 0;
   else if (diff < 0x100)
     ret = 1;
@@ -496,21 +513,21 @@ eh_frame_convert_frag (fragS *frag)
 {
   offsetT diff;
   fragS *loc4_frag;
-  int loc4_fix;
+  int loc4_fix, ca;
 
   loc4_frag = (fragS *) frag->fr_opcode;
   loc4_fix = (int) frag->fr_offset;
 
   diff = resolve_symbol_value (frag->fr_symbol);
 
+  ca = frag->fr_subtype >> 3;
+  assert (ca > 0);
+  diff /= ca;
   switch (frag->fr_subtype & 7)
     {
     case 0:
-      {
-	int ca = frag->fr_subtype >> 3;
-	assert (ca > 0 && diff % ca == 0 && diff / ca < 0x40);
-	loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc | (diff / ca);
-      }
+      assert (diff < 0x40);
+      loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc | diff;
       break;
 
     case 1:
--- gas/dw2gencfi.c.jj	2008-11-19 15:50:40.000000000 +0100
+++ gas/dw2gencfi.c	2008-11-19 16:01:28.000000000 +0100
@@ -1,5 +1,5 @@
 /* dw2gencfi.c - Support for generating Dwarf2 CFI information.
-   Copyright 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+   Copyright 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
    Contributed by Michal Ludvig <mludvig@suse.cz>
 
    This file is part of GAS, the GNU Assembler.
@@ -972,20 +972,20 @@ output_cfi_insn (struct cfi_insn_data *i
 
 	    if (scaled <= 0x3F)
 	      out_one (DW_CFA_advance_loc + scaled);
-	    else if (delta <= 0xFF)
+	    else if (scaled <= 0xFF)
 	      {
 		out_one (DW_CFA_advance_loc1);
-		out_one (delta);
+		out_one (scaled);
 	      }
-	    else if (delta <= 0xFFFF)
+	    else if (scaled <= 0xFFFF)
 	      {
 		out_one (DW_CFA_advance_loc2);
-		out_two (delta);
+		out_two (scaled);
 	      }
 	    else
 	      {
 		out_one (DW_CFA_advance_loc4);
-		out_four (delta);
+		out_four (scaled);
 	      }
 	  }
 	else

	Jakub


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