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]
Other format: [Raw text]

[RFC, PATCH] Automatic architecture selection for bi-arch hosts


Hello,

bi-arch 64-bit Linux systems support a 32-bit 'personality' that
causes 'uname' to return the 32-bit machine architecture variant
instead of the 64-bit one.  This allows building 32-bit packages
on the 64-bit system by having configure scripts detecting the
system as a 32-bit one.

However, invoking GCC as part of such a build process will still
generate binaries of the wrong architecture, even if the installed
compiler is bi-arch capable, unless care is taken to always pass
the correct flags.

The following patch intends to simplify this by allowing a bi-arch
compiler to default to the architecture mode implied by the current
personality setting.

Technically, the selection works by way of a new spec function,
"if-machine".  This function has two arguments; it compares the
first against the current host machine architecture name (as
provided by uname), and if they match, returns the second argument.

A back end can use this spec function in its DRIVER_SELF_SPECS
to add the appropriate architecture mode selection flags
depending on the current machine name.  I've implemented this
below for s390.

Bootstrapped/regtested on s390-ibm-linux and s390x-ibm-linux.

OK for mainline?

Bye,
Ulrich



ChangeLog:

	* configure.ac: Add sys/utsname.h to AC_CHECK_HEADERS.
	Add uname to AC_CHECK_FUNCS.
	* configure: Regenerate.
	* config.in: Likewise.
	* gcc.c: Include <sys/utsname.h> if present.
	(if_machine_spec_function): New spec function.
	(static_spec_functions): Add it.

	* config/s390/s390.h (DEFAULT_S390_ABI): Define.
	(DRIVER_SELF_SPECS): Use it.


Index: gcc/configure
===================================================================
*** gcc/configure	(revision 108545)
--- gcc/configure	(working copy)
*************** fi
*** 8152,8161 ****
  
  
  
  for ac_header in limits.h stddef.h string.h strings.h stdlib.h time.h iconv.h \
  		 fcntl.h unistd.h sys/file.h sys/time.h sys/mman.h \
  		 sys/resource.h sys/param.h sys/times.h sys/stat.h \
! 		 direct.h malloc.h langinfo.h ldfcn.h locale.h wchar.h
  do
  as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
  echo "$as_me:$LINENO: checking for $ac_header" >&5
--- 8152,8163 ----
  
  
  
+ 
  for ac_header in limits.h stddef.h string.h strings.h stdlib.h time.h iconv.h \
  		 fcntl.h unistd.h sys/file.h sys/time.h sys/mman.h \
  		 sys/resource.h sys/param.h sys/times.h sys/stat.h \
! 		 direct.h malloc.h langinfo.h ldfcn.h locale.h wchar.h \
! 		 sys/utsname.h
  do
  as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
  echo "$as_me:$LINENO: checking for $ac_header" >&5
*************** fi
*** 9116,9124 ****
  
  
  
  for ac_func in times clock kill getrlimit setrlimit atoll atoq \
  	sysconf strsignal getrusage nl_langinfo scandir alphasort \
! 	gettimeofday mbstowcs wcswidth mmap mincore setlocale \
  	clearerr_unlocked feof_unlocked   ferror_unlocked fflush_unlocked fgetc_unlocked fgets_unlocked   fileno_unlocked fprintf_unlocked fputc_unlocked fputs_unlocked   fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked   putchar_unlocked putc_unlocked
  do
  as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
--- 9118,9127 ----
  
  
  
+ 
  for ac_func in times clock kill getrlimit setrlimit atoll atoq \
  	sysconf strsignal getrusage nl_langinfo scandir alphasort \
! 	gettimeofday mbstowcs wcswidth mmap mincore setlocale uname \
  	clearerr_unlocked feof_unlocked   ferror_unlocked fflush_unlocked fgetc_unlocked fgets_unlocked   fileno_unlocked fprintf_unlocked fputc_unlocked fputs_unlocked   fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked   putchar_unlocked putc_unlocked
  do
  as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
Index: gcc/gcc.c
===================================================================
*** gcc/gcc.c	(revision 108545)
--- gcc/gcc.c	(working copy)
*************** compilation is specified by a string cal
*** 87,92 ****
--- 87,96 ----
  #include "gcc.h"
  #include "flags.h"
  
+ #ifdef HAVE_SYS_UTSNAME_H
+ #include <sys/utsname.h>
+ #endif
+ 
  /* By default there is no special suffix for target executables.  */
  /* FIXME: when autoconf is fixed, remove the host check - dj */
  #if defined(TARGET_EXECUTABLE_SUFFIX) && defined(HOST_EXECUTABLE_SUFFIX)
*************** static const char *convert_filename (con
*** 349,354 ****
--- 353,359 ----
  
  static const char *if_exists_spec_function (int, const char **);
  static const char *if_exists_else_spec_function (int, const char **);
+ static const char *if_machine_spec_function (int, const char **);
  static const char *replace_outfile_spec_function (int, const char **);
  static const char *version_compare_spec_function (int, const char **);
  
*************** static const struct spec_function static
*** 1578,1583 ****
--- 1583,1589 ----
  {
    { "if-exists",		if_exists_spec_function },
    { "if-exists-else",		if_exists_else_spec_function },
+   { "if-machine",		if_machine_spec_function },
    { "replace-outfile",		replace_outfile_spec_function },
    { "version-compare",		version_compare_spec_function },
    { 0, 0 }
*************** if_exists_else_spec_function (int argc, 
*** 7622,7627 ****
--- 7628,7661 ----
    return argv[1];
  }
  
+ /* if-machine built-in spec function.
+ 
+    Checks to see if the first argument matches the current machine
+    architecture name.  Returns the second argument if so.  */
+ 
+ static const char *
+ if_machine_spec_function (int argc, const char **argv)
+ {
+ #ifdef HAVE_UNAME
+   struct utsname uts;
+ 
+   /* Must have exactly two arguments.  */
+   if (argc != 2)
+     return NULL;
+ 
+   if (uname (&uts))
+     return NULL;
+   if (strcmp (uts.machine, argv[0]) != 0)
+     return NULL;
+ 
+   return argv[1];
+ 
+ #else
+   /* This function is currently only usable on hosts that have uname.  */
+   return NULL;
+ #endif
+ }
+ 
  /* replace-outfile built-in spec function.
  
     This looks for the first argument in the outfiles array's name and
Index: gcc/config.in
===================================================================
*** gcc/config.in	(revision 108545)
--- gcc/config.in	(working copy)
***************
*** 1090,1095 ****
--- 1090,1101 ----
  #endif
  
  
+ /* Define to 1 if you have the <sys/utsname.h> header file. */
+ #ifndef USED_FOR_TARGET
+ #undef HAVE_SYS_UTSNAME_H
+ #endif
+ 
+ 
  /* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
  #ifndef USED_FOR_TARGET
  #undef HAVE_SYS_WAIT_H
***************
*** 1108,1113 ****
--- 1114,1125 ----
  #endif
  
  
+ /* Define to 1 if you have the `uname' function. */
+ #ifndef USED_FOR_TARGET
+ #undef HAVE_UNAME
+ #endif
+ 
+ 
  /* Define to 1 if you have the <unistd.h> header file. */
  #ifndef USED_FOR_TARGET
  #undef HAVE_UNISTD_H
Index: gcc/configure.ac
===================================================================
*** gcc/configure.ac	(revision 108545)
--- gcc/configure.ac	(working copy)
*************** AC_HEADER_SYS_WAIT
*** 902,908 ****
  AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h time.h iconv.h \
  		 fcntl.h unistd.h sys/file.h sys/time.h sys/mman.h \
  		 sys/resource.h sys/param.h sys/times.h sys/stat.h \
! 		 direct.h malloc.h langinfo.h ldfcn.h locale.h wchar.h)
  
  # Check for thread headers.
  AC_CHECK_HEADER(thread.h, [have_thread_h=yes], [have_thread_h=])
--- 902,909 ----
  AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h time.h iconv.h \
  		 fcntl.h unistd.h sys/file.h sys/time.h sys/mman.h \
  		 sys/resource.h sys/param.h sys/times.h sys/stat.h \
! 		 direct.h malloc.h langinfo.h ldfcn.h locale.h wchar.h \
! 		 sys/utsname.h)
  
  # Check for thread headers.
  AC_CHECK_HEADER(thread.h, [have_thread_h=yes], [have_thread_h=])
*************** define(gcc_UNLOCKED_FUNCS, clearerr_unlo
*** 1001,1007 ****
    putchar_unlocked putc_unlocked)
  AC_CHECK_FUNCS(times clock kill getrlimit setrlimit atoll atoq \
  	sysconf strsignal getrusage nl_langinfo scandir alphasort \
! 	gettimeofday mbstowcs wcswidth mmap mincore setlocale \
  	gcc_UNLOCKED_FUNCS)
  
  if test x$ac_cv_func_mbstowcs = xyes; then
--- 1002,1008 ----
    putchar_unlocked putc_unlocked)
  AC_CHECK_FUNCS(times clock kill getrlimit setrlimit atoll atoq \
  	sysconf strsignal getrusage nl_langinfo scandir alphasort \
! 	gettimeofday mbstowcs wcswidth mmap mincore setlocale uname \
  	gcc_UNLOCKED_FUNCS)
  
  if test x$ac_cv_func_mbstowcs = xyes; then
Index: gcc/config/s390/s390.h
===================================================================
*** gcc/config/s390/s390.h	(revision 108545)
--- gcc/config/s390/s390.h	(working copy)
*************** extern enum processor_flags s390_arch_fl
*** 106,111 ****
--- 106,121 ----
  #define TARGET_DEFAULT             MASK_HARD_FLOAT
  #endif
  
+ /* Default architecture mode selection.   We want to support automatic
+    31-bit vs. 64-bit ABI selection on native bi-arch hosts.  */
+ #if !defined(CROSS_COMPILE)
+ #define DEFAULT_S390_ABI "%:if-machine(s390 -m31)%:if-machine(s390x -m64)"
+ #elif defined(DEFAULT_TARGET_64BIT)
+ #define DEFAULT_S390_ABI "-m64"
+ #else
+ #define DEFAULT_S390_ABI "-m31"
+ #endif
+ 
  /* Support for configure-time defaults.  */
  #define OPTION_DEFAULT_SPECS 					\
    { "mode", "%{!mesa:%{!mzarch:-m%(VALUE)}}" },			\
*************** extern enum processor_flags s390_arch_fl
*** 113,129 ****
    { "tune", "%{!mtune=*:-mtune=%(VALUE)}" }
  
  /* Defaulting rules.  */
- #ifdef DEFAULT_TARGET_64BIT
  #define DRIVER_SELF_SPECS					\
!   "%{!m31:%{!m64:-m64}}",					\
    "%{!mesa:%{!mzarch:%{m31:-mesa}%{m64:-mzarch}}}",		\
    "%{!march=*:%{mesa:-march=g5}%{mzarch:-march=z900}}"
- #else
- #define DRIVER_SELF_SPECS					\
-   "%{!m31:%{!m64:-m31}}",					\
-   "%{!mesa:%{!mzarch:%{m31:-mesa}%{m64:-mzarch}}}",		\
-   "%{!march=*:%{mesa:-march=g5}%{mzarch:-march=z900}}"
- #endif
  
  /* Target version string.  Overridden by the OS header.  */
  #ifdef DEFAULT_TARGET_64BIT
--- 123,132 ----
    { "tune", "%{!mtune=*:-mtune=%(VALUE)}" }
  
  /* Defaulting rules.  */
  #define DRIVER_SELF_SPECS					\
!   "%{!m31:%{!m64:" DEFAULT_S390_ABI "}}",			\
    "%{!mesa:%{!mzarch:%{m31:-mesa}%{m64:-mzarch}}}",		\
    "%{!march=*:%{mesa:-march=g5}%{mzarch:-march=z900}}"
  
  /* Target version string.  Overridden by the OS header.  */
  #ifdef DEFAULT_TARGET_64BIT
-- 
  Dr. Ulrich Weigand
  Linux on zSeries Development
  Ulrich.Weigand@de.ibm.com


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