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 [1/n]: Initial x32 support


Hi,

This patch add the initial x32 support.  It does a few things:

1. Introduce data-machine to override "$(config-machine) $(base-machine)"
when checking for C++ type data.  config-machine and base-machine for x32
are x86_64.  But its C++ type data is different from x86_64.
2. Add support for sysdeps/$base_machine/preconfigure:
   a. Select x32 or x86_64 target by checking if __LP64__ is defined 
   b. Set data-machine to x32 for x32.
   c. Set machine to x86_64/x32 for x32 and to x86_64/64 for x86_64.
   d. Use libx32 as libdir for x32.
   e. Enable sysdeps/x86_64/lib-names.awk and sysdeps/x86_64/stubs-biarch.h
      so that we can properly generate <gnu/lib-names.h> and <gnu/stubs.h>
3. Update syscall-list-32bit-condition and syscall-list-64bit-condition
to check __x86_64__ instead of __WORDSIZE as well as add -D__LP64__ to
syscall-list-64bit-options.  We can't check __WORDSIZE since it is 32
for x32.  Since x32 implements the same set of system calls as x86_64,
we build x32 system call list like x86_64 by checking __x86_64__ instead
of __WORDSIZE.
4. Update sysdeps/unix/sysv/linux/configure.in to check if $machine is
x86_64/64 instead of x86_64 when setting lib64 as libdir.  It sets
x32 minimum kernel to 2.6.35 although kernel 3.4 is the first upsteam
kernel with x32 support. I backported x32 support to kernel 3.0, 3.1 and
3.2 as well as 2.6.4x kernels on Fedora 15.  I can change it to 3.4.0
if needed.

Thanks.


H.J.
---
2012-03-15  H.J. Lu  <hongjiu.lu@intel.com>

	* Makeconfig ($(common-objpfx)gnu/lib-names.stmp): Depend on
	$(lib-names_awk) instead of scripts/lib-names.awk.

	* Makefile ($(inst_includedir)/gnu/stubs.h): Depend on
	$(stubs-biarch_h) instead of include/stubs-biarch.h.
	(data-machine): New.
	(check-data): Use it.

	* config.make.in (data-machine): New.
	(stubs-biarch_h): Likewise.
	(lib-names_awk): Likewise.

	* configure.in: Add sysdeps preconfigure fragment support.
	(data_machine): Substitute.
	(stubs_biarch_h): Set to include/stubs-biarch.h if not set.
	Substitute.
	(lib_names_awk): Set to scripts/lib-names.awk if not set.
	Substitute.
	* configure: Regenerated.

	* scripts/data/c++-types-x32-linux-gnu.data: New.
	* sysdeps/unix/sysv/linux/x86_64/stubs-triarch.h: Likewise.
	* sysdeps/x86_64/lib-names.awk: Likewise.
	* sysdeps/x86_64/preconfigure: Likewise.
	* sysdeps/x86_64/stubs-biarch.h: Likewise.

	* sysdeps/unix/sysv/linux/configure.in: Require kernel 2.6.35
	or above for x32.  Check x86_64/x64 instead of x86_64.
	* sysdeps/unix/sysv/linux/configure: Regenerated.

	* sysdeps/unix/sysv/linux/x86_64/Makefile
	(syscall-list-32bit-condition): Changed to !defined __x86_64__
	(syscall-list-64bit-options): Add __LP64__.
	(syscall-list-64bit-condition): Changed to defined __x86_64__.

diff --git a/Makeconfig b/Makeconfig
index 4fc1141..4e27c52 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -854,7 +854,7 @@ postclean-generated += soversions.mk soversions.i \
 before-compile += $(common-objpfx)gnu/lib-names.h
 ifeq ($(soversions.mk-done),t)
 $(common-objpfx)gnu/lib-names.h: $(common-objpfx)gnu/lib-names.stmp; @:
-$(common-objpfx)gnu/lib-names.stmp: $(..)scripts/lib-names.awk \
+$(common-objpfx)gnu/lib-names.stmp: $(..)$(lib-names_awk) \
 				    $(common-objpfx)soversions.i
 	$(make-target-directory)
 	@rm -f ${@:stmp=T} $@
diff --git a/Makefile b/Makefile
index 5a31adb..1db1f93 100644
--- a/Makefile
+++ b/Makefile
@@ -176,7 +176,7 @@ installed-stubs = $(inst_includedir)/gnu/stubs.h
 else
 installed-stubs = $(inst_includedir)/gnu/stubs-$(biarch).h
 
-$(inst_includedir)/gnu/stubs.h: include/stubs-biarch.h $(+force)
+$(inst_includedir)/gnu/stubs.h: $(stubs-biarch_h) $(+force)
 	$(make-target-directory)
 	$(INSTALL_DATA) $< $@
 
@@ -258,13 +258,15 @@ tests-clean:
 
 tests: $(objpfx)c++-types-check.out $(objpfx)check-local-headers.out
 ifneq ($(CXX),no)
+ifeq ($(data-machine),)
+data-machine = $(config-machine) $(base-machine)
+endif
 check-data := $(firstword $(wildcard \
 		$(foreach D,$(add-ons) scripts,\
 			  $(patsubst %,$D/data/c++-types-%.data,\
 				     $(abi-name) \
 				     $(addsuffix -$(config-os),\
-						 $(config-machine) \
-						 $(base-machine))))))
+						 $(data-machine))))))
 ifneq (,$(check-data))
 $(objpfx)c++-types-check.out: $(check-data) scripts/check-c++-types.sh
 	scripts/check-c++-types.sh $< $(CXX) $(filter-out -std=gnu99 -Wstrict-prototypes,$(CFLAGS)) $(CPPFLAGS) > $@
diff --git a/config.make.in b/config.make.in
index 2b9a939..58be62c 100644
--- a/config.make.in
+++ b/config.make.in
@@ -28,6 +28,7 @@ ldd-rewrite-script = @ldd_rewrite_script@
 # System configuration.
 config-machine = @host_cpu@
 base-machine = @base_machine@
+data-machine = @data_machine@
 config-vendor = @host_vendor@
 config-os = @host_os@
 config-sysdirs = @sysnames@
@@ -78,6 +79,9 @@ oldest-abi = @oldest_abi@
 exceptions = @exceptions@
 multi-arch = @multi_arch@
 
+stubs-biarch_h = @stubs_biarch_h@
+lib-names_awk = @lib_names_awk@
+
 mach-interface-list = @mach_interface_list@
 
 have-bash2 = @libc_cv_have_bash2@
diff --git a/configure b/configure
index 94b15bb..44171dd 100755
--- a/configure
+++ b/configure
@@ -607,6 +607,8 @@ ac_subst_vars='LTLIBOBJS
 LIBOBJS
 RELEASE
 VERSION
+lib_names_awk
+stubs_biarch_h
 mach_interface_list
 DEFINES
 static_nss
@@ -685,6 +687,7 @@ sysdeps_add_ons
 sysnames
 submachine
 multi_arch
+data_machine
 base_machine
 add_on_subdirs
 add_ons
@@ -4024,6 +4027,17 @@ if test "$base_machine" = "i386"; then
 
 fi
 
+# Now run sysdeps preconfigure fragment.
+preconfigure=$srcdir/sysdeps/$base_machine/preconfigure
+if test -r $preconfigure; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: running preconfigure fragment for $base_machine" >&5
+$as_echo "running preconfigure fragment for $base_machine" >&6; }
+  . $preconfigure
+fi
+
+# sysdeps preconfigure fragment may set data_machine.
+
+
 # For the multi-arch option we need support in the assembler.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for assembler gnu_indirect_function symbol type support" >&5
 $as_echo_n "checking for assembler gnu_indirect_function symbol type support... " >&6; }
@@ -7676,6 +7690,16 @@ $as_echo "$libc_cv_pic_default" >&6; }
 
 
 
+if test -z "${stubs_biarch_h}"; then
+  stubs_biarch_h=include/stubs-biarch.h
+fi
+
+
+if test -z "${lib_names_awk}"; then
+  lib_names_awk=scripts/lib-names.awk
+fi
+
+
 if test "`(cd $srcdir; pwd)`" = "`pwd`"; then
   config_makefile=
 else
diff --git a/configure.in b/configure.in
index 119d5be..776cbdb 100644
--- a/configure.in
+++ b/configure.in
@@ -525,6 +525,16 @@ if test "$base_machine" = "i386"; then
   AC_DEFINE(USE_REGPARMS)
 fi
 
+# Now run sysdeps preconfigure fragment.
+preconfigure=$srcdir/sysdeps/$base_machine/preconfigure
+if test -r $preconfigure; then
+  AC_MSG_RESULT(running preconfigure fragment for $base_machine)
+  . $preconfigure
+fi
+
+# sysdeps preconfigure fragment may set data_machine.
+AC_SUBST(data_machine)
+
 # For the multi-arch option we need support in the assembler.
 AC_CACHE_CHECK([for assembler gnu_indirect_function symbol type support],
 	       libc_cv_asm_gnu_indirect_function, [dnl
@@ -2180,6 +2190,16 @@ AC_SUBST(DEFINES)
 dnl See sysdeps/mach/configure.in for this variable.
 AC_SUBST(mach_interface_list)
 
+if test -z "${stubs_biarch_h}"; then
+  stubs_biarch_h=include/stubs-biarch.h
+fi
+AC_SUBST(stubs_biarch_h)
+
+if test -z "${lib_names_awk}"; then
+  lib_names_awk=scripts/lib-names.awk
+fi
+AC_SUBST(lib_names_awk)
+
 if test "`(cd $srcdir; pwd)`" = "`pwd`"; then
   config_makefile=
 else
diff --git a/scripts/data/c++-types-x32-linux-gnu.data b/scripts/data/c++-types-x32-linux-gnu.data
new file mode 100644
index 0000000..348bf52
--- /dev/null
+++ b/scripts/data/c++-types-x32-linux-gnu.data
@@ -0,0 +1,67 @@
+blkcnt64_t:x
+blkcnt_t:x
+blksize_t:x
+caddr_t:Pc
+clockid_t:i
+clock_t:x
+daddr_t:i
+dev_t:y
+fd_mask:l
+fsblkcnt64_t:y
+fsblkcnt_t:y
+fsfilcnt64_t:y
+fsfilcnt_t:y
+fsid_t:8__fsid_t
+gid_t:j
+id_t:j
+ino64_t:y
+ino_t:y
+int16_t:s
+int32_t:i
+int64_t:x
+int8_t:a
+intptr_t:i
+key_t:i
+loff_t:x
+mode_t:j
+nlink_t:y
+off64_t:x
+off_t:x
+pid_t:i
+pthread_attr_t:14pthread_attr_t
+pthread_barrier_t:17pthread_barrier_t
+pthread_barrierattr_t:21pthread_barrierattr_t
+pthread_cond_t:14pthread_cond_t
+pthread_condattr_t:18pthread_condattr_t
+pthread_key_t:j
+pthread_mutex_t:15pthread_mutex_t
+pthread_mutexattr_t:19pthread_mutexattr_t
+pthread_once_t:i
+pthread_rwlock_t:16pthread_rwlock_t
+pthread_rwlockattr_t:20pthread_rwlockattr_t
+pthread_spinlock_t:i
+pthread_t:m
+quad_t:x
+register_t:x
+rlim64_t:y
+rlim_t:y
+sigset_t:10__sigset_t
+size_t:j
+socklen_t:j
+ssize_t:i
+suseconds_t:x
+time_t:x
+u_char:h
+uid_t:j
+uint:j
+u_int:j
+u_int16_t:t
+u_int32_t:j
+u_int64_t:y
+u_int8_t:h
+ulong:m
+u_long:m
+u_quad_t:y
+useconds_t:j
+ushort:t
+u_short:t
diff --git a/sysdeps/unix/sysv/linux/configure b/sysdeps/unix/sysv/linux/configure
index 33821c0..9818315 100644
--- a/sysdeps/unix/sysv/linux/configure
+++ b/sysdeps/unix/sysv/linux/configure
@@ -313,6 +313,9 @@ case "$machine" in
     libc_cv_gcc_unwind_find_fde=yes
     arch_minimum_kernel=2.0.10
     ;;
+  x86_64/x32*)
+    arch_minimum_kernel=2.6.35
+    ;;
   x86_64*)
     arch_minimum_kernel=2.4.0
     ;;
@@ -393,7 +396,7 @@ case "$prefix" in
   # and libc_cv_localedir.
   test -n "$libc_cv_slibdir" || \
   case $machine in
-  sparc/sparc64 | x86_64 | powerpc/powerpc64 | s390/s390-64)
+  sparc/sparc64 | x86_64/64 | powerpc/powerpc64 | s390/s390-64)
     libc_cv_slibdir="/lib64"
     if test "$libdir" = '${exec_prefix}/lib'; then
       libdir='${exec_prefix}/lib64';
diff --git a/sysdeps/unix/sysv/linux/configure.in b/sysdeps/unix/sysv/linux/configure.in
index 59a1311..cff7c29 100644
--- a/sysdeps/unix/sysv/linux/configure.in
+++ b/sysdeps/unix/sysv/linux/configure.in
@@ -70,6 +70,9 @@ case "$machine" in
     libc_cv_gcc_unwind_find_fde=yes
     arch_minimum_kernel=2.0.10
     ;;
+  x86_64/x32*)
+    arch_minimum_kernel=2.6.35
+    ;;
   x86_64*)
     arch_minimum_kernel=2.4.0
     ;;
@@ -132,7 +135,7 @@ case "$prefix" in
   # and libc_cv_localedir.
   test -n "$libc_cv_slibdir" || \
   case $machine in
-  sparc/sparc64 | x86_64 | powerpc/powerpc64 | s390/s390-64)
+  sparc/sparc64 | x86_64/64 | powerpc/powerpc64 | s390/s390-64)
     libc_cv_slibdir="/lib64"
     if test "$libdir" = '${exec_prefix}/lib'; then
       libdir='${exec_prefix}/lib64';
diff --git a/sysdeps/unix/sysv/linux/x86_64/Makefile b/sysdeps/unix/sysv/linux/x86_64/Makefile
index 9c9e615..d025db9 100644
--- a/sysdeps/unix/sysv/linux/x86_64/Makefile
+++ b/sysdeps/unix/sysv/linux/x86_64/Makefile
@@ -1,8 +1,8 @@
 syscall-list-variants := 32bit 64bit
 syscall-list-32bit-options := -D__i386__ -U__x86_64__
-syscall-list-32bit-condition := __WORDSIZE == 32
-syscall-list-64bit-options := -U__i386__ -D__x86_64__
-syscall-list-64bit-condition := __WORDSIZE == 64
+syscall-list-32bit-condition := !defined __x86_64__
+syscall-list-64bit-options := -U__i386__ -D__x86_64__ -D__LP64__
+syscall-list-64bit-condition := defined __x86_64__
 
 ifeq ($(subdir),misc)
 sysdep_routines += ioperm iopl
diff --git a/sysdeps/x86_64/lib-names.awk b/sysdeps/x86_64/lib-names.awk
new file mode 100644
index 0000000..e402c6e
--- /dev/null
+++ b/sysdeps/x86_64/lib-names.awk
@@ -0,0 +1,114 @@
+# awk script for soversions.i -> gnu/lib-names.h; see Makeconfig.
+
+$1 != "DEFAULT" { multi = 1 }
+
+#
+{
+  lib = $2;
+  version = $3;
+  if ($3 !~ /^[0-9]/) {
+    soname = $3;
+    extra = $3;
+    sub(/\.so.*$/, "", extra);
+  }
+  else {
+    soname = lib ".so." $3;
+    extra = "";
+  }
+  soname = "\"" soname "\"";
+  lib = toupper(lib);
+  extra = toupper(extra);
+  gsub(/-/, "_", lib);
+  gsub(/-/, "_", extra);
+  if (extra) {
+    if (extra == "LD_LINUX_X32") {
+      x32_macros[$1 FS lib "_SO"] = soname;
+      x32_macros[$1 FS extra "_SO"] = soname;
+      x86_64_macros[$1 FS lib "_SO"] = "\"ld-linux-x86-64.so.2\"";
+      x86_64_macros[$1 FS "LD_LINUX_X86_64_SO"] = "\"ld-linux-x86-64.so.2\"";
+    }
+    else if (extra == "LD_LINUX_X86_64") {
+      x86_64_macros[$1 FS lib "_SO"] = soname;
+      x86_64_macros[$1 FS extra "_SO"] = soname;
+      x32_macros[$1 FS lib "_SO"] = "\"ld-linux-x32.so.2\"";
+      x32_macros[$1 FS "LD_LINUX_X32_SO"] = "\"ld-linux-x32.so.2\"";
+    }
+    else {
+      macros[$1 FS lib "_SO"] = soname;
+      macros[$1 FS extra "_SO"] = soname;
+    }
+  }
+  else {
+    macros[$1 FS lib "_SO"] = soname;
+  }
+}
+
+END {
+  print "/* This file is automatically generated.";
+  print "   It defines macros to allow user program to find the shared";
+  print "   library files which come as part of GNU libc.  */";
+  print "#ifndef __GNU_LIB_NAMES_H";
+  print "#define __GNU_LIB_NAMES_H	1";
+  print "";
+
+  pfx = multi ? "# define " : "#define ";
+  for (elt in macros) {
+    split(elt, x);
+    line = sprintf("%-40s%s", pfx x[2], macros[elt]);
+    if (x[1] in lines)
+      lines[x[1]] = lines[x[1]] "\n" line;
+    else
+      lines[x[1]] = line;
+  }
+
+  if (multi) {
+    # Print these in a fixed order so the result is identical
+    # on both sides of the coin.
+    pfx = "#  define ";
+    for (elt in x32_macros) {
+      split(elt, x);
+      line = sprintf("%-40s%s", pfx x[2], x32_macros[elt]);
+      if (x[1] in x32_lines)
+	x32_lines[x[1]] = x32_lines[x[1]] "\n" line;
+      else
+	x32_lines[x[1]] = line;
+    }
+    for (elt in x86_64_macros) {
+      split(elt, x);
+      line = sprintf("%-40s%s", pfx x[2], x86_64_macros[elt]);
+      if (x[1] in x86_64_lines)
+	x86_64_lines[x[1]] = x86_64_lines[x[1]] "\n" line;
+      else
+	x86_64_lines[x[1]] = line;
+    }
+    if (!("WORDSIZE32" in lines))
+      lines["WORDSIZE32"] = lines["DEFAULT"];
+    if (!("WORDSIZE64" in lines))
+      lines["WORDSIZE64"] = lines["DEFAULT"];
+    if (!("WORDSIZE32" in x32_lines))
+      x32_lines["WORDSIZE32"] = x32_lines["DEFAULT"];
+    if (!("WORDSIZE64" in x32_lines))
+      x32_lines["WORDSIZE64"] = x32_lines["DEFAULT"];
+    if (!("WORDSIZE32" in x86_64_lines))
+      x86_64_lines["WORDSIZE32"] = x86_64_lines["DEFAULT"];
+    if (!("WORDSIZE64" in x86_64_lines))
+      x86_64_lines["WORDSIZE64"] = x86_64_lines["DEFAULT"];
+    print "#include <bits/wordsize.h>\n";
+    print "#ifndef __x86_64__";
+    cmd = "LC_ALL=C sort"; print lines["WORDSIZE32"] | cmd; close(cmd);
+    print "#else"
+    print "# if __WORDSIZE == 32"
+    cmd = "LC_ALL=C sort"; print x32_lines["WORDSIZE64"] | cmd; close(cmd);
+    print "# else"
+    cmd = "LC_ALL=C sort"; print x86_64_lines["WORDSIZE64"] | cmd; close(cmd);
+    print "# endif"
+    cmd = "LC_ALL=C sort"; print lines["WORDSIZE64"] | cmd; close(cmd);
+    print "#endif";
+  }
+  else {
+    cmd = "LC_ALL=C sort"; print lines["DEFAULT"] | cmd; close(cmd);
+  }
+
+  print "";
+  print "#endif	/* gnu/lib-names.h */"
+}
diff --git a/sysdeps/x86_64/preconfigure b/sysdeps/x86_64/preconfigure
new file mode 100644
index 0000000..d8df7ba
--- /dev/null
+++ b/sysdeps/x86_64/preconfigure
@@ -0,0 +1,17 @@
+case "$base_machine" in
+x86_64)
+  stubs_biarch_h=sysdeps/x86_64/stubs-biarch.h
+  lib_names_awk=sysdeps/x86_64/lib-names.awk
+  if echo __LP64__ | ${CC-cc} $CFLAGS $CPPFLAGS -E - | grep __LP64__ > /dev/null; then
+    machine=x86_64/x32
+    data_machine=x32
+    libc_cv_slibdir="/libx32"
+    if test "$libdir" = '${exec_prefix}/lib'; then
+      libdir='${exec_prefix}/libx32';
+      # Locale data can be shared.
+      libc_cv_localedir='${exec_prefix}/lib/locale'
+    fi
+  else
+    machine=x86_64/64
+  fi
+esac
diff --git a/sysdeps/x86_64/stubs-biarch.h b/sysdeps/x86_64/stubs-biarch.h
new file mode 100644
index 0000000..2579ec6
--- /dev/null
+++ b/sysdeps/x86_64/stubs-biarch.h
@@ -0,0 +1,8 @@
+/* This file selects the right generated file of `__stub_FUNCTION' macros
+   based on the architecture being compiled for.  */
+
+#ifdef __x86_64__
+# include <gnu/stubs-64.h>
+#else
+# include <gnu/stubs-32.h>
+#endif
-- 
1.7.6.5


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