Commit 6fe6a283 authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Andrei Vagin

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: 's avatarDmitry Safonov <dsafonov@virtuozzo.com>
Reviewed-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 89978b5b
...@@ -205,6 +205,9 @@ $(eval $(call gen-built-in,images)) ...@@ -205,6 +205,9 @@ $(eval $(call gen-built-in,images))
compel/%: compel/%:
$(Q) $(MAKE) $(build)=compel $@ $(Q) $(MAKE) $(build)=compel $@
test/compel/%:
$(Q) $(MAKE) $(build)=compel $@
# #
# Next the socket CR library # Next the socket CR library
# #
...@@ -244,6 +247,7 @@ lib: criu ...@@ -244,6 +247,7 @@ lib: criu
subclean: subclean:
$(Q) $(MAKE) -C Documentation clean $(Q) $(MAKE) -C Documentation clean
$(Q) $(MAKE) $(build)=test/compel clean
$(Q) $(RM) .gitid $(Q) $(RM) .gitid
.PHONY: subclean .PHONY: subclean
......
...@@ -6,8 +6,10 @@ ccflags-y += -iquote compel/arch/$(ARCH)/include ...@@ -6,8 +6,10 @@ ccflags-y += -iquote compel/arch/$(ARCH)/include
ccflags-y += -DCOMPEL_VERSION=\"$(COMPEL_SO_VERSION_MAJOR).$(COMPEL_SO_VERSION_MINOR)\" ccflags-y += -DCOMPEL_VERSION=\"$(COMPEL_SO_VERSION_MAJOR).$(COMPEL_SO_VERSION_MINOR)\"
host-ccflags-y += $(filter-out -pg $(CFLAGS-GCOV),$(ccflags-y)) 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)) HOSTLDFLAGS += $(filter-out -pg $(CFLAGS-GCOV),$(LDFLAGS))
HOSTCFLAGS := $(filter-out -DCONFIG_X86_64,$(HOSTCFLAGS))
export host-ccflags-y HOSTCFLAGS HOSTLDFLAGS
hostprogs-y += compel hostprogs-y += compel
compel-objs += main.o compel-objs += main.o
...@@ -17,10 +19,18 @@ compel-objs += arch/$(ARCH)/handle-elf.o ...@@ -17,10 +19,18 @@ compel-objs += arch/$(ARCH)/handle-elf.o
ifeq ($(ARCH),x86) ifeq ($(ARCH),x86)
# Add -DCONFIG_X86_64 or -DCONFIG_X86_32 to HOSTCFLAGS # Add -DCONFIG_X86_64 or -DCONFIG_X86_32 to HOSTCFLAGS
define ccflags-defines define ccflags-defines
HOSTCFLAGS_$(notdir $(1)) += -DCONFIG_X86_64 export HOSTCFLAGS_$(notdir $(1)) += -DCONFIG_X86_64
endef endef
$(eval $(call map,ccflags-defines,$(compel-objs))) $(eval $(call map,ccflags-defines,$(compel-objs)))
compel-objs += handle-elf-32.o 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 endif # ARCH == x86
export compel-objs
test/compel/%:
$(Q) $(MAKE) $(build)=test/compel $@
test: test/compel/test_handle_binary
.PHONY: test
# 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
#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__ */
#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__ */
#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__ */
#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__ */
#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;
}
handle_binary.c
\ No newline at end of file
/*
* 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;
}
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