[CRIU] [PATCHv2 11/17] pie: generate native and compat parasites
Dmitry Safonov
dsafonov at virtuozzo.com
Tue Apr 12 09:10:49 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 | 168 +++++++++++++++++++++++++++-----------
criu/pie/compat/parasite-compat.c | 1 +
criu/pie/parasite-blob.h | 6 ++
6 files changed, 133 insertions(+), 56 deletions(-)
create mode 120000 criu/pie/compat/parasite-compat.c
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..3679e24438a4 100644
--- a/criu/pie/Makefile
+++ b/criu/pie/Makefile
@@ -1,35 +1,73 @@
-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
+
+native-obj-y += parasite.o
+compat-obj-y += compat/parasite-compat.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-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
+ 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
-restorer-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)
+
+ifeq ($(ARCH),x86)
+ NATIVE_CFLAGS += -DCONFIG_X86_64
+ COMPAT_CFLAGS += -fno-pic -m32 -DCONFIG_X86_32
+ COMPAT_LDFLAGS += -m elf_i386
endif
+CFLAGS_restorer.o += $(NATIVE_CFLAGS)
+# $1 - object name
+define obj-export-native-flags
+ CFLAGS_$(notdir $(1)) := $(NATIVE_CFLAGS)
+endef
+# $1 - object name
+define obj-export-compat-flags
+ CFLAGS_$(notdir $(1)) := $(COMPAT_CFLAGS)
+ LDFLAGS_$(notdir $(1)) := $(COMPAT_LDFLAGS)
+endef
+
+$(eval $(call map,obj-export-native-flags,$(native-obj-y) native))
+$(eval $(call map,obj-export-compat-flags,$(compat-obj-y) compat))
+
ifeq ($(SRCARCH),arm)
ccflags-y += -marm
endif
@@ -37,45 +75,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 +151,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 +173,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/compat/parasite-compat.c b/criu/pie/compat/parasite-compat.c
new file mode 120000
index 000000000000..bc5cbac9d786
--- /dev/null
+++ b/criu/pie/compat/parasite-compat.c
@@ -0,0 +1 @@
+../parasite.c
\ No newline at end of file
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