1 2static bool block_check_invariants(RAnal *anal) { 3 RBIter iter; 4 RAnalBlock *block; 5 ut64 last_start = UT64_MAX; 6 r_rbtree_foreach (anal->bb_tree, iter, block, RAnalBlock, _rb) { 7 if (last_start != UT64_MAX) { 8 mu_assert ("corrupted binary tree", block->addr >= last_start); 9 mu_assert_neq (block->addr, last_start, "double blocks"); 10 } 11 last_start = block->addr; 12 13 mu_assert ("block->ref < 1, but it is still in the tree", block->ref >= 1); 14 mu_assert ("block->ref < r_list_length (block->fcns)", block->ref >= r_list_length (block->fcns)); 15 16 RListIter *fcniter; 17 RAnalFunction *fcn; 18 r_list_foreach (block->fcns, fcniter, fcn) { 19 RListIter *fcniter2; 20 RAnalFunction *fcn2; 21 for (fcniter2 = fcniter->n; fcniter2 && (fcn2 = fcniter2->data, 1); fcniter2 = fcniter2->n) { 22 mu_assert_ptrneq (fcn, fcn2, "duplicate function in basic block"); 23 } 24 mu_assert ("block references function, but function does not reference block", r_list_contains (fcn->bbs, block)); 25 } 26 } 27 28 RListIter *fcniter; 29 RAnalFunction *fcn; 30 r_list_foreach (anal->fcns, fcniter, fcn) { 31 RListIter *blockiter; 32 ut64 min = UT64_MAX; 33 ut64 max = UT64_MIN; 34 ut64 realsz = 0; 35 r_list_foreach (fcn->bbs, blockiter, block) { 36 RListIter *blockiter2; 37 RAnalBlock *block2; 38 if (block->addr < min) { 39 min = block->addr; 40 } 41 if (block->addr + block->size > max) { 42 max = block->addr + block->size; 43 } 44 realsz += block->size; 45 for (blockiter2 = blockiter->n; blockiter2 && (block2 = blockiter2->data, 1); blockiter2 = blockiter2->n) { 46 mu_assert_ptrneq (block, block2, "duplicate basic block in function"); 47 } 48 mu_assert ("function references block, but block does not reference function", r_list_contains (block->fcns, fcn)); 49 } 50 51 if (fcn->meta._min != UT64_MAX) { 52 mu_assert_eq (fcn->meta._min, min, "function min wrong"); 53 mu_assert_eq (fcn->meta._max, max, "function max wrong"); 54 } 55 56 mu_assert_eq (r_anal_function_realsize (fcn), realsz, "realsize wrong"); 57 } 58 return true; 59} 60 61static bool block_check_leaks(RAnal *anal) { 62 RBIter iter; 63 RAnalBlock *block; 64 r_rbtree_foreach (anal->bb_tree, iter, block, RAnalBlock, _rb) { 65 if (block->ref != r_list_length (block->fcns)) { 66 mu_assert ("leaked basic block", false); 67 } 68 } 69 return true; 70} 71