Commit b6668af6 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Pavel Emelyanov

piegen: Implement tool building, v2

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.

Currently only x86-32 x86-64 is supported.

v2 (by ldufour@):
 - Filter PIEGEN
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 7a981334
......@@ -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
......
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
#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"
#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"
This diff is collapsed.
#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;
}
#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__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment