diff mbox series

Fix debug for -mcall-ms2sysv-xlogues stubs fallout (PR target/83917)

Message ID 20180227082936.GB5867@tucnak
State New
Headers show
Series Fix debug for -mcall-ms2sysv-xlogues stubs fallout (PR target/83917) | expand

Commit Message

Jakub Jelinek Feb. 27, 2018, 8:29 a.m. UTC
On Mon, Feb 26, 2018 at 08:05:56PM -0600, Daniel Santos wrote:
> >>> --- libgcc/config/i386/cygwin.S.jj	2018-01-03 10:42:56.309763515 +0100
> >>> +++ libgcc/config/i386/cygwin.S	2018-02-22 15:30:34.597925496 +0100
> >>> @@ -23,31 +23,13 @@
> >>>   * <http://www.gnu.org/licenses/>.
> >>>   */
> >>>  
> >>> -#include "auto-host.h"
> >> The following include should be here.
> >>
> >> +#include "i386-asm.h"
> > I don't understand this.  i386-asm.h needs (both before my patch and after
> > it) both auto-host.h and auto-target.h, as it tests
> > HAVE_GAS_SECTIONS_DIRECTIVE (this one newly, comes from cygwin.S)
> 
> The problem is that HAVE_GAS_SECTIONS_DIRECTIVE gets defined (or not) in
> ../../gcc/auto-host.h, but you are testing it before including
> auto-host.h, either directly or via i386-asm.h.  So if i386-asm.h
> depends upon HAVE_GAS_SECTIONS_DIRECTIVE first being defined then it is
> a circular dependency.
> 
> In its current form, cygwin.S would never define USE_GAS_CFI_DIRECTIVES
> prior to including i386-asm.h and also never emit
>         .cfi_sections    .debug_frame
> and rather or not USE_GAS_CFI_DIRECTIVES ends up being defined to 1 or 0
> depends upon the test of __GCC_HAVE_DWARF2_CFI_ASM in i386-asm.h.

Ugh, you're right.  I was trying to preserve existing behavior for cygwin.S,
but failed to do so.  Unfortunately the patch which added this stuff from
Kai T. and Richard H. from 2010 is not in gcc-patches archives; in any case,
I think nothing seriously bad happens if with older gas versions which do
support .cfi_* directives but not .cfi_sections .debug_frame we emit the CFI
into .eh_frame section rather than .debug_frame.

So this patch simplifies it, with only one guard for the non-trivial
vs. trivial cfi_* definitions (based on whether GCC itself would use it)
and only guard the .cfi_sections directive on whether it is really
available.

The __GCC_HAVE_DWARF2_CFI_ASM definition actually sometimes depends on the
.cfi_sections presence too:
  /* If we can't get the assembler to emit only .debug_frame, and we don't need
     dwarf2 unwind info for exceptions, then emit .debug_frame by hand.  */
  if (!HAVE_GAS_CFI_SECTIONS_DIRECTIVE && !dwarf2out_do_eh_frame ())
    return false;
but doesn't actually guarantee it always, as when doing .eh_frame it will
not require .cfi_sections.

This spot brings in another, preexisting bug in cygwin.S though - 
the HAVE_GAS_CFI_SECTIONS_DIRECTIVE macro is always defined, to 0 or 1,
rather than sometimes #define and sometines #undef.

> Ultimately, the proper cleanup will be moving these tests out of
> {gcc,libgcc}/configure.ac and into .m4 files in the root config
> directory so that we don't uglify them with massive copy & pastes. 
> These tests are also fairly complex as there are a lot of dependencies. 
> m4 isn't my strong suite, but I can look at this after we're out of code
> freeze.

Not really sure about that, because we really want to do a different thing
in gcc/configure.ac (need to test the assembler directly, use
GCC_TARGET_TEMPLATE) while in libgcc it does usually something different.

The libgcc configure already has all the code for the .hidden directive,
as it uses it too, just it is only a pair of AC_SUBSTs rather than
AC_DEFINE_UNQUOTED.
The test for HAVE_GAS_CFI_SECTIONS_DIRECTIVE alternative can be compile
int foo (int, char *);
int bar (int x) { char *y = __builtin_alloca (x); return foo (x + 1, y) + 1; }
with -g -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-exceptions
and scan for .cfi_sections .debug_frame.

So here is a new (I've committed the previous patch since then), only lightly
tested (only on x86_64-linux and don't have too old binutils around), patch:

2018-02-27  Jakub Jelinek  <jakub@redhat.com>

	PR debug/83917
	* configure.ac (AS_HIDDEN_DIRECTIVE): AC_DEFINE_UNQUOTED this to
	$asm_hidden_op if visibility ("hidden") attribute works.
	(HAVE_AS_CFI_SECTIONS): New AC_DEFINE.
	* config/i386/i386-asm.h: Don't include auto-host.h.
	(PACKAGE_VERSION, PACKAGE_NAME, PACKAGE_STRING, PACKAGE_TARNAME,
	PACKAGE_URL): Don't undefine.
	(USE_GAS_CFI_DIRECTIVES): Don't use nor define this macro, instead
	guard cfi_startproc only on ifdef __GCC_HAVE_DWARF2_CFI_ASM.
	(FN_HIDDEN): Change guard from #ifdef HAVE_GAS_HIDDEN to
	#ifdef AS_HIDDEN_DIRECTIVE, use AS_HIDDEN_DIRECTIVE macro in the
	definition instead of hardcoded .hidden.
	* config/i386/cygwin.S: Include i386-asm.h first before .cfi_sections
	directive.  Use #ifdef HAVE_AS_CFI_SECTIONS rather than
	#ifdef HAVE_GAS_CFI_SECTIONS_DIRECTIVE to guard .cfi_sections.
	(USE_GAS_CFI_DIRECTIVES): Don't define.
	* configure: Regenerated.
	* config.in: Likewise.



	Jakub

Comments

Jakub Jelinek Feb. 28, 2018, 12:13 a.m. UTC | #1
On Tue, Feb 27, 2018 at 09:29:36AM +0100, Jakub Jelinek wrote:
> So here is a new (I've committed the previous patch since then), only lightly
> tested (only on x86_64-linux and don't have too old binutils around), patch:
> 
> 2018-02-27  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR debug/83917
> 	* configure.ac (AS_HIDDEN_DIRECTIVE): AC_DEFINE_UNQUOTED this to
> 	$asm_hidden_op if visibility ("hidden") attribute works.
> 	(HAVE_AS_CFI_SECTIONS): New AC_DEFINE.
> 	* config/i386/i386-asm.h: Don't include auto-host.h.
> 	(PACKAGE_VERSION, PACKAGE_NAME, PACKAGE_STRING, PACKAGE_TARNAME,
> 	PACKAGE_URL): Don't undefine.
> 	(USE_GAS_CFI_DIRECTIVES): Don't use nor define this macro, instead
> 	guard cfi_startproc only on ifdef __GCC_HAVE_DWARF2_CFI_ASM.
> 	(FN_HIDDEN): Change guard from #ifdef HAVE_GAS_HIDDEN to
> 	#ifdef AS_HIDDEN_DIRECTIVE, use AS_HIDDEN_DIRECTIVE macro in the
> 	definition instead of hardcoded .hidden.
> 	* config/i386/cygwin.S: Include i386-asm.h first before .cfi_sections
> 	directive.  Use #ifdef HAVE_AS_CFI_SECTIONS rather than
> 	#ifdef HAVE_GAS_CFI_SECTIONS_DIRECTIVE to guard .cfi_sections.
> 	(USE_GAS_CFI_DIRECTIVES): Don't define.
> 	* configure: Regenerated.
> 	* config.in: Likewise.

Now successfully bootstrapped/regtested on x86_64-linux and i686-linux.

	Jakub
Jeff Law Feb. 28, 2018, 6:09 a.m. UTC | #2
On 02/27/2018 01:29 AM, Jakub Jelinek wrote:
> On Mon, Feb 26, 2018 at 08:05:56PM -0600, Daniel Santos wrote:
>>>>> --- libgcc/config/i386/cygwin.S.jj	2018-01-03 10:42:56.309763515 +0100
>>>>> +++ libgcc/config/i386/cygwin.S	2018-02-22 15:30:34.597925496 +0100
>>>>> @@ -23,31 +23,13 @@
>>>>>   * <http://www.gnu.org/licenses/>.
>>>>>   */
>>>>>  
>>>>> -#include "auto-host.h"
>>>> The following include should be here.
>>>>
>>>> +#include "i386-asm.h"
>>> I don't understand this.  i386-asm.h needs (both before my patch and after
>>> it) both auto-host.h and auto-target.h, as it tests
>>> HAVE_GAS_SECTIONS_DIRECTIVE (this one newly, comes from cygwin.S)
>>
>> The problem is that HAVE_GAS_SECTIONS_DIRECTIVE gets defined (or not) in
>> ../../gcc/auto-host.h, but you are testing it before including
>> auto-host.h, either directly or via i386-asm.h.  So if i386-asm.h
>> depends upon HAVE_GAS_SECTIONS_DIRECTIVE first being defined then it is
>> a circular dependency.
>>
>> In its current form, cygwin.S would never define USE_GAS_CFI_DIRECTIVES
>> prior to including i386-asm.h and also never emit
>>         .cfi_sections    .debug_frame
>> and rather or not USE_GAS_CFI_DIRECTIVES ends up being defined to 1 or 0
>> depends upon the test of __GCC_HAVE_DWARF2_CFI_ASM in i386-asm.h.
> 
> Ugh, you're right.  I was trying to preserve existing behavior for cygwin.S,
> but failed to do so.  Unfortunately the patch which added this stuff from
> Kai T. and Richard H. from 2010 is not in gcc-patches archives; in any case,
> I think nothing seriously bad happens if with older gas versions which do
> support .cfi_* directives but not .cfi_sections .debug_frame we emit the CFI
> into .eh_frame section rather than .debug_frame.
> 
> So this patch simplifies it, with only one guard for the non-trivial
> vs. trivial cfi_* definitions (based on whether GCC itself would use it)
> and only guard the .cfi_sections directive on whether it is really
> available.
> 
> The __GCC_HAVE_DWARF2_CFI_ASM definition actually sometimes depends on the
> .cfi_sections presence too:
>   /* If we can't get the assembler to emit only .debug_frame, and we don't need
>      dwarf2 unwind info for exceptions, then emit .debug_frame by hand.  */
>   if (!HAVE_GAS_CFI_SECTIONS_DIRECTIVE && !dwarf2out_do_eh_frame ())
>     return false;
> but doesn't actually guarantee it always, as when doing .eh_frame it will
> not require .cfi_sections.
> 
> This spot brings in another, preexisting bug in cygwin.S though - 
> the HAVE_GAS_CFI_SECTIONS_DIRECTIVE macro is always defined, to 0 or 1,
> rather than sometimes #define and sometines #undef.
> 
>> Ultimately, the proper cleanup will be moving these tests out of
>> {gcc,libgcc}/configure.ac and into .m4 files in the root config
>> directory so that we don't uglify them with massive copy & pastes. 
>> These tests are also fairly complex as there are a lot of dependencies. 
>> m4 isn't my strong suite, but I can look at this after we're out of code
>> freeze.
> 
> Not really sure about that, because we really want to do a different thing
> in gcc/configure.ac (need to test the assembler directly, use
> GCC_TARGET_TEMPLATE) while in libgcc it does usually something different.
> 
> The libgcc configure already has all the code for the .hidden directive,
> as it uses it too, just it is only a pair of AC_SUBSTs rather than
> AC_DEFINE_UNQUOTED.
> The test for HAVE_GAS_CFI_SECTIONS_DIRECTIVE alternative can be compile
> int foo (int, char *);
> int bar (int x) { char *y = __builtin_alloca (x); return foo (x + 1, y) + 1; }
> with -g -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-exceptions
> and scan for .cfi_sections .debug_frame.
> 
> So here is a new (I've committed the previous patch since then), only lightly
> tested (only on x86_64-linux and don't have too old binutils around), patch:
> 
> 2018-02-27  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR debug/83917
> 	* configure.ac (AS_HIDDEN_DIRECTIVE): AC_DEFINE_UNQUOTED this to
> 	$asm_hidden_op if visibility ("hidden") attribute works.
> 	(HAVE_AS_CFI_SECTIONS): New AC_DEFINE.
> 	* config/i386/i386-asm.h: Don't include auto-host.h.
> 	(PACKAGE_VERSION, PACKAGE_NAME, PACKAGE_STRING, PACKAGE_TARNAME,
> 	PACKAGE_URL): Don't undefine.
> 	(USE_GAS_CFI_DIRECTIVES): Don't use nor define this macro, instead
> 	guard cfi_startproc only on ifdef __GCC_HAVE_DWARF2_CFI_ASM.
> 	(FN_HIDDEN): Change guard from #ifdef HAVE_GAS_HIDDEN to
> 	#ifdef AS_HIDDEN_DIRECTIVE, use AS_HIDDEN_DIRECTIVE macro in the
> 	definition instead of hardcoded .hidden.
> 	* config/i386/cygwin.S: Include i386-asm.h first before .cfi_sections
> 	directive.  Use #ifdef HAVE_AS_CFI_SECTIONS rather than
> 	#ifdef HAVE_GAS_CFI_SECTIONS_DIRECTIVE to guard .cfi_sections.
> 	(USE_GAS_CFI_DIRECTIVES): Don't define.
> 	* configure: Regenerated.
> 	* config.in: Likewise.
OK.
jeff
diff mbox series

Patch

--- libgcc/configure.ac.jj	2017-11-20 11:02:56.877786488 +0100
+++ libgcc/configure.ac	2018-02-27 09:20:45.939385138 +0100
@@ -486,11 +486,29 @@  AC_CACHE_CHECK([for __attribute__((visib
 
 if test $libgcc_cv_hidden_visibility_attribute = yes; then
     vis_hide='-fvisibility=hidden -DHIDE_EXPORTS'
+    AC_DEFINE_UNQUOTED(AS_HIDDEN_DIRECTIVE, $asm_hidden_op, [Define to the .hidden-like directive if it exists.])
 else
     vis_hide=
 fi
 AC_SUBST(vis_hide)
 
+# Check for .cfi_sections .debug_frame support.
+AC_CACHE_CHECK([for .cfi_sections .debug_frame],
+    libgcc_cv_cfi_sections_directive, [
+	echo 'int foo (int, char *);' > conftest.c
+	echo 'int bar (int x) { char *y = __builtin_alloca (x); return foo (x + 1, y) + 1; }' >> conftest.c
+	libgcc_cv_cfi_sections_directive=no
+	if AC_TRY_COMMAND(${CC-cc} -Werror -g -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-exceptions -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
+	    if grep "\\.cfi_sections.*\\.debug_frame" conftest.s >/dev/null; then
+		libgcc_cv_cfi_sections_directive=yes
+	    fi
+	fi
+	rm -f conftest.*
+    ])
+if test $libgcc_cv_cfi_sections_directive = yes; then
+    AC_DEFINE(HAVE_AS_CFI_SECTIONS, 1, [Define to 1 if the assembler supports .cfi_sections .debug_frame directive.])
+fi
+
 # See if we have thread-local storage.  We can only test assembler
 # since link-time and run-time tests require the newly built
 # gcc, which can't be used to build executable due to that libgcc
--- libgcc/config/i386/i386-asm.h.jj	2018-02-26 20:46:08.493354695 +0100
+++ libgcc/config/i386/i386-asm.h	2018-02-27 09:15:23.533496520 +0100
@@ -27,21 +27,8 @@  see the files COPYING3 and COPYING.RUNTI
 #define I386_ASM_H
 
 #include "auto-target.h"
-#undef PACKAGE_VERSION
-#undef PACKAGE_NAME
-#undef PACKAGE_STRING
-#undef PACKAGE_TARNAME
-#undef PACKAGE_URL
-#include "auto-host.h"
 
-#ifndef USE_GAS_CFI_DIRECTIVES
-# ifdef __GCC_HAVE_DWARF2_CFI_ASM
-#  define USE_GAS_CFI_DIRECTIVES 1
-# else
-#  define USE_GAS_CFI_DIRECTIVES 0
-# endif
-#endif
-#if USE_GAS_CFI_DIRECTIVES
+#ifdef __GCC_HAVE_DWARF2_CFI_ASM
 # define cfi_startproc()		.cfi_startproc
 # define cfi_endproc()			.cfi_endproc
 # define cfi_adjust_cfa_offset(X) 	.cfi_adjust_cfa_offset X
@@ -76,8 +63,8 @@  see the files COPYING3 and COPYING.RUNTI
 #ifdef __ELF__
 # define FN_TYPE(fn) .type fn,@function
 # define FN_SIZE(fn) .size fn,.-fn
-# ifdef HAVE_GAS_HIDDEN
-#  define FN_HIDDEN(fn) .hidden fn
+# ifdef AS_HIDDEN_DIRECTIVE
+#  define FN_HIDDEN(fn) AS_HIDDEN_DIRECTIVE fn
 # endif
 #else
 # define FN_TYPE(fn)
--- libgcc/config/i386/cygwin.S.jj	2018-02-26 20:46:08.494354695 +0100
+++ libgcc/config/i386/cygwin.S	2018-02-27 09:16:32.077472841 +0100
@@ -23,13 +23,11 @@ 
  * <http://www.gnu.org/licenses/>.
  */
 
-#ifdef HAVE_GAS_CFI_SECTIONS_DIRECTIVE
-# define USE_GAS_CFI_DIRECTIVES 1
+#include "i386-asm.h"
+
+#ifdef HAVE_AS_CFI_SECTIONS
 	.cfi_sections	.debug_frame
-#else
-# define USE_GAS_CFI_DIRECTIVES 0
 #endif
-#include "i386-asm.h"
 
 #ifdef L_chkstk
 /* Function prologue calls __chkstk to probe the stack when allocating more
--- libgcc/configure.jj	2018-02-19 19:57:05.758280231 +0100
+++ libgcc/configure	2018-02-27 09:20:57.346381203 +0100
@@ -5214,11 +5214,47 @@  $as_echo "$libgcc_cv_hidden_visibility_a
 
 if test $libgcc_cv_hidden_visibility_attribute = yes; then
     vis_hide='-fvisibility=hidden -DHIDE_EXPORTS'
+
+cat >>confdefs.h <<_ACEOF
+#define AS_HIDDEN_DIRECTIVE $asm_hidden_op
+_ACEOF
+
 else
     vis_hide=
 fi
 
 
+# Check for .cfi_sections .debug_frame support.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for .cfi_sections .debug_frame" >&5
+$as_echo_n "checking for .cfi_sections .debug_frame... " >&6; }
+if test "${libgcc_cv_cfi_sections_directive+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+	echo 'int foo (int, char *);' > conftest.c
+	echo 'int bar (int x) { char *y = __builtin_alloca (x); return foo (x + 1, y) + 1; }' >> conftest.c
+	libgcc_cv_cfi_sections_directive=no
+	if { ac_try='${CC-cc} -Werror -g -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-exceptions -S conftest.c -o conftest.s 1>&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+	    if grep "\\.cfi_sections.*\\.debug_frame" conftest.s >/dev/null; then
+		libgcc_cv_cfi_sections_directive=yes
+	    fi
+	fi
+	rm -f conftest.*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcc_cv_cfi_sections_directive" >&5
+$as_echo "$libgcc_cv_cfi_sections_directive" >&6; }
+if test $libgcc_cv_cfi_sections_directive = yes; then
+
+$as_echo "#define HAVE_AS_CFI_SECTIONS 1" >>confdefs.h
+
+fi
+
 # See if we have thread-local storage.  We can only test assembler
 # since link-time and run-time tests require the newly built
 # gcc, which can't be used to build executable due to that libgcc
--- libgcc/config.in.jj	2017-09-25 10:38:45.182468927 +0200
+++ libgcc/config.in	2018-02-27 09:12:08.000000000 +0100
@@ -1,8 +1,15 @@ 
 /* config.in.  Generated from configure.ac by autoheader.  */
 
+/* Define to the .hidden-like directive if it exists. */
+#undef AS_HIDDEN_DIRECTIVE
+
 /* Define to 1 if the assembler supports AVX. */
 #undef HAVE_AS_AVX
 
+/* Define to 1 if the assembler supports .cfi_sections .debug_frame directive.
+   */
+#undef HAVE_AS_CFI_SECTIONS
+
 /* Define to 1 if the target assembler supports thread-local storage. */
 #undef HAVE_CC_TLS