[CRIU] [PATCH 13/15] pie: generate native and compat parasites

Dmitry Safonov dsafonov at virtuozzo.com
Mon Apr 11 05:19:27 PDT 2016


Only parasite should be mode-depended, not restorer, as
restorer will just switch to compatible mode with arch_prctl
at the end and jump to 32-bit executable with sigreturn.

So for parasite there are two targets: "native" and "compat",
and one for restorer with the same name "restorer".
It will result in parasite-native.o, parasite-compat.o and restorer.o
objects.

Pie build still may work with piegen or without it (gen-offset.sh).

There are many FIXME in this patch, all them are in C code, that should
be fixed to use compatible parsite when needed.

Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
---
 .gitignore               |   4 +-
 criu/include/parasite.h  |   2 +-
 criu/parasite-syscall.c  |   8 +--
 criu/pie/Makefile        | 157 +++++++++++++++++++++++++++++++++--------------
 criu/pie/parasite-blob.h |   6 ++
 5 files changed, 123 insertions(+), 54 deletions(-)
 create mode 100644 criu/pie/parasite-blob.h

diff --git a/.gitignore b/.gitignore
index 54c94eb93a21..e8c47d589389 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,8 +31,8 @@ criu/include/syscall-codes*.h
 criu/include/syscall*.h
 criu/include/version.h
 criu/pie/restorer-blob.h
-criu/pie/parasite-blob.h
+criu/pie/parasite-*-blob.h
 criu/pie/piegen/piegen
-criu/pie/pie.lds.S
+criu/pie/pie.lds*.S
 criu/protobuf-desc-gen.h
 scripts/build/qemu-user-static/*
diff --git a/criu/include/parasite.h b/criu/include/parasite.h
index 52e3c634d66b..c2bd0c3304b8 100644
--- a/criu/include/parasite.h
+++ b/criu/include/parasite.h
@@ -270,7 +270,7 @@ struct parasite_dump_cgroup_args {
 
 /* the parasite prefix is added by gen_offsets.sh */
 #define __pblob_offset(ptype, symbol)					\
-	parasite ## _blob_offset__ ## symbol
+	parasite_ ## ptype ## _blob_offset__ ## symbol
 #define parasite_sym(pblob, ptype, symbol)				\
 	((void *)(pblob) + __pblob_offset(ptype, symbol))
 
diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c
index 8f4c04b99553..845a4c3609ad 100644
--- a/criu/parasite-syscall.c
+++ b/criu/parasite-syscall.c
@@ -1355,7 +1355,7 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 
 	ctl->args_size = round_up(parasite_args_size, PAGE_SIZE);
 	parasite_args_size = PARASITE_ARG_SIZE_MIN; /* reset for next task */
-	map_exchange_size = pie_size(parasite) + ctl->args_size;
+	map_exchange_size = pie_size(parasite_native) + ctl->args_size;
 	map_exchange_size += RESTORE_STACK_SIGFRAME + PARASITE_STACK_SIZE;
 	if (item->nr_threads > 1)
 		map_exchange_size += PARASITE_STACK_SIZE;
@@ -1367,16 +1367,16 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 		goto err_restore;
 
 	pr_info("Putting parasite blob into %p->%p\n", ctl->local_map, ctl->remote_map);
-	memcpy(ctl->local_map, parasite_blob, sizeof(parasite_blob));
+	memcpy(ctl->local_map, parasite_native_blob, sizeof(parasite_native_blob));
 
-	ELF_RELOCS_APPLY(parasite, ctl->local_map, ctl->remote_map);
+	ELF_RELOCS_APPLY(parasite_native, ctl->local_map, ctl->remote_map);
 
 	/* Setup the rest of a control block */
 	ctl->parasite_ip	= (unsigned long)parasite_sym(ctl->remote_map, native, __export_parasite_head_start);
 	ctl->addr_cmd		= parasite_sym(ctl->local_map, native, __export_parasite_cmd);
 	ctl->addr_args		= parasite_sym(ctl->local_map, native, __export_parasite_args);
 
-	p = pie_size(parasite) + ctl->args_size;
+	p = pie_size(parasite_native) + ctl->args_size;
 
 	ctl->rsigframe	= ctl->remote_map + p;
 	ctl->sigframe	= ctl->local_map  + p;
diff --git a/criu/pie/Makefile b/criu/pie/Makefile
index 55a9cff7a356..5f973fd2833f 100644
--- a/criu/pie/Makefile
+++ b/criu/pie/Makefile
@@ -1,33 +1,64 @@
-target			+= parasite
-target			+= restorer
+# native/compat target names are _only_ for parasite
+# restorer is always native (64-bit)
+parasite_target		:= native
 
-parasite-obj-y		+= parasite.o
+ifeq ($(ARCH),x86)
+        parasite_target	+= compat
+endif
+
+# $1 - parasite target
+define gen-parasite-rules
+$(1)-obj-uniq		+= parasite.o
+endef
+$(eval $(call map,gen-parasite-rules,$(parasite_target)))
 
 restorer-obj-y		+= restorer.o
 restorer-obj-y		+= ./$(ARCH_DIR)/restorer.o
 
 ifeq ($(ARCH),x86)
-# FIXME: depend on 32/64 pie type
-parasite-obj-y		+= ./$(ARCH_DIR)/parasite-head-64.o
-parasite-obj-e		+= ./$(ARCH_DIR)/syscalls-64.built-in.o
 restorer-obj-e		+= ./$(ARCH_DIR)/syscalls-64.built-in.o
+
+native-obj-y		+= ./$(ARCH_DIR)/parasite-head-64.o
+native-obj-e		+= ./$(ARCH_DIR)/syscalls-64.built-in.o
+compat-obj-y		+= ./$(ARCH_DIR)/parasite-head-32.o
+compat-obj-e		+= ./$(ARCH_DIR)/syscalls-32.built-in.o
+
+AFLAGS_parasite-head-64.o += -fpie -DCONFIG_X86_64
+AFLAGS_parasite-head-64.d += -fpie -DCONFIG_X86_64
+
+AFLAGS_parasite-head-32.o += -fno-pic -m32 -DCONFIG_X86_32
+AFLAGS_parasite-head-32.d += -fno-pic -m32 -DCONFIG_X86_32
 else
-parasite-obj-y		+= ./$(ARCH_DIR)/parasite-head.o
-parasite-obj-e		+= ./$(ARCH_DIR)/syscalls.built-in.o
+native-obj-y		+= ./$(ARCH_DIR)/parasite-head.o
+native-obj-e		+= ./$(ARCH_DIR)/syscalls.built-in.o
 restorer-obj-e		+= ./$(ARCH_DIR)/syscalls.built-in.o
 endif
 
+target			+= $(parasite_target) restorer
+
 #
 # We can't provide proper mount implementation
 # in parasite code -- it requires run-time rellocation
 # applications, which is not the target of the
 # project.
 #
-CFLAGS			:= $(filter-out -pg $(CFLAGS-GCOV),$(CFLAGS)) -iquote $(SRC_DIR)/compel/include -iquote arch/$(ARCH)/include -iquote $(SRC_DIR) -iquote $(SRC_DIR)/criu/include
+CFLAGS			:= $(filter-out -pg $(CFLAGS-GCOV),$(CFLAGS))
+CFLAGS			:= $(filter-out -DCONFIG_X86_64,$(CFLAGS))
+CFLAGS			+= -iquote $(SRC_DIR)/compel/include
+CFLAGS			+= -iquote arch/$(ARCH)/include -iquote $(SRC_DIR)
+CFLAGS			+= -iquote $(SRC_DIR)/criu/include
 
 ccflags-y		+= -DCR_NOGLIBC
-ifneq ($(filter-out clean mrproper,$(MAKECMDGOALS)),)
-	ccflags-y	+= $(shell $(SRC_DIR)/compel/compel --arch=$(ARCH) cflags)
+NATIVE_CFLAGS		:= $(shell $(SRC_DIR)/compel/compel --arch=$(ARCH) cflags)
+
+CFLAGS_native		+= $(NATIVE_CFLAGS)
+CFLAGS_restorer.o	+= $(NATIVE_CFLAGS)
+
+ifeq ($(ARCH),x86)
+        CFLAGS_restorer.o += -DCONFIG_X86_64
+        CFLAGS_native	+= -DCONFIG_X86_64
+        CFLAGS_compat	+= -fno-pic -m32 -DCONFIG_X86_32
+	LDFLAGS_compat	+= -m elf_i386
 endif
 
 ifeq ($(SRCARCH),arm)
@@ -37,45 +68,73 @@ endif
 asflags-y		+= -D__ASSEMBLY__
 
 GEN-OFFSETS		:= $(obj)/../../scripts/gen-offsets.sh
-BLOBS			:= $(obj)/parasite-blob.h $(obj)/restorer-blob.h
 
-PIELDS			:= pie.lds.S
+BLOBS			+= $(obj)/restorer-blob.h
+
+define gen-pields-blobs-var
+PIELDS			+= $(obj)/pie.lds-$(1).S
+BLOBS			+= $(obj)/parasite-$(1)-blob.h
+endef
+$(eval $(call map,gen-pields-blobs-var,$(parasite_target)))
 
 .SECONDARY:
 
 ifeq ($(piegen-y),y)
-target-name = $(patsubst pie/%-blob.h,%,$(1))
-
-ifeq ($(SRCARCH),ppc64)
-$(obj)/$(PIELDS): $(obj)/pie-reloc.lds.S.in
-	$(call msg-gen, $@)
-	$(Q) echo "OUTPUT_ARCH($(LDARCH))"              >  $(obj)/$(PIELDS)
-	$(Q) cat $<					>> $(obj)/$(PIELDS)
+PIELDS_INCLUDE		:= $(obj)/pie-reloc.lds.S.in
 else
+PIELDS_INCLUDE		:= $(obj)/pie.lds.S.in
+endif
+
 ifeq ($(ARCH),x86)
-$(obj)/$(PIELDS): $(obj)/pie-reloc.lds.S.in
+$(obj)/pie.lds-native.S: $(PIELDS_INCLUDE)
 	$(call msg-gen, $@)
-	$(Q) echo "OUTPUT_ARCH(i386:x86-64)"		>  $(obj)/$(PIELDS)
-	$(Q) echo "TARGET(elf64-x86-64)"		>> $(obj)/$(PIELDS)
-	$(Q) cat $<					>> $(obj)/$(PIELDS)
-else # i386 ia32
-$(obj)/$(PIELDS): $(obj)/pie-reloc.lds.S.in
+	$(Q) echo "OUTPUT_ARCH(i386:x86-64)"		>  $@
+	$(Q) echo "TARGET(elf64-x86-64)"		>> $@
+	$(Q) cat $<					>> $@
+
+$(obj)/pie.lds-compat.S: $(PIELDS_INCLUDE)
 	$(call msg-gen, $@)
-	$(Q) echo "OUTPUT_ARCH(i386)"			>  $(obj)/$(PIELDS)
-	$(Q) echo "TARGET(elf32-i386)"			>> $(obj)/$(PIELDS)
-	$(Q) cat $<					>> $(obj)/$(PIELDS)
-endif
-endif
+	$(Q) echo "OUTPUT_ARCH(i386)"			>  $@
+	$(Q) echo "TARGET(elf32-i386)"			>> $@
+	$(Q) cat $<					>> $@
+else # !x86
+ifeq ($(filter-out i386 ia32,$(ARCH)),)
+$(PIELDS): $(PIELDS_INCLUDE)
+	$(call msg-gen, $@)
+	$(Q) echo "OUTPUT_ARCH(i386)"			>  $@
+	$(Q) echo "TARGET(elf32-i386)"			>> $@
+	$(Q) cat $<					>> $@
+else # arm, aarch64, ppc64
+$(PIELDS): $(PIELDS_INCLUDE)
+	$(call msg-gen, $@)
+	$(Q) echo "OUTPUT_ARCH($(LDARCH))"              >  $@
+	$(Q) cat $<					>> $@
+endif # non i386
+endif # non x86 ARCH
+
+# for C files, we need "parasite-native" to be "parasite_native"
+target-name = $(patsubst pie/%_blob.h,%,$(subst -,_,$(1)))
 
+ifeq ($(piegen-y),y)
 ifeq ($(strip $(V)),)
         piegen_stdout := >/dev/null
 endif
 
-$(obj)/%.built-in.bin.o: $(obj)/%.built-in.o $(obj)/native.lib.a $(obj)/$(PIELDS)
+$(obj)/restorer.built-in.bin.o: $(obj)/restorer.built-in.o		\
+				$(obj)/native.lib.a $(obj)/pie.lds-native.S
 	$(call msg-gen, $@)
-	$(Q) $(LD) -r -T $(obj)/$(PIELDS) -o $@ $< $(obj)/native.lib.a
-
-$(obj)/%-blob.h: $(obj)/%.built-in.bin.o $(obj)/$(PIELDS) $(SRC_DIR)/compel/compel
+	$(Q) $(LD) -r -T $(obj)/pie.lds-native.S -o $@ $< $(obj)/native.lib.a
+
+# $1 - binary mode: native/compat
+define gen-rule-built-in.bin.o
+$(obj)/parasite-$(1).built-in.bin.o: $(obj)/$(1).built-in.o		\
+				$(obj)/$(1).lib.a $(obj)/pie.lds-$(1).S
+	$$(call msg-gen, $$@)
+	$(Q) $(LD) -r -T $(obj)/pie.lds-$(1).S -o $$@ $$< $(obj)/$(1).lib.a
+endef
+$(eval $(call map,gen-rule-built-in.bin.o,$(parasite_target)))
+
+$(obj)/%-blob.h: $(obj)/%.built-in.bin.o $(SRC_DIR)/compel/compel
 	$(call msg-gen, $@)
 	$(Q) $(SRC_DIR)/compel/compel piegen -f $<		 	\
 		-v $(call target-name,$@)_relocs			\
@@ -85,16 +144,21 @@ $(obj)/%-blob.h: $(obj)/%.built-in.bin.o $(obj)/$(PIELDS) $(SRC_DIR)/compel/comp
 		-u $(SRC_DIR)/compel/include/uapi			\
 		-o $@ $(piegen_stdout)
 
-else
+else # !piegen-y
 
-$(obj)/$(PIELDS): $(obj)/$(PIELDS).in
-	$(call msg-gen, $@)
-	$(Q) $(SH) -c "echo 'OUTPUT_ARCH($(LDARCH))'	 > $(obj)/$(PIELDS)"
-	$(Q) $(SH) -c "cat $(obj)/$(PIELDS).in		>> $(obj)/$(PIELDS)"
+define gen-rule-built-in.bin.o
+$(obj)/parasite-$(1).built-in.bin.o: $(obj)/$(1).built-in.o		\
+				$(obj)/pie.lds-$(1).S
+	$$(call msg-gen, $$@)
+	$(Q) $(LD) -r -T $(obj)/pie.lds-$(1).S -o $$@ $$<
+endef
+
+$(eval $(call map,gen-rule-built-in.bin.o,$(parasite_target)))
 
-$(obj)/%.built-in.bin.o: $(obj)/%.built-in.o $(obj)/$(PIELDS)
+$(obj)/restorer.built-in.bin.o: $(obj)/restorer.built-in.o		\
+				$(obj)/pie.lds-native.S
 	$(call msg-gen, $@)
-	$(Q) $(LD) -r -T $(obj)/$(PIELDS) -o $@ $<
+	$(Q) $(LD) -r -T $(obj)/pie.lds-native.S -o $@ $<
 
 $(obj)/%.built-in.bin: $(obj)/%.built-in.bin.o
 	$(call msg-gen, $@)
@@ -102,17 +166,16 @@ $(obj)/%.built-in.bin: $(obj)/%.built-in.bin.o
 
 $(obj)/%-blob.h: $(obj)/%.built-in.bin $(GEN-OFFSETS)
 	$(call msg-gen, $@)
-	$(Q) $(SH) $(GEN-OFFSETS) $(@:-blob.h=) $(notdir $(@:-blob.h=)) $(CROSS_COMPILE) > $@
+	$(Q) $(SH) $(GEN-OFFSETS) $(@:-blob.h=) $(call target-name,$@) $(CROSS_COMPILE) > $@
 
-endif
 
-$(BLOBS): $(obj)/$(PIELDS)
-all-y += $(BLOBS)
+endif # !piegen-y
 
+all-y += $(BLOBS)
 # blobs and pields are in cleanup, rather than in mrproper because
 # we want them to be re-generated after `make clean && make`
 cleanup-y += $(BLOBS)
-cleanup-y += $(obj)/$(PIELDS)
+cleanup-y += $(PIELDS)
 cleanup-y += $(obj)/*.bin
 cleanup-y += $(obj)/*.built-in.bin.o
 cleanup-y += $(obj)/*.built-in.bin
diff --git a/criu/pie/parasite-blob.h b/criu/pie/parasite-blob.h
new file mode 100644
index 000000000000..278ca6d85845
--- /dev/null
+++ b/criu/pie/parasite-blob.h
@@ -0,0 +1,6 @@
+#include "parasite-native-blob.h"
+
+#ifdef CONFIG_X86_64
+/* FIXME: parasite_compat_blob defined but not used */
+/* # include "parasite-compat-blob.h"*/
+#endif
-- 
2.8.0



More information about the CRIU mailing list