#define _GNU_SOURCE #include #include #include #include #include #include "asmsh_check.h" #include "compile.h" static const char *valid_syntax[] = { "mov %rax, %rbx", "mov %al, %ah", "add 1, %rbx", }; static const int valid_syntax_sz = sizeof(valid_syntax)/sizeof(*valid_syntax); START_TEST(test_syntax_valid) { const char *instr = valid_syntax[_i]; char *reason = NULL; int ret; ret = asmsh_asmc_syntax(instr, &reason); ck_assert_int_eq(ret, 0); ck_assert_ptr_null(reason); } END_TEST static const char *invalid_syntax[] = { "mov %al,\x0A %ah", "mov %rax, %rbx;", "mov %al, %ah\n", "#add 1, %rbx", ".section text", }; static const int invalid_syntax_sz = sizeof(invalid_syntax)/sizeof(*invalid_syntax); START_TEST(test_syntax_invalid) { const char *instr = invalid_syntax[_i]; char *reason = NULL; int ret; ret = asmsh_asmc_syntax(instr, &reason); ck_assert_int_eq(ret, -1); ck_assert_ptr_nonnull(reason); free(reason); } END_TEST static char* const bargs0[] = ASMSH_COMPILE_ARGS; static char* const bargs1[] = { "foo", "bar", NULL, NULL, "poison"}; static char* const* const bargs[] = {bargs0, bargs1}; static const char *bobj[] = { ASMSH_COMPILE_OBJ, "abcXXXXXX", }; static const char *basmc[] = { ASMSH_COMPILE_AS, "cc" }; static const int buildarg_sz = sizeof(bobj)/sizeof(*bobj); START_TEST(test_buildarg) { char *const *args_in = bargs[_i]; const char *result_tpl = bobj[_i]; const char *prgname = basmc[_i]; int ret; char *progname, *respath; char **args; int i; ret = asmsh_asmc_buildarg(prgname, result_tpl, args_in, &args, &progname, &respath); ck_assert_int_eq(ret, 0); ck_assert_ptr_nonnull(respath); unlink(respath); ck_assert_ptr_nonnull(args); ck_assert_ptr_nonnull(progname); i=0; while(args[i]) { if(i == 0) { ck_assert_str_eq(progname, args[0]); ck_assert_str_eq(progname, prgname); } else if(args_in[i]) { ck_assert_str_eq(args_in[i], args[i]); } else { ck_assert_str_eq(args[i], respath); } free(args[i]); i++; } ck_assert_ptr_null(args[i]); free(args); } END_TEST START_TEST(test_ctx) { int i; const char *_args[] = ASMSH_COMPILE_ARGS; const char **args = _args; asmsh_asmc_ctx_t *ctx = asmsh_asmc_ctx_default(); ck_assert_ptr_nonnull(ctx); ck_assert_ptr_nonnull(ctx->respath); unlink(ctx->respath); ck_assert_ptr_nonnull(ctx->progname); ck_assert_str_eq(ctx->args[0], ctx->progname); i=1; while(args[i]) { ck_assert_str_eq(ctx->args[i], args[i]); i++; } ck_assert_str_eq(ctx->args[i], ctx->respath); i++; while(args[i]) { ck_assert_str_eq(ctx->args[i], args[i]); i++; } ck_assert_ptr_null(ctx->args[i]); asmsh_asmc_ctx_free(ctx); } END_TEST typedef struct { asmsh_bytecode_t bcode; char *instr; } compile_sample_t; static const compile_sample_t comp_samples[] = { {{"\x48\x83\xc0\x03\0", 4}, "add $3, %rax"}, {{"\x48\x89\xc3\0", 3}, "mov %rax, %rbx"}, {{"\xbf\x2a\x00\x00\x00", 5}, "mov $42, %rdi"}, {{"\x31\xc0\0", 2}, "xor %rax, %rax"}, {{"\x53\0", 1}, "push %rbx"}, {{"\x0f\x05\0", 2}, "syscall"}, }; static const int comp_samples_sz = sizeof(comp_samples)/sizeof(*comp_samples); START_TEST(test_compile) { int ret; asmsh_bytecode_t bcode; asmsh_asmc_ctx_t *ctx = asmsh_asmc_ctx_default(); ret = asmsh_asmc_compile(ctx, comp_samples[_i].instr, &bcode); ck_assert_int_eq(ret, 0); ck_assert_int_eq(bcode.size, comp_samples[_i].bcode.size); ck_assert_mem_eq(bcode.bytes, comp_samples[_i].bcode.bytes, bcode.size); //ck_assert_str_eq(bcode.bytes, comp_samples[_i].bcode.bytes); asmsh_asmc_ctx_free(ctx); } END_TEST START_TEST(test_compile_recover_err) { int ret; asmsh_bytecode_t bcode; asmsh_asmc_ctx_t *ctx = asmsh_asmc_ctx_default(); ret = asmsh_asmc_compile(ctx, "bad instruction %are not compiled", &bcode); ck_assert_int_ne(ret, 0); ret = asmsh_asmc_compile(ctx, "syscall", &bcode); ck_assert_int_eq(ret, 0); ck_assert_int_eq(bcode.size, 2); ck_assert_mem_eq(bcode.bytes, "\x0f\x05\0", bcode.size); asmsh_asmc_ctx_free(ctx); } END_TEST /// TODO test error cases /// TODO loop test on asmsh_asmc_ctx with various args ASMSH_CHECK_START("compilation tests", "testing compilation functions") ASMSH_ADD_LOOP_TEST(test_buildarg, 0, buildarg_sz); ASMSH_ADD_LOOP_TEST(test_syntax_valid, 0, valid_syntax_sz); ASMSH_ADD_LOOP_TEST(test_syntax_invalid, 0, invalid_syntax_sz); ASMSH_ADD_TEST(test_ctx); ASMSH_ADD_LOOP_TEST(test_compile, 0, comp_samples_sz); ASMSH_ADD_TEST(test_compile_recover_err); ASMSH_CHECK_END