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

Cyrill Gorcunov gorcunov at openvz.org
Tue Mar 22 12:09:38 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 +++
 compel/include/piegen.h         |  36 +++
 compel/include/uapi/libcompel.h |   4 +
 compel/include/uapi/types.h     |  15 ++
 compel/lib/compel.c             |   0
 compel/src/elf-ppc64.c          |  16 ++
 compel/src/elf-x86-32.c         |  16 ++
 compel/src/elf-x86-64.c         |  16 ++
 compel/src/elf.c                | 512 ++++++++++++++++++++++++++++++++++++++++
 compel/src/main.c               | 239 +++++++++++++++++++
 criu/Makefile                   |  19 +-
 criu/pie/Makefile               |  12 +-
 criu/pie/pie-relocs.c           |   2 +-
 criu/pie/pie-relocs.h           |   2 +-
 criu/pie/piegen/Makefile        |  17 --
 criu/pie/piegen/elf-ppc64.c     |  16 --
 criu/pie/piegen/elf-x86-32.c    |  16 --
 criu/pie/piegen/elf-x86-64.c    |  16 --
 criu/pie/piegen/elf.c           | 512 ----------------------------------------
 criu/pie/piegen/main.c          | 161 -------------
 criu/pie/piegen/piegen.h        |  35 ---
 criu/pie/piegen/uapi/types.h    |  15 --
 24 files changed, 908 insertions(+), 817 deletions(-)
 create mode 100644 compel/Makefile
 create mode 100644 compel/include/piegen.h
 create mode 100644 compel/include/uapi/libcompel.h
 create mode 100644 compel/include/uapi/types.h
 create mode 100644 compel/lib/compel.c
 create mode 100644 compel/src/elf-ppc64.c
 create mode 100644 compel/src/elf-x86-32.c
 create mode 100644 compel/src/elf-x86-64.c
 create mode 100644 compel/src/elf.c
 create mode 100644 compel/src/main.c
 delete mode 100644 criu/pie/piegen/Makefile
 delete mode 100644 criu/pie/piegen/elf-ppc64.c
 delete mode 100644 criu/pie/piegen/elf-x86-32.c
 delete mode 100644 criu/pie/piegen/elf-x86-64.c
 delete mode 100644 criu/pie/piegen/elf.c
 delete mode 100644 criu/pie/piegen/main.c
 delete mode 100644 criu/pie/piegen/piegen.h
 delete mode 100644 criu/pie/piegen/uapi/types.h

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/compel/include/piegen.h b/compel/include/piegen.h
new file mode 100644
index 000000000000..0c695c6a7b48
--- /dev/null
+++ b/compel/include/piegen.h
@@ -0,0 +1,36 @@
+#ifndef __ELFTIL_H__
+#define __ELFTIL_H__
+
+#include <stdio.h>
+#include <unistd.h>
+
+typedef struct {
+	char		*input_filename;
+	char		*output_filename;
+	char		*uapi_dir;
+	char		*stream_name;
+	char		*prefix_name;
+	char		*var_name;
+	char		*nrgotpcrel_name;
+} piegen_opt_t;
+
+extern piegen_opt_t opts;
+extern FILE *fout;
+
+#if defined(CONFIG_X86_32) || defined(CONFIG_X86_64)
+extern int handle_elf_x86_32(void *mem, size_t size);
+extern int handle_elf_x86_64(void *mem, size_t size);
+#endif
+
+#if defined(CONFIG_PPC64)
+extern int handle_elf_ppc64(void *mem, size_t size);
+#endif
+
+#define pr_out(fmt, ...)	fprintf(fout, fmt, ##__VA_ARGS__)
+
+#define pr_debug(fmt, ...)	printf("%s: "fmt, opts.stream_name, ##__VA_ARGS__)
+
+#define pr_err(fmt, ...)	fprintf(stderr, "%s: Error (%s:%d): "fmt, opts.stream_name, __FILE__, __LINE__, ##__VA_ARGS__)
+#define pr_perror(fmt, ...)	fprintf(stderr, "%s: Error (%s:%d): "fmt ": %m\n", opts.stream_name, __FILE__, __LINE__, ##__VA_ARGS__)
+
+#endif /* __ELFTIL_H__ */
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/compel/include/uapi/types.h b/compel/include/uapi/types.h
new file mode 100644
index 000000000000..34696e8c6aa5
--- /dev/null
+++ b/compel/include/uapi/types.h
@@ -0,0 +1,15 @@
+#ifndef __PIEGEN_TYPES_H__
+#define __PIEGEN_TYPES_H__
+
+#define PIEGEN_TYPE_INT		(1u << 0)
+#define PIEGEN_TYPE_LONG	(1u << 1)
+#define PIEGEN_TYPE_GOTPCREL	(1u << 2)
+
+typedef struct {
+	unsigned int	offset;
+	unsigned int	type;
+	long		addend;
+	long		value;
+} elf_reloc_t;
+
+#endif /* __PIEGEN_TYPES_H__ */
diff --git a/compel/lib/compel.c b/compel/lib/compel.c
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/compel/src/elf-ppc64.c b/compel/src/elf-ppc64.c
new file mode 100644
index 000000000000..472725f9fe7c
--- /dev/null
+++ b/compel/src/elf-ppc64.c
@@ -0,0 +1,16 @@
+#define ELF_PPC64
+#define handle_elf	handle_elf_ppc64
+
+#define Ehdr_t		Elf64_Ehdr
+#define Shdr_t		Elf64_Shdr
+#define Sym_t		Elf64_Sym
+#define Rel_t		Elf64_Rel
+#define Rela_t		Elf64_Rela
+
+#define ELF_ST_TYPE	ELF64_ST_TYPE
+#define ELF_ST_BIND	ELF64_ST_BIND
+
+#define ELF_R_SYM	ELF64_R_SYM
+#define ELF_R_TYPE	ELF64_R_TYPE
+
+#include "elf.c"
diff --git a/compel/src/elf-x86-32.c b/compel/src/elf-x86-32.c
new file mode 100644
index 000000000000..413113ef396b
--- /dev/null
+++ b/compel/src/elf-x86-32.c
@@ -0,0 +1,16 @@
+#define ELF_X86_32
+#define handle_elf	handle_elf_x86_32
+
+#define Ehdr_t		Elf32_Ehdr
+#define Shdr_t		Elf32_Shdr
+#define Sym_t		Elf32_Sym
+#define Rel_t		Elf32_Rel
+#define Rela_t		Elf32_Rela
+
+#define ELF_ST_TYPE	ELF32_ST_TYPE
+#define ELF_ST_BIND	ELF32_ST_BIND
+
+#define ELF_R_SYM	ELF32_R_SYM
+#define ELF_R_TYPE	ELF32_R_TYPE
+
+#include "elf.c"
diff --git a/compel/src/elf-x86-64.c b/compel/src/elf-x86-64.c
new file mode 100644
index 000000000000..8ba26672bc82
--- /dev/null
+++ b/compel/src/elf-x86-64.c
@@ -0,0 +1,16 @@
+#define ELF_X86_64
+#define handle_elf	handle_elf_x86_64
+
+#define Ehdr_t		Elf64_Ehdr
+#define Shdr_t		Elf64_Shdr
+#define Sym_t		Elf64_Sym
+#define Rel_t		Elf64_Rel
+#define Rela_t		Elf64_Rela
+
+#define ELF_ST_TYPE	ELF64_ST_TYPE
+#define ELF_ST_BIND	ELF64_ST_BIND
+
+#define ELF_R_SYM	ELF64_R_SYM
+#define ELF_R_TYPE	ELF64_R_TYPE
+
+#include "elf.c"
diff --git a/compel/src/elf.c b/compel/src/elf.c
new file mode 100644
index 000000000000..00f8c4926276
--- /dev/null
+++ b/compel/src/elf.c
@@ -0,0 +1,512 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <fcntl.h>
+#include <elf.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include "asm-generic/int.h"
+
+#include "compiler.h"
+#include "piegen.h"
+
+static bool __ptr_oob(const void *ptr, const void *start, const size_t size)
+{
+	const void *end = (const void *)((const unsigned long)start + size);
+	return ptr > end || ptr < start;
+}
+
+static bool test_pointer(const void *ptr, const void *start, const size_t size,
+			 const char *name, const char *file, const int line)
+{
+	if (__ptr_oob(ptr, start, size)) {
+		pr_err("Corrupted pointer %p (%s) at %s:%d\n",
+		       ptr, name, file, line);
+		return true;
+	}
+	return false;
+}
+
+#define ptr_func_exit(__ptr)						\
+	do {								\
+		if (test_pointer((__ptr), mem, size, #__ptr,		\
+				 __FILE__, __LINE__)) {			\
+			free(sec_hdrs);					\
+			return -1;					\
+		}							\
+	} while (0)
+
+#ifdef ELF_PPC64
+static int do_relative_toc(long value, uint16_t *location,
+			   unsigned long mask, int complain_signed)
+{
+        if (complain_signed && (value + 0x8000 > 0xffff)) {
+		pr_err("TOC16 relocation overflows (%ld)\n", value);
+		return -1;
+        }
+
+	if ((~mask & 0xffff) & value) {
+		pr_err("bad TOC16 relocation (%ld) (0x%lx)\n", value, (~mask & 0xffff) & value);
+		return -1;
+	}
+
+	*location = (*location & ~mask) | (value & mask);
+	return 0;
+}
+#endif
+
+int handle_elf(void *mem, size_t size)
+{
+	const char *symstrings = NULL;
+	Shdr_t *symtab_hdr = NULL;
+	Sym_t *symbols = NULL;
+	Ehdr_t *hdr = mem;
+
+	Shdr_t *secstrings_hdr = NULL;
+	Shdr_t *strtab_hdr = NULL;
+	Shdr_t **sec_hdrs = NULL;
+	const char *secstrings;
+
+	size_t i, k, nr_gotpcrel = 0;
+#ifdef ELF_PPC64
+	s64 toc_offset = 0;
+#endif
+
+	pr_debug("Header\n");
+	pr_debug("------------\n");
+	pr_debug("\ttype 0x%x machine 0x%x version 0x%x\n",
+		 (unsigned)hdr->e_type, (unsigned)hdr->e_machine, (unsigned)hdr->e_version);
+
+#ifdef ELF_X86_64
+	if (hdr->e_type != ET_REL || hdr->e_machine != EM_X86_64 || hdr->e_version != EV_CURRENT) {
+		pr_err("Unsupported header detected\n");
+		goto err;
+	}
+#endif
+
+#ifdef ELF_X86_32
+	if (hdr->e_type != ET_REL || hdr->e_machine != EM_386 || hdr->e_version != EV_CURRENT) {
+		pr_err("Unsupported header detected\n");
+		goto err;
+	}
+#endif
+
+	sec_hdrs = malloc(sizeof(*sec_hdrs) * hdr->e_shnum);
+	if (!sec_hdrs) {
+		pr_err("No memory for section headers\n");
+		goto err;
+	}
+
+	secstrings_hdr = mem + hdr->e_shoff + hdr->e_shentsize * hdr->e_shstrndx;
+	secstrings = mem + secstrings_hdr->sh_offset;
+	ptr_func_exit(secstrings_hdr);
+	ptr_func_exit(secstrings);
+
+	pr_debug("Sections\n");
+	pr_debug("------------\n");
+	for (i = 0; i < hdr->e_shnum; i++) {
+		Shdr_t *sh = mem + hdr->e_shoff + hdr->e_shentsize * i;
+		ptr_func_exit(sh);
+
+		if (sh->sh_type == SHT_SYMTAB)
+			symtab_hdr = sh;
+
+		ptr_func_exit(&secstrings[sh->sh_name]);
+		pr_debug("\t index %-2zd type 0x%-2x name %s\n", i,
+			 (unsigned)sh->sh_type, &secstrings[sh->sh_name]);
+
+		sec_hdrs[i] = sh;
+
+#ifdef ELF_PPC64
+		if (!strcmp(&secstrings[sh->sh_name], ".toc")) {
+			toc_offset = sh->sh_addr + 0x8000;
+			pr_debug("\t\tTOC offset 0x%lx\n", toc_offset);
+		}
+#endif
+	}
+
+	if (!symtab_hdr) {
+		pr_err("No symbol table present\n");
+		goto err;
+	}
+
+	if (!symtab_hdr->sh_link || symtab_hdr->sh_link >= hdr->e_shnum) {
+		pr_err("Corrupted symtab header\n");
+		goto err;
+	}
+
+	pr_debug("Symbols\n");
+	pr_debug("------------\n");
+	strtab_hdr = sec_hdrs[symtab_hdr->sh_link];
+	ptr_func_exit(strtab_hdr);
+
+	symbols = mem + symtab_hdr->sh_offset;
+	ptr_func_exit(symbols);
+	symstrings = mem + strtab_hdr->sh_offset;
+	ptr_func_exit(symstrings);
+
+	if (sizeof(*symbols) != symtab_hdr->sh_entsize) {
+		pr_err("Symbol table align differ\n");
+		goto err;
+	}
+
+	pr_out("/* Autogenerated from %s */\n", opts.input_filename);
+	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];
+		const char *name;
+		Shdr_t *sh_src;
+
+		ptr_func_exit(sym);
+		name = &symstrings[sym->st_name];
+		ptr_func_exit(name);
+
+		if (*name) {
+			pr_debug("\ttype 0x%-2x bind 0x%-2x shndx 0x%-4x value 0x%-2lx name %s\n",
+				 (unsigned)ELF_ST_TYPE(sym->st_info), (unsigned)ELF_ST_BIND(sym->st_info),
+				 (unsigned)sym->st_shndx, (unsigned long)sym->st_value, name);
+#ifdef ELF_PPC64
+			if (!sym->st_value && !strncmp(name, ".TOC.", 6)) {
+				if (!toc_offset) {
+					pr_err("No TOC pointer\n");
+					goto err;
+				}
+				sym->st_value = toc_offset;
+				continue;
+			}
+#endif
+			if (strncmp(name, "__export", 8))
+				continue;
+			if ((sym->st_shndx && sym->st_shndx < hdr->e_shnum) || sym->st_shndx == SHN_ABS) {
+				if (sym->st_shndx == SHN_ABS) {
+					sh_src = NULL;
+				} else {
+					sh_src = sec_hdrs[sym->st_shndx];
+					ptr_func_exit(sh_src);
+				}
+				pr_out("#define %s%s 0x%lx\n",
+				       opts.prefix_name, name,
+				       (unsigned long)(sym->st_value + (sh_src ? sh_src->sh_addr : 0)));
+			}
+		}
+	}
+
+	pr_out("static __maybe_unused elf_reloc_t %s[] = {\n", opts.var_name);
+
+	pr_debug("Relocations\n");
+	pr_debug("------------\n");
+	for (i = 0; i < hdr->e_shnum; i++) {
+		Shdr_t *sh = sec_hdrs[i];
+		Shdr_t *sh_rel;
+
+		if (sh->sh_type != SHT_REL && sh->sh_type != SHT_RELA)
+			continue;
+
+		sh_rel = sec_hdrs[sh->sh_info];
+		ptr_func_exit(sh_rel);
+
+		pr_debug("\tsection %2zd type 0x%-2x link 0x%-2x info 0x%-2x name %s\n", i,
+			 (unsigned)sh->sh_type, (unsigned)sh->sh_link,
+			 (unsigned)sh->sh_info, &secstrings[sh->sh_name]);
+
+		for (k = 0; k < sh->sh_size / sh->sh_entsize; k++) {
+			s64 __maybe_unused addend64, __maybe_unused value64;
+			s32 addend32, value32;
+			unsigned long place;
+			const char *name;
+			void *where;
+			Sym_t *sym;
+
+			union {
+				Rel_t rel;
+				Rela_t rela;
+			} *r = mem + sh->sh_offset + sh->sh_entsize * k;
+			ptr_func_exit(r);
+
+			sym = &symbols[ELF_R_SYM(r->rel.r_info)];
+			ptr_func_exit(sym);
+
+			name = &symstrings[sym->st_name];
+			ptr_func_exit(name);
+
+			where = mem + sh_rel->sh_offset + r->rel.r_offset;
+			ptr_func_exit(where);
+
+			pr_debug("\t\tr_offset 0x%-4lx r_info 0x%-4lx / sym 0x%-2lx type 0x%-2lx symsecoff 0x%-4lx\n",
+				 (unsigned long)r->rel.r_offset, (unsigned long)r->rel.r_info,
+				 (unsigned long)ELF_R_SYM(r->rel.r_info),
+				 (unsigned long)ELF_R_TYPE(r->rel.r_info),
+				 (unsigned long)sh_rel->sh_addr);
+
+			if (sym->st_shndx == SHN_UNDEF) {
+#ifdef ELF_PPC64
+				/* On PowerPC, TOC symbols appear to be
+				 * undefined but should be processed as well.
+				 * Their type is STT_NOTYPE, so report any
+				 * other one.
+				 */
+				if (ELF32_ST_TYPE(sym->st_info) != STT_NOTYPE
+				    || strncmp(name, ".TOC.", 6)) {
+					pr_err("Unexpected undefined symbol:%s\n", name);
+					goto err;
+				}
+#else
+				continue;
+#endif
+			}
+
+			if (sh->sh_type == SHT_REL) {
+				addend32 = *(s32 *)where;
+				addend64 = *(s64 *)where;
+			} else {
+				addend32 = (s32)r->rela.r_addend;
+				addend64 = (s64)r->rela.r_addend;
+			}
+
+			place = sh_rel->sh_addr + r->rel.r_offset;
+
+			pr_debug("\t\t\tvalue 0x%-8lx addend32 %-4d addend64 %-8ld place %-8lx symname %s\n",
+				 (unsigned long)sym->st_value, addend32, (long)addend64, (long)place, name);
+
+			if (sym->st_shndx == SHN_ABS) {
+				value32 = (s32)sym->st_value;
+				value64 = (s64)sym->st_value;
+			} else {
+				Shdr_t *sh_src;
+
+				if ((unsigned)sym->st_shndx > (unsigned)hdr->e_shnum) {
+					pr_err("Unexpected symbol section index %u/%u\n",
+					       (unsigned)sym->st_shndx, hdr->e_shnum);
+					goto err;
+				}
+				sh_src = sec_hdrs[sym->st_shndx];
+				ptr_func_exit(sh_src);
+
+				value32 = (s32)sh_src->sh_addr + (s32)sym->st_value;
+				value64 = (s64)sh_src->sh_addr + (s64)sym->st_value;
+			}
+
+#ifdef ELF_PPC64
+/* Snippet from the OpenPOWER ABI for Linux Supplement:
+ * The OpenPOWER ABI uses the three most-significant bits in the symbol
+ * st_other field specifies the number of instructions between a function's
+ * global entry point and local entry point. The global entry point is used
+ * when it is necessary to set up the TOC pointer (r2) for the function. The
+ * local entry point is used when r2 is known to already be valid for the
+ * function. A value of zero in these bits asserts that the function does
+ * not use r2.
+ * The st_other values have the following meanings:
+ * 0 and 1, the local and global entry points are the same.
+ * 2, the local entry point is at 1 instruction past the global entry point.
+ * 3, the local entry point is at 2 instructions past the global entry point.
+ * 4, the local entry point is at 4 instructions past the global entry point.
+ * 5, the local entry point is at 8 instructions past the global entry point.
+ * 6, the local entry point is at 16 instructions past the global entry point.
+ * 7, reserved.
+ *
+ * Here we are only handle the case '3' which is the most commonly seen.
+ */
+#define LOCAL_OFFSET(s)	((s->st_other >> 5) & 0x7)
+			if (LOCAL_OFFSET(sym)) {
+				if (LOCAL_OFFSET(sym) != 3) {
+					pr_err("Unexpected local offset value %d\n",
+					       LOCAL_OFFSET(sym));
+					goto err;
+				}
+				pr_debug("\t\t\tUsing local offset\n");
+				value64 += 8;
+				value32 += 8;
+			}
+#endif
+
+			switch (ELF_R_TYPE(r->rel.r_info)) {
+#ifdef ELF_PPC64
+			case R_PPC64_REL24:
+				/* Update PC relative offset, linker has not done this yet */
+				pr_debug("\t\t\tR_PPC64_REL24 at 0x%-4lx val 0x%lx\n",
+					 place, value64);
+				/* Convert value to relative */
+				value64 -= place;
+				if (value64 + 0x2000000 > 0x3ffffff || (value64 & 3) != 0) {
+					pr_err("REL24 %li out of range!\n", (long int)value64);
+					goto err;
+				}
+				/* Only replace bits 2 through 26 */
+				*(uint32_t *)where = (*(uint32_t *)where & ~0x03fffffc) |
+                                        (value64 & 0x03fffffc);
+				break;
+
+			case R_PPC64_ADDR32:
+				pr_debug("\t\t\tR_PPC64_ADDR32 at 0x%-4lx val 0x%x\n",
+					 place, (unsigned int)(value32 + addend32));
+				pr_out("	{ .offset = 0x%-8x, .type = PIEGEN_TYPE_INT, "
+				       " .addend = %-8d, .value = 0x%-16x, "
+				       "}, /* R_PPC64_ADDR32 */\n",
+				       (unsigned int) place,  addend32, value32);
+				break;
+
+			case R_PPC64_ADDR64:
+			case R_PPC64_REL64:
+				pr_debug("\t\t\tR_PPC64_ADDR64 at 0x%-4lx val 0x%lx\n",
+					 place, value64 + addend64);
+				pr_out("\t{ .offset = 0x%-8x, .type = PIEGEN_TYPE_LONG,"
+				       " .addend = %-8ld, .value = 0x%-16lx, "
+				       "}, /* R_PPC64_ADDR64 */\n",
+				       (unsigned int) place, (long)addend64, (long)value64);
+				break;
+
+			case R_PPC64_TOC16_HA:
+				pr_debug("\t\t\tR_PPC64_TOC16_HA at 0x%-4lx val 0x%lx\n",
+					 place, value64 + addend64 - toc_offset + 0x8000);
+				if (do_relative_toc((value64 + addend64 - toc_offset + 0x8000) >> 16,
+						    where, 0xffff, 1))
+					goto err;
+				break;
+
+			case R_PPC64_TOC16_LO:
+				pr_debug("\t\t\tR_PPC64_TOC16_LO at 0x%-4lx val 0x%lx\n",
+					 place, value64 + addend64 - toc_offset);
+				if (do_relative_toc(value64 + addend64 - toc_offset,
+						    where, 0xffff, 1))
+					goto err;
+				break;
+
+			case R_PPC64_TOC16_LO_DS:
+				pr_debug("\t\t\tR_PPC64_TOC16_LO_DS at 0x%-4lx val 0x%lx\n",
+					 place, value64 + addend64 - toc_offset);
+				if (do_relative_toc(value64 + addend64 - toc_offset,
+						    where, 0xfffc, 0))
+					goto err;
+				break;
+
+			case R_PPC64_REL16_HA:
+				value64 += addend64 - place;
+				pr_debug("\t\t\tR_PPC64_REL16_HA at 0x%-4lx val 0x%lx\n",
+					 place, value64);
+				/* check that we are dealing with the addis 2,12 instruction */
+				if (((*(uint32_t*)where) & 0xffff0000) != 0x3c4c0000) {
+					pr_err("Unexpected instruction for R_PPC64_REL16_HA\n");
+					goto err;
+				}
+				*(uint16_t *)where = ((value64 + 0x8000) >> 16) & 0xffff;
+				break;
+
+			case R_PPC64_REL16_LO:
+				value64 += addend64 - place;
+				pr_debug("\t\t\tR_PPC64_REL16_LO at 0x%-4lx val 0x%lx\n",
+					 place, value64);
+				/* check that we are dealing with the addi 2,2 instruction */
+				if (((*(uint32_t*)where) & 0xffff0000) != 0x38420000) {
+					pr_err("Unexpected instruction for R_PPC64_REL16_LO\n");
+					goto err;
+				}
+				*(uint16_t *)where = value64 & 0xffff;
+				break;
+
+#endif /* ELF_PPC64 */
+
+#ifdef ELF_X86_64
+			case R_X86_64_32: /* Symbol + Addend (4 bytes) */
+				pr_debug("\t\t\t\tR_X86_64_32       at 0x%-4lx val 0x%x\n", place, value32);
+				pr_out("	{ .offset = 0x%-8x, .type = PIEGEN_TYPE_INT, "
+				       ".addend = %-8d, .value = 0x%-16x, }, /* R_X86_64_32 */\n",
+				       (unsigned int)place, addend32, value32);
+				break;
+			case R_X86_64_64: /* Symbol + Addend (8 bytes) */
+				pr_debug("\t\t\t\tR_X86_64_64       at 0x%-4lx val 0x%lx\n", place, (long)value64);
+				pr_out("	{ .offset = 0x%-8x, .type = PIEGEN_TYPE_LONG, "
+				       ".addend = %-8ld, .value = 0x%-16lx, }, /* R_X86_64_64 */\n",
+				       (unsigned int)place, (long)addend64, (long)value64);
+				break;
+			case R_X86_64_PC32: /* Symbol + Addend - Place (4 bytes) */
+				pr_debug("\t\t\t\tR_X86_64_PC32     at 0x%-4lx val 0x%x\n", place, value32 + addend32 - (s32)place);
+				/*
+				 * R_X86_64_PC32 are relative, patch them inplace.
+				 */
+				*((s32 *)where) = value32 + addend32 - place;
+				break;
+			case R_X86_64_PLT32: /* ProcLinkage + Addend - Place (4 bytes) */
+				pr_debug("\t\t\t\tR_X86_64_PLT32    at 0x%-4lx val 0x%x\n", place, value32 + addend32 - (s32)place);
+				/*
+				 * R_X86_64_PLT32 are relative, patch them inplace.
+				 */
+				*((s32 *)where) = value32 + addend32 - place;
+				break;
+			case R_X86_64_GOTPCREL: /* SymbolOffsetInGot + GOT + Addend - Place  (4 bytes) */
+				pr_debug("\t\t\t\tR_X86_64_GOTPCREL at 0x%-4lx val 0x%x\n", place, value32);
+				pr_out("	{ .offset = 0x%-8x, .type = PIEGEN_TYPE_LONG | PIEGEN_TYPE_GOTPCREL, "
+				       ".addend = %-8d, .value = 0x%-16x, }, /* R_X86_64_GOTPCREL */\n",
+				       (unsigned int)place, addend32, value32);
+				nr_gotpcrel++;
+				break;
+#endif
+
+#ifdef ELF_X86_32
+			case R_386_32: /* Symbol + Addend */
+				pr_debug("\t\t\t\tR_386_32   at 0x%-4lx val 0x%x\n", place, value32 + addend32);
+				pr_out("	{ .offset = 0x%-8x, .type = PIEGEN_TYPE_INT, "
+				       ".addend = %-4d, .value = 0x%x, },\n",
+				       (unsigned int)place, addend32, value32);
+				break;
+			case R_386_PC32: /* Symbol + Addend - Place */
+				pr_debug("\t\t\t\tR_386_PC32 at 0x%-4lx val 0x%x\n", place, value32 + addend32 - (s32)place);
+				/*
+				 * R_386_PC32 are relative, patch them inplace.
+				 */
+				*((s32 *)where) = value32 + addend32 - place;
+				break;
+#endif
+
+			default:
+				pr_err("Unsupported relocation\n");
+				goto err;
+			}
+		}
+	}
+	pr_out("};\n");
+	pr_out("static __maybe_unused size_t %s = %zd;\n", opts.nrgotpcrel_name, nr_gotpcrel);
+
+	pr_out("static __maybe_unused const char %s[] = {\n\t", opts.stream_name);
+
+	for (i=0, k=0; i < hdr->e_shnum; i++) {
+		Shdr_t *sh = sec_hdrs[i];
+		unsigned char *shdata;
+		size_t j;
+
+		if (!(sh->sh_flags & SHF_ALLOC) || !sh->sh_size)
+			continue;
+
+		shdata =  mem + sh->sh_offset;
+		pr_debug("Copying section '%s'\n" \
+			 "\tstart:0x%lx (gap:0x%lx) size:0x%lx\n",
+			 &secstrings[sh->sh_name], (unsigned long) sh->sh_addr,
+			 (unsigned long)(sh->sh_addr - k), (unsigned long) sh->sh_size);
+
+		/* write 0 in the gap between the 2 sections */
+		for (;k < sh->sh_addr; k++) {
+			if (k && (k % 8) == 0)
+				pr_out("\n\t");
+			pr_out("0x00,");
+		}
+
+		for (j=0; j < sh->sh_size; j++, k++) {
+			if (k && (k % 8) == 0)
+				pr_out("\n\t");
+			pr_out("0x%02x,", shdata[j]);
+		}
+	}
+	pr_out("};\n");
+	free(sec_hdrs);
+	return 0;
+err:
+	free(sec_hdrs);
+	return -1;
+}
diff --git a/compel/src/main.c b/compel/src/main.c
new file mode 100644
index 000000000000..5f1f058a2a67
--- /dev/null
+++ b/compel/src/main.c
@@ -0,0 +1,239 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+
+#include <fcntl.h>
+#include <elf.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include "compiler.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",
+};
+
+static int handle_elf(void *mem, size_t size)
+{
+#if defined(CONFIG_X86_32) || defined(CONFIG_X86_64)
+	unsigned char elf_ident_x86_32[EI_NIDENT] = {
+		0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	};
+
+	unsigned char elf_ident_x86_64[EI_NIDENT] = {
+		0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	};
+
+	if (memcmp(mem, elf_ident_x86_32, sizeof(elf_ident_x86_32)) == 0)
+		return handle_elf_x86_32(mem, size);
+	else if (memcmp(mem, elf_ident_x86_64, sizeof(elf_ident_x86_64)) == 0)
+		return handle_elf_x86_64(mem, size);
+#endif
+
+#if defined(CONFIG_PPC64)
+	const unsigned char elf_ident[EI_NIDENT] = {
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+                0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+#else
+		0x7f, 0x45, 0x4c, 0x46, 0x02, 0x02, 0x01, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+#endif
+	};
+
+	if (memcmp(mem, elf_ident, sizeof(elf_ident)) == 0)
+		return handle_elf_ppc64(mem, size);
+#endif /* CONFIG_PPC64 */
+
+	pr_err("Unsupported Elf format detected\n");
+	return -1;
+}
+
+static int piegen(void)
+{
+	struct stat st;
+	void *mem;
+	int fd;
+
+	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[] = {
+		{ "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' },
+		{ },
+	};
+
+	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;
+		case 'p':
+			opts.prefix_name = optarg;
+			break;
+		case 'v':
+			opts.var_name = optarg;
+			break;
+		case 'r':
+			opts.nrgotpcrel_name = optarg;
+			break;
+		case 'V':
+			printf("version %s\n", COMPEL_VERSION);
+			return 0;
+		case 'h':
+			goto usage;
+		default:
+			break;
+		}
+	}
+
+	if (optind >= argc)
+		goto usage;
+
+	action = argv[optind++];
+
+	if (!strcmp(action, "cflags")) {
+		if (!current_cflags)
+			goto usage;
+		printf("%s", current_cflags);
+		return 0;
+	}
+
+	if (!strcmp(action, "ldflags")) {
+		printf("%s", compel_ldflags);
+		return 0;
+	}
+
+	if (!strcmp(action, "piegen")) {
+		if (!opts.input_filename)
+			goto usage;
+
+		return piegen();
+	}
+
+usage:
+	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
diff --git a/criu/pie/piegen/elf-ppc64.c b/criu/pie/piegen/elf-ppc64.c
deleted file mode 100644
index 472725f9fe7c..000000000000
--- a/criu/pie/piegen/elf-ppc64.c
+++ /dev/null
@@ -1,16 +0,0 @@
-#define ELF_PPC64
-#define handle_elf	handle_elf_ppc64
-
-#define Ehdr_t		Elf64_Ehdr
-#define Shdr_t		Elf64_Shdr
-#define Sym_t		Elf64_Sym
-#define Rel_t		Elf64_Rel
-#define Rela_t		Elf64_Rela
-
-#define ELF_ST_TYPE	ELF64_ST_TYPE
-#define ELF_ST_BIND	ELF64_ST_BIND
-
-#define ELF_R_SYM	ELF64_R_SYM
-#define ELF_R_TYPE	ELF64_R_TYPE
-
-#include "elf.c"
diff --git a/criu/pie/piegen/elf-x86-32.c b/criu/pie/piegen/elf-x86-32.c
deleted file mode 100644
index 413113ef396b..000000000000
--- a/criu/pie/piegen/elf-x86-32.c
+++ /dev/null
@@ -1,16 +0,0 @@
-#define ELF_X86_32
-#define handle_elf	handle_elf_x86_32
-
-#define Ehdr_t		Elf32_Ehdr
-#define Shdr_t		Elf32_Shdr
-#define Sym_t		Elf32_Sym
-#define Rel_t		Elf32_Rel
-#define Rela_t		Elf32_Rela
-
-#define ELF_ST_TYPE	ELF32_ST_TYPE
-#define ELF_ST_BIND	ELF32_ST_BIND
-
-#define ELF_R_SYM	ELF32_R_SYM
-#define ELF_R_TYPE	ELF32_R_TYPE
-
-#include "elf.c"
diff --git a/criu/pie/piegen/elf-x86-64.c b/criu/pie/piegen/elf-x86-64.c
deleted file mode 100644
index 8ba26672bc82..000000000000
--- a/criu/pie/piegen/elf-x86-64.c
+++ /dev/null
@@ -1,16 +0,0 @@
-#define ELF_X86_64
-#define handle_elf	handle_elf_x86_64
-
-#define Ehdr_t		Elf64_Ehdr
-#define Shdr_t		Elf64_Shdr
-#define Sym_t		Elf64_Sym
-#define Rel_t		Elf64_Rel
-#define Rela_t		Elf64_Rela
-
-#define ELF_ST_TYPE	ELF64_ST_TYPE
-#define ELF_ST_BIND	ELF64_ST_BIND
-
-#define ELF_R_SYM	ELF64_R_SYM
-#define ELF_R_TYPE	ELF64_R_TYPE
-
-#include "elf.c"
diff --git a/criu/pie/piegen/elf.c b/criu/pie/piegen/elf.c
deleted file mode 100644
index c6b97257ba61..000000000000
--- a/criu/pie/piegen/elf.c
+++ /dev/null
@@ -1,512 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <string.h>
-
-#include <fcntl.h>
-#include <elf.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#include "asm-generic/int.h"
-
-#include "compiler.h"
-#include "piegen.h"
-
-static bool __ptr_oob(const void *ptr, const void *start, const size_t size)
-{
-	const void *end = (const void *)((const unsigned long)start + size);
-	return ptr > end || ptr < start;
-}
-
-static bool test_pointer(const void *ptr, const void *start, const size_t size,
-			 const char *name, const char *file, const int line)
-{
-	if (__ptr_oob(ptr, start, size)) {
-		pr_err("Corrupted pointer %p (%s) at %s:%d\n",
-		       ptr, name, file, line);
-		return true;
-	}
-	return false;
-}
-
-#define ptr_func_exit(__ptr)						\
-	do {								\
-		if (test_pointer((__ptr), mem, size, #__ptr,		\
-				 __FILE__, __LINE__)) {			\
-			free(sec_hdrs);					\
-			return -1;					\
-		}							\
-	} while (0)
-
-#ifdef ELF_PPC64
-static int do_relative_toc(long value, uint16_t *location,
-			   unsigned long mask, int complain_signed)
-{
-        if (complain_signed && (value + 0x8000 > 0xffff)) {
-		pr_err("TOC16 relocation overflows (%ld)\n", value);
-		return -1;
-        }
-
-	if ((~mask & 0xffff) & value) {
-		pr_err("bad TOC16 relocation (%ld) (0x%lx)\n", value, (~mask & 0xffff) & value);
-		return -1;
-	}
-
-	*location = (*location & ~mask) | (value & mask);
-	return 0;
-}
-#endif
-
-int handle_elf(void *mem, size_t size)
-{
-	const char *symstrings = NULL;
-	Shdr_t *symtab_hdr = NULL;
-	Sym_t *symbols = NULL;
-	Ehdr_t *hdr = mem;
-
-	Shdr_t *secstrings_hdr = NULL;
-	Shdr_t *strtab_hdr = NULL;
-	Shdr_t **sec_hdrs = NULL;
-	const char *secstrings;
-
-	size_t i, k, nr_gotpcrel = 0;
-#ifdef ELF_PPC64
-	s64 toc_offset = 0;
-#endif
-
-	pr_debug("Header\n");
-	pr_debug("------------\n");
-	pr_debug("\ttype 0x%x machine 0x%x version 0x%x\n",
-		 (unsigned)hdr->e_type, (unsigned)hdr->e_machine, (unsigned)hdr->e_version);
-
-#ifdef ELF_X86_64
-	if (hdr->e_type != ET_REL || hdr->e_machine != EM_X86_64 || hdr->e_version != EV_CURRENT) {
-		pr_err("Unsupported header detected\n");
-		goto err;
-	}
-#endif
-
-#ifdef ELF_X86_32
-	if (hdr->e_type != ET_REL || hdr->e_machine != EM_386 || hdr->e_version != EV_CURRENT) {
-		pr_err("Unsupported header detected\n");
-		goto err;
-	}
-#endif
-
-	sec_hdrs = malloc(sizeof(*sec_hdrs) * hdr->e_shnum);
-	if (!sec_hdrs) {
-		pr_err("No memory for section headers\n");
-		goto err;
-	}
-
-	secstrings_hdr = mem + hdr->e_shoff + hdr->e_shentsize * hdr->e_shstrndx;
-	secstrings = mem + secstrings_hdr->sh_offset;
-	ptr_func_exit(secstrings_hdr);
-	ptr_func_exit(secstrings);
-
-	pr_debug("Sections\n");
-	pr_debug("------------\n");
-	for (i = 0; i < hdr->e_shnum; i++) {
-		Shdr_t *sh = mem + hdr->e_shoff + hdr->e_shentsize * i;
-		ptr_func_exit(sh);
-
-		if (sh->sh_type == SHT_SYMTAB)
-			symtab_hdr = sh;
-
-		ptr_func_exit(&secstrings[sh->sh_name]);
-		pr_debug("\t index %-2zd type 0x%-2x name %s\n", i,
-			 (unsigned)sh->sh_type, &secstrings[sh->sh_name]);
-
-		sec_hdrs[i] = sh;
-
-#ifdef ELF_PPC64
-		if (!strcmp(&secstrings[sh->sh_name], ".toc")) {
-			toc_offset = sh->sh_addr + 0x8000;
-			pr_debug("\t\tTOC offset 0x%lx\n", toc_offset);
-		}
-#endif
-	}
-
-	if (!symtab_hdr) {
-		pr_err("No symbol table present\n");
-		goto err;
-	}
-
-	if (!symtab_hdr->sh_link || symtab_hdr->sh_link >= hdr->e_shnum) {
-		pr_err("Corrupted symtab header\n");
-		goto err;
-	}
-
-	pr_debug("Symbols\n");
-	pr_debug("------------\n");
-	strtab_hdr = sec_hdrs[symtab_hdr->sh_link];
-	ptr_func_exit(strtab_hdr);
-
-	symbols = mem + symtab_hdr->sh_offset;
-	ptr_func_exit(symbols);
-	symstrings = mem + strtab_hdr->sh_offset;
-	ptr_func_exit(symstrings);
-
-	if (sizeof(*symbols) != symtab_hdr->sh_entsize) {
-		pr_err("Symbol table align differ\n");
-		goto err;
-	}
-
-	pr_out("/* Autogenerated from %s */\n", opts.input_filename);
-	pr_out("#include \"piegen/uapi/types.h\"\n");
-
-	for (i = 0; i < symtab_hdr->sh_size / symtab_hdr->sh_entsize; i++) {
-		Sym_t *sym = &symbols[i];
-		const char *name;
-		Shdr_t *sh_src;
-
-		ptr_func_exit(sym);
-		name = &symstrings[sym->st_name];
-		ptr_func_exit(name);
-
-		if (*name) {
-			pr_debug("\ttype 0x%-2x bind 0x%-2x shndx 0x%-4x value 0x%-2lx name %s\n",
-				 (unsigned)ELF_ST_TYPE(sym->st_info), (unsigned)ELF_ST_BIND(sym->st_info),
-				 (unsigned)sym->st_shndx, (unsigned long)sym->st_value, name);
-#ifdef ELF_PPC64
-			if (!sym->st_value && !strncmp(name, ".TOC.", 6)) {
-				if (!toc_offset) {
-					pr_err("No TOC pointer\n");
-					goto err;
-				}
-				sym->st_value = toc_offset;
-				continue;
-			}
-#endif
-			if (strncmp(name, "__export", 8))
-				continue;
-			if ((sym->st_shndx && sym->st_shndx < hdr->e_shnum) || sym->st_shndx == SHN_ABS) {
-				if (sym->st_shndx == SHN_ABS) {
-					sh_src = NULL;
-				} else {
-					sh_src = sec_hdrs[sym->st_shndx];
-					ptr_func_exit(sh_src);
-				}
-				pr_out("#define %s%s 0x%lx\n",
-				       opts.prefix_name, name,
-				       (unsigned long)(sym->st_value + (sh_src ? sh_src->sh_addr : 0)));
-			}
-		}
-	}
-
-	pr_out("static __maybe_unused elf_reloc_t %s[] = {\n", opts.var_name);
-
-	pr_debug("Relocations\n");
-	pr_debug("------------\n");
-	for (i = 0; i < hdr->e_shnum; i++) {
-		Shdr_t *sh = sec_hdrs[i];
-		Shdr_t *sh_rel;
-
-		if (sh->sh_type != SHT_REL && sh->sh_type != SHT_RELA)
-			continue;
-
-		sh_rel = sec_hdrs[sh->sh_info];
-		ptr_func_exit(sh_rel);
-
-		pr_debug("\tsection %2zd type 0x%-2x link 0x%-2x info 0x%-2x name %s\n", i,
-			 (unsigned)sh->sh_type, (unsigned)sh->sh_link,
-			 (unsigned)sh->sh_info, &secstrings[sh->sh_name]);
-
-		for (k = 0; k < sh->sh_size / sh->sh_entsize; k++) {
-			s64 __maybe_unused addend64, __maybe_unused value64;
-			s32 addend32, value32;
-			unsigned long place;
-			const char *name;
-			void *where;
-			Sym_t *sym;
-
-			union {
-				Rel_t rel;
-				Rela_t rela;
-			} *r = mem + sh->sh_offset + sh->sh_entsize * k;
-			ptr_func_exit(r);
-
-			sym = &symbols[ELF_R_SYM(r->rel.r_info)];
-			ptr_func_exit(sym);
-
-			name = &symstrings[sym->st_name];
-			ptr_func_exit(name);
-
-			where = mem + sh_rel->sh_offset + r->rel.r_offset;
-			ptr_func_exit(where);
-
-			pr_debug("\t\tr_offset 0x%-4lx r_info 0x%-4lx / sym 0x%-2lx type 0x%-2lx symsecoff 0x%-4lx\n",
-				 (unsigned long)r->rel.r_offset, (unsigned long)r->rel.r_info,
-				 (unsigned long)ELF_R_SYM(r->rel.r_info),
-				 (unsigned long)ELF_R_TYPE(r->rel.r_info),
-				 (unsigned long)sh_rel->sh_addr);
-
-			if (sym->st_shndx == SHN_UNDEF) {
-#ifdef ELF_PPC64
-				/* On PowerPC, TOC symbols appear to be
-				 * undefined but should be processed as well.
-				 * Their type is STT_NOTYPE, so report any
-				 * other one.
-				 */
-				if (ELF32_ST_TYPE(sym->st_info) != STT_NOTYPE
-				    || strncmp(name, ".TOC.", 6)) {
-					pr_err("Unexpected undefined symbol:%s\n", name);
-					goto err;
-				}
-#else
-				continue;
-#endif
-			}
-
-			if (sh->sh_type == SHT_REL) {
-				addend32 = *(s32 *)where;
-				addend64 = *(s64 *)where;
-			} else {
-				addend32 = (s32)r->rela.r_addend;
-				addend64 = (s64)r->rela.r_addend;
-			}
-
-			place = sh_rel->sh_addr + r->rel.r_offset;
-
-			pr_debug("\t\t\tvalue 0x%-8lx addend32 %-4d addend64 %-8ld place %-8lx symname %s\n",
-				 (unsigned long)sym->st_value, addend32, (long)addend64, (long)place, name);
-
-			if (sym->st_shndx == SHN_ABS) {
-				value32 = (s32)sym->st_value;
-				value64 = (s64)sym->st_value;
-			} else {
-				Shdr_t *sh_src;
-
-				if ((unsigned)sym->st_shndx > (unsigned)hdr->e_shnum) {
-					pr_err("Unexpected symbol section index %u/%u\n",
-					       (unsigned)sym->st_shndx, hdr->e_shnum);
-					goto err;
-				}
-				sh_src = sec_hdrs[sym->st_shndx];
-				ptr_func_exit(sh_src);
-
-				value32 = (s32)sh_src->sh_addr + (s32)sym->st_value;
-				value64 = (s64)sh_src->sh_addr + (s64)sym->st_value;
-			}
-
-#ifdef ELF_PPC64
-/* Snippet from the OpenPOWER ABI for Linux Supplement:
- * The OpenPOWER ABI uses the three most-significant bits in the symbol
- * st_other field specifies the number of instructions between a function's
- * global entry point and local entry point. The global entry point is used
- * when it is necessary to set up the TOC pointer (r2) for the function. The
- * local entry point is used when r2 is known to already be valid for the
- * function. A value of zero in these bits asserts that the function does
- * not use r2.
- * The st_other values have the following meanings:
- * 0 and 1, the local and global entry points are the same.
- * 2, the local entry point is at 1 instruction past the global entry point.
- * 3, the local entry point is at 2 instructions past the global entry point.
- * 4, the local entry point is at 4 instructions past the global entry point.
- * 5, the local entry point is at 8 instructions past the global entry point.
- * 6, the local entry point is at 16 instructions past the global entry point.
- * 7, reserved.
- *
- * Here we are only handle the case '3' which is the most commonly seen.
- */
-#define LOCAL_OFFSET(s)	((s->st_other >> 5) & 0x7)
-			if (LOCAL_OFFSET(sym)) {
-				if (LOCAL_OFFSET(sym) != 3) {
-					pr_err("Unexpected local offset value %d\n",
-					       LOCAL_OFFSET(sym));
-					goto err;
-				}
-				pr_debug("\t\t\tUsing local offset\n");
-				value64 += 8;
-				value32 += 8;
-			}
-#endif
-
-			switch (ELF_R_TYPE(r->rel.r_info)) {
-#ifdef ELF_PPC64
-			case R_PPC64_REL24:
-				/* Update PC relative offset, linker has not done this yet */
-				pr_debug("\t\t\tR_PPC64_REL24 at 0x%-4lx val 0x%lx\n",
-					 place, value64);
-				/* Convert value to relative */
-				value64 -= place;
-				if (value64 + 0x2000000 > 0x3ffffff || (value64 & 3) != 0) {
-					pr_err("REL24 %li out of range!\n", (long int)value64);
-					goto err;
-				}
-				/* Only replace bits 2 through 26 */
-				*(uint32_t *)where = (*(uint32_t *)where & ~0x03fffffc) |
-                                        (value64 & 0x03fffffc);
-				break;
-
-			case R_PPC64_ADDR32:
-				pr_debug("\t\t\tR_PPC64_ADDR32 at 0x%-4lx val 0x%x\n",
-					 place, (unsigned int)(value32 + addend32));
-				pr_out("	{ .offset = 0x%-8x, .type = PIEGEN_TYPE_INT, "
-				       " .addend = %-8d, .value = 0x%-16x, "
-				       "}, /* R_PPC64_ADDR32 */\n",
-				       (unsigned int) place,  addend32, value32);
-				break;
-
-			case R_PPC64_ADDR64:
-			case R_PPC64_REL64:
-				pr_debug("\t\t\tR_PPC64_ADDR64 at 0x%-4lx val 0x%lx\n",
-					 place, value64 + addend64);
-				pr_out("\t{ .offset = 0x%-8x, .type = PIEGEN_TYPE_LONG,"
-				       " .addend = %-8ld, .value = 0x%-16lx, "
-				       "}, /* R_PPC64_ADDR64 */\n",
-				       (unsigned int) place, (long)addend64, (long)value64);
-				break;
-
-			case R_PPC64_TOC16_HA:
-				pr_debug("\t\t\tR_PPC64_TOC16_HA at 0x%-4lx val 0x%lx\n",
-					 place, value64 + addend64 - toc_offset + 0x8000);
-				if (do_relative_toc((value64 + addend64 - toc_offset + 0x8000) >> 16,
-						    where, 0xffff, 1))
-					goto err;
-				break;
-
-			case R_PPC64_TOC16_LO:
-				pr_debug("\t\t\tR_PPC64_TOC16_LO at 0x%-4lx val 0x%lx\n",
-					 place, value64 + addend64 - toc_offset);
-				if (do_relative_toc(value64 + addend64 - toc_offset,
-						    where, 0xffff, 1))
-					goto err;
-				break;
-
-			case R_PPC64_TOC16_LO_DS:
-				pr_debug("\t\t\tR_PPC64_TOC16_LO_DS at 0x%-4lx val 0x%lx\n",
-					 place, value64 + addend64 - toc_offset);
-				if (do_relative_toc(value64 + addend64 - toc_offset,
-						    where, 0xfffc, 0))
-					goto err;
-				break;
-
-			case R_PPC64_REL16_HA:
-				value64 += addend64 - place;
-				pr_debug("\t\t\tR_PPC64_REL16_HA at 0x%-4lx val 0x%lx\n",
-					 place, value64);
-				/* check that we are dealing with the addis 2,12 instruction */
-				if (((*(uint32_t*)where) & 0xffff0000) != 0x3c4c0000) {
-					pr_err("Unexpected instruction for R_PPC64_REL16_HA\n");
-					goto err;
-				}
-				*(uint16_t *)where = ((value64 + 0x8000) >> 16) & 0xffff;
-				break;
-
-			case R_PPC64_REL16_LO:
-				value64 += addend64 - place;
-				pr_debug("\t\t\tR_PPC64_REL16_LO at 0x%-4lx val 0x%lx\n",
-					 place, value64);
-				/* check that we are dealing with the addi 2,2 instruction */
-				if (((*(uint32_t*)where) & 0xffff0000) != 0x38420000) {
-					pr_err("Unexpected instruction for R_PPC64_REL16_LO\n");
-					goto err;
-				}
-				*(uint16_t *)where = value64 & 0xffff;
-				break;
-
-#endif /* ELF_PPC64 */
-
-#ifdef ELF_X86_64
-			case R_X86_64_32: /* Symbol + Addend (4 bytes) */
-				pr_debug("\t\t\t\tR_X86_64_32       at 0x%-4lx val 0x%x\n", place, value32);
-				pr_out("	{ .offset = 0x%-8x, .type = PIEGEN_TYPE_INT, "
-				       ".addend = %-8d, .value = 0x%-16x, }, /* R_X86_64_32 */\n",
-				       (unsigned int)place, addend32, value32);
-				break;
-			case R_X86_64_64: /* Symbol + Addend (8 bytes) */
-				pr_debug("\t\t\t\tR_X86_64_64       at 0x%-4lx val 0x%lx\n", place, (long)value64);
-				pr_out("	{ .offset = 0x%-8x, .type = PIEGEN_TYPE_LONG, "
-				       ".addend = %-8ld, .value = 0x%-16lx, }, /* R_X86_64_64 */\n",
-				       (unsigned int)place, (long)addend64, (long)value64);
-				break;
-			case R_X86_64_PC32: /* Symbol + Addend - Place (4 bytes) */
-				pr_debug("\t\t\t\tR_X86_64_PC32     at 0x%-4lx val 0x%x\n", place, value32 + addend32 - (s32)place);
-				/*
-				 * R_X86_64_PC32 are relative, patch them inplace.
-				 */
-				*((s32 *)where) = value32 + addend32 - place;
-				break;
-			case R_X86_64_PLT32: /* ProcLinkage + Addend - Place (4 bytes) */
-				pr_debug("\t\t\t\tR_X86_64_PLT32    at 0x%-4lx val 0x%x\n", place, value32 + addend32 - (s32)place);
-				/*
-				 * R_X86_64_PLT32 are relative, patch them inplace.
-				 */
-				*((s32 *)where) = value32 + addend32 - place;
-				break;
-			case R_X86_64_GOTPCREL: /* SymbolOffsetInGot + GOT + Addend - Place  (4 bytes) */
-				pr_debug("\t\t\t\tR_X86_64_GOTPCREL at 0x%-4lx val 0x%x\n", place, value32);
-				pr_out("	{ .offset = 0x%-8x, .type = PIEGEN_TYPE_LONG | PIEGEN_TYPE_GOTPCREL, "
-				       ".addend = %-8d, .value = 0x%-16x, }, /* R_X86_64_GOTPCREL */\n",
-				       (unsigned int)place, addend32, value32);
-				nr_gotpcrel++;
-				break;
-#endif
-
-#ifdef ELF_X86_32
-			case R_386_32: /* Symbol + Addend */
-				pr_debug("\t\t\t\tR_386_32   at 0x%-4lx val 0x%x\n", place, value32 + addend32);
-				pr_out("	{ .offset = 0x%-8x, .type = PIEGEN_TYPE_INT, "
-				       ".addend = %-4d, .value = 0x%x, },\n",
-				       (unsigned int)place, addend32, value32);
-				break;
-			case R_386_PC32: /* Symbol + Addend - Place */
-				pr_debug("\t\t\t\tR_386_PC32 at 0x%-4lx val 0x%x\n", place, value32 + addend32 - (s32)place);
-				/*
-				 * R_386_PC32 are relative, patch them inplace.
-				 */
-				*((s32 *)where) = value32 + addend32 - place;
-				break;
-#endif
-
-			default:
-				pr_err("Unsupported relocation\n");
-				goto err;
-			}
-		}
-	}
-	pr_out("};\n");
-	pr_out("static __maybe_unused size_t %s = %zd;\n", opts.nrgotpcrel_name, nr_gotpcrel);
-
-	pr_out("static __maybe_unused const char %s[] = {\n\t", opts.stream_name);
-
-	for (i=0, k=0; i < hdr->e_shnum; i++) {
-		Shdr_t *sh = sec_hdrs[i];
-		unsigned char *shdata;
-		size_t j;
-
-		if (!(sh->sh_flags & SHF_ALLOC) || !sh->sh_size)
-			continue;
-
-		shdata =  mem + sh->sh_offset;
-		pr_debug("Copying section '%s'\n" \
-			 "\tstart:0x%lx (gap:0x%lx) size:0x%lx\n",
-			 &secstrings[sh->sh_name], (unsigned long) sh->sh_addr,
-			 (unsigned long)(sh->sh_addr - k), (unsigned long) sh->sh_size);
-
-		/* write 0 in the gap between the 2 sections */
-		for (;k < sh->sh_addr; k++) {
-			if (k && (k % 8) == 0)
-				pr_out("\n\t");
-			pr_out("0x00,");
-		}
-
-		for (j=0; j < sh->sh_size; j++, k++) {
-			if (k && (k % 8) == 0)
-				pr_out("\n\t");
-			pr_out("0x%02x,", shdata[j]);
-		}
-	}
-	pr_out("};\n");
-	free(sec_hdrs);
-	return 0;
-err:
-	free(sec_hdrs);
-	return -1;
-}
diff --git a/criu/pie/piegen/main.c b/criu/pie/piegen/main.c
deleted file mode 100644
index c89b1575fb61..000000000000
--- a/criu/pie/piegen/main.c
+++ /dev/null
@@ -1,161 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <getopt.h>
-#include <string.h>
-
-#include <fcntl.h>
-#include <elf.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#include "compiler.h"
-#include "config.h"
-#include "piegen.h"
-
-piegen_opt_t opts = {
-	.input_filename		= NULL,
-	.stream_name		= "stream",
-	.prefix_name		= "__",
-	.var_name		= "elf_relocs",
-	.nrgotpcrel_name	= "nr_gotpcrel",
-};
-
-FILE *fout;
-
-static int handle_elf(void *mem, size_t size)
-{
-#if defined(CONFIG_X86_32) || defined(CONFIG_X86_64)
-	unsigned char elf_ident_x86_32[EI_NIDENT] = {
-		0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	};
-
-	unsigned char elf_ident_x86_64[EI_NIDENT] = {
-		0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	};
-
-	if (memcmp(mem, elf_ident_x86_32, sizeof(elf_ident_x86_32)) == 0)
-		return handle_elf_x86_32(mem, size);
-	else if (memcmp(mem, elf_ident_x86_64, sizeof(elf_ident_x86_64)) == 0)
-		return handle_elf_x86_64(mem, size);
-#endif
-
-#if defined(CONFIG_PPC64)
-	const unsigned char elf_ident[EI_NIDENT] = {
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-                0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00,
-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-#else
-		0x7f, 0x45, 0x4c, 0x46, 0x02, 0x02, 0x01, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-#endif
-	};
-
-	if (memcmp(mem, elf_ident, sizeof(elf_ident)) == 0)
-		return handle_elf_ppc64(mem, size);
-#endif /* CONFIG_PPC64 */
-
-	pr_err("Unsupported Elf format detected\n");
-	return -1;
-}
-
-/*
- * That;s the tool to generate patches object files.
- */
-int main(int argc, char *argv[])
-{
-	struct stat st;
-	int opt, idx;
-	void *mem;
-	int fd;
-
-	static const char short_opts[] = "f:o:s:p:v:r:h";
-	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' },
-		{ },
-	};
-
-	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 'f':
-			opts.input_filename = optarg;
-			break;
-		case 'o':
-			opts.output_filename = optarg;
-			break;
-		case 's':
-			opts.stream_name = optarg;
-			break;
-		case 'p':
-			opts.prefix_name = optarg;
-			break;
-		case 'v':
-			opts.var_name = optarg;
-			break;
-		case 'r':
-			opts.nrgotpcrel_name = optarg;
-			break;
-		case 'h':
-		default:
-			goto usage;
-		}
-	}
-
-	if (!opts.input_filename)
-		goto usage;
-
-	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;
-	}
-	fclose(fout);
-	printf("%s generated successfully.\n", opts.output_filename);
-	return 0;
-usage:
-	fprintf(stderr, "Usage: %s -f filename\n", argv[0]);
-err:
-	return 1;
-}
diff --git a/criu/pie/piegen/piegen.h b/criu/pie/piegen/piegen.h
deleted file mode 100644
index 8ac5b34b43c2..000000000000
--- a/criu/pie/piegen/piegen.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef __ELFTIL_H__
-#define __ELFTIL_H__
-
-#include <stdio.h>
-#include <unistd.h>
-
-typedef struct {
-	char		*input_filename;
-	char		*output_filename;
-	char		*stream_name;
-	char		*prefix_name;
-	char		*var_name;
-	char		*nrgotpcrel_name;
-} piegen_opt_t;
-
-extern piegen_opt_t opts;
-extern FILE *fout;
-
-#if defined(CONFIG_X86_32) || defined(CONFIG_X86_64)
-extern int handle_elf_x86_32(void *mem, size_t size);
-extern int handle_elf_x86_64(void *mem, size_t size);
-#endif
-
-#if defined(CONFIG_PPC64)
-extern int handle_elf_ppc64(void *mem, size_t size);
-#endif
-
-#define pr_out(fmt, ...)	fprintf(fout, fmt, ##__VA_ARGS__)
-
-#define pr_debug(fmt, ...)	printf("%s: "fmt, opts.stream_name, ##__VA_ARGS__)
-
-#define pr_err(fmt, ...)	fprintf(stderr, "%s: Error (%s:%d): "fmt, opts.stream_name, __FILE__, __LINE__, ##__VA_ARGS__)
-#define pr_perror(fmt, ...)	fprintf(stderr, "%s: Error (%s:%d): "fmt ": %m\n", opts.stream_name, __FILE__, __LINE__, ##__VA_ARGS__)
-
-#endif /* __ELFTIL_H__ */
diff --git a/criu/pie/piegen/uapi/types.h b/criu/pie/piegen/uapi/types.h
deleted file mode 100644
index 34696e8c6aa5..000000000000
--- a/criu/pie/piegen/uapi/types.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef __PIEGEN_TYPES_H__
-#define __PIEGEN_TYPES_H__
-
-#define PIEGEN_TYPE_INT		(1u << 0)
-#define PIEGEN_TYPE_LONG	(1u << 1)
-#define PIEGEN_TYPE_GOTPCREL	(1u << 2)
-
-typedef struct {
-	unsigned int	offset;
-	unsigned int	type;
-	long		addend;
-	long		value;
-} elf_reloc_t;
-
-#endif /* __PIEGEN_TYPES_H__ */
-- 
2.5.0



More information about the CRIU mailing list