[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