This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc 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] Rework -fno-omit-frame-pointer support on i386


Commit 6b1df8b27f fixed the -OS build issue on i386 (BZ#20729) by
expliciting disabling frame pointer (-fomit-frame-pointer) on the
faulty objects.  Although it does fix the issue, it is a subpar
workaround that adds complexity in build process (a rule for each
object to add the required compiler option and pontentially more
rules for objects that call {INLINE,INTERNAL}_SYSCALL) and does not
allow the implementations to get all the possible debug/calltrack
information possible (used mainly in debuggers and performance
measurement tools).

This patch fixes it by adding an explicit configure check to see
if -fno-omit-frame-pointer is set and to act accordingly (set or
not OPTIMIZE_FOR_GCC_5).  The make rules is simplified and only
one is required: to add libc-do-syscall on loader due mmap
(which will be empty anyway for default build with
-fomit-frame-pointer).

Checked on i386-linux-gnu with GCC 6.2.1 with CFLAGS sets as
'-Os', '-O2 -fno-omit-frame-pointer', and '-O2 -fomit-frame-pointer'.
For '-Os' the testsuite issues described by BZ#19463 and BZ#15105
still applied.

It fixes BZ #21029, although it is marked as duplicated of #20729
(I reopened to track this cleanup).

	[BZ #21029]
	* config.h.in [NO_OMIT_FRAME_POINTER]: New define.
	* sysdeps/unix/sysv/linux/i386/Makefile
	[$(subdir) = elf] (sysdep-dl-routines): Add libc-do-syscall.
	(uses-6-syscall-arguments): Remove.
	[$(subdir) = misc] (CFLAGS-epoll_pwait.o): Likewise.
	[$(subdir) = misc] (CFLAGS-epoll_pwait.os): Likewise.
	[$(subdir) = misc] (CFLAGS-mmap.o): Likewise.
	[$(subdir) = misc] (CFLAGS-mmap.os): Likewise.
	[$(subdir) = misc] (CFLAGS-mmap64.o): Likewise.
	[$(subdir) = misc] (CFLAGS-mmap64.os): Likewise.
	[$(subdir) = misc] (CFLAGS-pselect.o): Likewise.
	[$(subdir) = misc] (cflags-pselect.o): Likewise.
	[$(subdir) = misc] (cflags-pselect.os): Likewise.
	[$(subdir) = misc] (cflags-rtld-mmap.os): Likewise.
	[$(subdir) = sysvipc] (cflags-semtimedop.o): Likewise.
	[$(subdir) = sysvipc] (cflags-semtimedop.os): Likewise.
	[$(subdir) = io] (CFLAGS-posix_fadvise64.o): Likewise.
	[$(subdir) = io] (CFLAGS-posix_fadvise64.os): Likewise.
	[$(subdir) = io] (CFLAGS-posix_fallocate.o): Likewise.
	[$(subdir) = io] (CFLAGS-posix_fallocate.os): Likewise.
	[$(subdir) = io] (CFLAGS-posix_fallocate64.o): Likewise.
	[$(subdir) = io] (CFLAGS-posix_fallocate64.os): Likewise.
	[$(subdir) = io] (CFLAGS-sync_file_range.o): Likewise.
	[$(subdir) = io] (CFLAGS-sync_file_range.os): Likewise.
	[$(subdir) = io] (CFLAGS-fallocate.o): Likewise.
	[$(subdir) = io] (CFLAGS-fallocate.os): Likewise.
	[$(subdir) = io] (CFLAGS-fallocate64.o): Likewise.
	[$(subdir) = io] (CFLAGS-fallocate64.os): Likewise.
	[$(subdir) = nptl] (CFLAGS-pthread_rwlock_timedrdlock.o):
	Likewise.
	[$(subdir) = nptl] (CFLAGS-pthread_rwlock_timedrdlock.os):
	Likewise.
	[$(subdir) = nptl] (CFLAGS-pthread_rwlock_timedrwlock.o):
	Likewise.
	[$(subdir) = nptl] (CFLAGS-pthread_rwlock_timedrwlock.os):
	Likewise.
	[$(subdir) = nptl] (CFLAGS-sem_wait.o): Likewise.
	[$(subdir) = nptl] (CFLAGS-sem_wait.os): Likewise.
	[$(subdir) = nptl] (CFLAGS-sem_timedwait.o): Likewise.
	[$(subdir) = nptl] (CFLAGS-sem_timedwait.os): Likewise.
	* sysdeps/unix/sysv/linux/i386/configure.ac: Add check for
	-fno-omit-frame-pointer usage.
	* sysdeps/unix/sysv/linux/i386/configure: Regenerate.
	* sysdeps/unix/sysv/linux/i386/sysdep.h (OPTIMIZE_FOR_GCC_5):
	Set iff NO_OMIT_FRAME_POINTER is not defined.
	(check_consistency): Likewise.
---
 ChangeLog                                 | 50 +++++++++++++++++++++++++++++++
 config.h.in                               |  3 ++
 sysdeps/unix/sysv/linux/i386/Makefile     | 39 +-----------------------
 sysdeps/unix/sysv/linux/i386/configure    | 31 +++++++++++++++++++
 sysdeps/unix/sysv/linux/i386/configure.ac | 19 ++++++++++++
 sysdeps/unix/sysv/linux/i386/sysdep.h     |  9 +++---
 6 files changed, 109 insertions(+), 42 deletions(-)

diff --git a/config.h.in b/config.h.in
index 7bfe923..50da4ba 100644
--- a/config.h.in
+++ b/config.h.in
@@ -259,4 +259,7 @@
 /* Build glibc with tunables support.  */
 #define HAVE_TUNABLES 0
 
+/* Define if compiler flags sets -fno-omit-frame-pointer.  */
+#undef NO_OMIT_FRAME_POINTER
+
 #endif
diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefile
index 9609752..6aac0df 100644
--- a/sysdeps/unix/sysv/linux/i386/Makefile
+++ b/sysdeps/unix/sysv/linux/i386/Makefile
@@ -1,47 +1,18 @@
 # The default ABI is 32.
 default-abi := 32
 
-# %ebp is used to pass the 6th argument to system calls, so these
-# system calls are incompatible with a frame pointer.
-uses-6-syscall-arguments = -fomit-frame-pointer
-
 ifeq ($(subdir),misc)
 sysdep_routines += ioperm iopl vm86
-CFLAGS-epoll_pwait.o += $(uses-6-syscall-arguments)
-CFLAGS-epoll_pwait.os += $(uses-6-syscall-arguments)
-CFLAGS-mmap.o += $(uses-6-syscall-arguments)
-CFLAGS-mmap.os += $(uses-6-syscall-arguments)
-CFLAGS-mmap64.o += $(uses-6-syscall-arguments)
-CFLAGS-mmap64.os += $(uses-6-syscall-arguments)
-CFLAGS-pselect.o += $(uses-6-syscall-arguments)
-CFLAGS-pselect.os += $(uses-6-syscall-arguments)
-CFLAGS-rtld-mmap.os += $(uses-6-syscall-arguments)
-endif
-
-ifeq ($(subdir),sysvipc)
-CFLAGS-semtimedop.o += $(uses-6-syscall-arguments)
-CFLAGS-semtimedop.os += $(uses-6-syscall-arguments)
 endif
 
 ifeq ($(subdir),elf)
+sysdep-dl-routines += libc-do-syscall
 sysdep-others += lddlibc4
 install-bin += lddlibc4
 endif
 
 ifeq ($(subdir),io)
 sysdep_routines += libc-do-syscall
-CFLAGS-posix_fadvise64.o += $(uses-6-syscall-arguments)
-CFLAGS-posix_fadvise64.os += $(uses-6-syscall-arguments)
-CFLAGS-posix_fallocate.o += $(uses-6-syscall-arguments)
-CFLAGS-posix_fallocate.os += $(uses-6-syscall-arguments)
-CFLAGS-posix_fallocate64.o += $(uses-6-syscall-arguments)
-CFLAGS-posix_fallocate64.os += $(uses-6-syscall-arguments)
-CFLAGS-sync_file_range.o += $(uses-6-syscall-arguments)
-CFLAGS-sync_file_range.os += $(uses-6-syscall-arguments)
-CFLAGS-fallocate.o += $(uses-6-syscall-arguments)
-CFLAGS-fallocate.os += $(uses-6-syscall-arguments)
-CFLAGS-fallocate64.o += $(uses-6-syscall-arguments)
-CFLAGS-fallocate64.os += $(uses-6-syscall-arguments)
 endif
 
 ifeq ($(subdir),nptl)
@@ -61,14 +32,6 @@ ifeq ($(subdir),nptl)
 # pull in __syscall_error routine
 libpthread-routines += sysdep
 libpthread-shared-only-routines += sysdep
-CFLAGS-pthread_rwlock_timedrdlock.o += $(uses-6-syscall-arguments)
-CFLAGS-pthread_rwlock_timedrdlock.os += $(uses-6-syscall-arguments)
-CFLAGS-pthread_rwlock_timedwrlock.o += $(uses-6-syscall-arguments)
-CFLAGS-pthread_rwlock_timedwrlock.os += $(uses-6-syscall-arguments)
-CFLAGS-sem_wait.o += $(uses-6-syscall-arguments)
-CFLAGS-sem_wait.os += $(uses-6-syscall-arguments)
-CFLAGS-sem_timedwait.o += $(uses-6-syscall-arguments)
-CFLAGS-sem_timedwait.os += $(uses-6-syscall-arguments)
 endif
 
 ifeq ($(subdir),rt)
diff --git a/sysdeps/unix/sysv/linux/i386/configure b/sysdeps/unix/sysv/linux/i386/configure
index eb72659..a1381e6 100644
--- a/sysdeps/unix/sysv/linux/i386/configure
+++ b/sysdeps/unix/sysv/linux/i386/configure
@@ -3,5 +3,36 @@
 
 arch_minimum_kernel=2.6.32
 
+# Check if CFLAGS sets -fno-omit-frame-pointer
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for if compiler flags sets -fno-omit-frame-pointer" >&5
+$as_echo_n "checking for if compiler flags sets -fno-omit-frame-pointer... " >&6; }
+if ${libc_cv_no_omit_frame_pointer+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat > conftest.c << EOF
+	       void foo (void) { }
+EOF
+	       libc_cv_no_omit_frame_pointer=no
+	       if { ac_try='${CC-cc} $CFLAGS -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 'push.*%ebp' conftest.s >/dev/null &&
+		    grep 'pop.*%ebp' conftest.s >/dev/null; then
+		   libc_cv_no_omit_frame_pointer=yes
+		 fi
+	       fi
+	       rm -f conftest.c conftest.s
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_no_omit_frame_pointer" >&5
+$as_echo "$libc_cv_no_omit_frame_pointer" >&6; }
+if test $libc_cv_no_omit_frame_pointer = yes; then
+  $as_echo "#define NO_OMIT_FRAME_POINTER 1" >>confdefs.h
+
+fi
+
 libc_cv_gcc_unwind_find_fde=yes
 ldd_rewrite_script=sysdeps/unix/sysv/linux/ldd-rewrite.sed
diff --git a/sysdeps/unix/sysv/linux/i386/configure.ac b/sysdeps/unix/sysv/linux/i386/configure.ac
index 1a11da6..06ccb7b 100644
--- a/sysdeps/unix/sysv/linux/i386/configure.ac
+++ b/sysdeps/unix/sysv/linux/i386/configure.ac
@@ -3,5 +3,24 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
 
 arch_minimum_kernel=2.6.32
 
+# Check if CFLAGS sets -fno-omit-frame-pointer
+AC_CACHE_CHECK(for if compiler flags sets -fno-omit-frame-pointer,
+	       libc_cv_no_omit_frame_pointer,
+	       [cat > conftest.c << EOF
+	       void foo (void) { }
+EOF
+	       libc_cv_no_omit_frame_pointer=no
+	       if AC_TRY_COMMAND(${CC-cc} $CFLAGS -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
+		 if grep 'push.*%ebp' conftest.s >/dev/null &&
+		    grep 'pop.*%ebp' conftest.s >/dev/null; then
+		   libc_cv_no_omit_frame_pointer=yes
+		 fi
+	       fi
+	       rm -f conftest.c conftest.s
+	       ])
+if test $libc_cv_no_omit_frame_pointer = yes; then
+  AC_DEFINE(NO_OMIT_FRAME_POINTER)
+fi
+
 libc_cv_gcc_unwind_find_fde=yes
 ldd_rewrite_script=sysdeps/unix/sysv/linux/ldd-rewrite.sed
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index baf4642..591aaf7 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -44,9 +44,9 @@
 /* Since GCC 5 and above can properly spill %ebx with PIC when needed,
    we can inline syscalls with 6 arguments if GCC 5 or above is used
    to compile glibc.  Disable GCC 5 optimization when compiling for
-   profiling since asm ("ebp") can't be used to put the 6th argument
-   in %ebp for syscall.  */
-#if __GNUC_PREREQ (5,0) && !defined PROF
+   profiling or when -fno-omit-frame-pointer is used since asm ("ebp")
+   can't be used to put the 6th argument in %ebp for syscall.  */
+#if __GNUC_PREREQ (5,0) && !defined PROF && !defined NO_OMIT_FRAME_POINTER
 # define OPTIMIZE_FOR_GCC_5
 #endif
 
@@ -611,7 +611,8 @@ struct libc_do_syscall_args
 #endif
 
 /* Consistency check for position-independent code.  */
-#if defined __PIC__ && !defined OPTIMIZE_FOR_GCC_5
+#if defined __PIC__ && !defined OPTIMIZE_FOR_GCC_5 \
+    && !defined NO_OMIT_FRAME_POINTER
 # define check_consistency()						      \
   ({ int __res;								      \
      __asm__ __volatile__						      \
-- 
2.7.4


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