[CRIU] [PATCH 11/38] compel: Implement pack action

Cyrill Gorcunov gorcunov at openvz.org
Tue Oct 11 09:04:01 PDT 2016


Since it requires loggin we use simple log
engine as well, which forces to drop old
logging from piegen mode.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 compel/Makefile                          |  3 ++
 compel/arch/aarch64/src/lib/handle-elf.c |  1 +
 compel/arch/arm/src/lib/handle-elf.c     |  1 +
 compel/arch/ppc64/src/lib/handle-elf.c   |  1 +
 compel/arch/x86/src/lib/handle-elf.c     |  1 +
 compel/include/piegen.h                  | 23 ---------
 compel/include/uapi/compel.h             | 10 ++--
 compel/src/lib/handle-elf.c              |  1 +
 compel/src/lib/log-host.c                |  1 +
 compel/src/lib/pack-host.c               |  1 +
 compel/src/lib/pack.c                    | 81 ++++++++++++++++++++++++++++++++
 compel/src/main.c                        | 28 +++++++++--
 12 files changed, 123 insertions(+), 29 deletions(-)
 create mode 120000 compel/src/lib/log-host.c
 create mode 120000 compel/src/lib/pack-host.c
 create mode 100644 compel/src/lib/pack.c

diff --git a/compel/Makefile b/compel/Makefile
index b55b9a5b3f6f..d9e75ffd5e34 100644
--- a/compel/Makefile
+++ b/compel/Makefile
@@ -17,6 +17,9 @@ host-lib-y		+= src/lib/handle-elf.o
 
 lib-y			+= src/lib/argv.o
 lib-y			+= src/lib/log.o
+host-lib-y		+= src/lib/log.o
+lib-y			+= src/lib/pack.o
+host-lib-y		+= src/lib/pack.o
 
 ifeq ($(ARCH),x86)
 lib-y			+= src/lib/handle-elf-32.o
diff --git a/compel/arch/aarch64/src/lib/handle-elf.c b/compel/arch/aarch64/src/lib/handle-elf.c
index 633a382cc2da..1c3686c48466 100644
--- a/compel/arch/aarch64/src/lib/handle-elf.c
+++ b/compel/arch/aarch64/src/lib/handle-elf.c
@@ -4,6 +4,7 @@
 
 #include "handle-elf.h"
 #include "piegen.h"
+#include "log.h"
 
 static const unsigned char __maybe_unused
 elf_ident_64_le[EI_NIDENT] = {
diff --git a/compel/arch/arm/src/lib/handle-elf.c b/compel/arch/arm/src/lib/handle-elf.c
index e2df0f90ddf5..8abf8dad1d43 100644
--- a/compel/arch/arm/src/lib/handle-elf.c
+++ b/compel/arch/arm/src/lib/handle-elf.c
@@ -4,6 +4,7 @@
 
 #include "handle-elf.h"
 #include "piegen.h"
+#include "log.h"
 
 static const unsigned char __maybe_unused
 elf_ident_32[EI_NIDENT] = {
diff --git a/compel/arch/ppc64/src/lib/handle-elf.c b/compel/arch/ppc64/src/lib/handle-elf.c
index 6491f20850ad..3d4020f597d4 100644
--- a/compel/arch/ppc64/src/lib/handle-elf.c
+++ b/compel/arch/ppc64/src/lib/handle-elf.c
@@ -4,6 +4,7 @@
 
 #include "handle-elf.h"
 #include "piegen.h"
+#include "log.h"
 
 static const unsigned char __maybe_unused
 elf_ident_64_le[EI_NIDENT] = {
diff --git a/compel/arch/x86/src/lib/handle-elf.c b/compel/arch/x86/src/lib/handle-elf.c
index 7cfbaa1dd026..38e27abd3a8a 100644
--- a/compel/arch/x86/src/lib/handle-elf.c
+++ b/compel/arch/x86/src/lib/handle-elf.c
@@ -4,6 +4,7 @@
 
 #include "handle-elf.h"
 #include "piegen.h"
+#include "log.h"
 
 static const unsigned char __maybe_unused
 elf_ident_64_le[EI_NIDENT] = {
diff --git a/compel/include/piegen.h b/compel/include/piegen.h
index f1ed2e13d309..4ad4ec40539a 100644
--- a/compel/include/piegen.h
+++ b/compel/include/piegen.h
@@ -16,8 +16,6 @@ typedef struct {
 	char		*var_name;
 	char		*nrgotpcrel_name;
 	FILE		*fout;
-	FILE		*ferr;
-	FILE		*fdebug;
 } piegen_opt_t;
 
 extern piegen_opt_t opts;
@@ -28,27 +26,6 @@ do {										\
 		fprintf(opts.fout, fmt, ##__VA_ARGS__);				\
 } while (0)
 
-#define pr_debug(fmt, ...)							\
-do {										\
-	if (opts.fdebug)							\
-		fprintf(opts.fdebug, "%s: "fmt,					\
-			opts.stream_name, ##__VA_ARGS__);			\
-} while (0)
-
-#define pr_err(fmt, ...)							\
-do {										\
-	if (opts.ferr)								\
-		fprintf(opts.ferr, "%s: Error (%s:%d): "fmt,			\
-			opts.stream_name, __FILE__, __LINE__, ##__VA_ARGS__);	\
-} while (0)
-
-#define pr_perror(fmt, ...)							\
-do {										\
-	if (opts.ferr)								\
-		fprintf(opts.ferr, "%s: Error (%s:%d): "fmt ": %m\n",		\
-			opts.stream_name, __FILE__, __LINE__, ##__VA_ARGS__);	\
-} while (0)
-
 extern int handle_binary(void *mem, size_t size);
 
 #endif /* COMPEL_PIEGEN_H__ */
diff --git a/compel/include/uapi/compel.h b/compel/include/uapi/compel.h
index a39e696d7389..a12e8451284e 100644
--- a/compel/include/uapi/compel.h
+++ b/compel/include/uapi/compel.h
@@ -14,9 +14,13 @@ typedef struct {
 	long		value;
 } compel_reloc_t;
 
-extern int libcompel_pack_argv(void *blob, size_t blob_size,
-			       int argc, char **argv,
-			       void **arg_p, size_t *arg_size);
+/*
+ * Packing objects
+ */
+extern int libcompel_pack_objs(char **objs, size_t nobjs,
+			       const char *lib_path,
+			       char **libs, size_t nlibs,
+			       char *out);
 
 /*
  * Logging
diff --git a/compel/src/lib/handle-elf.c b/compel/src/lib/handle-elf.c
index b7e540ed78e0..87683aa7898a 100644
--- a/compel/src/lib/handle-elf.c
+++ b/compel/src/lib/handle-elf.c
@@ -17,6 +17,7 @@
 
 #include "handle-elf.h"
 #include "piegen.h"
+#include "log.h"
 
 /* Check if pointer is out-of-bound */
 static bool __ptr_oob(const uintptr_t ptr, const uintptr_t start, const size_t size)
diff --git a/compel/src/lib/log-host.c b/compel/src/lib/log-host.c
new file mode 120000
index 000000000000..918e3d32f6ad
--- /dev/null
+++ b/compel/src/lib/log-host.c
@@ -0,0 +1 @@
+log.c
\ No newline at end of file
diff --git a/compel/src/lib/pack-host.c b/compel/src/lib/pack-host.c
new file mode 120000
index 000000000000..e2900df18bd9
--- /dev/null
+++ b/compel/src/lib/pack-host.c
@@ -0,0 +1 @@
+pack.c
\ No newline at end of file
diff --git a/compel/src/lib/pack.c b/compel/src/lib/pack.c
new file mode 100644
index 000000000000..2844dddd971c
--- /dev/null
+++ b/compel/src/lib/pack.c
@@ -0,0 +1,81 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <linux/limits.h>
+
+#include "uapi/compel.h"
+
+#include "log.h"
+
+#define COMPEL_DEFAULT_LIB_DIR	"/usr/share/compel"
+#define COMPEL_DEFAULT_PACK_OUT	"a.compel.o"
+
+#define COMPEL_LDS		"pack.lds.S"
+#define COMPEL_STD		"std.compel.o"
+
+int libcompel_pack_objs(char **objs, size_t nobjs,
+			const char *lib_path,
+			char **libs, size_t nlibs,
+			char *out)
+{
+	char command[1024] = { 0 };
+	char data[1024] = { 0 };
+	int ret = -1, pos, i;
+	FILE *f;
+
+	/*
+	 * Figure out where the scripts we need are sitting.
+	 */
+	if (!lib_path) {
+		char *prefix = getenv("COMPEL_LIB_DIR");
+		char path[PATH_MAX];
+		if (!prefix)
+			prefix = COMPEL_DEFAULT_LIB_DIR;
+		snprintf(path, sizeof(path), "%s/%s", prefix, COMPEL_LDS);
+		if (access(path, R_OK)) {
+			snprintf(path, sizeof(path), "%s/%s", prefix, COMPEL_STD);
+			if (!access(path, R_OK)) {
+				pr_err("Can't access %s file\n", path);
+				goto err_no_res;
+			}
+			lib_path = prefix;
+		} else {
+			pr_err("Can't access %s file\n", path);
+			goto err_no_res;
+		}
+	}
+
+	pos = snprintf(command, sizeof(command),
+		       "ld -r -T %s/" COMPEL_LDS " -o %s %s/" COMPEL_STD,
+		       lib_path, out ? : COMPEL_DEFAULT_PACK_OUT, lib_path);
+
+	for (i = 0; pos < sizeof(command) - 1 && i < nobjs; i++) {
+		pos += snprintf(&command[pos], sizeof(command) - pos - 1,
+				" %s", objs[i]);
+	}
+
+	for (i = 0; pos < sizeof(command) - 1 && i < nlibs; i++) {
+		pos += snprintf(&command[pos], sizeof(command) - pos - 1,
+				" %s/%s.compel.o", lib_path, libs[i]);
+	}
+
+	pr_debug("pack as: `%s'\n", command);
+
+	f = popen(command, "r");
+	if (f) {
+		fgets(data, sizeof(data), f);
+		ret = data[0] == '\0' ? 0 : 1;
+		pclose(f);
+//		if (!ret)
+//			ret = libcompel_verify_packed(out ? : COMPEL_DEFAULT_PACK_OUT);
+	} else
+		pr_perror("Can't run pack");
+	if (ret)
+		pr_err("Pack failed\n");
+	return ret;
+
+err_no_res:
+	pr_err("Can't find resource files needed for `pack' action\n");
+	return -1;
+}
diff --git a/compel/src/main.c b/compel/src/main.c
index ca191c768363..340dd699d46f 100644
--- a/compel/src/main.c
+++ b/compel/src/main.c
@@ -12,7 +12,10 @@
 #include <sys/stat.h>
 #include <sys/mman.h>
 
+#include "uapi/compel.h"
+
 #include "version.h"
+#include "xmalloc.h"
 #include "piegen.h"
 
 static const char compel_cflags_pie[] =
@@ -88,8 +91,9 @@ int main(int argc, char *argv[])
 	int opt, idx, i;
 	char *action;
 
-	opts.fdebug = stdout;
-	opts.ferr = stderr;
+	char *libdir = NULL;
+	size_t nlibs = 0;
+	char *libs[512];
 
 	typedef struct {
 		const char	*arch;
@@ -115,7 +119,7 @@ int main(int argc, char *argv[])
 		},
 	};
 
-	static const char short_opts[] = "a:f:o:s:p:v:r:u:h";
+	static const char short_opts[] = "a:f:o:s:p:v:r:u:hl:L:";
 	static struct option long_opts[] = {
 		{ "arch",	required_argument,	0, 'a' },
 		{ "file",	required_argument,	0, 'f' },
@@ -126,6 +130,8 @@ int main(int argc, char *argv[])
 		{ "variable",	required_argument,	0, 'v' },
 		{ "pcrelocs",	required_argument,	0, 'r' },
 		{ "help",	required_argument,	0, 'h' },
+		{ "library",	required_argument,	0, 'l' },
+		{ "library-path",required_argument,	0, 'L' },
 		{ },
 	};
 
@@ -172,6 +178,16 @@ int main(int argc, char *argv[])
 			break;
 		case 'h':
 			goto usage;
+		case 'L':
+			libdir = optarg;
+			break;
+		case 'l':
+			if (nlibs >= ARRAY_SIZE(libs)) {
+				pr_err("Too many libraries specified, max %d\n",
+				       (int)ARRAY_SIZE(libs));
+				exit(1);
+			}
+			libs[nlibs++] = optarg;
 		default:
 			break;
 		}
@@ -200,6 +216,12 @@ int main(int argc, char *argv[])
 		return piegen();
 	}
 
+	if (!strcmp(action, "pack")) {
+		return libcompel_pack_objs(argv + optind, argc - optind,
+					   libdir, libs, nlibs,
+					   opts.output_filename);
+	}
+
 usage:
 	printf("Usage:\n");
 	printf("  compel --arch=(x86|ia32|aarch64|arm|ppc64) cflags\n");
-- 
2.7.4



More information about the CRIU mailing list