1 /* radare - LGPL - Copyright 2020 - thestr4ng3r */ 2 3 #ifndef RADARE2_R2R_H 4 #define RADARE2_R2R_H 5 6 #include <r_util.h> 7 8 #if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) 9 #define R2R_OS "freebsd" 10 #elif defined(__linux__) 11 #define R2R_OS "linux" 12 #elif defined(__APPLE__) 13 #define R2R_OS "darwin" 14 #elif __WINDOWS__ 15 #define R2R_OS "windows" 16 #else 17 #define R2R_OS "unknown" 18 #endif 19 20 #if __i386__ 21 #define R2R_ARCH "x86" 22 #elif __x86_64__ 23 #define R2R_ARCH "x64" 24 #else 25 #define R2R_ARCH "unknown" 26 #endif 27 28 #define R2R_ARCH_OS R2R_OS"-"R2R_ARCH 29 30 typedef struct r2r_cmd_test_string_record { 31 char *value; 32 ut64 line_begin; // inclusive 33 ut64 line_end; // exclusive 34 } R2RCmdTestStringRecord; 35 36 typedef struct r2r_cmd_test_bool_record { 37 bool value; 38 ut64 line; // bools are always oneliners (e.g. BROKEN=1) 39 bool set; 40 } R2RCmdTestBoolRecord; 41 42 typedef struct r2r_cmd_test_num_record { 43 ut64 value; 44 ut64 line; // nums are always oneliners (e.g. TIMEOUT=10) 45 bool set; 46 } R2RCmdTestNumRecord; 47 48 typedef struct r2r_cmd_test_t { 49 R2RCmdTestStringRecord name; 50 R2RCmdTestStringRecord file; 51 R2RCmdTestStringRecord args; 52 R2RCmdTestStringRecord source; 53 R2RCmdTestStringRecord cmds; 54 R2RCmdTestStringRecord expect; 55 R2RCmdTestStringRecord expect_err; 56 R2RCmdTestStringRecord regexp_out; 57 R2RCmdTestStringRecord regexp_err; 58 R2RCmdTestBoolRecord broken; 59 R2RCmdTestNumRecord timeout; 60 ut64 run_line; 61 bool load_plugins; 62 } R2RCmdTest; 63 64 #define R2R_CMD_TEST_FOREACH_RECORD_NOP(name, field) 65 #define R2R_CMD_TEST_FOREACH_RECORD(macro_str, macro_bool, macro_int) \ 66 macro_str ("NAME", name) \ 67 macro_str ("FILE", file) \ 68 macro_str ("ARGS", args) \ 69 macro_int ("TIMEOUT", timeout) \ 70 macro_str ("SOURCE", source) \ 71 macro_str ("CMDS", cmds) \ 72 macro_str ("EXPECT", expect) \ 73 macro_str ("EXPECT_ERR", expect_err) \ 74 macro_str ("REGEXP_OUT", regexp_out) \ 75 macro_str ("REGEXP_ERR", regexp_err) \ 76 macro_bool ("BROKEN", broken) 77 78 typedef enum r2r_asm_test_mode_t { 79 R2R_ASM_TEST_MODE_ASSEMBLE = 1, 80 R2R_ASM_TEST_MODE_DISASSEMBLE = (1 << 1), 81 R2R_ASM_TEST_MODE_BIG_ENDIAN = (1 << 2), 82 R2R_ASM_TEST_MODE_BROKEN = (1 << 3) 83 } R2RAsmTestMode; 84 85 typedef struct r2r_asm_test_t { 86 ut64 line; 87 const char *arch; 88 const char *cpu; 89 int bits; 90 int mode; 91 ut64 offset; 92 char *disasm; 93 ut8 *bytes; 94 size_t bytes_size; 95 } R2RAsmTest; 96 97 typedef struct r2r_json_test_t { 98 ut64 line; 99 char *cmd; 100 bool broken; 101 bool load_plugins; 102 } R2RJsonTest; 103 104 typedef struct r2r_fuzz_test_t { 105 char *file; 106 } R2RFuzzTest; 107 108 typedef enum r2r_test_type_t { 109 R2R_TEST_TYPE_CMD, 110 R2R_TEST_TYPE_ASM, 111 R2R_TEST_TYPE_JSON, 112 R2R_TEST_TYPE_FUZZ 113 } R2RTestType; 114 115 typedef struct r2r_test_t { 116 const char *path; 117 R2RTestType type; 118 union { 119 R2RCmdTest *cmd_test; 120 R2RAsmTest *asm_test; 121 R2RJsonTest *json_test; 122 R2RFuzzTest *fuzz_test; 123 }; 124 } R2RTest; 125 126 typedef struct r2r_test_database_t { 127 RPVector tests; 128 RStrConstPool strpool; 129 } R2RTestDatabase; 130 131 typedef struct r2r_run_config_t { 132 const char *r2_cmd; 133 const char *rasm2_cmd; 134 const char *json_test_file; 135 ut64 timeout_ms; 136 } R2RRunConfig; 137 138 typedef struct r2r_process_output_t { 139 char *out; // stdout 140 char *err; // stderr 141 int ret; // exit code of the process 142 bool timeout; 143 } R2RProcessOutput; 144 145 typedef struct r2r_asm_test_output_t { 146 char *disasm; 147 ut8 *bytes; 148 size_t bytes_size; 149 bool as_timeout; 150 bool disas_timeout; 151 } R2RAsmTestOutput; 152 153 typedef enum r2r_test_result_t { 154 R2R_TEST_RESULT_OK, 155 R2R_TEST_RESULT_FAILED, 156 R2R_TEST_RESULT_BROKEN, 157 R2R_TEST_RESULT_FIXED 158 } R2RTestResult; 159 160 typedef struct r2r_test_result_info_t { 161 R2RTest *test; 162 R2RTestResult result; 163 bool timeout; 164 bool run_failed; // something went seriously wrong (e.g. r2 not found) 165 ut64 time_elapsed; 166 union { 167 R2RProcessOutput *proc_out; // for test->type == R2R_TEST_TYPE_CMD, R2R_TEST_TYPE_JSON or R2R_TEST_TYPE_FUZZ 168 R2RAsmTestOutput *asm_out; // for test->type == R2R_TEST_TYPE_ASM 169 }; 170 } R2RTestResultInfo; 171 172 R_API R2RCmdTest *r2r_cmd_test_new(void); 173 R_API void r2r_cmd_test_free(R2RCmdTest *test); 174 R_API RPVector *r2r_load_cmd_test_file(const char *file); 175 176 R_API R2RAsmTest *r2r_asm_test_new(void); 177 R_API void r2r_asm_test_free(R2RAsmTest *test); 178 R_API RPVector *r2r_load_asm_test_file(RStrConstPool *strpool, const char *file); 179 180 R_API R2RJsonTest *r2r_json_test_new(void); 181 R_API void r2r_json_test_free(R2RJsonTest *test); 182 R_API RPVector *r2r_load_json_test_file(const char *file); 183 184 R_API R2RTestDatabase *r2r_test_database_new(void); 185 R_API void r2r_test_database_free(R2RTestDatabase *db); 186 R_API bool r2r_test_database_load(R2RTestDatabase *db, const char *path); 187 R_API bool r2r_test_database_load_fuzz(R2RTestDatabase *db, const char *path); 188 189 typedef struct r2r_subprocess_t R2RSubprocess; 190 191 R_API bool r2r_subprocess_init(void); 192 R_API void r2r_subprocess_fini(void); 193 R_API R2RSubprocess *r2r_subprocess_start( 194 const char *file, const char *args[], size_t args_size, 195 const char *envvars[], const char *envvals[], size_t env_size); 196 R_API bool r2r_subprocess_wait(R2RSubprocess *proc, ut64 timeout_ms); 197 R_API void r2r_subprocess_free(R2RSubprocess *proc); 198 199 typedef R2RProcessOutput *(*R2RCmdRunner)(const char *file, const char *args[], size_t args_size, 200 const char *envvars[], const char *envvals[], size_t env_size, ut64 timeout_ms, void *user); 201 202 R_API void r2r_process_output_free(R2RProcessOutput *out); 203 R_API R2RProcessOutput *r2r_run_cmd_test(R2RRunConfig *config, R2RCmdTest *test, R2RCmdRunner runner, void *user); 204 R_API bool r2r_check_cmd_test(R2RProcessOutput *out, R2RCmdTest *test); 205 R_API bool r2r_check_jq_available(void); 206 R_API R2RProcessOutput *r2r_run_json_test(R2RRunConfig *config, R2RJsonTest *test, R2RCmdRunner runner, void *user); 207 R_API bool r2r_check_json_test(R2RProcessOutput *out, R2RJsonTest *test); 208 R_API R2RAsmTestOutput *r2r_run_asm_test(R2RRunConfig *config, R2RAsmTest *test); 209 R_API bool r2r_check_asm_test(R2RAsmTestOutput *out, R2RAsmTest *test); 210 R_API void r2r_asm_test_output_free(R2RAsmTestOutput *out); 211 R_API R2RProcessOutput *r2r_run_fuzz_test(R2RRunConfig *config, R2RFuzzTest *test, R2RCmdRunner runner, void *user); 212 R_API bool r2r_check_fuzz_test(R2RProcessOutput *out); 213 214 R_API void r2r_test_free(R2RTest *test); 215 R_API char *r2r_test_name(R2RTest *test); 216 R_API bool r2r_test_broken(R2RTest *test); 217 R_API R2RTestResultInfo *r2r_run_test(R2RRunConfig *config, R2RTest *test); 218 R_API void r2r_test_result_info_free(R2RTestResultInfo *result); 219 220 #endif //RADARE2_R2R_H 221