[CRIU] [PATCH 11/16] pie: piegen -- Slightly rework the building procedure

Cyrill Gorcunov gorcunov at openvz.org
Thu Jun 4 14:04:12 PDT 2015


 - Move relocs application into a separate file which get
   compiled as a regular C file in criu (pie/pie-relocs.[ch])
 - Move types used by piegen into pie/piegen/uapi/types.h

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 Makefile.crtools        |  1 +
 cr-restore.c            |  7 ++++---
 parasite-syscall.c      |  5 ++---
 pie/Makefile            |  2 +-
 pie/pie-relocs.c        | 47 +++++++++++++++++++++++++++++++++++++++++++++
 pie/pie-relocs.h        | 15 +++++++++++++++
 pie/piegen/elf.c        | 51 ++++++++++---------------------------------------
 pie/piegen/main.c       |  7 +------
 pie/piegen/piegen.h     |  1 -
 pie/piegen/uapi/types.h | 15 +++++++++++++++
 10 files changed, 96 insertions(+), 55 deletions(-)
 create mode 100644 pie/pie-relocs.c
 create mode 100644 pie/pie-relocs.h
 create mode 100644 pie/piegen/uapi/types.h

diff --git a/Makefile.crtools b/Makefile.crtools
index 403d6fa1cb00..a331684730aa 100644
--- a/Makefile.crtools
+++ b/Makefile.crtools
@@ -72,6 +72,7 @@ obj-y	+= cr-service.o
 obj-y	+= sd-daemon.o
 obj-y	+= plugin.o
 obj-y	+= cr-errno.o
+obj-y	+= pie/pie-relocs.o
 
 ifneq ($(MAKECMDGOALS),clean)
 incdeps := y
diff --git a/cr-restore.c b/cr-restore.c
index ac0fb6e6a9bb..68bc0b2940fe 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -91,6 +91,8 @@
 
 #include "cr-errno.h"
 
+#include "pie/pie-relocs.h"
+
 #ifndef arch_export_restore_thread
 #define arch_export_restore_thread	__export_restore_thread
 #endif
@@ -2384,10 +2386,9 @@ static int remap_restorer_blob(void *addr)
 		return -1;
 	}
 
-#if defined(CONFIG_X86_64) || defined(CONFIG_X86_32)
-	elf_apply_relocs(addr, addr, sizeof(restorer_blob),
+	elf_relocs_apply(addr, addr, sizeof(restorer_blob),
 			 elf_relocs, ARRAY_SIZE(elf_relocs));
-#endif
+
 	return 0;
 }
 
diff --git a/parasite-syscall.c b/parasite-syscall.c
index e158c0385897..b5776090076a 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -37,6 +37,7 @@
 #include "asm/parasite-syscall.h"
 #include "asm/dump.h"
 #include "asm/restorer.h"
+#include "pie/pie-relocs.h"
 
 #if defined(CONFIG_X86_32) || defined(CONFIG_X86_64)
 # define parasite_size		(round_up(sizeof(parasite_blob) + nr_gotpcrel * sizeof(long), PAGE_SIZE))
@@ -1223,10 +1224,8 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 	pr_info("Putting parasite blob into %p->%p\n", ctl->local_map, ctl->remote_map);
 	memcpy(ctl->local_map, parasite_blob, sizeof(parasite_blob));
 
-#if defined(CONFIG_X86_64) || defined(CONFIG_X86_32)
-	elf_apply_relocs(ctl->local_map, ctl->remote_map, sizeof(parasite_blob),
+	elf_relocs_apply(ctl->local_map, ctl->remote_map, sizeof(parasite_blob),
 			 elf_relocs, ARRAY_SIZE(elf_relocs));
-#endif
 
 	/* Setup the rest of a control block */
 	ctl->parasite_ip	= (unsigned long)parasite_sym(ctl->remote_map, __export_parasite_head_start);
diff --git a/pie/Makefile b/pie/Makefile
index 6ecf253060f1..add7a0011c82 100644
--- a/pie/Makefile
+++ b/pie/Makefile
@@ -34,7 +34,7 @@ restorer-libs-e		+= $(SYSCALL-LIB)
 # applications, which is not the target of the
 # project.
 #
-CFLAGS			:= $(filter-out -pg,$(CFLAGS))
+CFLAGS			:= $(filter-out -pg,$(CFLAGS)) -iquote pie/piegen
 
 ifneq ($(filter-out i386 ia32, $(ARCH)),)
 cflags-y		+= -DCR_NOGLIBC -fpie -Wa,--noexecstack -fno-stack-protector
diff --git a/pie/pie-relocs.c b/pie/pie-relocs.c
new file mode 100644
index 000000000000..7e825b2320d9
--- /dev/null
+++ b/pie/pie-relocs.c
@@ -0,0 +1,47 @@
+#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/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)
+{
+	size_t i, j;
+
+	for (i = 0, j = 0; i < nr_relocs; i++) {
+		if (elf_relocs[i].type & PIEGEN_TYPE_LONG) {
+			long *where = mem + elf_relocs[i].offset;
+			long *p = mem + size;
+
+			if (elf_relocs[i].type & PIEGEN_TYPE_GOTPCREL) {
+				int *value = (int *)where;
+				int rel;
+
+				p[j] = (long)vbase + elf_relocs[i].value;
+				rel = (unsigned)((void *)&p[j] - (void *)mem) - elf_relocs[i].offset + elf_relocs[i].addend;
+
+				*value = rel;
+				j++;
+			} else
+				*where = elf_relocs[i].value + elf_relocs[i].addend + (unsigned long)vbase;
+		} else if (elf_relocs[i].type & PIEGEN_TYPE_INT) {
+			int *where = (mem + elf_relocs[i].offset);
+			*where = elf_relocs[i].value + elf_relocs[i].addend + (unsigned long)vbase;
+		} else
+			BUG();
+	}
+}
diff --git a/pie/pie-relocs.h b/pie/pie-relocs.h
new file mode 100644
index 000000000000..0b64c7b7ccc3
--- /dev/null
+++ b/pie/pie-relocs.h
@@ -0,0 +1,15 @@
+#ifndef __PIE_RELOCS_H__
+#define __PIE_RELOCS_H__
+
+#include "piegen/uapi/types.h"
+
+#include "compiler.h"
+#include "config.h"
+
+#if defined(CONFIG_X86_64) || defined(CONFIG_X86_32)
+extern __maybe_unused void elf_relocs_apply(void *mem, void *vbase, size_t size, elf_reloc_t *elf_relocs, size_t nr_relocs);
+#else
+static always_inline void elf_relocs_apply(void *mem, void *vbase, size_t size, elf_reloc_t *elf_relocs, size_t nr_relocs) { }
+#endif
+
+#endif /* __PIE_RELOCS_H__ */
diff --git a/pie/piegen/elf.c b/pie/piegen/elf.c
index 76cbefb52a7a..8d36cbf64845 100644
--- a/pie/piegen/elf.c
+++ b/pie/piegen/elf.c
@@ -126,6 +126,8 @@ int handle_elf(const piegen_opt_t *opts, void *mem, size_t size)
 	}
 
 	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;
@@ -155,13 +157,7 @@ int handle_elf(const piegen_opt_t *opts, void *mem, size_t size)
 		}
 	}
 
-	pr_out("typedef struct {\n"
-	       "	unsigned int	offset;\n"
-	       "	unsigned int	type;\n"
-	       "	long		addend;\n"
-	       "	long		value;\n"
-	       "} %s;\nstatic __maybe_unused %s %s[] = {\n",
-	       opts->type_name, opts->type_name, opts->var_name);
+	pr_out("static __maybe_unused elf_reloc_t %s[] = {\n", opts->var_name);
 
 	pr_debug("Relocations\n------------\n");
 	for (i = 0; i < hdr->e_shnum; i++) {
@@ -232,16 +228,17 @@ int handle_elf(const piegen_opt_t *opts, void *mem, size_t size)
 			value64 = (s64)sh_src->sh_offset + (s64)sym->st_value;
 
 			switch (ELF_R_TYPE(r->rel.r_info)) {
+
 #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 = 0, "
+				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, value64);
-				pr_out("	{ .offset = 0x%-8x, .type = 1, "
+				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;
@@ -261,16 +258,17 @@ int handle_elf(const piegen_opt_t *opts, void *mem, size_t size)
 				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 = 3, "
+				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 = 0, "
+				pr_out("	{ .offset = 0x%-8x, .type = PIEGEN_TYPE_INT, "
 				       ".addend = %-4d, .value = 0x%x, },\n",
 				       (unsigned int)place, addend32, value32);
 				break;
@@ -282,6 +280,7 @@ int handle_elf(const piegen_opt_t *opts, void *mem, size_t size)
 				*((s32 *)where) = value32 + addend32 - place;
 				break;
 #endif
+
 			default:
 				pr_err("Unsupported relocation\n");
 				goto err;
@@ -302,36 +301,6 @@ int handle_elf(const piegen_opt_t *opts, void *mem, size_t size)
 	}
 	pr_out("};\n");
 
-#if defined(CONFIG_X86_64) || defined(CONFIG_X86_32)
-pr_out(
-"static __maybe_unused void elf_apply_relocs(void *mem, void *vbase, size_t size, %s *elf_relocs, size_t nr_relocs)\n"
-"{\n"
-"	size_t i, j;\n"
-"\n"
-"	for (i = 0, j = 0; i < nr_relocs; i++) {\n"
-"		if (elf_relocs[i].type) {\n"
-"			long *where = mem + elf_relocs[i].offset;\n"
-"			long *p = mem + size;\n"
-"\n"
-"			if (elf_relocs[i].type & 2) {\n"
-"				int *value = (int *)where;\n"
-"				int rel;\n"
-"\n"
-"				p[j] = (long)vbase + elf_relocs[i].value;\n"
-"				rel = (unsigned)((void *)&p[j] - (void *)mem) - elf_relocs[i].offset + elf_relocs[i].addend;\n"
-"\n"
-"				*value = rel;\n"
-"				j++;\n"
-"			} else\n"
-"				*where = elf_relocs[i].value + elf_relocs[i].addend + (unsigned long)vbase;\n"
-"		} else {\n"
-"			int *where = (mem + elf_relocs[i].offset);\n"
-"			*where = elf_relocs[i].value + elf_relocs[i].addend + (unsigned long)vbase;\n"
-"		}\n"
-"	}\n"
-"}\n", opts->type_name);
-#endif
-
 err:
 	free(sec_hdrs);
 	return -1;
diff --git a/pie/piegen/main.c b/pie/piegen/main.c
index 45bbf24545a0..64e82497469d 100644
--- a/pie/piegen/main.c
+++ b/pie/piegen/main.c
@@ -20,7 +20,6 @@
 piegen_opt_t opts = {
 	.input_filename		= "file.o",
 	.stream_name		= "stream",
-	.type_name		= "elf_reloc_t",
 	.prefix_name		= "__",
 	.var_name		= "elf_relocs",
 	.nrgotpcrel_name	= "nr_gotpcrel",
@@ -59,11 +58,10 @@ int main(int argc, char *argv[])
 	void *mem;
 	int fd;
 
-	static const char short_opts[] = "f:s:t:p:v:h";
+	static const char short_opts[] = "f:s:p:v:h";
 	static struct option long_opts[] = {
 		{ "file",	required_argument,	0, 'f' },
 		{ "stream",	required_argument,	0, 's' },
-		{ "type",	required_argument,	0, 't' },
 		{ "sym-prefix",	required_argument,	0, 'p' },
 		{ "variable",	required_argument,	0, 'v' },
 		{ "help",	required_argument,	0, 'h' },
@@ -88,9 +86,6 @@ int main(int argc, char *argv[])
 		case 'p':
 			opts.prefix_name = optarg;
 			break;
-		case 't':
-			opts.type_name = optarg;
-			break;
 		case 'v':
 			opts.var_name = optarg;
 			break;
diff --git a/pie/piegen/piegen.h b/pie/piegen/piegen.h
index 10505d758125..79a97e5b2f53 100644
--- a/pie/piegen/piegen.h
+++ b/pie/piegen/piegen.h
@@ -7,7 +7,6 @@
 typedef struct {
 	char		*input_filename;
 	char		*stream_name;
-	char		*type_name;
 	char		*prefix_name;
 	char		*var_name;
 	char		*nrgotpcrel_name;
diff --git a/pie/piegen/uapi/types.h b/pie/piegen/uapi/types.h
new file mode 100644
index 000000000000..34696e8c6aa5
--- /dev/null
+++ b/pie/piegen/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__ */
-- 
2.4.2



More information about the CRIU mailing list