lib32: Add support for linking 32bit programs on 64bit
RFC PATCH 1/1 lib32: Add support for linking 32bit programs on 64bit
This is proof of concept for building 32bit testcases on 64bit platform.
What we do is:
* Configure test if compiler supports -m32
TODO: Does 32bit compiler accept -m32?
If so, we should fail the test on 32bit
platforms by default.
* The directory lib32 contains symlinks of minimal set of sources needed to link newlib testcase + Makefile.
* The testcases.mk builds 32bit library as well if 32bit compiler was installed (-m32 configure test was succesful)
* And finally the env_post.mk switches between lib and lib32 depeding on if -m32 was passed in the CFLAGS
TODO: Check if LTP works with -m32 in CFLAGS passed to configure as well
--- configure.ac | 1 + include/mk/config.mk.in | 2 ++ include/mk/env_post.mk | 4 ++++ include/mk/testcases.mk | 9 +++++++ lib32/Makefile | 38 ++++++++++++++++++++++++++++++ lib32/errnos.h | 1 + lib32/ltp_priv.h | 1 + lib32/safe_file_ops.c | 1 + lib32/safe_macros.c | 1 + lib32/signame.h | 1 + lib32/tst_ansi_color.c | 1 + lib32/tst_checkpoint.c | 1 + lib32/tst_device.c | 1 + lib32/tst_fill_file.c | 1 + lib32/tst_kvercmp.c | 1 + lib32/tst_mkfs.c | 1 + lib32/tst_res.c | 1 + lib32/tst_resource.c | 1 + lib32/tst_run_cmd.c | 1 + lib32/tst_safe_macros.c | 1 + lib32/tst_test.c | 1 + lib32/tst_tmpdir.c | 1 + m4/ltp-m32.m4 | 36 ++++++++++++++++++++++++++++ testcases/kernel/syscalls/add_key/Makefile | 2 ++ 24 files changed, 109 insertions(+) create mode 100644 lib32/Makefile create mode 120000 lib32/errnos.h create mode 120000 lib32/ltp_priv.h create mode 120000 lib32/safe_file_ops.c create mode 120000 lib32/safe_macros.c create mode 120000 lib32/signame.h create mode 120000 lib32/tst_ansi_color.c create mode 120000 lib32/tst_checkpoint.c create mode 120000 lib32/tst_device.c create mode 120000 lib32/tst_fill_file.c create mode 120000 lib32/tst_kvercmp.c create mode 120000 lib32/tst_mkfs.c create mode 120000 lib32/tst_res.c create mode 120000 lib32/tst_resource.c create mode 120000 lib32/tst_run_cmd.c create mode 120000 lib32/tst_safe_macros.c create mode 120000 lib32/tst_test.c create mode 120000 lib32/tst_tmpdir.c create mode 100644 m4/ltp-m32.m4
configure.ac +1 -0
@@ -190,5 +190,6 @@ LTP_CHECK_EPOLL_PWAIT LTP_CHECK_KEYUTILS_SUPPORT LTP_CHECK_SYNC_ADD_AND_FETCH LTP_CHECK_BUILTIN_CLEAR_CACHE +LTP_CHECK_CC_M32 AC_OUTPUT
include/mk/config.mk.in +2 -0
@@ -76,6 +76,8 @@ LDFLAGS += $(WLDFLAGS) CFLAGS += $(DEBUG_CFLAGS) $(OPT_CFLAGS) $(WCFLAGS) CXXFLAGS += $(DEBUG_CXXFLAGS) $(OPT_CXXFLAGS) $(WCXXFLAGS) +CC_M32 := @CC_M32@ + LINUX_VERSION := @LINUX_VERSION@ LINUX_DIR := @LINUX_DIR@ LINUX_VERSION_MAJOR := @LINUX_VERSION_MAJOR@
include/mk/env_post.mk +4 -0
@@ -35,7 +35,11 @@ vpath %.c $(abs_srcdir) # For config.h, et all. CPPFLAGS += -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_srcdir)/include/old/ +ifeq ($(filter -m32,$(CFLAGS)),) LDFLAGS += -L$(top_builddir)/lib +else +LDFLAGS += -L$(top_builddir)/lib32 +endif ifeq ($(UCLINUX),1) CPPFLAGS += -D__UCLIBC__ -DUCLINUX
include/mk/testcases.mk +9 -0
@@ -30,8 +30,10 @@ TKI_DIR := testcases/kernel/include LSN_H := $(abs_top_builddir)/$(TKI_DIR)/linux_syscall_numbers.h LIBLTP_DIR := $(abs_top_builddir)/lib +LIBLTP_DIR32 := $(abs_top_builddir)/lib32 LIBLTP := $(LIBLTP_DIR)/libltp.a +LIBLTP32 := $(LIBLTP_DIR32)/libltp.a $(APICMDS_DIR)/tst_kvercmp: $(APICMDS_DIR) $(MAKE) -C "$^" -f "$(abs_top_srcdir)/tools/apicmds/Makefile" all
@@ -39,11 +41,18 @@ $(APICMDS_DIR)/tst_kvercmp: $(APICMDS_DIR) $(LIBLTP): $(LIBLTP_DIR) $(MAKE) -C "$^" -f "$(abs_top_srcdir)/lib/Makefile" all +$(LIBLTP32): $(LIBLTP_DIR32) + $(MAKE) -C "$^" -f "$(abs_top_srcdir)/lib32/Makefile" all + $(LSN_H): $(abs_top_builddir)/$(TKI_DIR) $(MAKE) -C "$^" -f "$(abs_top_srcdir)/$(TKI_DIR)/Makefile" all MAKE_DEPS := $(LIBLTP) $(LSN_H) +ifneq ($(CC_M32),) +MAKE_DEPS += $(LIBLTP32) +endif + # For linux_syscall_numbers.h CPPFLAGS += -I$(abs_top_builddir)/$(TKI_DIR)
lib32/Makefile new file +38 -0
@@ -0,0 +1,38 @@ +# +# lib Makefile. +# +# Copyright (C) 2009, Cisco Systems Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Ngie Cooper, July 2009 +# + +top_srcdir ?= .. + +include $(top_srcdir)/include/mk/env_pre.mk + +CFLAGS += -I -DLTPLIB -m32 + +ifneq ($(ANDROID),1) +FILTER_OUT_DIRS += android_libpthread android_librt +else +FILTER_OUT_LIBSRCS += tlibio.c tst_path_has_mnt_flags.c +endif + +LIB := libltp.a + +include $(top_srcdir)/include/mk/lib.mk +include $(top_srcdir)/include/mk/generic_trunk_target.mk
lib32/errnos.h new file +1 -0
@@ -0,0 +1 @@ +../lib/errnos.h
lib32/ltp_priv.h new file +1 -0
@@ -0,0 +1 @@ +../lib/ltp_priv.h
lib32/safe_file_ops.c new file +1 -0
@@ -0,0 +1 @@ +../lib/safe_file_ops.c
lib32/safe_macros.c new file +1 -0
@@ -0,0 +1 @@ +../lib/safe_macros.c
lib32/signame.h new file +1 -0
@@ -0,0 +1 @@ +../lib/signame.h
lib32/tst_ansi_color.c new file +1 -0
@@ -0,0 +1 @@ +../lib/tst_ansi_color.c
lib32/tst_checkpoint.c new file +1 -0
@@ -0,0 +1 @@ +../lib/tst_checkpoint.c
lib32/tst_device.c new file +1 -0
@@ -0,0 +1 @@ +../lib/tst_device.c
lib32/tst_fill_file.c new file +1 -0
@@ -0,0 +1 @@ +../lib/tst_fill_file.c
lib32/tst_kvercmp.c new file +1 -0
@@ -0,0 +1 @@ +../lib/tst_kvercmp.c
lib32/tst_mkfs.c new file +1 -0
@@ -0,0 +1 @@ +../lib/tst_mkfs.c
lib32/tst_res.c new file +1 -0
@@ -0,0 +1 @@ +../lib/tst_res.c
lib32/tst_resource.c new file +1 -0
@@ -0,0 +1 @@ +../lib/tst_resource.c
lib32/tst_run_cmd.c new file +1 -0
@@ -0,0 +1 @@ +../lib/tst_run_cmd.c
lib32/tst_safe_macros.c new file +1 -0
@@ -0,0 +1 @@ +../lib/tst_safe_macros.c
lib32/tst_test.c new file +1 -0
@@ -0,0 +1 @@ +../lib/tst_test.c
lib32/tst_tmpdir.c new file +1 -0
@@ -0,0 +1 @@ +../lib/tst_tmpdir.c
m4/ltp-m32.m4 new file +36 -0
@@ -0,0 +1,36 @@ +dnl Copyright (c) 2017 Cyril Hrubis <[email protected]> +dnl +dnl This program is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU General Public License as +dnl published by the Free Software Foundation; either version 2 of +dnl the License, or (at your option) any later version. +dnl +dnl This program is distributed in the hope that it would be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write the Free Software Foundation, +dnl Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +dnl + +AC_DEFUN([LTP_CHECK_CC_M32],[dnl + +flag="-m32" +AC_MSG_CHECKING([if $CC supports $flag]) + +backup_cflags="$CFLAGS" +CFLAGS="$CFLAGS $flag" + +AC_LINK_IFELSE( + [AC_LANG_PROGRAM([])], + [CC_M32="$flag"] + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no])] +) + +AC_SUBST(CC_M32) +CFLAGS="$backup_cflags" + +])
testcases/kernel/syscalls/add_key/Makefile +2 -0
@@ -20,4 +20,6 @@ top_srcdir ?= ../../../.. include $(top_srcdir)/include/mk/testcases.mk +CFLAGS += $(CC_M32) + include $(top_srcdir)/include/mk/generic_leaf_target.mk
Signature · 1 line
2.10.2
RFC PATCH 1/1 lib32: Add support for linking 32bit programs on 64bit
Hi Metan!
Quoted 1 line · On Tue, 28 Mar 2017 12:01:14 +0200 "Cyril Hrubis" <[email protected]> wrote:
This is proof of concept for building 32bit testcases on 64bit platform.
Great thanks! I have tried running it and have a couple of minor issues.
Quoted 10 lines
What we do is:
* Configure test if compiler supports -m32
TODO: Does 32bit compiler accept -m32?
If so, we should fail the test on 32bit
platforms by default.* The directory lib32 contains symlinks of minimal set of sources needed to link newlib testcase +
Makefile.
Apparently missing safe_socket which is required for cve-2016-4997.c, but that is easy to fix I suppose.
Quoted 6 lines
* The testcases.mk builds 32bit library as well if 32bit compiler was installed (-m32 configure test was succesful)
* And finally the env_post.mk switches between lib and lib32 depeding on if -m32 was passed in the CFLAGS
I added "cve-2016-4997: CFLAGS += -m32" and it still tried to look in "../../lib"
include/mk/env_post.mk vpath %.c $(abs_srcdir) · line 42
Quoted 5 lines
include/mk/env_post.mk +4
-0+ifeq ($(filter -m32,$(CFLAGS)),) LDFLAGS += -L$(top_builddir)/lib +else +LDFLAGS += -L$(top_builddir)/lib32 +endif
I was able to remove the if statement (i.e. put both dirs on the search path) and the 64-bit tests still compiled fine and so did the 32-bit test, although maybe not all linkers can be trusted to ignore libs with the wrong number of bits.
Thank you,
Richard.
RFC PATCH 1/1 lib32: Add support for linking 32bit programs on 64bit
Hi!
Quoted 5 lines
Quoted 2 lines
* The directory lib32 contains symlinks of minimal set of sources needed to link newlib testcase +
Makefile.Apparently missing
safe_socketwhich is required forcve-2016-4997.c, but that is easy to fix I suppose.
That is just one symlink away...
Quoted 8 lines
Quoted 5 lines
* The testcases.mk builds 32bit library as well if 32bit compiler was installed (-m32 configure test was succesful)
* And finally the env_post.mk switches between lib and lib32 depeding on if -m32 was passed in the CFLAGS
I added "cve-2016-4997: CFLAGS += -m32" and it still tried to look in "../../lib"
Hmm, that is not easy to fix, since this is target specific variable and we simply do not see the -m32 in the CFLAGS in the condition below.
We would have to set the LDFLAGS per target and I'm not sure if we can easily do that.
Quoted 10 lines
include/mk/env_post.mk vpath %.c $(abs_srcdir) · line 42
Quoted 5 lines
include/mk/env_post.mk +4
-0+ifeq ($(filter -m32,$(CFLAGS)),) LDFLAGS += -L$(top_builddir)/lib +else +LDFLAGS += -L$(top_builddir)/lib32 +endifI was able to remove the if statement (i.e. put both dirs on the search path) and the 64-bit tests still compiled fine and so did the 32-bit test, although maybe not all linkers can be trusted to ignore libs with the wrong number of bits.
While this works mostly fine it produces warnings I would like to avoid.
Signature · 2 lines
Cyril Hrubis [email protected]
RFC PATCH 1/1 lib32: Add support for linking 32bit programs on 64bit
Hi!
Quoted 6 lines
Quoted 2 lines
I added "cve-2016-4997: CFLAGS += -m32" and it still tried to look in "../../lib"
Hmm, that is not easy to fix, since this is target specific variable and we simply do not see the -m32 in the CFLAGS in the condition below.
Quoted 8 lines
We would have to set the LDFLAGS per target and I'm not sure if we can easily do that.
Quoted 5 lines
include/mk/env_post.mk vpath %.c $(abs_srcdir) · line 42
Quoted 5 lines
include/mk/env_post.mk +4
-0+ifeq ($(filter -m32,$(CFLAGS)),) LDFLAGS += -L$(top_builddir)/lib +else +LDFLAGS += -L$(top_builddir)/lib32 +endif
Try with this condition instead of the above ifeqs:
$(MAKE_TARGETS): LDFLAGS += -L$(top_builddir)/lib$(subst -m,,$(filter -m32,$(CFLAGS)))
It's a bit hairy but seems to work.
Signature · 2 lines
Cyril Hrubis [email protected]
RFC PATCH 1/1 lib32: Add support for linking 32bit programs on 64bit
Hello Metan,
Quoted 7 lines · On Tue, 28 Mar 2017 17:46:47 +0200 "Cyril Hrubis" <[email protected]> wrote:
Try with this condition instead of the above ifeqs:
$(MAKE_TARGETS): LDFLAGS += -L$(top_builddir)/lib$(subst -m,,$(filter -m32,$(CFLAGS)))
It's a bit hairy but seems to work.
It works (if added after MAKE_TARGETS is defined ofcourse) and also I symlinked in the safe socket lib, so the test now compiles and runs fine, at least on x86_64 SUSE.
I will try it on SLE-11 SP4 i586.
Thank you,
Richard.
RFC PATCH 1/1 lib32: Add support for linking 32bit programs on 64bit
In reply to Cyril Hrubis----- Original Message -----
Quoted 14 lines
From: "Cyril Hrubis" <[email protected]>
To: [email protected]
Sent: Tuesday, 28 March, 2017 12:01:14 PM
Subject: [LTP] [RFC] [PATCH] lib32: Add support for linking 32bit programs on 64bitThis is proof of concept for building 32bit testcases on 64bit platform.
What we do is:
* Configure test if compiler supports -m32
TODO: Does 32bit compiler accept -m32?
If so, we should fail the test on 32bit
platforms by default.
Quoted 9 lines
* The directory lib32 contains symlinks of minimal set of sources needed to link newlib testcase +
Makefile.* The testcases.mk builds 32bit library as well if 32bit compiler was installed (-m32 configure test was succesful)
* And finally the env_post.mk switches between lib and lib32 depeding on if -m32 was passed in the CFLAGS
One issue I ran into is that configure checks can vary between default and -m32. Here's one exception from RHEL5.6:
# cat 1.c
int main(void) {
int i = 0;
return __sync_add_and_fetch(&i, 1);
}# gcc 1.c # gcc -m32 1.c /tmp/ccwrlcJi.o: In function `main': 1.c:(.text+0x27): undefined reference to `__sync_add_and_fetch_4' collect2: ld returned 1 exit status
Quoted 1 line
TODO: Check if LTP works with -m32 in CFLAGS passed to configure as well
This fails for me on RHEL7:
# make make[1]: Entering directory `/root/ltp/lib/newlib_tests' gcc -m32 -g -O2 -fno-strict-aliasing -pipe -Wall -W -Wold-style-definition -W -Wall -I../../include -I../../include -I../../include/old/ -L../../lib32 test14.c -lltp -o test14 /tmp/ccPZUDSr.o: In function `cleanup': /root/ltp/lib/newlib_tests/test14.c:31: undefined reference to `safe_fopen' /root/ltp/lib/newlib_tests/test14.c:32: undefined reference to `safe_socket' collect2: error: ld returned 1 exit status make[1]: *** [test14] Error 1 make[1]: Leaving directory `/root/ltp/lib/newlib_tests' make: *** [all] Error 2
I ran into one other problem, but I don't think that's relevant for this patch. I'll follow up in separate email thread.
Regards,
Jan
RFC PATCH 1/1 lib32: Add support for linking 32bit programs on 64bit
Hi!
Quoted 24 lines
Quoted 5 lines
* Configure test if compiler supports -m32
TODO: Does 32bit compiler accept -m32?
If so, we should fail the test on 32bit
platforms by default.Quoted 9 lines
* The directory lib32 contains symlinks of minimal set of sources needed to link newlib testcase +
Makefile.* The testcases.mk builds 32bit library as well if 32bit compiler was installed (-m32 configure test was succesful)
* And finally the env_post.mk switches between lib and lib32 depeding on if -m32 was passed in the CFLAGS
One issue I ran into is that configure checks can vary between default and -m32. Here's one exception from RHEL5.6:
# cat 1.c int main(void) { int i = 0; return __sync_add_and_fetch(&i, 1); }
Quoted 5 lines
# gcc 1.c # gcc -m32 1.c /tmp/ccwrlcJi.o: In function `main': 1.c:(.text+0x27): undefined reference to `__sync_add_and_fetch_4' collect2: ld returned 1 exit status
Right, we would have to check for atomic operations with -m32 as well.
I guess that we can add -DUSE_M32 into the lib32/Makefile and add a few ifdefs into the tst_atomic.h something as:
#if (defined(USE_M32) && HAVE_SYNC_AND_FETCH32 == 1) || \
(!defined(USE_M32) && HAVE_SYNC_AND_FETCH == 1)...
#elif ...
...
Quoted 4 lines
Quoted 1 line
TODO: Check if LTP works with -m32 in CFLAGS passed to configure as well
This fails for me on RHEL7:
Quoted 10 lines
# make make[1]: Entering directory `/root/ltp/lib/newlib_tests' gcc -m32 -g -O2 -fno-strict-aliasing -pipe -Wall -W -Wold-style-definition -W -Wall -I../../include -I../../include -I../../include/old/ -L../../lib32 test14.c -lltp -o test14 /tmp/ccPZUDSr.o: In function `cleanup': /root/ltp/lib/newlib_tests/test14.c:31: undefined reference to `safe_fopen' /root/ltp/lib/newlib_tests/test14.c:32: undefined reference to `safe_socket' collect2: error: ld returned 1 exit status make[1]: *** [test14] Error 1 make[1]: Leaving directory `/root/ltp/lib/newlib_tests' make: *** [all] Error 2
This is likely because we try to link against lib32 since -m32 is passed in CFLAGS but lib32/ directory links only subset of the C sources. I would like to disable all the lib32 machinery either when we run on 32bit machine or if -m32 was passed to the configure and use lib32 only in a case that we run on 64 bit machine and want to link 32 bit binary.
Signature · 2 lines
Cyril Hrubis [email protected]
RFC PATCH 1/1 lib32: Add support for linking 32bit programs on 64bit
In reply to Cyril HrubisHi Metan,
Quoted 9 lines · On Tue, 28 Mar 2017 12:01:14 +0200 "Cyril Hrubis" <[email protected]> wrote:
This is proof of concept for building 32bit testcases on 64bit platform.
What we do is:
* Configure test if compiler supports -m32
TODO: Does 32bit compiler accept -m32?
If so, we should fail the test on 32bit
platforms by default.
Yes it does accept -m32. I think the best thing to do is call tst_kernelbits(), as you suggested, at runtime anyway, as someone might be running a 32bit compiler on a 64bit kernel and/or cross compiling.
Also it turns out that I am using some C syntax which is not accepted by GCC 4.3.4. This is annoying considering the tests compile fine with -std=C99 on GCC 6.
Thank you,
Richard.
RFC PATCH 1/1 lib32: Add support for linking 32bit programs on 64bit
Quoted 5 lines · On Wed, 29 Mar 2017 14:48:00 +0200 "Richard Palethorpe"…
Also it turns out that I am using some C syntax which is not accepted by GCC 4.3.4. This is annoying considering the tests compile fine with -std=C99 on GCC 6.
Spoke too soon, it is just missing struct definitions.