This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


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

gas misoptimizes gcc3 .eh_frame


I've just committed a binutils patch that I believe fixes it.  However,
what remains is the problem of what to do for still broken assemblers.

The following doesn't exactly test what's broken with the old assembler.
The breakage was of a curious form that would give nonsensical error
messages on e.g. x86, while producing incorrect data on e.g. alpha.
Instead it tests something that should work with the fixed assembler,
and will definitely not work with a broken assembler.

Applied to branch and mainline.


r~


PS: At some point it'd be nice to say, "dammit, upgrade" instead
of working around the problem.  Perhaps gcc 3.1 configure should
hard error on all binutils bugs worked around for gcc 3.0.


        * configure.in (gcc_cv_as_eh_frame): New test.
        * config.in, configure: Rebuild.
        * gcc.c (init_spec): Honor USE_AS_TRADITIONAL_FORMAT.

Index: configure.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/configure.in,v
retrieving revision 1.522
diff -c -p -d -r1.522 configure.in
*** configure.in	2001/05/13 11:25:55	1.522
--- configure.in	2001/05/15 01:39:17
*************** if test x"$gcc_cv_as_leb128" = xyes; the
*** 1410,1415 ****
--- 1410,1486 ----
  fi
  AC_MSG_RESULT($gcc_cv_as_leb128)
  
+ AC_MSG_CHECKING(assembler eh_frame optimization)
+ gcc_cv_as_eh_frame=no
+ if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
+   if test "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 12 -o "$gcc_cv_gas_major_version" -gt 2 && grep 'obj_format = elf' ../gas/Makefile > /dev/null; then
+     gcc_cv_as_eh_frame="yes"
+   fi
+ elif test x$gcc_cv_as != x; then
+ 	# Check if this is GAS.
+ 	as_ver=`$gcc_cv_as --version 2>/dev/null | head -1`
+ 	if echo "$as_ver" | grep GNU > /dev/null; then
+ 		# Versions up to and including 2.11.0 may mis-optimize
+ 		# .eh_frame data.  Try something.
+ 		cat > conftest.s <<EOF
+ 	.text
+ .LFB1:
+ 	.4byte	0
+ .L1:
+ 	.4byte	0
+ .LFE1:
+ 	.section	.eh_frame,"aw",@progbits
+ __FRAME_BEGIN__:
+ 	.4byte	.LECIE1-.LSCIE1
+ .LSCIE1:
+ 	.4byte	0x0
+ 	.byte	0x1
+ 	.ascii "z\0"
+ 	.byte	0x1
+ 	.byte	0x78
+ 	.byte	0x1a
+ 	.byte	0x0
+ 	.byte	0x4
+ 	.4byte	1
+ 	.p2align 1
+ .LECIE1:
+ .LSFDE1:
+ 	.4byte	.LEFDE1-.LASFDE1
+ .LASFDE1:
+ 	.4byte	.LASFDE1-__FRAME_BEGIN__
+ 	.4byte	.LFB1
+ 	.4byte	.LFE1-.LFB1
+ 	.byte	0x4
+ 	.4byte	.LFE1-.LFB1
+ 	.byte	0x4
+ 	.4byte	.L1-.LFB1
+ .LEFDE1:
+ EOF
+ 		cat > conftest.exp <<EOF
+  0000 10000000 00000000 017a0001 781a0004  .........z..x...
+  0010 01000000 12000000 18000000 00000000  ................
+  0020 08000000 04080000 0044               .........D      
+ EOF
+ 		# If the assembler didn't choke, and we can objdump,
+ 		# and we got the correct data, then succeed.
+ 		if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1 \
+ 		   && objdump -s -j .eh_frame conftest.o 2>/dev/null \
+ 		      | tail -3 > conftest.got \
+ 		   && cmp conftest.exp conftest.got > /dev/null 2>&1
+ 		then
+ 			gcc_cv_as_eh_frame="yes"
+ 		else
+ 			gcc_cv_as_eh_frame="bad"
+ 			if $gcc_cv_as -o conftest.o --traditional-format /dev/null; then
+ 				AC_DEFINE(USE_AS_TRADITIONAL_FORMAT, 1,
+ 	[Define if your assembler mis-optimizes .eh_frame data.])
+ 			fi
+ 		fi
+ 	fi
+ 	rm -f conftest.*
+ fi
+ AC_MSG_RESULT($gcc_cv_as_eh_frame)
+ 
  case "$target" in 
    sparc*-*-*)
      AC_CACHE_CHECK([assembler .register pseudo-op support],
Index: gcc.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/gcc.c,v
retrieving revision 1.226
diff -c -p -d -r1.226 gcc.c
*** gcc.c	2001/05/13 22:17:02	1.226
--- gcc.c	2001/05/15 01:39:17
*************** init_spec ()
*** 1454,1459 ****
--- 1454,1468 ----
      libgcc_spec = obstack_finish (&obstack);
    }
  #endif
+ #ifdef USE_AS_TRADITIONAL_FORMAT
+   /* Prepend "--traditional-format" to whatever asm_spec we had before.  */
+   {
+     static char tf[] = "--traditional-format ";
+     obstack_grow (&obstack, tf, sizeof(tf) - 1);
+     obstack_grow0 (&obstack, asm_spec, strlen (asm_spec));
+     asm_spec = obstack_finish (&obstack);
+   }
+ #endif
  
    specs = sl;
  }


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