A shell that runs x86_64 assembly
c
x86-64
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

tests_compile.c 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. #define _GNU_SOURCE
  2. #include <check.h>
  3. #include <errno.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <unistd.h>
  7. #include "asmsh_check.h"
  8. #include "compile.h"
  9. static const char *valid_syntax[] = {
  10. "mov %rax, %rbx",
  11. "mov %al, %ah",
  12. "add 1, %rbx",
  13. };
  14. static const int valid_syntax_sz = sizeof(valid_syntax)/sizeof(*valid_syntax);
  15. START_TEST(test_syntax_valid)
  16. {
  17. const char *instr = valid_syntax[_i];
  18. char *reason = NULL;
  19. int ret;
  20. ret = asmsh_asmc_syntax(instr, &reason);
  21. ck_assert_int_eq(ret, 0);
  22. ck_assert_ptr_null(reason);
  23. }
  24. END_TEST
  25. static const char *invalid_syntax[] = {
  26. "mov %al,\x0A %ah",
  27. "mov %rax, %rbx;",
  28. "mov %al, %ah\n",
  29. "#add 1, %rbx",
  30. ".section text",
  31. };
  32. static const int invalid_syntax_sz = sizeof(invalid_syntax)/sizeof(*invalid_syntax);
  33. START_TEST(test_syntax_invalid)
  34. {
  35. const char *instr = invalid_syntax[_i];
  36. char *reason = NULL;
  37. int ret;
  38. ret = asmsh_asmc_syntax(instr, &reason);
  39. ck_assert_int_eq(ret, -1);
  40. ck_assert_ptr_nonnull(reason);
  41. free(reason);
  42. }
  43. END_TEST
  44. static char* const bargs0[] = ASMSH_COMPILE_ARGS;
  45. static char* const bargs1[] = { "foo", "bar", NULL, NULL, "poison"};
  46. static char* const* const bargs[] = {bargs0, bargs1};
  47. static const char *bobj[] = {
  48. ASMSH_COMPILE_OBJ,
  49. "abcXXXXXX",
  50. };
  51. static const char *basmc[] = {
  52. ASMSH_COMPILE_AS,
  53. "cc"
  54. };
  55. static const int buildarg_sz = sizeof(bobj)/sizeof(*bobj);
  56. START_TEST(test_buildarg)
  57. {
  58. char *const *args_in = bargs[_i];
  59. const char *result_tpl = bobj[_i];
  60. const char *prgname = basmc[_i];
  61. int ret;
  62. char *progname, *respath;
  63. char **args;
  64. int i;
  65. ret = asmsh_asmc_buildarg(prgname, result_tpl, args_in,
  66. &args, &progname, &respath);
  67. ck_assert_int_eq(ret, 0);
  68. ck_assert_ptr_nonnull(respath);
  69. unlink(respath);
  70. ck_assert_ptr_nonnull(args);
  71. ck_assert_ptr_nonnull(progname);
  72. i=0;
  73. while(args[i])
  74. {
  75. if(i == 0)
  76. {
  77. ck_assert_str_eq(progname, args[0]);
  78. ck_assert_str_eq(progname, prgname);
  79. }
  80. else if(args_in[i])
  81. {
  82. ck_assert_str_eq(args_in[i], args[i]);
  83. }
  84. else
  85. {
  86. ck_assert_str_eq(args[i], respath);
  87. }
  88. free(args[i]);
  89. i++;
  90. }
  91. ck_assert_ptr_null(args[i]);
  92. free(args);
  93. }
  94. END_TEST
  95. START_TEST(test_ctx)
  96. {
  97. int i;
  98. const char *_args[] = ASMSH_COMPILE_ARGS;
  99. const char **args = _args;
  100. asmsh_asmc_ctx_t *ctx = asmsh_asmc_ctx_default();
  101. ck_assert_ptr_nonnull(ctx);
  102. ck_assert_ptr_nonnull(ctx->respath);
  103. unlink(ctx->respath);
  104. ck_assert_ptr_nonnull(ctx->progname);
  105. ck_assert_str_eq(ctx->args[0], ctx->progname);
  106. i=1;
  107. while(args[i])
  108. {
  109. ck_assert_str_eq(ctx->args[i], args[i]);
  110. i++;
  111. }
  112. ck_assert_str_eq(ctx->args[i], ctx->respath);
  113. i++;
  114. while(args[i])
  115. {
  116. ck_assert_str_eq(ctx->args[i], args[i]);
  117. i++;
  118. }
  119. ck_assert_ptr_null(ctx->args[i]);
  120. asmsh_asmc_ctx_free(ctx);
  121. }
  122. END_TEST
  123. typedef struct
  124. {
  125. asmsh_bytecode_t bcode;
  126. char *instr;
  127. } compile_sample_t;
  128. static const compile_sample_t comp_samples[] = {
  129. {{"\x48\x83\xc0\x03\0", 4}, "add $3, %rax"},
  130. {{"\x48\x89\xc3\0", 3}, "mov %rax, %rbx"},
  131. {{"\xbf\x2a\x00\x00\x00", 5}, "mov $42, %rdi"},
  132. {{"\x31\xc0\0", 2}, "xor %rax, %rax"},
  133. {{"\x53\0", 1}, "push %rbx"},
  134. {{"\x0f\x05\0", 2}, "syscall"},
  135. };
  136. static const int comp_samples_sz = sizeof(comp_samples)/sizeof(*comp_samples);
  137. START_TEST(test_compile)
  138. {
  139. int ret;
  140. asmsh_bytecode_t bcode;
  141. asmsh_asmc_ctx_t *ctx = asmsh_asmc_ctx_default();
  142. ret = asmsh_asmc_compile(ctx, comp_samples[_i].instr, &bcode);
  143. ck_assert_int_eq(ret, 0);
  144. ck_assert_int_eq(bcode.size, comp_samples[_i].bcode.size);
  145. ck_assert_mem_eq(bcode.bytes, comp_samples[_i].bcode.bytes,
  146. bcode.size);
  147. //ck_assert_str_eq(bcode.bytes, comp_samples[_i].bcode.bytes);
  148. asmsh_asmc_ctx_free(ctx);
  149. }
  150. END_TEST
  151. START_TEST(test_compile_recover_err)
  152. {
  153. int ret;
  154. asmsh_bytecode_t bcode;
  155. asmsh_asmc_ctx_t *ctx = asmsh_asmc_ctx_default();
  156. ret = asmsh_asmc_compile(ctx, "bad instruction %are not compiled", &bcode);
  157. ck_assert_int_ne(ret, 0);
  158. ret = asmsh_asmc_compile(ctx, "syscall", &bcode);
  159. ck_assert_int_eq(ret, 0);
  160. ck_assert_int_eq(bcode.size, 2);
  161. ck_assert_mem_eq(bcode.bytes, "\x0f\x05\0", bcode.size);
  162. asmsh_asmc_ctx_free(ctx);
  163. }
  164. END_TEST
  165. /// TODO test error cases
  166. /// TODO loop test on asmsh_asmc_ctx with various args
  167. ASMSH_CHECK_START("compilation tests", "testing compilation functions")
  168. ASMSH_ADD_LOOP_TEST(test_buildarg, 0, buildarg_sz);
  169. ASMSH_ADD_LOOP_TEST(test_syntax_valid, 0, valid_syntax_sz);
  170. ASMSH_ADD_LOOP_TEST(test_syntax_invalid, 0, invalid_syntax_sz);
  171. ASMSH_ADD_TEST(test_ctx);
  172. ASMSH_ADD_LOOP_TEST(test_compile, 0, comp_samples_sz);
  173. ASMSH_ADD_TEST(test_compile_recover_err);
  174. ASMSH_CHECK_END