コード例 #1
0
ファイル: xdbfind.cpp プロジェクト: harite/xgill
// read a binary tag value from the specified buffer and get whatever
// hash object it represents from the buffer, returning a reference
// on that object. we will just match against the types of values that
// can appear at the top level of a database entry.
HashObject* ReadSingleValue(Buffer *buf)
{
  switch (PeekOpenTag(buf)) {

  case TAG_BlockCFG:         return BlockCFG::Read(buf);
  case TAG_CompositeCSU:     return CompositeCSU::Read(buf);
  case TAG_EscapeEdgeSet:    return EscapeEdgeSet::Read(buf);
  case TAG_EscapeAccessSet:  return EscapeAccessSet::Read(buf);
  case TAG_CallEdgeSet:      return CallEdgeSet::Read(buf);
  case TAG_BlockModset:      return BlockModset::Read(buf);
  case TAG_BlockSummary:     return BlockSummary::Read(buf);

  // special case: get the CFG too.
  case TAG_BlockMemory: {
    BlockMemory *mcfg = BlockMemory::Read(buf);
    BlockCFG *cfg = GetBlockCFG(mcfg->GetId());
    if (cfg)
      mcfg->SetCFG(cfg);
    return mcfg;
  }

  default:
    logout << "ERROR: Unknown top-level tag in entry: "
           << PeekOpenTag(buf) << endl;
    Assert(false);
  }
}
コード例 #2
0
ファイル: summary.cpp プロジェクト: wh5a/xgill
void BlockSummary::ComputeAssertNames()
{
  BlockCFG *cfg = GetBlockCFG(m_id);
  Assert(cfg);

  // the assertion names need the filename of the containing function.
  Location *loc = cfg->GetPointLocation(cfg->GetEntryPoint());

  // keep track of the last kind/index to be generated for an assertion.
  // the index space should be different for each assertion kind so that
  // different assertions do not interfere with one another. we can get this
  // with a simple counter because the assertions are sorted by kind.
  AssertKind last_kind = ASK_None;
  size_t last_index = 0;

  for (size_t ind = 0; m_assert_list && ind < m_assert_list->Size(); ind++) {
    AssertInfo &info = m_assert_list->At(ind);
    Assert(!info.name_buf);

    // only compute indexes for assertions which need to be checked.
    if (info.cls != ASC_Check) continue;

    // reset the index if this is a new kind of assertion.
    if (info.kind != last_kind) {
      last_kind = info.kind;
      last_index = 0;
    }
    last_index++;

    info.name_buf = new Buffer(256);
    BufferOutStream out(info.name_buf);

    out << AssertKindString(last_kind) << "$"
        << loc->FileName()->Value() << "$"
        << m_id->Function()->Value() << "$"
        << (m_id->Kind() == B_Loop ? m_id->Loop()->Value() : "func") << "$"
        << last_index << '\0';
  }

  cfg->DecRef();
}
コード例 #3
0
ファイル: checker.cpp プロジェクト: wh5a/xgill
// consumes a reference on callee.
bool CheckSingleCallee(CheckerState *state, CheckerFrame *frame, PPoint point,
                       WherePostcondition *postcondition,
                       BlockId *callee, bool direct)
{
  Assert(postcondition);
  Assert(postcondition->GetPoint() == point);

  BlockCFG *cfg = frame->Memory()->GetCFG();
  bool is_call = cfg->PointEdgeIsCall(point);

  CheckerFrame *callee_frame;
  if (is_call)
    callee_frame = frame->GetCalleeFrame(point);
  else
    callee_frame = frame->GetLoopTailFrame(point);

  // we should be going strictly backwards, and thus should never be
  // able to visit the exit point of a callee more than once.
  Assert(!callee_frame);

  callee_frame = state->MakeFrame(callee);
  callee->DecRef();

  if (callee_frame == NULL) {
    // there are two ways we can get here:
    // 1. we saw the definition but timed out generating the memory.
    //    emit a warning.
    // 2. we never saw a definition. emit a warning in the indirect call case,
    //    make a report in the direct call case. we should really make a report
    //    in all cases, but the indirect callgraph needs some more work.

    BlockCFG *cfg = GetBlockCFG(callee);
    if (!cfg) {
      const char *kind = direct ? "direct" : "indirect";
      logout << "WARNING: Missing " << kind
             << " callee: '" << callee << "'" << endl;

      if (!direct)
        return false;

      // make an empty propagation for before the call.
      CheckerPropagate propagate(frame, point, false);
      state->m_stack.PushBack(&propagate);

      state->SetReport(RK_NoCallee);
      return true;
    }
    cfg->DecRef();

    logout << "WARNING: Missing memory: '" << callee << "'" << endl;
    return false;
  }

  PPoint exit_point = callee_frame->Memory()->GetCFG()->GetExitPoint();
  callee_frame->AssertPointGuard(exit_point, true);

  if (is_call) {
    frame->ConnectCallee(callee_frame, point, true);
  }
  else {
    // we are getting the last iteration of the loop so there is no direct
    // callee to connect yet.
    frame->ConnectLoopTail(callee_frame, point);
  }

  // add the exit equalities for any callee_expand in frame and caller_expand
  // in callee_frame.
  frame->ExpandPendingExps();
  callee_frame->ExpandPendingExps();

  // get the safe bits for the callee frame.
  Bit *callee_base_bit;
  GuardBitVector callee_safe_list;
  postcondition->GetCalleeBits(callee_frame,
                               &callee_base_bit, &callee_safe_list);

  if (CheckFrameList(state, callee_frame, exit_point, false, false,
                     callee_base_bit, callee_safe_list)) {
    callee_base_bit->DecRef();
    return true;
  }

  callee_base_bit->DecRef();

  if (is_call)
    frame->DisconnectCallee(callee_frame, point);
  else
    frame->DisconnectLoopTail(callee_frame, point);

  state->DeleteFrame(callee_frame);
  return false;
}