Hi all, hi David,

I am trying to use the analyzer API to transform an element_region (such as 't[1]') to a binop_svalue with an inner region_svalue (such as '&t + 4' in case of integers array) for analysis purpose.

I managed to do it the other way around (i.e. from a binop_svalue to an element_region) using the analyzer API (code is in attached file offset_to_elm.cc).
And everything is working as intended within the analyzer and my analysis.

The problem I'm having here is probably due to a mistake I'm doing on some argument to a function call, but I cannot see it to be honest (code misbehaving is in elm_to_offset.cc).

I attached a commented sample code I'd like to be able to analyze (test.c), alongside the commented GIMPLE code seen by the analyzer (test.c.075i.analyzer obtained through '-fdump-ipa-analyzer').
Feel free to ask question if needed of course.

I manage to rebuild a binop_sval from an element_region (code is in attached file elm_to_offset.cc), but resulting object is not the same than the one already within the state_map of my state machine. To be clear, the svalue's pointer resulting from the code in elm_to_offset.cc is deifferent, though when they're logged with simple set to false, no difference seem to exist. And I really do have the intuition that the problem might be related to the call to region_model_manager::get_ptr_svalue on elm_to_offset.cc:17. I do think that the key is not find within region_model_manager::m_pointer_values_map is not found and the call to region_svalue constructor is performed within region_model_manager::get_ptr_svalue implementation.
But still, I have no idea why.

I did modified the analyzer state_map class to be able to also track regions states alongside svalues one (working on a patch, code is not respecting GCC's coding standard so far and most probably not optimized).

Any idea on what I'm doing wrong here would really be appreciated.

Beside this, I do think that enhancing the analyzer by allowing to track regions states could allow for a broader set of possible analysis. What do you think ?

Thank you,

Pierrick

P.S.: @David, sorry for double send. I did a mistake in the gcc's mailing list address.
const svalue *elm_to_offset(sm_context *sm_ctx, const region *reg, logger *logger) {
    
  const svalue* res = nullptr;

  if (logger)
    LOG_SCOPE(logger);

  auto model = sm_ctx->get_new_program_state()->m_region_model;
  auto mgr = model->get_manager();

  bit_offset_t offset;
  const svalue *offset_sval = nullptr;
  if (reg->get_relative_concrete_offset(&offset)) {
    auto offset_byte = offset / BITS_PER_UNIT;
    offset_sval = mgr->get_or_create_constant_svalue(wide_int_to_tree(sizetype, offset_byte));
    auto base = reg->get_base_region();
    auto base_sval = mgr->get_ptr_svalue(TYPE_POINTER_TO(base->get_type()), base);
    res = mgr->get_or_create_binop(base->get_type(), POINTER_PLUS_EXPR, base_sval, offset_sval);
  }
  // TODO: symbolic offset
  else if (logger)
      logger->log("Offset is symbolic, not implemented.");

  if (logger) {
    logger->start_log_line();
    logger->log_partial("res: %p | ", res);
    res ? res->dump_to_pp(logger->get_printer(), false) : logger->log_partial("nullptr");
    logger->log_partial(" | ");
    res ? res->dump_to_pp(logger->get_printer(), true) : logger->log_partial("nullptr");
    logger->end_log_line();
  }

  return res;
}
const region *offset_to_elm(sm_context * sm_ctx, const svalue *sval, logger *logger) {

  const region * res = nullptr;

  if (logger)
    LOG_SCOPE(logger);

  auto model = sm_ctx->get_new_program_state()->m_region_model;

  if (const region *deref = model->deref_rvalue(sval, NULL_TREE, nullptr)) {
    if (logger) {
      logger->start_log_line();
      logger->log_partial("deref: ");
      deref->dump_to_pp(logger->get_printer(), false);
      logger->end_log_line();
    }
    auto base = deref->get_base_region();
    bit_offset_t offset;
    bit_size_t size;
    if (deref->get_relative_concrete_offset(&offset)
      && deref->get_bit_size(&size)) {
      auto index = offset / size;
      auto model_mgr = model->get_manager();
      auto index_sized = wide_int_to_tree(sizetype, index);
      auto sval_index_sized = model_mgr->get_or_create_constant_svalue(index_sized);
      res = model_mgr->get_element_region(base, TREE_TYPE(base->get_type()), sval_index_sized);
    }
    // TODO: symbolic offset
    else if (logger)
        logger->log("Offset is symbolic, not implemented.");
  }

  if (logger) {
    logger->start_log_line();
    logger->log_partial("input: %p | ", sval);
    sval->dump_to_pp(logger->get_printer(), true);
    logger->log_partial(" | ");
    sval->dump_to_pp(logger->get_printer(), false);
    logger->end_log_line();
    logger->start_log_line();
    logger->log_partial("res: ");
    res ? res->dump_to_pp(logger->get_printer(), true) : logger->log_partial("nullptr");
    logger->end_log_line();
  }

  return res;
}
void some_func(void) {
  // var's value should not be used in certain instructions such as conditions
  int var = 42; // var is here tracked as source within the state_map, i.e. no origin
  int t[4] = { 0 };
  int *y = t + 1;
  *y = var; // y's svalue, i.e. '&t + 4' is here correctly tracked in the state map
  // I would like to correlate the tracked state of y's svalue to the region 't[1]'
  if (t[1])
    do_stuff();
}
void some_func ()
{
  int * y;
  int t[4];
  int var;
  int _1;

  <bb 2> :
  var_3 = 42; // var_3 is tracked, no origin
  t = {};
  y_6 = &t + 4;
  *y_6 = var_3; // y_6 svalue is tracked, origin var_3
  _1 = t[1]; // _1 should be tracked with y_6 as origin
  if (_1 != 0)
    goto <bb 3>; [INV]
  else
    goto <bb 4>; [INV]

  <bb 3> :
  do_stuff ();

  <bb 4> :
  t ={v} {CLOBBER(eol)};
  return;

}


Reply via email to