Exemple #1
0
void CR_ModuleEx::CreateFlowGraph64(CR_Addr64 entrance) {
    auto cf = Info64()->CodeFuncFromAddr(entrance);
    assert(cf);

    CR_Addr64Set leaders;
    leaders.insert(entrance);

    // insert jumpees
    auto& jumpees = cf->Jumpees();
    leaders.insert(jumpees.begin(), jumpees.end());

    // insert exits' next
    auto& exits = cf->Exits();
    for (auto addr : exits) {
        auto op_code = Info64()->OpCodeFromAddr(addr);
        auto size = op_code->Codes().size();
        auto next_addr = static_cast<CR_Addr64>(addr + size);
        leaders.insert(next_addr);
    }

    // insert jumpers' next
    auto& jumpers = cf->Jumpers();
    for (auto addr : jumpers) {
        auto op_code = Info64()->OpCodeFromAddr(addr);
        auto size = op_code->Codes().size();
        auto next_addr = static_cast<CR_Addr64>(addr + size);
        leaders.insert(next_addr);
    }

    // sort
    std::vector<CR_Addr64> vecLeaders(leaders.begin(), leaders.end());
    std::sort(vecLeaders.begin(), vecLeaders.end());

    // store leaders
    cf->Leaders() = std::move(leaders);

    const size_t size = vecLeaders.size() - 1;
    for (size_t i = 0; i < size; ++i) {
        // for every pair of two adjacent leaders
        auto addr1 = vecLeaders[i], addr2 = vecLeaders[i + 1];
        // prepare a basic block
        CR_BasicBlock64 block;
        block.m_addr = addr1;
        CR_Addr64 next_addr = cr_invalid_addr64;
        for (auto addr = addr1; addr < addr2; ) {
            if (cf->Leaders().count(addr)) {
                // set label at each leader
                block.AddLeaderLabel(addr);
            }
            // op.code from addr
            auto op_code = Info64()->OpCodeFromAddr(addr);
            if (op_code == NULL) {
                break;
            }
            auto type = op_code->OpCodeType();
            if (type == cr_OCT_JMP) {
                // jump
                auto oper = op_code->Operand(0);
                if (oper->GetOperandType() == cr_DF_IMM) {
                    block.m_jump_to = oper->Value64();  // jump to
                }
                next_addr = cr_invalid_addr64;
            } else if (type == cr_OCT_RETURN) {
                next_addr = cr_invalid_addr64;
            } else if (type == cr_OCT_JCC || type == cr_OCT_LOOP) {
                // conditional jump or loop
                auto oper = op_code->Operand(0);
                if (oper->GetOperandType() == cr_DF_IMM) {
                    block.m_jump_to = oper->Value64();  // jump to
                }
                block.m_cond_code = op_code->CondCode();
                next_addr =
                    static_cast<CR_Addr64>(addr + op_code->Codes().size());
            } else {
                next_addr =
                    static_cast<CR_Addr64>(addr + op_code->Codes().size());
            }
            // add op.code
            block.m_stmts.emplace_back(*op_code);
            // go to next addr
            addr += static_cast<CR_Addr64>(op_code->Codes().size());
        }
        // add label at last
        block.AddLeaderLabel(addr2);
        // set next addr
        block.m_next_addr = next_addr;
        // add block
        cf->BasicBlocks().emplace_back(block);
    }
} // CR_ModuleEx::CreateFlowGraph64
Exemple #2
0
/*!
  \param RecBufSw
*/
xbShort xbExpn::ProcessOperator( xbShort RecBufSw )
{
  xbExpNode * WorkNode;
  char Operator[6]; 
  char t;
  if( GetStackDepth() < 3 ) 
    return XB_PARSE_ERROR;
  WorkNode = (xbExpNode *) Pop();
  if( WorkNode->Len > 5 )
    return XB_PARSE_ERROR;

  memset( Operator, 0x00, 6 );
  strncpy( Operator, WorkNode->NodeText, WorkNode->Len );
  if( !WorkNode->InTree ) 
    delete WorkNode;

  /* load up operand 1 */
  WorkNode = (xbExpNode *) Pop();
  if(( OpType1 = GetOperandType( WorkNode )) == 0 )
    return XB_PARSE_ERROR;

  if( OpLen1 < WorkNode->DataLen+1 && WorkNode->Type != 'd' ) {
    if( OpLen1 > 0 ) free( Op1 );
    if(( Op1 = (char *) malloc( WorkNode->DataLen+1 )) == NULL ) {
      return XB_NO_MEMORY;
    }
    OpLen1 = WorkNode->DataLen+1;
  }
  OpDataLen1 = WorkNode->DataLen;
  memset( Op1, 0x00, WorkNode->DataLen+1 );
  if( WorkNode->Type == 'D' && WorkNode->dbf ) {    /* database field  */
    WorkNode->dbf->GetField( WorkNode->FieldNo, Op1, RecBufSw );
    t = WorkNode->dbf->GetFieldType( WorkNode->FieldNo );
    if( t == 'N' || t == 'F' )
      Opd1 = strtod( WorkNode->StringResult, 0 );
    else if( t == 'D' ){   // date field
      xbDate d;
      Opd1 = d.JulianDays( WorkNode->StringResult );
    }
  }
  else if( WorkNode->Type == 'C' )     /* constant        */
    memcpy( Op1, WorkNode->NodeText, WorkNode->DataLen );
  else if( WorkNode->Type == 's' )     /* previous result */
    memcpy( Op1, WorkNode->StringResult, WorkNode->DataLen+1 );
  else if( WorkNode->Type == 'd' )     /* previous numeric result */   
    Opd1 = WorkNode->DoubResult;
  else if( WorkNode->Type == 'N' )     /* previous numeric result */   
    Opd1 = strtod( WorkNode->StringResult, 0 );
  else if(WorkNode->Type == 'l')       /* previous logical result 3/26/00 dtb */
    Opd1 = WorkNode->IntResult;
  if( !WorkNode->InTree ) 
    delete WorkNode;

  /* load up operand 2 */
  WorkNode = (xbExpNode *) Pop();
  if(( OpType2 = GetOperandType( WorkNode )) == 0 )
    return XB_PARSE_ERROR;

  if( OpLen2 < WorkNode->DataLen+1 && WorkNode->Type != 'd' ) {
    if( OpLen2 > 0 ) free( Op2 );
    if(( Op2 = (char *) malloc( WorkNode->DataLen+1 )) == NULL ) {
      return XB_NO_MEMORY;
    }
    OpLen2 = WorkNode->DataLen+1;
  }
  OpDataLen2 = WorkNode->DataLen;
  memset( Op2, 0x00, WorkNode->DataLen+1 );
  if( WorkNode->Type == 'D' && WorkNode->dbf ) {    /* database field  */
    WorkNode->dbf->GetField( WorkNode->FieldNo, Op2, RecBufSw );
    t = WorkNode->dbf->GetFieldType( WorkNode->FieldNo );
    if( t == 'N' || t == 'F' )
      Opd2 = strtod( WorkNode->StringResult, 0 );
    else if( t == 'D' ){   // date field
      xbDate d;
      Opd2 = d.JulianDays( WorkNode->StringResult );
    }
  }
  else if( WorkNode->Type == 'C' )     /* constant        */
    memcpy( Op2, WorkNode->NodeText, WorkNode->DataLen );
  else if( WorkNode->Type == 's' )     /* previous result */
    memcpy( Op2, WorkNode->StringResult, WorkNode->DataLen+1 );
  else if( WorkNode->Type == 'd' )     /* previous numeric result */
    Opd2 = WorkNode->DoubResult;
  else if( WorkNode->Type == 'N' )     /* previous numeric result */   
    Opd2 = strtod( WorkNode->StringResult, 0 );
  else if(WorkNode->Type == 'l')       /* previous logical result 3/26/00 dtb*/
    Opd2 = WorkNode->IntResult;
  if( !WorkNode->InTree )
    delete WorkNode;
  if( !ValidOperation( Operator, OpType1, OpType2 ))
    return XB_PARSE_ERROR;

  if( OpType1 == 'N' || OpType1 == 'L' || OpType1 == 'D' ) /* numeric procesing */
    return NumericOperation( Operator );
  else                    /* must be character */
    return  AlphaOperation( Operator );
}