]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
* Makefile.am (ehopt.o): Add struc-symbol.h.
authorJakub Jelinek <jakub@redhat.com>
Fri, 28 Nov 2008 21:28:28 +0000 (21:28 +0000)
committerJakub Jelinek <jakub@redhat.com>
Fri, 28 Nov 2008 21:28:28 +0000 (21:28 +0000)
* 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.

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

gas/ChangeLog
gas/Makefile.am
gas/Makefile.in
gas/dw2gencfi.c
gas/ehopt.c

index a3b9384470720dfbdce7a2c98da1d58511189b7e..8874fe681c1e7e0922d0ca48e00d7539df32180e 100644 (file)
@@ -1,3 +1,20 @@
+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.
+
 2008-11-28  Joshua Kinard  <kumba@gentoo.org>
 
        * config/tc-mips.c (hilo_interlocks): Handle CPU_R14000, CPU_R16000.
index 38fe2557688c5c687030b32890d959dc4e4ad510..260c2110812cfbdb9649db7d4b4b023f58dae44b 100644 (file)
@@ -2159,7 +2159,8 @@ dwarf2dbg.o: dwarf2dbg.c $(INCDIR)/safe-ctype.h dwarf2dbg.h \
 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
index 5735a0a0a5ee9c67ca1abefa840af61498c2c9df..c0f932a1ae35b5c8fd85c122ef24064eec248fea 100644 (file)
@@ -3015,7 +3015,8 @@ dwarf2dbg.o: dwarf2dbg.c $(INCDIR)/safe-ctype.h dwarf2dbg.h \
 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
index 4adfeab97500fa3fc38b9d6a73bdaba50223b8e5..a9b58d4fbba0db37f8ab2216ab0ba466322f25a7 100644 (file)
@@ -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 *insn)
 
            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
index 048bc57b5a09f5fbcee50e93ab90e086a9571993..323e27e861a090045d353c730f86002cf3fce205 100644 (file)
@@ -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, unsigned int *pnbytes)
             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, unsigned int *pnbytes)
              *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 (fragS *frag)
 
   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: