Beispiel #1
0
// 構文木をトレースする
static void traceTree(int node) {
  if (node==SyNULL) return;                       // 何も無い
  int ty = syGetType(node);
  if (ty==SyIF) genIf(node);                      // if 文
  else if (ty==SyELS) genEls(node);               // if-else 文
  else if (ty==SyWHL) genWhl(node);               // while 文
  else if (ty==SyDO)  genDo(node);                // do-while 文
  else if (ty==SyBRK) genBrk(node);               // break 文
  else if (ty==SyCNT) genCnt(node);               // continue 文
  else if (ty==SyRET) genRet(node);               // retrun 文
  else if (ty==SyBLK || ty==SySEMI) {             // ブロック
    traceTree(syGetLVal(node));                   //   先に左側をコード生成
    traceTree(syGetRVal(node));                   //   次に右側をコード生成
  } else if (ty==SyVAR) {                         // ローカル変数宣言
    ;                                             //   特にやることがない
  } else {                                        // 式文
    struct Expr *c = newExpr();                   //   式の状態を管理するデータ
    genBoolExpr(node, c);                         //   式を処理する
    pop(c);                                       //   スタックにあれば捨てる
    free(c);                                      //   管理データを解放
  }
}    
Beispiel #2
0
// generate code for a captured BB
void generate(Rewriter* r, CBB* cbb)
{
    uint8_t* buf;
    uint64_t buf0;
    int used, i, usedTotal;

    if (cbb == 0) return;
    if (r->cs == 0) return;

    if (r->showEmuSteps)
        printf("Generating code for BB %s (%d instructions)\n",
               cbb_prettyName(cbb), cbb->count);

    usedTotal = 0;
    buf0 = (uint64_t) reserveCodeStorage(r->cs, 0); // remember start address
    for(i = 0; i < cbb->count; i++) {
        Instr* instr = cbb->instr + i;

        buf = reserveCodeStorage(r->cs, 15);

        if (instr->ptLen > 0) {
            used = genPassThrough(buf, instr);
        }
        else {
            switch(instr->type) {
            case IT_ADD:
                used = genAdd(buf, &(instr->src), &(instr->dst));
                break;
            case IT_CLTQ:
                used = genCltq(buf, instr->vtype);
                break;
            case IT_CQTO:
                used = genCqto(buf, instr->vtype);
                break;
            case IT_CMP:
                used = genCmp(buf, &(instr->src), &(instr->dst));
                break;
            case IT_DEC:
                used = genDec(buf, &(instr->dst));
                break;
            case IT_IMUL:
                used = genIMul(buf, &(instr->src), &(instr->dst));
                break;
            case IT_IDIV1:
                used = genIDiv1(buf, &(instr->dst));
                break;
            case IT_INC:
                used = genInc(buf, &(instr->dst));
                break;
            case IT_XOR:
                used = genXor(buf, &(instr->src), &(instr->dst));
                break;
            case IT_OR:
                used = genOr(buf, &(instr->src), &(instr->dst));
                break;
            case IT_AND:
                used = genAnd(buf, &(instr->src), &(instr->dst));
                break;
            case IT_SHL:
                used = genShl(buf, &(instr->src), &(instr->dst));
                break;
            case IT_SHR:
                used = genShr(buf, &(instr->src), &(instr->dst));
                break;
            case IT_SAR:
                used = genSar(buf, &(instr->src), &(instr->dst));
                break;
            case IT_LEA:
                used = genLea(buf, &(instr->src), &(instr->dst));
                break;
            case IT_MOV:
            case IT_MOVSX: // converting move
                used = genMov(buf, &(instr->src), &(instr->dst));
                break;
            case IT_CMOVO:
            case IT_CMOVNO:
            case IT_CMOVC:
            case IT_CMOVNC:
            case IT_CMOVZ:
            case IT_CMOVNZ:
            case IT_CMOVBE:
            case IT_CMOVA:
            case IT_CMOVS:
            case IT_CMOVNS:
            case IT_CMOVP:
            case IT_CMOVNP:
            case IT_CMOVL:
            case IT_CMOVGE:
            case IT_CMOVLE:
            case IT_CMOVG:
                used = genCMov(buf, instr->type, &(instr->src), &(instr->dst));
                break;
            case IT_POP:
                used = genPop(buf, &(instr->dst));
                break;
            case IT_PUSH:
                used = genPush(buf, &(instr->dst));
                break;
            case IT_RET:
                used = genRet(buf);
                break;
            case IT_SUB:
                used = genSub(buf, &(instr->src), &(instr->dst));
                break;
            case IT_TEST:
                used = genTest(buf, &(instr->src), &(instr->dst));
                break;
            case IT_HINT_CALL:
            case IT_HINT_RET:
                used = 0;
                break;
            default: assert(0);
            }
        }
        assert(used < 15);

        instr->addr = (uint64_t) buf;
        instr->len = used;
        usedTotal += used;

        if (r->showEmuSteps) {
            printf("  I%2d : %-32s", i, instr2string(instr, 1, 0));
            printf(" (%s)+%lx %s\n",
                   cbb_prettyName(cbb), instr->addr - buf0,
                   bytes2string(instr, 0, used));
        }

        useCodeStorage(r->cs, used);
    }

    if (r->showEmuSteps) {
        if (instrIsJcc(cbb->endType)) {
            assert(cbb->nextBranch != 0);
            assert(cbb->nextFallThrough != 0);

        printf("  I%2d : %s (%s),",
               i, instrName(cbb->endType, 0),
               cbb_prettyName(cbb->nextBranch));
        printf(" fall-through to (%s)\n",
               cbb_prettyName(cbb->nextFallThrough));
        }
    }

    // add padding space after generated code for jump instruction
    buf = useCodeStorage(r->cs, 10);

    cbb->size = usedTotal;
    // start address of generated code.
    // if CBB had no instruction, this points to the padding buffer
    cbb->addr1 = (cbb->count == 0) ? ((uint64_t)buf) : cbb->instr[0].addr;
}