From bbc2f1331f3752dee62028bb59eaa93c2e70ac7d Mon Sep 17 00:00:00 2001 From: Dmitry Safonov Date: Tue, 12 Apr 2016 19:10:41 +0300 Subject: [PATCH] x86/build: generate syscalls-{64,32}.built-in.o After uncommenting FIXME: It will add sc_exec_table_32 for compatible tasks to sys-exec-tbl.c Now it does: - add two different 32/64 syscall tables for cr-exec sys-exec-tbl-{64,32}. - add two different syscall headers syscall-{64,32}.h, that are included from more x86 generic syscall.h depending on -DCONFIG_X86_{32,64} option. - builds two different syscalls-{32,64}.built-in.o - for criu core files, that need SYS_memfd_create and other SYS_* __NR_* defines (currently kerndat.c and shmem.c), create simple syscall-codes.h that includes syscall-codes-64.h [Added after rebase on master] That way after apply, the compatible patch set will be simply able to bisect for regressions. Signed-off-by: Dmitry Safonov Acked-by: Cyrill Gorcunov Signed-off-by: Pavel Emelyanov Signed-off-by: Andrei Vagin --- .gitignore | 8 +- criu/Makefile | 5 + criu/arch/ppc64/Makefile.syscalls | 3 + criu/arch/scripts/arm/gen-sys-exec-tbl.pl | 4 + criu/arch/x86/Makefile.syscalls | 217 ++++++++++++++++------ criu/arch/x86/syscalls/syscall32.c | 2 +- criu/cr-exec.c | 3 - criu/pie/Makefile | 9 +- 8 files changed, 187 insertions(+), 64 deletions(-) diff --git a/.gitignore b/.gitignore index 92b480513b..ae5f8e3c56 100644 --- a/.gitignore +++ b/.gitignore @@ -23,11 +23,11 @@ images/google/protobuf/*.c images/google/protobuf/*.h .gitid criu/criu -criu/arch/*/sys-exec-tbl.c -criu/arch/*/syscalls.S +criu/arch/*/sys-exec-tbl*.c +criu/arch/*/syscalls*.S criu/include/config.h -criu/include/syscall-codes.h -criu/include/syscall.h +criu/include/syscall-codes*.h +criu/include/syscall*.h soccr/config.h criu/include/version.h criu/pie/restorer-blob.h diff --git a/criu/Makefile b/criu/Makefile index 6c0241f4b4..4f4d673b51 100644 --- a/criu/Makefile +++ b/criu/Makefile @@ -34,7 +34,12 @@ include $(SRC_DIR)/criu/Makefile.packages # # System calls library. +ifeq ($(ARCH),x86) +# Do not need 32-bit compatible syscall lib compiled in criu +SYSCALL-LIB := $(ARCH_DIR)/syscalls-64.built-in.o +else SYSCALL-LIB := $(ARCH_DIR)/syscalls.built-in.o +endif syscalls_lib: $(Q) $(MAKE) $(call build-as,Makefile.syscalls,$(ARCH_DIR)) all .PHONY: syscalls_lib diff --git a/criu/arch/ppc64/Makefile.syscalls b/criu/arch/ppc64/Makefile.syscalls index 979741a87d..d115978210 100644 --- a/criu/arch/ppc64/Makefile.syscalls +++ b/criu/arch/ppc64/Makefile.syscalls @@ -49,6 +49,9 @@ SYS-EXEC-TBL := sys-exec-tbl.c $(obj)/$(SYS-EXEC-TBL): $(obj)/syscalls/$(SYS-DEF) $(obj)/$(SYS-CODES) $(obj)/$(SYS-PROTO) $(E) " GEN " $@ $(Q) echo "/* Autogenerated, don't edit */" > $@ + $(Q) echo "static struct syscall_exec_desc sc_exec_table[] = {" >> $@ $(Q) cat $< | awk '/^__NR/{print "SYSCALL(", substr($$3, 5), ",", $$2, ")"}' >> $@ + $(Q) echo " { }, /* terminator */" >> $@ + $(Q) echo "};" >> $@ mrproper-y += $(obj)/$(SYS-EXEC-TBL) all-y += $(obj)/$(SYS-EXEC-TBL) diff --git a/criu/arch/scripts/arm/gen-sys-exec-tbl.pl b/criu/arch/scripts/arm/gen-sys-exec-tbl.pl index a3037b78c3..2f90c13fe9 100755 --- a/criu/arch/scripts/arm/gen-sys-exec-tbl.pl +++ b/criu/arch/scripts/arm/gen-sys-exec-tbl.pl @@ -13,6 +13,7 @@ open IN, "<", $in or die $!; print TBLOUT "/* Autogenerated, don't edit */\n"; +print TBLOUT "static struct syscall_exec_desc sc_exec_table[] = {\n"; for () { if ($_ =~ /\#/) { @@ -37,3 +38,6 @@ print TBLOUT "SYSCALL($sys_name, $sys_num)\n"; } } + +print TBLOUT " { }, /* terminator */"; +print TBLOUT "};" diff --git a/criu/arch/x86/Makefile.syscalls b/criu/arch/x86/Makefile.syscalls index a2c509df67..79c58be3a0 100644 --- a/criu/arch/x86/Makefile.syscalls +++ b/criu/arch/x86/Makefile.syscalls @@ -1,71 +1,178 @@ include $(__nmk_dir)msg.mk -builtin-name := syscalls.built-in.o CFLAGS := $(filter-out -pg $(CFLAGS-GCOV),$(CFLAGS)) +CFLAGS := $(filter-out -DCONFIG_X86_64,$(CFLAGS)) -SYS-TYPES := ../../include/syscall-types.h -SYS-CODES := ../../include/syscall-codes.h -SYS-PROTO := ../../include/syscall.h +SYS-PROTO-GENERIC := $(obj)/../../include/syscall.h +SYS-EXEC-TBL-GENERIC := sys-exec-tbl.c +SYS-CODES-GENERIC = $(obj)/../../include/syscall-codes.h +SYS-CODES = $(obj)/../../include/syscall-codes-$(1).h +SYS-PROTO = $(obj)/../../include/syscall-$(1).h +SYS-DEF = $(obj)/syscalls/syscall_$(1).tbl +SYS-ASM = syscalls-$(1).S +SYS-ASM-COMMON = syscall-common-x86-$(1).S +SYS-EXEC-TBL = $(obj)/sys-exec-tbl-$(1).c + +target := +target_32 := syscalls-32 +target_64 := syscalls-64 + +SYS-BITS := 32 + +# native x86_64 ifeq ($(ARCH),x86) - SYS-DEF := syscall_64.tbl - SYS-ASM-COMMON := syscall-common-x86-64.S - asflags-y += -fpie -Wstrict-prototypes -Wa,--noexecstack -else - SYS-DEF := syscall_32.tbl - SYS-ASM-COMMON := syscall-common-x86-32.S - asflags-y += -fno-pic -Wstrict-prototypes -Wa,--noexecstack - obj-y += syscalls/syscall32.o - -$(obj)/syscalls/syscall32.o: $(obj)/$(SYS-CODES) $(obj)/$(SYS-PROTO) + SYS-BITS += 64 endif +# targets +define gen-targets +target += $(target_$(1)) +endef + +$(eval $(call map,gen-targets,$(SYS-BITS))) + +# AFLAGS, LDFLAGS +asflags-y += -Wstrict-prototypes -Wa,--noexecstack asflags-y += -D__ASSEMBLY__ -nostdlib -fomit-frame-pointer -asflags-y += -iquote $(obj) -iquote $(obj)/include -iquote $(SRC_DIR)/criu/include +asflags-y += -iquote $(obj) -iquote $(obj)/include +asflags-y += -iquote $(SRC_DIR)/criu/include -SYS-ASM := syscalls.S -obj-y += $(SYS-ASM:.S=).o +AFLAGS_$(target_32) += -fno-pic -m32 +AFLAGS_$(target_64) += -fpie +LDFLAGS_$(target_32) += -m elf_i386 -$(obj)/$(SYS-CODES): $(obj)/syscalls/$(SYS-DEF) - $(call msg-gen, $@) - $(Q) echo "/* Autogenerated, don't edit */" > $@ - $(Q) echo "#ifndef __ASM_CR_SYSCALL_CODES_H__" >> $@ - $(Q) echo "#define __ASM_CR_SYSCALL_CODES_H__" >> $@ - $(Q) cat $< | awk '/^__NR/{SYSN=$$1; sub("^__NR", "SYS", SYSN);'\ - 'print "\n#ifndef ", $$1, "\n#define", $$1, $$2, "\n#endif";'\ - 'print "#ifndef ", SYSN, "\n#define ", SYSN, $$1, "\n#endif"}' >> $@ - $(Q) echo "#endif /* __ASM_CR_SYSCALL_CODES_H__ */" >> $@ -mrproper-y += $(obj)/$(SYS-CODES) - -$(obj)/$(SYS-PROTO): $(obj)/syscalls/$(SYS-DEF) - $(call msg-gen, $@) - $(Q) echo "/* Autogenerated, don't edit */" > $@ - $(Q) echo "#ifndef __ASM_CR_SYSCALL_PROTO_H__" >> $@ - $(Q) echo "#define __ASM_CR_SYSCALL_PROTO_H__" >> $@ - $(Q) echo "#ifndef CR_NOGLIBC" >> $@ - $(Q) echo "# error This file should only be used in the parasite code" >> $@ - $(Q) echo "#endif" >> $@ - $(Q) echo "#include \"syscall-codes.h\"" >> $@ - $(Q) echo "#include \"syscall-types.h\"" >> $@ -ifneq ($(ARCH),x86) - $(Q) echo "#include \"asm/syscall32.h\"" >> $@ +$(target_32)-obj-y += syscalls/syscall32.o +$(obj)/syscalls/syscall32.d: $(obj)/../../include/syscall-codes-32.h \ + $(obj)/../../include/syscall-32.h + +CFLAGS_syscall32.o += -fno-pic -m32 -DCR_NOGLIBC -DCONFIG_X86_32 +CFLAGS_syscall32.d += -fno-pic -m32 -DCR_NOGLIBC -DCONFIG_X86_32 +cleanup-y += $(obj)/syscalls/syscall32.o + +# Here are rules for 32/64-bit platforms. For compat mode we need both +# 32 and 64 bit syscalls, so generate the rules with SYS-BIT being +# $1 parameter in all gen-rule-* + +# awk variable should be escaped twice +AV := $$$$ + +define gen-rule-sys-codes +$(SYS-CODES): $(SYS-DEF) + $(call msg-gen, $$@) + $(Q) echo "/* Autogenerated, don't edit */" > $$@ + $(Q) echo "#ifndef __ASM_CR_SYSCALL_CODES_H_$(1)__" >> $$@ + $(Q) echo "#define __ASM_CR_SYSCALL_CODES_H_$(1)__" >> $$@ + $(Q) cat $$< | awk '/^__NR/{SYSN=$(AV)1; \ + sub("^__NR", "SYS", SYSN); \ + print "\n#ifndef ", $(AV)1; \ + print "#define", $(AV)1, $(AV)2; \ + print "#endif"; \ + print "\n#ifndef ", SYSN; \ + print "#define ", SYSN, $(AV)1; \ + print "#endif";}' >> $$@ + $(Q) echo "#endif /* __ASM_CR_SYSCALL_CODES_H_$(1)__ */" >> $$@ +mrproper-y += $(SYS-CODES) +endef + +define gen-rule-sys-proto +$(SYS-PROTO): $(SYS-DEF) + $(call msg-gen, $$@) + $(Q) echo "/* Autogenerated, don't edit */" > $$@ + $(Q) echo "#ifndef __ASM_CR_SYSCALL_PROTO_H_$(1)__" >> $$@ + $(Q) echo "#define __ASM_CR_SYSCALL_PROTO_H_$(1)__" >> $$@ + $(Q) echo "#ifndef CR_NOGLIBC" >> $$@ + $(Q) echo "# error This file should only be used in the parasite code" \ + >> $$@ + $(Q) echo "#endif" >> $$@ + $(Q) echo '#include "syscall-codes-$(1).h"' >> $$@ + $(Q) echo '#include "syscall-types.h"' >> $$@ +ifeq ($(1),32) + $(Q) echo '#include "asm/syscall32.h"' >> $$@ endif - $(Q) cat $< | awk '/^__NR/{print "extern long", $$3, substr($$0, index($$0,$$4)), ";"}' >> $@ - $(Q) echo "#endif /* __ASM_CR_SYSCALL_PROTO_H__ */" >> $@ -mrproper-y += $(obj)/$(SYS-PROTO) + $(Q) cat $$< | awk '/^__NR/{print "extern long", $(AV)3, \ + substr($(AV)0, index($(AV)0,$(AV)4)), ";"}' >> $$@ + $(Q) echo "#endif /* __ASM_CR_SYSCALL_PROTO_H_$(1)__ */" >> $$@ +mrproper-y += $(SYS-PROTO) +endef -$(obj)/$(SYS-ASM): $(obj)/syscalls/$(SYS-DEF) $(obj)/syscalls/$(SYS-ASM-COMMON) $(obj)/$(SYS-CODES) $(obj)/$(SYS-PROTO) - $(call msg-gen, $@) - $(Q) echo "/* Autogenerated, don't edit */" > $@ - $(Q) echo "#include \"syscall-codes.h\"" >> $@ - $(Q) echo "#include \"syscalls/$(SYS-ASM-COMMON)\"" >> $@ - $(Q) cat $< | awk '/^__NR/{print "SYSCALL(", $$3, ",", $$2, ")"}' >> $@ +define gen-rule-sys-asm +$(obj)/$(SYS-ASM): $(SYS-DEF) $(obj)/syscalls/$(SYS-ASM-COMMON) \ + $(SYS-CODES) $(SYS-PROTO) + $(call msg-gen, $$@) + $(Q) echo "/* Autogenerated, don't edit */" > $$@ + $(Q) echo '#include "syscall-codes-$(1).h"' >> $$@ + $(Q) echo '#include "syscalls/$(SYS-ASM-COMMON)"' >> $$@ + $(Q) cat $$< | awk '/^__NR/{print "SYSCALL(", $(AV)3, ",", $(AV)2, ")"}'\ + >> $$@ mrproper-y += $(obj)/$(SYS-ASM) +$(target_$(1))-obj-y += $(SYS-ASM:.S=).o +endef + +# for 32-bit $(SYS-ASM) +AFLAGS_syscalls-32.o += -fno-pic -m32 + +define gen-rule-sys-exec-tbl +$(SYS-EXEC-TBL): $(SYS-DEF) $(SYS-CODES) $(SYS-PROTO) $(SYS-PROTO-GENERIC) + $(call msg-gen, $$@) + $(Q) echo "/* Autogenerated, don't edit */" > $$@ + $(Q) cat $$< | awk '/^__NR/{print \ + "SYSCALL(", substr($(AV)3, 5), ",", $(AV)2, ")"}' >> $$@ +mrproper-y += $(SYS-EXEC-TBL) +all-y += $(SYS-EXEC-TBL) +endef + +# Some parts of criu need SYS_memfd_create and other ifndef/define syscalls +# Use 64-bit, native syscalls as-is, add __NR32_*/SYS32_* defines +# to generic file +$(SYS-CODES-GENERIC): $(obj)/syscalls/syscall_32.tbl + $(call msg-gen, $@) + $(Q) echo "/* Autogenerated, don't edit */" > $@ + $(Q) echo "#ifndef __ASM_CR_SYSCALL_CODES_H__" >> $@ + $(Q) echo "#define __ASM_CR_SYSCALL_CODES_H__" >> $@ + $(Q) echo '#include "syscall-codes-64.h"' >> $@ + $(Q) cat $< | awk '/^__NR/{NR32=$$1; \ + sub("^__NR", "__NR32", NR32); \ + print "\n#ifndef ", NR32; \ + print "#define ", NR32, $$2; \ + print "#endif";}' >> $@ + $(Q) echo "#endif /* __ASM_CR_SYSCALL_CODES_H__ */" >> $@ +mrproper-y += $(SYS-CODES-GENERIC) +all-y += $(SYS-CODES-GENERIC) -SYS-EXEC-TBL := sys-exec-tbl.c -$(obj)/$(SYS-EXEC-TBL): $(obj)/syscalls/$(SYS-DEF) $(obj)/$(SYS-CODES) $(obj)/$(SYS-PROTO) +$(SYS-PROTO-GENERIC): $(strip $(call map,SYS-PROTO,$(SYS-BITS))) $(call msg-gen, $@) - $(Q) echo "/* Autogenerated, don't edit */" > $@ - $(Q) cat $< | awk '/^__NR/{print "SYSCALL(", substr($$3, 5), ",", $$2, ")"}' >> $@ -mrproper-y += $(obj)/$(SYS-EXEC-TBL) -all-y += $(obj)/$(SYS-EXEC-TBL) + $(Q) echo "/* Autogenerated, don't edit */" > $@ + $(Q) echo "#ifndef __ASM_CR_SYSCALL_PROTO_H__" >> $@ + $(Q) echo "#define __ASM_CR_SYSCALL_PROTO_H__" >> $@ + $(Q) echo "" >> $@ + $(Q) echo "#ifdef CONFIG_X86_32" >> $@ + $(Q) echo '#include "syscall-32.h"' >> $@ + $(Q) echo "#else" >> $@ + $(Q) echo '#include "syscall-64.h"' >> $@ + $(Q) echo "#endif /* CONFIG_X86_32 */" >> $@ + $(Q) echo "" >> $@ + $(Q) echo "#endif /* __ASM_CR_SYSCALL_PROTO_H__ */" >> $@ +mrproper-y += $(SYS-PROTO-GENERIC) + +$(obj)/$(SYS-EXEC-TBL-GENERIC): + $(Q) echo "/* Autogenerated, don't edit */" > $@ + $(Q) echo "static struct syscall_exec_desc sc_exec_table[] = {" >> $@ +ifeq ($(ARCH),x86) + $(Q) echo '#include "sys-exec-tbl-64.c"' >> $@ + $(Q) echo " { }, /* terminator */" >> $@ + $(Q) echo "};" >> $@ + $(Q) echo "" >> $@ +# FIXME: uncomment to support 32-bit task +# $(Q) echo "static struct syscall_exec_desc sc_exec_table_32[] = {" >> $@ +endif +# $(Q) echo '#include "sys-exec-tbl-32.c"' >> $@ +# $(Q) echo " { }, /* terminator */" >> $@ +# $(Q) echo "};" >> $@ +mrproper-y += $(obj)/$(SYS-EXEC-TBL-GENERIC) +all-y += $(obj)/$(SYS-EXEC-TBL-GENERIC) + +$(eval $(call map,gen-rule-sys-codes,$(SYS-BITS))) +$(eval $(call map,gen-rule-sys-proto,$(SYS-BITS))) +$(eval $(call map,gen-rule-sys-asm,$(SYS-BITS))) +$(eval $(call map,gen-rule-sys-exec-tbl,$(SYS-BITS))) diff --git a/criu/arch/x86/syscalls/syscall32.c b/criu/arch/x86/syscalls/syscall32.c index b68ef09572..88af59330a 100644 --- a/criu/arch/x86/syscalls/syscall32.c +++ b/criu/arch/x86/syscalls/syscall32.c @@ -1,5 +1,5 @@ #include "asm/types.h" -#include "syscall.h" +#include "syscall-32.h" #define SYS_SOCKET 1 /* sys_socket(2) */ #define SYS_BIND 2 /* sys_bind(2) */ diff --git a/criu/cr-exec.c b/criu/cr-exec.c index 75dfd0f956..aa8b0f6342 100644 --- a/criu/cr-exec.c +++ b/criu/cr-exec.c @@ -17,12 +17,9 @@ struct syscall_exec_desc { unsigned nr; }; -static struct syscall_exec_desc sc_exec_table[] = { #define SYSCALL(__name, __nr) { .name = #__name, .nr = __nr, }, #include "sys-exec-tbl.c" #undef SYSCALL - { }, /* terminator */ -}; static struct syscall_exec_desc *find_syscall(char *name) { diff --git a/criu/pie/Makefile b/criu/pie/Makefile index 220ee6e0c5..4edcf4852f 100644 --- a/criu/pie/Makefile +++ b/criu/pie/Makefile @@ -3,11 +3,18 @@ target += restorer parasite-obj-y += parasite.o parasite-obj-y += ./$(ARCH_DIR)/parasite-head.o -parasite-obj-e += ./$(ARCH_DIR)/syscalls.built-in.o restorer-obj-y += restorer.o restorer-obj-y += ./$(ARCH_DIR)/restorer.o + +ifeq ($(ARCH),x86) +# FIXME: depend on 32/64 pie type +parasite-obj-e += ./$(ARCH_DIR)/syscalls-64.built-in.o +restorer-obj-e += ./$(ARCH_DIR)/syscalls-64.built-in.o +else +parasite-obj-e += ./$(ARCH_DIR)/syscalls.built-in.o restorer-obj-e += ./$(ARCH_DIR)/syscalls.built-in.o +endif # # We can't provide proper mount implementation