Because there is currently no reason to have non-ctrl effects after a ctrl effect (because then we have already jumped somewhere else), we reject this kind of code altogether. This leaves future semantics of such code open without breaking any existing IL, in case it will be needed at some point.
1336 lines
53 KiB
C
1336 lines
53 KiB
C
// SPDX-FileCopyrightText: 2022 Florian Märkl <info@florianmaerkl.de>
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
|
|
#include <rz_il.h>
|
|
#include <rz_util.h>
|
|
#include "minunit.h"
|
|
|
|
static bool test_il_validate_pure_bool() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
RzILOpPure *op = rz_il_op_new_b0();
|
|
RzILSortPure sort = rz_il_sort_pure_bv(0xffff);
|
|
RzILValidateReport report;
|
|
bool val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_bool()), "sort");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
op = rz_il_op_new_b1();
|
|
sort = rz_il_sort_pure_bv(0xffff);
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_bool()), "sort");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_pure_null() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
RzILSortPure sort;
|
|
RzILValidateReport report;
|
|
bool val = rz_il_validate_pure(NULL, ctx, &sort, &report);
|
|
mu_assert_false(val, "valid");
|
|
mu_assert_streq_free(report, "Encountered NULL for pure op.", "no report");
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_pure_bitv() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
RzILOpPure *op = rz_il_op_new_bitv_from_ut64(42, 123);
|
|
RzILSortPure sort;
|
|
RzILValidateReport report;
|
|
bool val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_bv(42)), "sort");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_pure_ite() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
RzILOpPure *op = rz_il_op_new_ite(rz_il_op_new_b0(), rz_il_op_new_bitv_from_ut64(32, 0), rz_il_op_new_bitv_from_ut64(32, 0));
|
|
RzILSortPure sort;
|
|
RzILValidateReport report;
|
|
bool val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_bv(32)), "sort");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
op = rz_il_op_new_ite(rz_il_op_new_b0(), rz_il_op_new_b0(), rz_il_op_new_b1());
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_bool()), "sort");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
op = rz_il_op_new_ite(rz_il_op_new_bitv_from_ut64(12, 0), rz_il_op_new_bitv_from_ut64(32, 0), rz_il_op_new_bitv_from_ut64(32, 0));
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "valid");
|
|
mu_assert_streq_free(report, "Condition of ite op is not boolean.", "report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
op = rz_il_op_new_ite(rz_il_op_new_b0(), rz_il_op_new_bitv_from_ut64(32, 0), rz_il_op_new_bitv_from_ut64(31, 0));
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "valid");
|
|
mu_assert_streq_free(report, "Types of ite branches do not agree: bitvector:32 vs. bitvector:31.", "report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_pure_let() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
// body type
|
|
RzILOpPure *op = rz_il_op_new_let(
|
|
"x", rz_il_op_new_b0(),
|
|
rz_il_op_new_bitv_from_ut64(64, 456));
|
|
RzILSortPure sort;
|
|
RzILValidateReport report;
|
|
bool val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_bv(64)), "sort");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
// bound
|
|
op = rz_il_op_new_let(
|
|
"x", rz_il_op_new_b0(),
|
|
rz_il_op_new_var("x", RZ_IL_VAR_KIND_LOCAL_PURE));
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_bool()), "sort");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
// shadowing
|
|
op = rz_il_op_new_let(
|
|
"x", rz_il_op_new_b0(),
|
|
rz_il_op_new_let(
|
|
"y", rz_il_op_new_bitv_from_ut64(32, 123),
|
|
rz_il_op_new_let(
|
|
"x", rz_il_op_new_bitv_from_ut64(42, 321),
|
|
rz_il_op_new_var("x", RZ_IL_VAR_KIND_LOCAL_PURE))));
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_bv(42)), "sort");
|
|
mu_assert_null(report, "no report");
|
|
free(report);
|
|
rz_il_op_pure_free(op);
|
|
|
|
op = rz_il_op_new_let(
|
|
"x", rz_il_op_new_b0(),
|
|
rz_il_op_new_let(
|
|
"y", rz_il_op_new_bitv_from_ut64(32, 123),
|
|
rz_il_op_new_let(
|
|
"x", rz_il_op_new_bitv_from_ut64(42, 321),
|
|
rz_il_op_new_var("y", RZ_IL_VAR_KIND_LOCAL_PURE))));
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_bv(32)), "sort");
|
|
mu_assert_null(report, "no report");
|
|
free(report);
|
|
rz_il_op_pure_free(op);
|
|
|
|
// invalid cases
|
|
op = rz_il_op_new_let(
|
|
"x", rz_il_op_new_b0(),
|
|
rz_il_op_new_var("x", RZ_IL_VAR_KIND_LOCAL));
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "valid");
|
|
free(report);
|
|
rz_il_op_pure_free(op);
|
|
|
|
op = rz_il_op_new_let(
|
|
"x", rz_il_op_new_b0(),
|
|
rz_il_op_new_var("x", RZ_IL_VAR_KIND_GLOBAL));
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "valid");
|
|
free(report);
|
|
rz_il_op_pure_free(op);
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_pure_var() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
rz_il_validate_global_context_add_var(ctx, "y", rz_il_sort_pure_bv(42));
|
|
|
|
RzILOpPure *op = rz_il_op_new_var("y", RZ_IL_VAR_KIND_GLOBAL);
|
|
RzILSortPure sort;
|
|
RzILValidateReport report;
|
|
bool val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_bv(42)), "sort");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
RzILOpEffect *eop = rz_il_op_new_seq(
|
|
rz_il_op_new_set("y", true, rz_il_op_new_bitv_from_ut64(24, 0x1234)),
|
|
rz_il_op_new_jmp(rz_il_op_new_var("y", RZ_IL_VAR_KIND_LOCAL)));
|
|
RzILTypeEffect t;
|
|
val = rz_il_validate_effect(eop, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_DATA | RZ_IL_TYPE_EFFECT_CTRL, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(eop);
|
|
|
|
op = rz_il_op_new_var("x", RZ_IL_VAR_KIND_GLOBAL);
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Global variable \"x\" referenced by var op does not exist.", "report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
op = rz_il_op_new_var("x", RZ_IL_VAR_KIND_LOCAL);
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Local variable \"x\" is not available at var op.", "report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
eop = rz_il_op_new_seq(
|
|
rz_il_op_new_set("y", true, rz_il_op_new_bitv_from_ut64(23, 0x1234)),
|
|
rz_il_op_new_jmp(rz_il_op_new_var("y", RZ_IL_VAR_KIND_LOCAL)));
|
|
val = rz_il_validate_effect(eop, ctx, NULL, &t, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Length of dst operand (23) of jmp op is not equal to pc length 24.", "report");
|
|
rz_il_op_effect_free(eop);
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_pure_inv() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
RzILOpPure *op = rz_il_op_new_bool_inv(rz_il_op_new_b0());
|
|
RzILSortPure sort;
|
|
RzILValidateReport report;
|
|
bool val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_bool()), "sort");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
op = rz_il_op_new_bool_inv(rz_il_op_new_bitv_from_ut64(32, 0));
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Operand of boolean inv op is not boolean.", "report");
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_pure_bool_binop() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
RzILOpPure *op = rz_il_op_new_bool_and(
|
|
rz_il_op_new_b0(),
|
|
rz_il_op_new_b1());
|
|
RzILSortPure sort;
|
|
RzILValidateReport report;
|
|
bool val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_bool()), "sort");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
op = rz_il_op_new_bool_and(
|
|
rz_il_op_new_b0(),
|
|
rz_il_op_new_bitv_from_ut64(64, 456));
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Right operand of and op is not bool.", "report");
|
|
|
|
op = rz_il_op_new_bool_and(
|
|
rz_il_op_new_bitv_from_ut64(64, 456),
|
|
rz_il_op_new_b0());
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Left operand of and op is not bool.", "report");
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_pure_bitv_binop() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
RzILOpPure *op = rz_il_op_new_add(
|
|
rz_il_op_new_bitv_from_ut64(64, 123),
|
|
rz_il_op_new_bitv_from_ut64(64, 456));
|
|
RzILSortPure sort;
|
|
RzILValidateReport report;
|
|
bool val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_bv(64)), "sort");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
op = rz_il_op_new_add(
|
|
rz_il_op_new_bitv_from_ut64(63, 123),
|
|
rz_il_op_new_bitv_from_ut64(64, 456));
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Operand sizes of add op do not agree: 63 vs. 64.", "report");
|
|
|
|
op = rz_il_op_new_add(
|
|
rz_il_op_new_b0(),
|
|
rz_il_op_new_bitv_from_ut64(64, 456));
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Left operand of add op is not a bitvector.", "report");
|
|
|
|
op = rz_il_op_new_add(
|
|
rz_il_op_new_bitv_from_ut64(64, 456),
|
|
rz_il_op_new_b0());
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Right operand of add op is not a bitvector.", "report");
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_pure_bitv_bool_unop() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
RzILOpPure *op = rz_il_op_new_msb(rz_il_op_new_bitv_from_ut64(64, 123));
|
|
RzILSortPure sort;
|
|
RzILValidateReport report;
|
|
bool val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_bool()), "sort");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
op = rz_il_op_new_msb(rz_il_op_new_b0());
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Operand of msb op is not a bitvector.", "report");
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_pure_bitv_unop() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
RzILOpPure *op = rz_il_op_new_log_not(rz_il_op_new_bitv_from_ut64(64, 123));
|
|
RzILSortPure sort;
|
|
RzILValidateReport report;
|
|
bool val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_bv(64)), "sort");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
op = rz_il_op_new_log_not(rz_il_op_new_b0());
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Operand of lognot op is not a bitvector.", "report");
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_pure_shift() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
RzILOpPure *op = rz_il_op_new_shiftl(rz_il_op_new_b0(),
|
|
rz_il_op_new_bitv_from_ut64(64, 123), rz_il_op_new_bitv_from_ut64(32, 32));
|
|
RzILSortPure sort;
|
|
RzILValidateReport report;
|
|
bool val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_bv(64)), "sort");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
op = rz_il_op_new_shiftl(rz_il_op_new_bitv_from_ut64(8, 0),
|
|
rz_il_op_new_bitv_from_ut64(64, 123), rz_il_op_new_bitv_from_ut64(32, 32));
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Fill operand of shiftl op is not bool.", "report");
|
|
|
|
op = rz_il_op_new_shiftl(rz_il_op_new_b0(),
|
|
rz_il_op_new_b0(), rz_il_op_new_bitv_from_ut64(32, 32));
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Value operand of shiftl op is not a bitvector.", "report");
|
|
|
|
op = rz_il_op_new_shiftl(rz_il_op_new_b0(),
|
|
rz_il_op_new_bitv_from_ut64(32, 32), rz_il_op_new_b0());
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Distance operand of shiftl op is not a bitvector.", "report");
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_pure_cmp() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
RzILOpPure *op = rz_il_op_new_eq(
|
|
rz_il_op_new_bitv_from_ut64(64, 123),
|
|
rz_il_op_new_bitv_from_ut64(64, 456));
|
|
RzILSortPure sort;
|
|
RzILValidateReport report;
|
|
bool val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_bool()), "sort");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
op = rz_il_op_new_eq(
|
|
rz_il_op_new_bitv_from_ut64(63, 123),
|
|
rz_il_op_new_bitv_from_ut64(64, 456));
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Operand sizes of eq op do not agree: 63 vs. 64.", "report");
|
|
|
|
op = rz_il_op_new_eq(
|
|
rz_il_op_new_b0(),
|
|
rz_il_op_new_bitv_from_ut64(64, 456));
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Left operand of eq op is not a bitvector.", "report");
|
|
|
|
op = rz_il_op_new_eq(
|
|
rz_il_op_new_bitv_from_ut64(64, 456),
|
|
rz_il_op_new_b0());
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Right operand of eq op is not a bitvector.", "report");
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_pure_cast() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
RzILOpPure *op = rz_il_op_new_cast(13,
|
|
rz_il_op_new_b0(),
|
|
rz_il_op_new_bitv_from_ut64(64, 456));
|
|
RzILSortPure sort;
|
|
RzILValidateReport report;
|
|
bool val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_bv(13)), "sort");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
op = rz_il_op_new_cast(13,
|
|
rz_il_op_new_b0(),
|
|
rz_il_op_new_bitv_from_ut64(64, 456));
|
|
op->op.cast.length = 0;
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Length of cast op is 0.", "report");
|
|
|
|
op = rz_il_op_new_cast(13,
|
|
rz_il_op_new_bitv_from_ut64(12, 0),
|
|
rz_il_op_new_bitv_from_ut64(64, 456));
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Fill operand of cast op is not bool.", "report");
|
|
|
|
op = rz_il_op_new_cast(13,
|
|
rz_il_op_new_b0(),
|
|
rz_il_op_new_b0());
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Value operand of cast op is not a bitvector.", "report");
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_pure_append() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
RzILOpPure *op = rz_il_op_new_append(
|
|
rz_il_op_new_bitv_from_ut64(64, 123),
|
|
rz_il_op_new_bitv_from_ut64(41, 456));
|
|
RzILSortPure sort;
|
|
RzILValidateReport report;
|
|
bool val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_bv(64 + 41)), "sort");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
op = rz_il_op_new_append(
|
|
rz_il_op_new_b0(),
|
|
rz_il_op_new_bitv_from_ut64(64, 456));
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "High operand of append op is not a bitvector.", "report");
|
|
|
|
op = rz_il_op_new_append(
|
|
rz_il_op_new_bitv_from_ut64(64, 456),
|
|
rz_il_op_new_b0());
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Low operand of append op is not a bitvector.", "report");
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_pure_load() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
rz_il_validate_global_context_add_mem(ctx, 1, 16, 9);
|
|
|
|
RzILOpPure *op = rz_il_op_new_load(1, rz_il_op_new_bitv_from_ut64(16, 123));
|
|
RzILSortPure sort;
|
|
RzILValidateReport report;
|
|
bool val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_bv(9)), "sort");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
op = rz_il_op_new_load(1, rz_il_op_new_bitv_from_ut64(9, 123));
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Length of key operand (9) of load op is not equal to key length 16 of mem 1.", "report");
|
|
|
|
op = rz_il_op_new_load(0, rz_il_op_new_bitv_from_ut64(16, 123));
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Mem 0 referenced by load op does not exist.", "report");
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_pure_loadw() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
rz_il_validate_global_context_add_mem(ctx, 1, 16, 9);
|
|
|
|
RzILOpPure *op = rz_il_op_new_loadw(1, rz_il_op_new_bitv_from_ut64(16, 123), 32);
|
|
RzILSortPure sort;
|
|
RzILValidateReport report;
|
|
bool val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_bv(32)), "sort");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_pure_free(op);
|
|
|
|
op = rz_il_op_new_loadw(1, rz_il_op_new_bitv_from_ut64(12, 123), 32);
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Length of key operand (12) of loadw op is not equal to key length 16 of mem 1.", "report");
|
|
|
|
op = rz_il_op_new_loadw(0, rz_il_op_new_bitv_from_ut64(16, 123), 32);
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Mem 0 referenced by loadw op does not exist.", "report");
|
|
|
|
op = rz_il_op_new_loadw(1, rz_il_op_new_bitv_from_ut64(16, 123), 32);
|
|
op->op.loadw.n_bits = 0;
|
|
val = rz_il_validate_pure(op, ctx, &sort, &report);
|
|
mu_assert_false(val, "invalid");
|
|
rz_il_op_pure_free(op);
|
|
mu_assert_streq_free(report, "Length of loadw op is 0.", "report");
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_effect_null() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
RzILValidateReport report;
|
|
bool val = rz_il_validate_effect(NULL, ctx, NULL, NULL, &report);
|
|
mu_assert_false(val, "valid");
|
|
mu_assert_streq_free(report, "Encountered NULL for effect op.", "no report");
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_effect_nop() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
RzILOpEffect *op = rz_il_op_new_nop();
|
|
RzILValidateReport report;
|
|
RzILTypeEffect t;
|
|
bool val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_NONE, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_effect_store() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
rz_il_validate_global_context_add_mem(ctx, 1, 16, 9);
|
|
|
|
RzILOpEffect *op = rz_il_op_new_store(1,
|
|
rz_il_op_new_bitv_from_ut64(16, 123),
|
|
rz_il_op_new_bitv_from_ut64(9, 42));
|
|
RzILValidateReport report;
|
|
RzILTypeEffect t;
|
|
bool val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_DATA, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_store(0,
|
|
rz_il_op_new_bitv_from_ut64(16, 123),
|
|
rz_il_op_new_bitv_from_ut64(9, 42));
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Mem 0 referenced by store op does not exist.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_store(1,
|
|
rz_il_op_new_bitv_from_ut64(12, 123),
|
|
rz_il_op_new_bitv_from_ut64(9, 42));
|
|
val = rz_il_validate_effect(op, ctx, NULL, NULL, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Length of key operand (12) of store op is not equal to key length 16 of mem 1.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_store(1,
|
|
rz_il_op_new_b0(),
|
|
rz_il_op_new_bitv_from_ut64(9, 42));
|
|
val = rz_il_validate_effect(op, ctx, NULL, NULL, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Key operand of store op is not a bitvector.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_store(1,
|
|
rz_il_op_new_bitv_from_ut64(16, 123),
|
|
rz_il_op_new_bitv_from_ut64(8, 42));
|
|
val = rz_il_validate_effect(op, ctx, NULL, NULL, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Length of value operand (8) of store op is not equal to value length 9 of mem 1.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_store(1,
|
|
rz_il_op_new_bitv_from_ut64(16, 123),
|
|
rz_il_op_new_b0());
|
|
val = rz_il_validate_effect(op, ctx, NULL, NULL, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Value operand of store op is not a bitvector.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_effect_storew() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
rz_il_validate_global_context_add_mem(ctx, 1, 16, 9);
|
|
|
|
RzILOpEffect *op = rz_il_op_new_storew(1,
|
|
rz_il_op_new_bitv_from_ut64(16, 123),
|
|
rz_il_op_new_bitv_from_ut64(42, 42));
|
|
RzILValidateReport report;
|
|
RzILTypeEffect t;
|
|
bool val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_DATA, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_storew(0,
|
|
rz_il_op_new_bitv_from_ut64(16, 123),
|
|
rz_il_op_new_bitv_from_ut64(9, 42));
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Mem 0 referenced by storew op does not exist.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_storew(1,
|
|
rz_il_op_new_bitv_from_ut64(12, 123),
|
|
rz_il_op_new_bitv_from_ut64(9, 42));
|
|
val = rz_il_validate_effect(op, ctx, NULL, NULL, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Length of key operand (12) of storew op is not equal to key length 16 of mem 1.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_storew(1,
|
|
rz_il_op_new_b0(),
|
|
rz_il_op_new_bitv_from_ut64(9, 42));
|
|
val = rz_il_validate_effect(op, ctx, NULL, NULL, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Key operand of storew op is not a bitvector.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_storew(1,
|
|
rz_il_op_new_bitv_from_ut64(16, 123),
|
|
rz_il_op_new_b0());
|
|
val = rz_il_validate_effect(op, ctx, NULL, NULL, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Value operand of storew op is not a bitvector.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_effect_set() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
rz_il_validate_global_context_add_var(ctx, "x", rz_il_sort_pure_bv(42));
|
|
|
|
// global
|
|
RzILOpEffect *op = rz_il_op_new_set("x", false, rz_il_op_new_bitv_from_ut64(42, 0));
|
|
RzILValidateReport report;
|
|
RzILTypeEffect t;
|
|
bool val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_DATA, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_set("y", false, rz_il_op_new_bitv_from_ut64(42, 0));
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Global variable \"y\" referenced by set op does not exist.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_set("x", false, rz_il_op_new_bitv_from_ut64(41, 0));
|
|
val = rz_il_validate_effect(op, ctx, NULL, NULL, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Types of global variable \"x\" and set op do not agree: bitvector:42 vs. bitvector:41.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
// local
|
|
op = rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(20, 0));
|
|
val = rz_il_validate_effect(op, ctx, NULL, NULL, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_seq(
|
|
rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(22, 0)),
|
|
rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(22, 42)));
|
|
val = rz_il_validate_effect(op, ctx, NULL, NULL, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_seq(
|
|
rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(22, 0)),
|
|
rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(21, 42)));
|
|
val = rz_il_validate_effect(op, ctx, NULL, NULL, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Types of local variable \"x\" and set op do not agree: bitvector:22 vs. bitvector:21.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_effect_jmp() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
RzILOpEffect *op = rz_il_op_new_jmp(rz_il_op_new_bitv_from_ut64(24, 0x1000));
|
|
RzILValidateReport report;
|
|
RzILTypeEffect t;
|
|
bool val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_CTRL, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_jmp(rz_il_op_new_bitv_from_ut64(42, 0x1000));
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Length of dst operand (42) of jmp op is not equal to pc length 24.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_jmp(rz_il_op_new_b0());
|
|
val = rz_il_validate_effect(op, ctx, NULL, NULL, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Dst operand of jmp op is not a bitvector.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_effect_goto() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
RzILOpEffect *op = rz_il_op_new_goto("beach");
|
|
RzILValidateReport report;
|
|
RzILTypeEffect t;
|
|
bool val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_CTRL, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_effect_seq() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
RzILOpEffect *op = rz_il_op_new_seq(rz_il_op_new_nop(), rz_il_op_new_nop());
|
|
RzILValidateReport report;
|
|
RzILTypeEffect t;
|
|
bool val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_NONE, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_seq(rz_il_op_new_set("nexist", false, rz_il_op_new_b0()), rz_il_op_new_nop());
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Global variable \"nexist\" referenced by set op does not exist.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_seq(rz_il_op_new_nop(), rz_il_op_new_set("nexist", false, rz_il_op_new_b0()));
|
|
val = rz_il_validate_effect(op, ctx, NULL, NULL, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Global variable \"nexist\" referenced by set op does not exist.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
// effect type handling
|
|
op = rz_il_op_new_seq(rz_il_op_new_set("x", true, rz_il_op_new_b0()), rz_il_op_new_nop());
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_DATA, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_seq(rz_il_op_new_set("x", true, rz_il_op_new_b0()), rz_il_op_new_jmp(rz_il_op_new_bitv_from_ut64(24, 0x100)));
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_DATA | RZ_IL_TYPE_EFFECT_CTRL, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_seq(rz_il_op_new_jmp(rz_il_op_new_bitv_from_ut64(24, 0x100)), rz_il_op_new_set("x", true, rz_il_op_new_b0()));
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Encountered further effects after a ctrl effect in seq op.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_seq(rz_il_op_new_jmp(rz_il_op_new_bitv_from_ut64(24, 0x100)), rz_il_op_new_nop());
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_CTRL, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_seq(rz_il_op_new_nop(), rz_il_op_new_jmp(rz_il_op_new_bitv_from_ut64(24, 0x100)));
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_CTRL, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_seq(rz_il_op_new_nop(), rz_il_op_new_set("x", true, rz_il_op_new_b0()));
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_DATA, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_effect_blk() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
RzILOpEffect *op = rz_il_op_new_blk(NULL, rz_il_op_new_nop(), rz_il_op_new_jmp(rz_il_op_new_bitv_from_ut64(24, 0x1000)));
|
|
RzILValidateReport report;
|
|
RzILTypeEffect t;
|
|
bool val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_CTRL, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_blk(NULL,
|
|
rz_il_op_new_set("nexist", false, rz_il_op_new_b0()),
|
|
rz_il_op_new_jmp(rz_il_op_new_bitv_from_ut64(24, 0x1000)));
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Global variable \"nexist\" referenced by set op does not exist.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_blk(NULL,
|
|
rz_il_op_new_nop(),
|
|
rz_il_op_new_jmp(rz_il_op_new_bitv_from_ut64(23, 0x1000)));
|
|
val = rz_il_validate_effect(op, ctx, NULL, NULL, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Length of dst operand (23) of jmp op is not equal to pc length 24.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
// effect type handling
|
|
op = rz_il_op_new_blk(NULL,
|
|
rz_il_op_new_set("x", true, rz_il_op_new_b0()),
|
|
rz_il_op_new_jmp(rz_il_op_new_bitv_from_ut64(24, 0x1000)));
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_DATA | RZ_IL_TYPE_EFFECT_CTRL, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_blk(NULL,
|
|
rz_il_op_new_set("x", true, rz_il_op_new_b0()),
|
|
rz_il_op_new_nop());
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_DATA, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_blk(NULL,
|
|
rz_il_op_new_nop(),
|
|
rz_il_op_new_set("x", true, rz_il_op_new_b0()));
|
|
val = rz_il_validate_effect(op, ctx, NULL, NULL, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Control effect operand of blk op does not only perform control effects.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_blk(NULL,
|
|
rz_il_op_new_jmp(rz_il_op_new_bitv_from_ut64(24, 0x1000)),
|
|
rz_il_op_new_nop());
|
|
val = rz_il_validate_effect(op, ctx, NULL, NULL, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Data effect operand of blk op does not only perform data effects.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_effect_repeat() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
RzILOpEffect *op = rz_il_op_new_repeat(rz_il_op_new_b0(), rz_il_op_new_nop());
|
|
RzILValidateReport report;
|
|
RzILTypeEffect t;
|
|
bool val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_NONE, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_repeat(rz_il_op_new_bitv_from_ut64(16, 0), rz_il_op_new_nop());
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Condition of repeat op is not boolean.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_repeat(rz_il_op_new_b0(), rz_il_op_new_set("nexist", false, rz_il_op_new_b0()));
|
|
val = rz_il_validate_effect(op, ctx, NULL, NULL, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Global variable \"nexist\" referenced by set op does not exist.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
//////////////////////////
|
|
// local context handling
|
|
|
|
// types remembered from the loop
|
|
op = rz_il_op_new_repeat(rz_il_op_new_b0(), rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(14, 0)));
|
|
HtPP *local_var_sorts;
|
|
val = rz_il_validate_effect(op, ctx, &local_var_sorts, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_DATA, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
mu_assert_notnull(local_var_sorts, "local var sorts");
|
|
mu_assert_eq(local_var_sorts->count, 1, "local var sorts count");
|
|
RzILSortPure *sort = ht_pp_find(local_var_sorts, "x", NULL);
|
|
mu_assert_notnull(sort, "local var sort");
|
|
mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bv(14)), "local var sort");
|
|
ht_pp_free(local_var_sorts);
|
|
local_var_sorts = NULL;
|
|
rz_il_op_effect_free(op);
|
|
|
|
// vars available before are still available after
|
|
op = rz_il_op_new_seqn(3,
|
|
rz_il_op_new_set("y", true, rz_il_op_new_b0()),
|
|
rz_il_op_new_repeat(rz_il_op_new_b0(), rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(14, 0))),
|
|
rz_il_op_new_set("y", true, rz_il_op_new_ite(rz_il_op_new_var("y", RZ_IL_VAR_KIND_LOCAL), rz_il_op_new_b0(), rz_il_op_new_b1())));
|
|
val = rz_il_validate_effect(op, ctx, &local_var_sorts, NULL, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_null(report, "no report");
|
|
mu_assert_notnull(local_var_sorts, "local var sorts");
|
|
mu_assert_eq(local_var_sorts->count, 2, "local var sorts count");
|
|
sort = ht_pp_find(local_var_sorts, "x", NULL);
|
|
mu_assert_notnull(sort, "local var sort");
|
|
mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bv(14)), "local var sort");
|
|
sort = ht_pp_find(local_var_sorts, "y", NULL);
|
|
mu_assert_notnull(sort, "local var sort");
|
|
mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bool()), "local var sort");
|
|
ht_pp_free(local_var_sorts);
|
|
local_var_sorts = NULL;
|
|
rz_il_op_effect_free(op);
|
|
|
|
// vars available only inside the loop can be made available again if they have the same type
|
|
op = rz_il_op_new_seqn(3,
|
|
rz_il_op_new_set("y", true, rz_il_op_new_b0()),
|
|
rz_il_op_new_repeat(rz_il_op_new_b0(), rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(14, 0))),
|
|
rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(14, 32)));
|
|
val = rz_il_validate_effect(op, ctx, &local_var_sorts, NULL, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_null(report, "no report");
|
|
mu_assert_notnull(local_var_sorts, "local var sorts");
|
|
mu_assert_eq(local_var_sorts->count, 2, "local var sorts count");
|
|
sort = ht_pp_find(local_var_sorts, "x", NULL);
|
|
mu_assert_notnull(sort, "local var sort");
|
|
mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bv(14)), "local var sort");
|
|
sort = ht_pp_find(local_var_sorts, "y", NULL);
|
|
mu_assert_notnull(sort, "local var sort");
|
|
mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bool()), "local var sort");
|
|
ht_pp_free(local_var_sorts);
|
|
local_var_sorts = NULL;
|
|
rz_il_op_effect_free(op);
|
|
|
|
// vars defined inside the loop already can not be used again with another type
|
|
op = rz_il_op_new_seqn(3,
|
|
rz_il_op_new_set("y", true, rz_il_op_new_b0()),
|
|
rz_il_op_new_repeat(rz_il_op_new_b0(), rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(14, 0))),
|
|
rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(13, 32)));
|
|
val = rz_il_validate_effect(op, ctx, &local_var_sorts, &t, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Types of local variable \"x\" and set op do not agree: bitvector:14 vs. bitvector:13.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
// vars available only inside the loop are not available after it anymore
|
|
op = rz_il_op_new_seqn(3,
|
|
rz_il_op_new_set("y", true, rz_il_op_new_b0()),
|
|
rz_il_op_new_repeat(rz_il_op_new_b0(), rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(14, 0))),
|
|
rz_il_op_new_set("x", true, rz_il_op_new_var("x", RZ_IL_VAR_KIND_LOCAL)));
|
|
val = rz_il_validate_effect(op, ctx, &local_var_sorts, NULL, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Local variable \"x\" is not available at var op.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
//////////////////////////
|
|
// effect type handling
|
|
|
|
op = rz_il_op_new_repeat(rz_il_op_new_b0(), rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(14, 0)));
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_DATA, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_repeat(rz_il_op_new_b0(), rz_il_op_new_jmp(rz_il_op_new_bitv_from_ut64(24, 0x100)));
|
|
val = rz_il_validate_effect(op, ctx, &local_var_sorts, &t, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Body operand of repeat op does not only perform data effects.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
static bool test_il_validate_effect_branch() {
|
|
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
|
|
|
RzILOpEffect *op = rz_il_op_new_branch(rz_il_op_new_b0(), rz_il_op_new_nop(), rz_il_op_new_nop());
|
|
RzILValidateReport report;
|
|
RzILTypeEffect t;
|
|
bool val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_NONE, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_branch(rz_il_op_new_bitv_from_ut64(8, 0), rz_il_op_new_nop(), rz_il_op_new_nop());
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Condition of branch op is not boolean.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_branch(rz_il_op_new_b0(), rz_il_op_new_set("nexist", false, rz_il_op_new_b0()), rz_il_op_new_nop());
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Global variable \"nexist\" referenced by set op does not exist.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_branch(rz_il_op_new_b0(), rz_il_op_new_nop(), rz_il_op_new_set("nexist", false, rz_il_op_new_b0()));
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Global variable \"nexist\" referenced by set op does not exist.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
//////////////////////////
|
|
// local context handling
|
|
|
|
// types remembered from the branches
|
|
op = rz_il_op_new_branch(rz_il_op_new_b0(),
|
|
rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(14, 0)),
|
|
rz_il_op_new_set("y", true, rz_il_op_new_b0()));
|
|
HtPP *local_var_sorts;
|
|
val = rz_il_validate_effect(op, ctx, &local_var_sorts, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_null(report, "no report");
|
|
mu_assert_notnull(local_var_sorts, "local var sorts");
|
|
mu_assert_eq(local_var_sorts->count, 2, "local var sorts count");
|
|
RzILSortPure *sort = ht_pp_find(local_var_sorts, "x", NULL);
|
|
mu_assert_notnull(sort, "local var sort");
|
|
mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bv(14)), "local var sort");
|
|
sort = ht_pp_find(local_var_sorts, "y", NULL);
|
|
mu_assert_notnull(sort, "local var sort");
|
|
mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bool()), "local var sort");
|
|
ht_pp_free(local_var_sorts);
|
|
local_var_sorts = NULL;
|
|
rz_il_op_effect_free(op);
|
|
|
|
// vars available before are still available after
|
|
op = rz_il_op_new_seqn(3,
|
|
rz_il_op_new_set("y", true, rz_il_op_new_b0()),
|
|
rz_il_op_new_branch(rz_il_op_new_b0(), rz_il_op_new_nop(), rz_il_op_new_nop()),
|
|
rz_il_op_new_set("y", true, rz_il_op_new_ite(rz_il_op_new_var("y", RZ_IL_VAR_KIND_LOCAL), rz_il_op_new_b0(), rz_il_op_new_b1())));
|
|
val = rz_il_validate_effect(op, ctx, &local_var_sorts, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_DATA, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
mu_assert_notnull(local_var_sorts, "local var sorts");
|
|
mu_assert_eq(local_var_sorts->count, 1, "local var sorts count");
|
|
sort = ht_pp_find(local_var_sorts, "y", NULL);
|
|
mu_assert_notnull(sort, "local var sort");
|
|
mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bool()), "local var sort");
|
|
ht_pp_free(local_var_sorts);
|
|
local_var_sorts = NULL;
|
|
rz_il_op_effect_free(op);
|
|
|
|
// vars available only inside a branch can be made available again if they have the same type
|
|
op = rz_il_op_new_seqn(3,
|
|
rz_il_op_new_set("y", true, rz_il_op_new_b0()),
|
|
rz_il_op_new_branch(rz_il_op_new_b0(), rz_il_op_new_nop(), rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(14, 0))),
|
|
rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(14, 32)));
|
|
val = rz_il_validate_effect(op, ctx, &local_var_sorts, NULL, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_null(report, "no report");
|
|
mu_assert_notnull(local_var_sorts, "local var sorts");
|
|
mu_assert_eq(local_var_sorts->count, 2, "local var sorts count");
|
|
sort = ht_pp_find(local_var_sorts, "x", NULL);
|
|
mu_assert_notnull(sort, "local var sort");
|
|
mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bv(14)), "local var sort");
|
|
sort = ht_pp_find(local_var_sorts, "y", NULL);
|
|
mu_assert_notnull(sort, "local var sort");
|
|
mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bool()), "local var sort");
|
|
ht_pp_free(local_var_sorts);
|
|
local_var_sorts = NULL;
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_seqn(3,
|
|
rz_il_op_new_set("y", true, rz_il_op_new_b0()),
|
|
rz_il_op_new_branch(rz_il_op_new_b0(), rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(14, 0)), rz_il_op_new_nop()),
|
|
rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(14, 32)));
|
|
val = rz_il_validate_effect(op, ctx, &local_var_sorts, NULL, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_null(report, "no report");
|
|
mu_assert_notnull(local_var_sorts, "local var sorts");
|
|
mu_assert_eq(local_var_sorts->count, 2, "local var sorts count");
|
|
sort = ht_pp_find(local_var_sorts, "x", NULL);
|
|
mu_assert_notnull(sort, "local var sort");
|
|
mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bv(14)), "local var sort");
|
|
sort = ht_pp_find(local_var_sorts, "y", NULL);
|
|
mu_assert_notnull(sort, "local var sort");
|
|
mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bool()), "local var sort");
|
|
ht_pp_free(local_var_sorts);
|
|
local_var_sorts = NULL;
|
|
rz_il_op_effect_free(op);
|
|
|
|
// vars defined in both branches are still available after it
|
|
op = rz_il_op_new_seqn(3,
|
|
rz_il_op_new_set("y", true, rz_il_op_new_b0()),
|
|
rz_il_op_new_branch(rz_il_op_new_b0(),
|
|
rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(14, 0)),
|
|
rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(14, 42))),
|
|
rz_il_op_new_set("x", true, rz_il_op_new_var("x", RZ_IL_VAR_KIND_LOCAL)));
|
|
val = rz_il_validate_effect(op, ctx, &local_var_sorts, NULL, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_null(report, "no report");
|
|
mu_assert_notnull(local_var_sorts, "local var sorts");
|
|
mu_assert_eq(local_var_sorts->count, 2, "local var sorts count");
|
|
sort = ht_pp_find(local_var_sorts, "x", NULL);
|
|
mu_assert_notnull(sort, "local var sort");
|
|
mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bv(14)), "local var sort");
|
|
sort = ht_pp_find(local_var_sorts, "y", NULL);
|
|
mu_assert_notnull(sort, "local var sort");
|
|
mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bool()), "local var sort");
|
|
ht_pp_free(local_var_sorts);
|
|
local_var_sorts = NULL;
|
|
rz_il_op_effect_free(op);
|
|
|
|
// vars defined already inside the branch can not be used again with another type
|
|
op = rz_il_op_new_seqn(3,
|
|
rz_il_op_new_set("y", true, rz_il_op_new_b0()),
|
|
rz_il_op_new_branch(rz_il_op_new_b0(), rz_il_op_new_nop(), rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(14, 0))),
|
|
rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(13, 32)));
|
|
val = rz_il_validate_effect(op, ctx, &local_var_sorts, NULL, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Types of local variable \"x\" and set op do not agree: bitvector:14 vs. bitvector:13.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_seqn(3,
|
|
rz_il_op_new_set("y", true, rz_il_op_new_b0()),
|
|
rz_il_op_new_branch(rz_il_op_new_b0(), rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(14, 0)), rz_il_op_new_nop()),
|
|
rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(13, 32)));
|
|
val = rz_il_validate_effect(op, ctx, &local_var_sorts, NULL, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Types of local variable \"x\" and set op do not agree: bitvector:14 vs. bitvector:13.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
// vars defined only inside one branch are not available after it anymore
|
|
op = rz_il_op_new_seqn(3,
|
|
rz_il_op_new_set("y", true, rz_il_op_new_b0()),
|
|
rz_il_op_new_branch(rz_il_op_new_b0(), rz_il_op_new_nop(), rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(14, 0))),
|
|
rz_il_op_new_set("x", true, rz_il_op_new_var("x", RZ_IL_VAR_KIND_LOCAL)));
|
|
val = rz_il_validate_effect(op, ctx, &local_var_sorts, NULL, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Local variable \"x\" is not available at var op.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_seqn(3,
|
|
rz_il_op_new_set("y", true, rz_il_op_new_b0()),
|
|
rz_il_op_new_branch(rz_il_op_new_b0(), rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(14, 0)), rz_il_op_new_nop()),
|
|
rz_il_op_new_set("x", true, rz_il_op_new_var("x", RZ_IL_VAR_KIND_LOCAL)));
|
|
val = rz_il_validate_effect(op, ctx, &local_var_sorts, NULL, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report, "Local variable \"x\" is not available at var op.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
// vars defined in both branches must agree in their types
|
|
op = rz_il_op_new_seqn(3,
|
|
rz_il_op_new_set("y", true, rz_il_op_new_b0()),
|
|
rz_il_op_new_branch(rz_il_op_new_b0(),
|
|
rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(13, 0)),
|
|
rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(14, 42))),
|
|
rz_il_op_new_set("x", true, rz_il_op_new_var("x", RZ_IL_VAR_KIND_LOCAL)));
|
|
val = rz_il_validate_effect(op, ctx, &local_var_sorts, NULL, &report);
|
|
mu_assert_false(val, "invalid");
|
|
mu_assert_streq_free(report,
|
|
"Control flow paths from branch op do not agree on the type of local variable \"x\": bitvector:14 vs. bitvector:13.", "report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
//////////////////////////
|
|
// effect type handling
|
|
|
|
op = rz_il_op_new_branch(rz_il_op_new_b0(), rz_il_op_new_set("x", true, rz_il_op_new_b0()), rz_il_op_new_nop());
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_DATA, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_branch(rz_il_op_new_b0(), rz_il_op_new_nop(), rz_il_op_new_set("x", true, rz_il_op_new_b0()));
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_DATA, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_branch(rz_il_op_new_b0(), rz_il_op_new_nop(), rz_il_op_new_jmp(rz_il_op_new_bitv_from_ut64(24, 0x100)));
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_CTRL, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_branch(rz_il_op_new_b0(), rz_il_op_new_jmp(rz_il_op_new_bitv_from_ut64(24, 0x100)), rz_il_op_new_nop());
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_CTRL, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
op = rz_il_op_new_branch(rz_il_op_new_b0(),
|
|
rz_il_op_new_jmp(rz_il_op_new_bitv_from_ut64(24, 0x100)),
|
|
rz_il_op_new_set("x", true, rz_il_op_new_b0()));
|
|
val = rz_il_validate_effect(op, ctx, NULL, &t, &report);
|
|
mu_assert_true(val, "valid");
|
|
mu_assert_eq(t, RZ_IL_TYPE_EFFECT_DATA | RZ_IL_TYPE_EFFECT_CTRL, "effect type");
|
|
mu_assert_null(report, "no report");
|
|
rz_il_op_effect_free(op);
|
|
|
|
rz_il_validate_global_context_free(ctx);
|
|
mu_end;
|
|
}
|
|
|
|
bool all_tests() {
|
|
mu_run_test(test_il_validate_pure_null);
|
|
mu_run_test(test_il_validate_pure_bitv);
|
|
mu_run_test(test_il_validate_pure_bool);
|
|
mu_run_test(test_il_validate_pure_ite);
|
|
mu_run_test(test_il_validate_pure_let);
|
|
mu_run_test(test_il_validate_pure_var);
|
|
mu_run_test(test_il_validate_pure_inv);
|
|
mu_run_test(test_il_validate_pure_bool_binop);
|
|
mu_run_test(test_il_validate_pure_bitv_binop);
|
|
mu_run_test(test_il_validate_pure_bitv_bool_unop);
|
|
mu_run_test(test_il_validate_pure_bitv_unop);
|
|
mu_run_test(test_il_validate_pure_shift);
|
|
mu_run_test(test_il_validate_pure_cmp);
|
|
mu_run_test(test_il_validate_pure_cast);
|
|
mu_run_test(test_il_validate_pure_append);
|
|
mu_run_test(test_il_validate_pure_load);
|
|
mu_run_test(test_il_validate_pure_loadw);
|
|
mu_run_test(test_il_validate_effect_null);
|
|
mu_run_test(test_il_validate_effect_nop);
|
|
mu_run_test(test_il_validate_effect_store);
|
|
mu_run_test(test_il_validate_effect_storew);
|
|
mu_run_test(test_il_validate_effect_set);
|
|
mu_run_test(test_il_validate_effect_jmp);
|
|
mu_run_test(test_il_validate_effect_goto);
|
|
mu_run_test(test_il_validate_effect_seq);
|
|
mu_run_test(test_il_validate_effect_blk);
|
|
mu_run_test(test_il_validate_effect_repeat);
|
|
mu_run_test(test_il_validate_effect_branch);
|
|
return tests_passed != tests_run;
|
|
}
|
|
|
|
mu_main(all_tests)
|