[CRIU] [PATCH 1/8] piegen: Implement tool building, v2
Pavel Emelyanov
xemul at parallels.com
Fri May 15 04:20:17 PDT 2015
On 05/11/2015 07:06 PM, Cyrill Gorcunov wrote:
> Here we simply build piegen tool which gonna be used
> to generate parasite code safe to rellocate. The tool
> is taking object file as an argument, parses it and
> generates C file with rellocations encoded in form
> suitable for fast appliance.
Can you sketch how the PIE blobs are built now and how they
will be built with this tool? We have a page on wiki about
it (http://criu.org/Code_blobs) the "Example" section is what
I'm talking about :)
> Currently only x86-32 x86-64 is supported.
>
> v2 (by ldufour@):
> - Filter PIEGEN
>
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
> Makefile | 19 ++-
> pie/piegen/Makefile | 14 ++
> pie/piegen/elf-x86-32.c | 16 +++
> pie/piegen/elf-x86-64.c | 16 +++
> pie/piegen/elf.c | 338 ++++++++++++++++++++++++++++++++++++++++++++++++
> pie/piegen/main.c | 127 ++++++++++++++++++
> pie/piegen/piegen.h | 34 +++++
> 7 files changed, 562 insertions(+), 2 deletions(-)
> create mode 100644 pie/piegen/Makefile
> create mode 100644 pie/piegen/elf-x86-32.c
> create mode 100644 pie/piegen/elf-x86-64.c
> create mode 100644 pie/piegen/elf.c
> create mode 100644 pie/piegen/main.c
> create mode 100644 pie/piegen/piegen.h
>
> diff --git a/Makefile b/Makefile
> index dbbbbf2a7da5..78cc761c5dca 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -142,6 +142,9 @@ ARCH-LIB := $(ARCH_DIR)/crtools.built-in.o
> CRIU-SO := libcriu
> CRIU-LIB := lib/$(CRIU-SO).so
> CRIU-INC := lib/criu.h include/criu-plugin.h include/criu-log.h protobuf/rpc.proto
> +ifneq ($(filter i386 ia32 x86_64, $(ARCH)),)
> +PIEGEN := pie/piegen/piegen
> +endif
>
> export CC MAKE CFLAGS LIBS SRCARCH DEFINES MAKEFLAGS CRIU-SO
> export SRC_DIR SYSCALL-LIB SH RM ARCH_DIR OBJCOPY LDARCH LD
> @@ -184,9 +187,20 @@ $(ARCH_DIR)/%:: protobuf config
> $(ARCH_DIR): protobuf config
> $(Q) $(MAKE) $(build)=$(ARCH_DIR) all
>
> -pie/%:: $(ARCH_DIR)
> +ifneq ($(filter i386 ia32 x86_64, $(ARCH)),)
> +pie/piegen/%:
> + $(Q) $(MAKE) $(build)=pie/piegen $@
> +pie/piegen:
> + $(Q) $(MAKE) $(build)=pie/piegen all
> +$(PIEGEN): pie/piegen/built-in.o
> + $(E) " LINK " $@
> + $(Q) $(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@
> +.PHONY: pie/piegen
> +endif
> +
> +pie/%:: $(ARCH_DIR) $(PIEGEN)
> $(Q) $(MAKE) $(build)=pie $@
> -pie: $(ARCH_DIR)
> +pie: $(ARCH_DIR) $(PIEGEN)
> $(Q) $(MAKE) $(build)=pie all
>
> %.o %.i %.s %.d: $(VERSION_HEADER) pie
> @@ -235,6 +249,7 @@ clean-built:
> $(Q) $(RM) $(VERSION_HEADER)
> $(Q) $(MAKE) $(build)=$(ARCH_DIR) clean
> $(Q) $(MAKE) $(build)=protobuf clean
> + $(Q) $(MAKE) $(build)=pie/piegen clean
> $(Q) $(MAKE) $(build)=pie clean
> $(Q) $(MAKE) $(build)=lib clean
> $(Q) $(MAKE) $(build-crtools)=. clean
> diff --git a/pie/piegen/Makefile b/pie/piegen/Makefile
> new file mode 100644
> index 000000000000..dd54c3f0b546
> --- /dev/null
> +++ b/pie/piegen/Makefile
> @@ -0,0 +1,14 @@
> +CFLAGS += -iquote pie/piegen
> +
> +obj-y += main.o
> +ifneq ($(filter i386 ia32 x86_64, $(ARCH)),)
> +obj-y += elf-x86-32.o
> +obj-y += elf-x86-64.o
> +endif
> +
> +cleanup-y += $(obj)/piegen
> +cleanup-y += $(obj)/*.o
> +
> +ifneq ($(MAKECMDGOALS),clean)
> +incdeps := y
> +endif
> diff --git a/pie/piegen/elf-x86-32.c b/pie/piegen/elf-x86-32.c
> new file mode 100644
> index 000000000000..413113ef396b
> --- /dev/null
> +++ b/pie/piegen/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/pie/piegen/elf-x86-64.c b/pie/piegen/elf-x86-64.c
> new file mode 100644
> index 000000000000..8ba26672bc82
> --- /dev/null
> +++ b/pie/piegen/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/pie/piegen/elf.c b/pie/piegen/elf.c
> new file mode 100644
> index 000000000000..5812c4ca351f
> --- /dev/null
> +++ b/pie/piegen/elf.c
> @@ -0,0 +1,338 @@
> +#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)
> +
> +int handle_elf(const piegen_opt_t *opts, 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;
> +
> + pr_debug("Header\n------------\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------------\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;
> + }
> +
> + 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------------\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);
> + 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);
> + if (strncmp(name, "__export", 8))
> + continue;
> + if (sym->st_shndx && sym->st_shndx < hdr->e_shnum) {
> + sh_src = sec_hdrs[sym->st_shndx];
> + ptr_func_exit(sh_src);
> +#if 0
> + if (ELF_ST_TYPE(sym->st_info) == STT_FUNC ||
> + ELF_ST_TYPE(sym->st_info) == STT_OBJECT)
> +#endif
> + pr_out("#define %s%s 0x%lx\n",
> + opts->prefix_name, name,
> + (unsigned long)(sym->st_value + sh_src->sh_offset));
> + }
> + }
> + }
> +
> + 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_debug("Relocations\n------------\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;
> + Shdr_t *sh_src;
> + 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);
> +
> + sh_src = sec_hdrs[sym->st_shndx];
> + ptr_func_exit(sh_src);
> +
> + 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_src->sh_offset);
> +
> + if (sym->st_shndx == SHN_UNDEF)
> + continue;
> +
> + ptr_func_exit((mem + sh_rel->sh_offset + r->rel.r_offset));
> + 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 = where - mem;
> +
> + pr_debug("\t\t\tvalue 0x%-8lx addend32 %-4d addend64 %-8ld symname %s\n",
> + (unsigned long)sym->st_value, addend32, (long)addend64, name);
> +
> + value32 = (s32)sh_src->sh_offset + (s32)sym->st_value;
> + 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, "
> + ".addend = 0 , .value = 0x%-16x, }, /* R_X86_64_32 */\n",
> + (unsigned int)place, value32 + addend32);
> + 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, "
> + ".addend = 0 , .value = 0x%-16lx, }, /* R_X86_64_64 */\n",
> + (unsigned int)place, (long)(value64 + addend64));
> + break;
> + case R_X86_64_PC32: /* Symbol + Addend - Place (4 bytes) */
> + pr_debug("\t\t\t\tR_386_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_386_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 = 3, "
> + ".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, "
> + ".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; i < ALIGN(size, 8); i++) {
> + if (i && (i % 8) == 0)
> + pr_out("\n\t");
> + if (i < size)
> + pr_out("0x%02x,", ((unsigned char *)mem)[i]);
> + else
> + pr_out("0x00,");
> + }
> + pr_out("};\n");
> +
> +#if defined(CONFIG_X86_64) || defined(CONFIG_X86_32)
> +pr_out(
> +"static __maybe_unused void elf_apply_relocs(void *mem, size_t size, %s *elf_relocs, size_t nr_relocs)\n"
> +"{\n"
> +" size_t i, j;\n"
> +"\n"
> +" for (i = 0, j = 0; i < ARRAY_SIZE(elf_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)mem + 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)mem;\n"
> +" } else {\n"
> +" int *where = (mem + elf_relocs[i].offset);\n"
> +" *where = elf_relocs[i].value + elf_relocs[i].addend + (unsigned long)mem;\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
> new file mode 100644
> index 000000000000..45bbf24545a0
> --- /dev/null
> +++ b/pie/piegen/main.c
> @@ -0,0 +1,127 @@
> +#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 = "file.o",
> + .stream_name = "stream",
> + .type_name = "elf_reloc_t",
> + .prefix_name = "__",
> + .var_name = "elf_relocs",
> + .nrgotpcrel_name = "nr_gotpcrel",
> +};
> +
> +static int handle_elf(const piegen_opt_t *opts, 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(opts, mem, size);
> + else if (memcmp(mem, elf_ident_x86_64, sizeof(elf_ident_x86_64)) == 0)
> + return handle_elf_x86_64(opts, mem, size);
> +#endif
> +
> + 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:s:t: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' },
> + { },
> + };
> +
> + 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 's':
> + opts.stream_name = optarg;
> + break;
> + case 'p':
> + opts.prefix_name = optarg;
> + break;
> + case 't':
> + opts.type_name = optarg;
> + break;
> + case 'v':
> + opts.var_name = optarg;
> + break;
> + case 'h':
> + default:
> + 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;
> + }
> +
> + 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(&opts, mem, st.st_size))
> + goto err;
> + return 1;
> +usage:
> + printf("Usage: %s -f filename\n", argv[0]);
> +err:
> + return 0;
> +}
> diff --git a/pie/piegen/piegen.h b/pie/piegen/piegen.h
> new file mode 100644
> index 000000000000..10505d758125
> --- /dev/null
> +++ b/pie/piegen/piegen.h
> @@ -0,0 +1,34 @@
> +#ifndef __ELFTIL_H__
> +#define __ELFTIL_H__
> +
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +typedef struct {
> + char *input_filename;
> + char *stream_name;
> + char *type_name;
> + char *prefix_name;
> + char *var_name;
> + char *nrgotpcrel_name;
> +} piegen_opt_t;
> +
> +extern piegen_opt_t opts;
> +
> +#if defined(CONFIG_X86_32) || defined(CONFIG_X86_64)
> +extern int handle_elf_x86_32(const piegen_opt_t *opts, void *mem, size_t size);
> +extern int handle_elf_x86_64(const piegen_opt_t *opts, void *mem, size_t size);
> +#endif
> +
> +#define pr_out(fmt, ...) fprintf(stdout, fmt, ##__VA_ARGS__)
> +
> +#if 0
> +# define pr_debug(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
> +#else
> +# define pr_debug(fmt, ...)
> +#endif
> +
> +#define pr_err(fmt, ...) fprintf(stderr, "Error (%s:%d): "fmt, __FILE__, __LINE__, ##__VA_ARGS__)
> +#define pr_perror(fmt, ...) fprintf(stderr, "Error (%s:%d): "fmt "%m\n", __FILE__, __LINE__, ##__VA_ARGS__)
> +
> +#endif /* __ELFTIL_H__ */
>
More information about the CRIU
mailing list