qemu翻译过程分析(二)

    技术2022-05-19  21

    qemu把翻译过的目标指令集保存在一个类型为TranslationBlock的结构体中,其结构体定义如下:

     

    struct TranslationBlock { target_ulong pc; /* simulated PC corresponding to this block (EIP + CS base) */ target_ulong cs_base; /* CS base for this block */ uint64_t flags; /* flags defining in which context the code was generated */ uint16_t size; /* size of target code for this block (1 <= size <= TARGET_PAGE_SIZE) */ uint16_t cflags; /* compile flags */ #define CF_COUNT_MASK 0x7fff #define CF_LAST_IO 0x8000 /* Last insn may be an IO access. */ uint8_t *tc_ptr; /* pointer to the translated code */ /* next matching tb for physical address. */ struct TranslationBlock *phys_hash_next; /* first and second physical page containing code. The lower bit of the pointer tells the index in page_next[] */ struct TranslationBlock *page_next[2]; tb_page_addr_t page_addr[2]; /* the following data are used to directly call another TB from the code of this one. */ uint16_t tb_next_offset[2]; /* offset of original jump target */ #ifdef USE_DIRECT_JUMP uint16_t tb_jmp_offset[2]; /* offset of jump instruction */ #else unsigned long tb_next[2]; /* address of jump generated code */ #endif /* list of TBs jumping to this one. This is a circular list using the two least significant bits of the pointers to tell what is the next pointer: 0 = jmp_next[0], 1 = jmp_next[1], 2 = jmp_first */ struct TranslationBlock *jmp_next[2]; struct TranslationBlock *jmp_first; uint32_t icount; };

     

    这些TB保存在一个hash数组中,其中索引是以目标机的pc杂凑生成的hash值,其hash函数如下:

    static inline unsigned int tb_jmp_cache_hash_func(target_ulong pc) { target_ulong tmp; tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)); return (((tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK) | (tmp & TB_JMP_ADDR_MASK)); }

     

     其中tb的分配函数如下:

    /* Allocate a new translation block. Flush the translation buffer if too many translation blocks or too much generated code. */ TranslationBlock *tb_alloc(target_ulong pc) { TranslationBlock *tb; if (nb_tbs >= code_gen_max_blocks || (code_gen_ptr - code_gen_buffer) >= code_gen_buffer_max_size) return NULL; tb = &tbs[nb_tbs++]; tb->pc = pc; tb->cflags = 0; return tb; }


    最新回复(0)