[CRIU] [PATCH 09/10] compel: Initial commit

Cyrill Gorcunov gorcunov at openvz.org
Tue Mar 22 12:15:35 PDT 2016


The compel component is a replacement for several aspects of CRIU
functionality: binary blobs generation for PIE parasite/restore code,
and a library for parasite code injection and execution (to be implemented).

Here we simply shuffle old piegen code around adding support for
flags fetching via compel executable directly.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 Makefile                                         |  11 +-
 Makefile.versions                                |   4 +
 compel/Makefile                                  |  33 +++++
 {criu/pie/piegen => compel/include}/piegen.h     |   1 +
 compel/include/uapi/libcompel.h                  |   4 +
 {criu/pie/piegen => compel/include}/uapi/types.h |   0
 compel/lib/compel.c                              |   0
 {criu/pie/piegen => compel/src}/elf-ppc64.c      |   0
 {criu/pie/piegen => compel/src}/elf-x86-32.c     |   0
 {criu/pie/piegen => compel/src}/elf-x86-64.c     |   0
 {criu/pie/piegen => compel/src}/elf.c            |   2 +-
 {criu/pie/piegen => compel/src}/main.c           | 178 ++++++++++++++++-------
 criu/Makefile                                    |  19 +--
 criu/pie/Makefile                                |  12 +-
 criu/pie/pie-relocs.c                            |   2 +-
 criu/pie/pie-relocs.h                            |   2 +-
 criu/pie/piegen/Makefile                         |  17 ---
 17 files changed, 188 insertions(+), 97 deletions(-)
 create mode 100644 compel/Makefile
 rename {criu/pie/piegen => compel/include}/piegen.h (98%)
 create mode 100644 compel/include/uapi/libcompel.h
 rename {criu/pie/piegen => compel/include}/uapi/types.h (100%)
 create mode 100644 compel/lib/compel.c
 rename {criu/pie/piegen => compel/src}/elf-ppc64.c (100%)
 rename {criu/pie/piegen => compel/src}/elf-x86-32.c (100%)
 rename {criu/pie/piegen => compel/src}/elf-x86-64.c (100%)
 rename {criu/pie/piegen => compel/src}/elf.c (99%)
 rename {criu/pie/piegen => compel/src}/main.c (57%)
 delete mode 100644 criu/pie/piegen/Makefile

diff --git a/Makefile b/Makefile
index 32fb75d6549d..24033e7c2c33 100644
--- a/Makefile
+++ b/Makefile
@@ -109,6 +109,10 @@ CFLAGS			+= $(WARNINGS) $(DEFINES)
 $(eval $(call gen-built-in,images))
 
 #
+# Compel get used by CRIU, build it earlier
+$(eval $(call gen-built-in,compel))
+
+#
 # CRIU building done in own directory
 # with slightly different rules so we
 # can't use nmk engine directly (we
@@ -116,9 +120,9 @@ $(eval $(call gen-built-in,images))
 #
 # But note that we're already included
 # the nmk so we can reuse it there.
-criu/%: images/built-in.o
+criu/%: images/built-in.o compel/compel
 	$(Q) $(MAKE) -C criu $@
-criu: images/built-in.o
+criu: images/built-in.o compel/compel
 	$(Q) $(MAKE) -C criu all
 .PHONY: criu
 
@@ -132,11 +136,12 @@ lib: criu
 	$(Q) $(MAKE) -C lib all
 .PHONY: lib
 
-all: criu lib
+all: compel criu lib
 .PHONY: all
 
 clean-built:
 	$(Q) $(MAKE) $(build)=images clean
+	$(Q) $(MAKE) $(build)=compel clean
 	$(Q) $(MAKE) -C criu clean
 	$(Q) $(MAKE) -C lib clean
 	$(Q) $(MAKE) -C Documentation clean
diff --git a/Makefile.versions b/Makefile.versions
index 1c66439bd805..6980320751c5 100644
--- a/Makefile.versions
+++ b/Makefile.versions
@@ -17,3 +17,7 @@ CRIU_SO_VERSION_MINOR	:= 0
 
 export CRIU_SO_VERSION_MAJOR CRIU_SO_VERSION_MINOR
 
+COMPEL_SO_VERSION_MAJOR	:= 1
+COMPEL_SO_VERSION_MINOR	:= 0
+
+export COMPEL_SO_VERSION_MAJOR COMPEL_SO_VERSION_MINOR
diff --git a/compel/Makefile b/compel/Makefile
new file mode 100644
index 000000000000..6bcb825f9e2c
--- /dev/null
+++ b/compel/Makefile
@@ -0,0 +1,33 @@
+include $(SRC_DIR)/Makefile.versions
+
+ccflags-y	+= -iquote criu/include
+ccflags-y	+= -iquote compel/include
+ccflags-y	+= -DCOMPEL_VERSION=\"$(COMPEL_SO_VERSION_MAJOR).$(COMPEL_SO_VERSION_MINOR)\"
+
+host-ccflags-y	+= $(ccflags-y)
+HOSTCFLAGS	+= $(WARNINGS) $(DEFINES)
+HOSTLDFLAGS	+= $(LDFLAGS)
+
+hostprogs-y	+= compel
+compel-objs	+= src/main.o
+
+ifneq ($(filter ia32 x86, $(ARCH)),)
+compel-objs	+= src/elf-x86-32.o
+compel-objs	+= src/elf-x86-64.o
+endif
+ifeq ($(SRCARCH),ppc64)
+compel-objs	+= src/elf-ppc64.o
+endif
+
+#
+# Compel library.
+lib-name	:= lib/compel.a
+lib-y		+= lib/compel.o
+
+COMPEL_SO	:= libcompel.so
+cflags-so	+= $(CFLAGS) -rdynamic -Wl,-soname,$(COMPEL_SO).$(COMPEL_SO_VERSION_MAJOR)
+$(obj)/$(COMPEL_SO): $(obj)/$(lib-name)
+	$(call msg-link, $@)
+	$(Q) $(CC) -shared $(cflags-so) -o $@ $^ $(ldflags-so) $(LDFLAGS)
+all-y += $(obj)/$(COMPEL_SO)
+cleanup-y += $(obj)/$(COMPEL_SO)
diff --git a/criu/pie/piegen/piegen.h b/compel/include/piegen.h
similarity index 98%
rename from criu/pie/piegen/piegen.h
rename to compel/include/piegen.h
index 8ac5b34b43c2..0c695c6a7b48 100644
--- a/criu/pie/piegen/piegen.h
+++ b/compel/include/piegen.h
@@ -7,6 +7,7 @@
 typedef struct {
 	char		*input_filename;
 	char		*output_filename;
+	char		*uapi_dir;
 	char		*stream_name;
 	char		*prefix_name;
 	char		*var_name;
diff --git a/compel/include/uapi/libcompel.h b/compel/include/uapi/libcompel.h
new file mode 100644
index 000000000000..6eae570937f0
--- /dev/null
+++ b/compel/include/uapi/libcompel.h
@@ -0,0 +1,4 @@
+#ifndef __LIBCOMPEL_H__
+#define __LIBCOMPEL_H__
+
+#endif /* __LIBCOMPEL_H__ */
diff --git a/criu/pie/piegen/uapi/types.h b/compel/include/uapi/types.h
similarity index 100%
rename from criu/pie/piegen/uapi/types.h
rename to compel/include/uapi/types.h
diff --git a/compel/lib/compel.c b/compel/lib/compel.c
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/criu/pie/piegen/elf-ppc64.c b/compel/src/elf-ppc64.c
similarity index 100%
rename from criu/pie/piegen/elf-ppc64.c
rename to compel/src/elf-ppc64.c
diff --git a/criu/pie/piegen/elf-x86-32.c b/compel/src/elf-x86-32.c
similarity index 100%
rename from criu/pie/piegen/elf-x86-32.c
rename to compel/src/elf-x86-32.c
diff --git a/criu/pie/piegen/elf-x86-64.c b/compel/src/elf-x86-64.c
similarity index 100%
rename from criu/pie/piegen/elf-x86-64.c
rename to compel/src/elf-x86-64.c
diff --git a/criu/pie/piegen/elf.c b/compel/src/elf.c
similarity index 99%
rename from criu/pie/piegen/elf.c
rename to compel/src/elf.c
index c6b97257ba61..00f8c4926276 100644
--- a/criu/pie/piegen/elf.c
+++ b/compel/src/elf.c
@@ -158,7 +158,7 @@ int handle_elf(void *mem, size_t size)
 	}
 
 	pr_out("/* Autogenerated from %s */\n", opts.input_filename);
-	pr_out("#include \"piegen/uapi/types.h\"\n");
+	pr_out("#include \"%s/types.h\"\n", opts.uapi_dir);
 
 	for (i = 0; i < symtab_hdr->sh_size / symtab_hdr->sh_entsize; i++) {
 		Sym_t *sym = &symbols[i];
diff --git a/criu/pie/piegen/main.c b/compel/src/main.c
similarity index 57%
rename from criu/pie/piegen/main.c
rename to compel/src/main.c
index c89b1575fb61..5f1f058a2a67 100644
--- a/criu/pie/piegen/main.c
+++ b/compel/src/main.c
@@ -1,10 +1,11 @@
 #include <stdio.h>
 #include <stdlib.h>
-#include <stdbool.h>
+#include <fcntl.h>
 #include <unistd.h>
-#include <stdint.h>
-#include <getopt.h>
+#include <ctype.h>
 #include <string.h>
+#include <errno.h>
+#include <getopt.h>
 
 #include <fcntl.h>
 #include <elf.h>
@@ -14,19 +15,23 @@
 #include <sys/mman.h>
 
 #include "compiler.h"
-#include "config.h"
 #include "piegen.h"
 
+FILE *fout;
+
+static const char compel_cflags_pie[] = "-fpie -Wa,--noexecstack -fno-stack-protector";
+static const char compel_cflags_nopic[] = "-fno-pic -Wa,--noexecstack -fno-stack-protector";
+static const char compel_ldflags[] = "-r";
+
 piegen_opt_t opts = {
 	.input_filename		= NULL,
 	.stream_name		= "stream",
 	.prefix_name		= "__",
 	.var_name		= "elf_relocs",
 	.nrgotpcrel_name	= "nr_gotpcrel",
+	.uapi_dir		= "compel/uapi",
 };
 
-FILE *fout;
-
 static int handle_elf(void *mem, size_t size)
 {
 #if defined(CONFIG_X86_32) || defined(CONFIG_X86_64)
@@ -65,43 +70,120 @@ static int handle_elf(void *mem, size_t size)
 	return -1;
 }
 
-/*
- * That;s the tool to generate patches object files.
- */
-int main(int argc, char *argv[])
+static int piegen(void)
 {
 	struct stat st;
-	int opt, idx;
 	void *mem;
 	int fd;
 
-	static const char short_opts[] = "f:o:s:p:v:r:h";
+	fd = open(opts.input_filename, O_RDONLY);
+	if (fd < 0) {
+		pr_perror("Can't open file %s", opts.input_filename);
+		goto err;
+	}
+
+	if (fstat(fd, &st)) {
+		pr_perror("Can't stat file %s", opts.input_filename);
+		goto err;
+	}
+
+	fout = fopen(opts.output_filename, "w");
+	if (fout == NULL) {
+		pr_perror("Can't open %s", opts.output_filename);
+		goto err;
+	}
+
+	mem = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FILE, fd, 0);
+	if (mem == MAP_FAILED) {
+		pr_perror("Can't mmap file %s", opts.input_filename);
+		goto err;
+	}
+
+	if (handle_elf(mem, st.st_size)) {
+		fclose(fout);
+		unlink(opts.output_filename);
+		goto err;
+	}
+
+err:
+	fclose(fout);
+	printf("%s generated successfully.\n", opts.output_filename);
+	return 0;
+}
+
+int main(int argc, char *argv[])
+{
+	const char *current_cflags = NULL;
+	int opt, idx, i;
+	char *action;
+
+	typedef struct {
+		const char	*arch;
+		const char	*cflags;
+	} compel_cflags_t;
+
+	static const compel_cflags_t compel_cflags[] = {
+		{
+			.arch	= "x86",
+			.cflags	= compel_cflags_pie,
+		}, {
+			.arch	= "ia32",
+			.cflags	= compel_cflags_nopic,
+		}, {
+			.arch	= "aarch64",
+			.cflags	= compel_cflags_pie,
+		}, {
+			.arch	= "arm",
+			.cflags	= compel_cflags_pie,
+		}, {
+			.arch	= "ppc64",
+			.cflags	= compel_cflags_pie,
+		},
+	};
+
+	const char short_opts[] = "f:o:s:p:v:r:a:u:Vh";
 	static struct option long_opts[] = {
-		{ "file",	required_argument,	0, 'f' },
-		{ "output",	required_argument,	0, 'o' },
-		{ "stream",	required_argument,	0, 's' },
-		{ "sym-prefix",	required_argument,	0, 'p' },
-		{ "variable",	required_argument,	0, 'v' },
-		{ "pcrelocs",	required_argument,	0, 'r' },
-		{ "help",	required_argument,	0, 'h' },
+		{ "arch",		required_argument,	0, 'a' },
+		{ "file",		required_argument,	0, 'f' },
+		{ "output",		required_argument,	0, 'o' },
+		{ "stream",		required_argument,	0, 's' },
+		{ "uapi-dir",		required_argument,	0, 'u' },
+		{ "sym-prefix",		required_argument,	0, 'p' },
+		{ "variable",		required_argument,	0, 'v' },
+		{ "pcrelocs",		required_argument,	0, 'r' },
+		{ "version",		no_argument,		0, 'V' },
+		{ "help",		no_argument,		0, 'h' },
 		{ },
 	};
 
-	if (argc < 3)
-		goto usage;
-
 	while (1) {
 		idx = -1;
 		opt = getopt_long(argc, argv, short_opts, long_opts, &idx);
 		if (opt == -1)
 			break;
+
 		switch (opt) {
+		case 'a':
+			for (i = 0; i < ARRAY_SIZE(compel_cflags); i++) {
+				if (!strcmp(optarg, compel_cflags[i].arch)) {
+					current_cflags = compel_cflags[i].cflags;
+					break;
+				}
+
+			}
+
+			if (!current_cflags)
+				goto usage;
+			break;
 		case 'f':
 			opts.input_filename = optarg;
 			break;
 		case 'o':
 			opts.output_filename = optarg;
 			break;
+		case 'u':
+			opts.uapi_dir = optarg;
+			break;
 		case 's':
 			opts.stream_name = optarg;
 			break;
@@ -114,48 +196,44 @@ int main(int argc, char *argv[])
 		case 'r':
 			opts.nrgotpcrel_name = optarg;
 			break;
+		case 'V':
+			printf("version %s\n", COMPEL_VERSION);
+			return 0;
 		case 'h':
-		default:
 			goto usage;
+		default:
+			break;
 		}
 	}
 
-	if (!opts.input_filename)
+	if (optind >= argc)
 		goto usage;
 
-	fd = open(opts.input_filename, O_RDONLY);
-	if (fd < 0) {
-		pr_perror("Can't open file %s", opts.input_filename);
-		goto err;
-	}
+	action = argv[optind++];
 
-	if (fstat(fd, &st)) {
-		pr_perror("Can't stat file %s", opts.input_filename);
-		goto err;
+	if (!strcmp(action, "cflags")) {
+		if (!current_cflags)
+			goto usage;
+		printf("%s", current_cflags);
+		return 0;
 	}
 
-	fout = fopen(opts.output_filename, "w");
-	if (fout == NULL) {
-		pr_perror("Can't open %s", opts.output_filename);
-		goto err;
+	if (!strcmp(action, "ldflags")) {
+		printf("%s", compel_ldflags);
+		return 0;
 	}
 
-	mem = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FILE, fd, 0);
-	if (mem == MAP_FAILED) {
-		pr_perror("Can't mmap file %s", opts.input_filename);
-		goto err;
-	}
+	if (!strcmp(action, "piegen")) {
+		if (!opts.input_filename)
+			goto usage;
 
-	if (handle_elf(mem, st.st_size)) {
-		fclose(fout);
-		unlink(opts.output_filename);
-		goto err;
+		return piegen();
 	}
-	fclose(fout);
-	printf("%s generated successfully.\n", opts.output_filename);
-	return 0;
+
 usage:
-	fprintf(stderr, "Usage: %s -f filename\n", argv[0]);
-err:
+	printf("Usage:\n");
+	printf("  compel --arch=(x86|ia32|aarch64|arm|ppc64) cflags\n");
+	printf("  compel --arch=(x86|ia32|aarch64|arm|ppc64) ldflags\n");
+	printf("  compel -f filename piegen\n");
 	return 1;
 }
diff --git a/criu/Makefile b/criu/Makefile
index 25d75dfd7d3e..4a9464d4dcaf 100644
--- a/criu/Makefile
+++ b/criu/Makefile
@@ -142,33 +142,22 @@ arch_lib: syscalls_lib
 .PHONY: arch_lib
 
 #
-# piegen tool needed for PIE code.
-ifeq ($(piegen-y),y)
-piegen-bin		:= pie/piegen/piegen
-
-pie/piegen/%: config
-	$(Q) CC=$(HOSTCC) LD=$(HOSTLD) CFLAGS="$(ccflags-y) $(HOSTCFLAGS) $(WARNINGS) $(DEFINES)" $(MAKE) $(build)=pie/piegen $@
-$(piegen-bin): pie/piegen/built-in.o
-	$(call msg-link, $@)
-	$(Q) $(HOSTCC) $(HOSTCFLAGS) $^ $(LDFLAGS) -o $@
-endif
-
-#
 # PIE library code.
 pie/lib.a: arch_lib
 	$(Q) $(MAKE) $(call build-as,Makefile.library,pie) all
 
 #
 # PIE code blobs themseves.
-pie: $(piegen-bin) pie/lib.a
+pie: pie/lib.a
 	$(Q) $(MAKE) $(build)=pie all
 .PHONY: pie
 
 #
 # CRIU executable
-PROGRAM-BUILTINS	+= ../images/built-in.o
+PROGRAM-BUILTINS	+= $(SRC_DIR)/images/built-in.o
 PROGRAM-BUILTINS	+= built-in.o
 PROGRAM-BUILTINS	+= pie/lib.a
+PROGRAM-BUILTINS	+= $(SRC_DIR)/compel/lib/compel.a
 
 built-in.o: pie
 	$(Q) $(MAKE) $(call build-as,Makefile.crtools,.) all
@@ -183,11 +172,9 @@ clean:
 	$(Q) $(MAKE) $(call build-as,Makefile.syscalls,$(ARCH_DIR)) $@
 	$(Q) $(MAKE) $(call build-as,Makefile.library,pie) $@
 	$(Q) $(MAKE) $(call build-as,Makefile.crtools,.) $@
-	$(Q) $(MAKE) $(build)=pie/piegen $@
 	$(Q) $(MAKE) $(build)=pie $@
 	$(Q) $(RM) ./*.{gcda,gcno,gcov}
 	$(Q) $(RM) ./pie/*.{gcda,gcno,gcov}
-	$(Q) $(RM) ./pie/piegen/*.{gcda,gcno,gcov}
 	$(Q) $(RM) -r ./gcov
 	$(Q) $(RM) $(VERSION_HEADER)
 	$(Q) $(RM) $(CONFIG_HEADER)
diff --git a/criu/pie/Makefile b/criu/pie/Makefile
index b455a02a6331..04836d999536 100644
--- a/criu/pie/Makefile
+++ b/criu/pie/Makefile
@@ -15,13 +15,9 @@ restorer-obj-e		+= ./$(ARCH_DIR)/syscalls.built-in.o
 # applications, which is not the target of the
 # project.
 #
-CFLAGS			:= $(filter-out -pg $(CFLAGS-GCOV),$(CFLAGS)) -iquote pie/piegen -iquote arch/$(ARCH)/include -iquote $(SRC_DIR) -iquote $(SRC_DIR)/criu/include
+CFLAGS			:= $(filter-out -pg $(CFLAGS-GCOV),$(CFLAGS)) -iquote $(SRC_DIR)/compel/include -iquote arch/$(ARCH)/include -iquote $(SRC_DIR) -iquote $(SRC_DIR)/criu/include
 
-ifneq ($(filter-out ia32,$(ARCH)),)
-        ccflags-y	+= -DCR_NOGLIBC -fpie -Wa,--noexecstack -fno-stack-protector
-else
-        ccflags-y	+= -DCR_NOGLIBC -fno-pic -Wa,--noexecstack -fno-stack-protector
-endif
+ccflags-y		+= -DCR_NOGLIBC $(shell $(SRC_DIR)/compel/compel --arch=$(ARCH) cflags)
 
 ifeq ($(SRCARCH),arm)
         ccflags-y	+= -marm
@@ -68,9 +64,9 @@ $(obj)/%.built-in.bin.o: $(obj)/%.built-in.o $(obj)/lib.a $(obj)/$(PIELDS)
 	$(call msg-gen, $@)
 	$(Q) $(LD) -r -T $(obj)/$(PIELDS) -o $@ $< $(obj)/lib.a
 
-$(obj)/%-blob.h: $(obj)/%.built-in.bin.o $(obj)/$(PIELDS) pie/piegen
+$(obj)/%-blob.h: $(obj)/%.built-in.bin.o $(obj)/$(PIELDS) $(SRC_DIR)/compel/compel
 	$(call msg-gen, $@)
-	$(Q) pie/piegen/piegen -f $< -v $(call target-name,$@)_relocs -p $(call target-name,$@)_blob_offset__ -s $(call target-name,$@)_blob -o $@ $(piegen_stdout)
+	$(Q) $(SRC_DIR)/compel/compel piegen -f $< -v $(call target-name,$@)_relocs -p $(call target-name,$@)_blob_offset__ -s $(call target-name,$@)_blob -u $(SRC_DIR)/compel/include/uapi -o $@ $(piegen_stdout)
 
 else
 
diff --git a/criu/pie/pie-relocs.c b/criu/pie/pie-relocs.c
index 7e825b2320d9..72665e39621f 100644
--- a/criu/pie/pie-relocs.c
+++ b/criu/pie/pie-relocs.c
@@ -15,7 +15,7 @@
 #include "asm-generic/int.h"
 
 #include "compiler.h"
-#include "piegen/uapi/types.h"
+#include "compel/include/uapi/types.h"
 #include "bug.h"
 
 __maybe_unused void elf_relocs_apply(void *mem, void *vbase, size_t size, elf_reloc_t *elf_relocs, size_t nr_relocs)
diff --git a/criu/pie/pie-relocs.h b/criu/pie/pie-relocs.h
index 1449ca630908..bd313f8bfcba 100644
--- a/criu/pie/pie-relocs.h
+++ b/criu/pie/pie-relocs.h
@@ -1,7 +1,7 @@
 #ifndef __PIE_RELOCS_H__
 #define __PIE_RELOCS_H__
 
-#include "piegen/uapi/types.h"
+#include "compel/include/uapi/types.h"
 
 #include "compiler.h"
 #include "config.h"
diff --git a/criu/pie/piegen/Makefile b/criu/pie/piegen/Makefile
deleted file mode 100644
index 5c3d68b84817..000000000000
--- a/criu/pie/piegen/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-CFLAGS += -iquote pie/piegen
-
-obj-y += main.o
-ifneq ($(filter ia32 x86, $(ARCH)),)
-obj-y += elf-x86-32.o
-obj-y += elf-x86-64.o
-endif
-ifeq ($(SRCARCH),ppc64)
-obj-y += elf-ppc64.o
-endif
-
-cleanup-y += $(obj)/piegen
-cleanup-y += $(obj)/*.o
-
-ifneq ($(MAKECMDGOALS),clean)
-incdeps := y
-endif
-- 
2.5.0



More information about the CRIU mailing list