[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