compel: add tests for compel

Yet they only test for ELF header, but soon I'll add more of them.
It's build with
  $ make test/compel/handle_binary
and test output is in TAP format:
  $ ./test/compel/handle_binary
  ok 1 - check zero ELF header
  ok 2 - check non-supported ELF header
  ok 3 - check non-relocatable ELF header
  ok 4 - check zero ELF header
  ok 5 - check non-supported ELF header
  ok 6 - check non-relocatable ELF header
(here two runs for x86_64 and x86_32 ELF binaries)
I'm planning to integrate it with Travis, so we will be
sure that compel is properly working (as this tests doesn't need
any ns and may be run on qemu-static).

Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com>
Reviewed-by: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
Dmitry Safonov 2016-05-11 15:49:00 +03:00 committed by Andrei Vagin
parent 89978b5b1d
commit 6fe6a283e1
10 changed files with 234 additions and 3 deletions

View file

@ -205,6 +205,9 @@ $(eval $(call gen-built-in,images))
compel/%:
$(Q) $(MAKE) $(build)=compel $@
test/compel/%:
$(Q) $(MAKE) $(build)=compel $@
#
# Next the socket CR library
#
@ -244,6 +247,7 @@ lib: criu
subclean:
$(Q) $(MAKE) -C Documentation clean
$(Q) $(MAKE) $(build)=test/compel clean
$(Q) $(RM) .gitid
.PHONY: subclean

View file

@ -6,8 +6,10 @@ ccflags-y += -iquote compel/arch/$(ARCH)/include
ccflags-y += -DCOMPEL_VERSION=\"$(COMPEL_SO_VERSION_MAJOR).$(COMPEL_SO_VERSION_MINOR)\"
host-ccflags-y += $(filter-out -pg $(CFLAGS-GCOV),$(ccflags-y))
HOSTCFLAGS += $(filter-out -pg $(CFLAGS-GCOV),$(WARNINGS) $(filter-out -DCONFIG_X86_64,$(DEFINES)))
HOSTCFLAGS += $(filter-out -pg $(CFLAGS-GCOV),$(WARNINGS) $(DEFINES))
HOSTLDFLAGS += $(filter-out -pg $(CFLAGS-GCOV),$(LDFLAGS))
HOSTCFLAGS := $(filter-out -DCONFIG_X86_64,$(HOSTCFLAGS))
export host-ccflags-y HOSTCFLAGS HOSTLDFLAGS
hostprogs-y += compel
compel-objs += main.o
@ -17,10 +19,18 @@ compel-objs += arch/$(ARCH)/handle-elf.o
ifeq ($(ARCH),x86)
# Add -DCONFIG_X86_64 or -DCONFIG_X86_32 to HOSTCFLAGS
define ccflags-defines
HOSTCFLAGS_$(notdir $(1)) += -DCONFIG_X86_64
export HOSTCFLAGS_$(notdir $(1)) += -DCONFIG_X86_64
endef
$(eval $(call map,ccflags-defines,$(compel-objs)))
compel-objs += handle-elf-32.o
HOSTCFLAGS_handle-elf-32.o += -DCONFIG_X86_32
export HOSTCFLAGS_handle-elf-32.o += -DCONFIG_X86_32
endif # ARCH == x86
export compel-objs
test/compel/%:
$(Q) $(MAKE) $(build)=test/compel $@
test: test/compel/test_handle_binary
.PHONY: test

18
test/compel/Makefile Normal file
View file

@ -0,0 +1,18 @@
# Relative path to original objects
define compel_obj_path
$(addprefix ../../compel/,$(1))
endef
host-ccflags-y += -iquote test/compel/arch/$(ARCH)/include
test_objs := $(filter-out main.o,$(compel-objs))
hostprogs-y += handle_binary
handle_binary-objs += $(call compel_obj_path,$(test_objs))
handle_binary-objs += main.o
handle_binary-objs += handle_binary.o
ifeq ($(ARCH),x86)
handle_binary-objs += handle_binary_32.o
HOSTCFLAGS_handle_binary.o += -DCONFIG_X86_64
HOSTCFLAGS_handle_binary_32.o += -DCONFIG_X86_32
endif

View file

@ -0,0 +1,21 @@
#ifndef __ARCH_TEST_HANDLE_BINARY__
#define __ARCH_TEST_HANDLE_BINARY__
#include "uapi/elf64-types.h"
#define __run_tests arch_run_tests
static __maybe_unused void arch_test_set_elf_hdr_ident(void *mem)
{
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
memcpy(mem, elf_ident_64_le, sizeof(elf_ident_64_le));
#else
memcpy(mem, elf_ident_64_be, sizeof(elf_ident_64_be));
#endif
}
static __maybe_unused void arch_test_set_elf_hdr_machine(Ehdr_t *hdr)
{
hdr->e_machine = EM_AARCH64;
}
#endif /* __ARCH_TEST_HANDLE_BINARY__ */

View file

@ -0,0 +1,18 @@
#ifndef __ARCH_TEST_HANDLE_BINARY__
#define __ARCH_TEST_HANDLE_BINARY__
#include "uapi/elf32-types.h"
#define __run_tests arch_run_tests
static __maybe_unused void arch_test_set_elf_hdr_ident(void *mem)
{
memcpy(mem, elf_ident_32, sizeof(elf_ident_32));
}
static __maybe_unused void arch_test_set_elf_hdr_machine(Ehdr_t *hdr)
{
hdr->e_machine = EM_ARM;
}
#endif /* __ARCH_TEST_HANDLE_BINARY__ */

View file

@ -0,0 +1,21 @@
#ifndef __ARCH_TEST_HANDLE_BINARY__
#define __ARCH_TEST_HANDLE_BINARY__
#include "uapi/elf64-types.h"
#define __run_tests arch_run_tests
static __maybe_unused void arch_test_set_elf_hdr_ident(void *mem)
{
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
memcpy(mem, elf_ident_64_le, sizeof(elf_ident_64_le));
#else
memcpy(mem, elf_ident_64_be, sizeof(elf_ident_64_be));
#endif
}
static __maybe_unused void arch_test_set_elf_hdr_machine(Ehdr_t *hdr)
{
hdr->e_machine = EM_PPC64;
}
#endif /* __ARCH_TEST_HANDLE_BINARY__ */

View file

@ -0,0 +1,45 @@
#ifndef __ARCH_TEST_HANDLE_BINARY__
#define __ARCH_TEST_HANDLE_BINARY__
#include <string.h>
#ifdef CONFIG_X86_64
#include "uapi/elf64-types.h"
#define __run_tests run_tests_64
static __maybe_unused void arch_test_set_elf_hdr_ident(void *mem)
{
memcpy(mem, elf_ident_64_le, sizeof(elf_ident_64_le));
}
static __maybe_unused void arch_test_set_elf_hdr_machine(Ehdr_t *hdr)
{
hdr->e_machine = EM_X86_64;
}
#else /* !CONFIG_X86_64 */
#include "uapi/elf32-types.h"
#define __run_tests run_tests_32
static __maybe_unused void arch_test_set_elf_hdr_ident(void *mem)
{
memcpy(mem, elf_ident_32, sizeof(elf_ident_32));
}
static __maybe_unused void arch_test_set_elf_hdr_machine(Ehdr_t *hdr)
{
hdr->e_machine = EM_386;
}
#endif /* CONFIG_X86_32 */
extern void run_tests_64(void *mem);
extern void run_tests_32(void *mem);
static __maybe_unused void arch_run_tests(void *mem)
{
run_tests_64(mem);
run_tests_32(mem);
}
#endif /* __ARCH_TEST_HANDLE_BINARY__ */

View file

@ -0,0 +1,39 @@
#include <string.h>
#include "uapi/piegen-err.h"
#include "piegen.h"
#include "arch_test_handle_binary.h"
extern int launch_test(void *mem, int expected_ret, const char *test_name);
static void set_elf_hdr_relocatable(Ehdr_t *hdr)
{
hdr->e_type = ET_REL;
hdr->e_version = EV_CURRENT;
}
static int test_prepare_elf_header(void *elf)
{
memset(elf, 0, sizeof(Ehdr_t));
if (launch_test(elf, -E_NOT_ELF, "check zero ELF header"))
return -1;
arch_test_set_elf_hdr_ident(elf);
if (launch_test(elf, -E_NOT_ELF, "check non-supported ELF header"))
return -1;
arch_test_set_elf_hdr_machine(elf);
if (launch_test(elf, -E_NOT_ELF, "check non-relocatable ELF header"))
return -1;
set_elf_hdr_relocatable(elf);
return 0;
}
void __run_tests(void *mem)
{
if (test_prepare_elf_header(mem))
return;
}

View file

@ -0,0 +1 @@
handle_binary.c

54
test/compel/main.c Normal file
View file

@ -0,0 +1,54 @@
/*
* Test for handle_binary().
* In this test ELF binary file is constructed from
* header up to sections and relocations.
* On each stage it tests non-valid ELF binaries to be parsed.
* For passing test, handle_binary should return errors for all
* non-valid binaries and handle all relocations.
*
* Test author: Dmitry Safonov <dsafonov@virtuozzo.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "piegen.h"
#include "arch_test_handle_binary.h"
/* size of buffer with formed ELF file */
#define ELF_BUF_SIZE 4096
extern int handle_binary(void *mem, size_t size);
extern void run_tests(void *mem);
piegen_opt_t opts = {
.fout = NULL,
.ferr = NULL,
.fdebug = NULL,
};
int launch_test(void *mem, int expected_ret, const char *test_name)
{
static unsigned test_nr = 1;
int ret = handle_binary(mem, ELF_BUF_SIZE);
if (ret != expected_ret)
printf("not ok %u - %s, expected %d but ret is %d\n",
test_nr, test_name, expected_ret, ret);
else
printf("ok %u - %s\n", test_nr, test_name);
test_nr++;
fflush(stdout);
return ret != expected_ret;
}
int main(int argc, char **argv)
{
void *elf_buf = malloc(ELF_BUF_SIZE);
arch_run_tests(elf_buf);
free(elf_buf);
return 0;
}