This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
PATCH [1/n]: Initial x32 support
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: GNU C Library <libc-alpha at sourceware dot org>
- Date: Thu, 15 Mar 2012 11:17:27 -0700
- Subject: PATCH [1/n]: Initial x32 support
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
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