在qmeu中,將qmeu 本身所執行的平台稱為 host,模擬的平台稱target,而將target code 轉為 host code 的過程稱為code generation。但因為qemu 是在動態執行中將target code 轉為 host code,所以多加了一個dynammic來形容。而整個過程在qemu 中稱為 dyngen。

0.9.1 版之前的dyngen 概念很簡單(但實作起來有很多細部的東東,整個就是複雜),dyegen 定義了四個pesudo register:env, T0, T1, T2,這四個register分別mapping 到 host 上真實的general register,在x86上就是 ebp, ebx, esi, edi,在x86_64上就是 r14, r15, r12, r13 (為什麼不是r12, r13, 14, 15,怪),定義在dyngen-exec.h

之後target 必需定義一些簡單的operation function,此operation function 被定義在每個  target-machine/op.c ,底下是target-arm 的例是,每個平台大同小異

,這些operation 很簡單,定義如何在pesudo register 之間搬資料,做一些簡單的動作。

 

void OPPROTO op_movl_T0_T1(void)
{
    T0 = T1;
}

void OPPROTO op_movl_T1_im(void)
{
    T1 = PARAM1;
}

void OPPROTO op_addl_T1_im(void)
{
    T1 += PARAM1;
}

void OPPROTO op_addl_T1_T2(void)
{
    T1 += T2;
}

void OPPROTO op_subl_T1_T2(void)
{
    T1 -= T2;
}

有了這些基本的operation後,在build qemu時會將的會將op.c 編譯成 op.o,再從op.o 將每個operation 所對應的host code抽出來,產生op.h opc.h,target-machine/translate.c 利用產生出來的個這兩個header file將每個target instruction 對應到數個operation function。就像底下的arm 例子,

 

        op = (insn >> 11) & 3;
        rd = (insn >> 8) & 0x7;
        if (op == 0) {
            gen_op_movl_T0_im(insn & 0xff);
        } else {
            gen_movl_T0_reg(s, rd);
           gen_op_movl_T1_im(insn & 0xff);
        }
        switch (op) {
        case 0: /* mov */
            gen_op_logic_T0_cc();
            break;
        case 1: /* cmp */
            gen_op_subl_T0_T1_cc();
            break;
        case 2: /* add */
            gen_op_addl_T0_T1_cc();
            break;
        case 3: /* sub */
            gen_op_subl_T0_T1_cc();
            break;
        }
        if (op != 1)
            gen_movl_reg_T0(s, rd);

 

底下是截取 objdump op.o 的部份,dyngen 會把retq 以上的部份copy 出來,再經過一些patch 就產生相對應的code 啦,上面粗體的gen_xxx_xxx的function 就會把相對應的找出來,轉換就完成啦

00000000000001e7 <op_addl_T1_T2>:
     1e7:       45 01 ec                add    %r13d,%r12d
     1ea:       c3                      retq

00000000000001eb <op_subl_T1_T2>:
     1eb:       45 29 ec                sub    %r13d,%r12d
     1ee:       c3                      retq

00000000000001ef <op_addl_T0_T1>:
     1ef:       45 01 e7                add    %r12d,%r15d
     1f2:       c3                      retq

 

講起來好像很簡單,那是因為假裝略過 control flow 的東東,有興趣的人自已看吧,講寫的東東其實是第二篇,先騙騙錢。

arrow
arrow
    全站熱搜

    cmchao 發表在 痞客邦 留言(0) 人氣()