示例#1
0
def gen_modrm_lookup(united_lookup, debug):
    modrm_lookup = {}
    for insn_map in ild_info.get_dump_maps():
        modrm_lookup[insn_map] = {}
        for opcode in range(0, 256):
            info_list = united_lookup.get_info_list(insn_map, hex(opcode))
            info_list = ild_info.get_min_prio_list(info_list)
            if len(info_list) == 0:
                #no infos in map-opcode, illegal opcode
                has_modrm = _has_modrm_undef
            elif _is_modrm_conflict(info_list):
                #conflict in has_modrm value in map-opcode's info_list
                #try to resolve
                info = _resolve_modrm_conflict(info_list)
                if not info:
                    ildutil.ild_err(
                        'UNRESOLVED CONFLICT IN MODRM\n infos:\n%s\n' %
                        "\n".join([str(info) for info in info_list]))
                has_modrm = info.has_modrm
            else:
                #several infos that agree on has_modrm property, we can choose
                #any of them to get has_modrm
                info = info_list[0]
                has_modrm = info.has_modrm
            modrm_lookup[insn_map][hex(opcode)] = has_modrm
    return modrm_lookup
示例#2
0
def gen_l1_functions_and_lookup(agi, instr_by_map_opcode, imm_dict):
    """Compute L1(conflict resolution) functions list and imm_bytes 
    lookup tables dict.
    @param agi: all generators info
    
    @param instr_by_map_opcode: the 2D lookup by map-opcode to info objects list.
    instr_by_map_opcode['0x0']['0x78'] == [ild_info1, ild_info2, ... ]
    @type instr_by_map_opcode: 
    {string(insn_map) : {string(opcode): [ild_info.ild_info_t]} }
    
    
    """
    l1_resolution_fos = []
    l1_lookup = {}
    for insn_map in ild_info.get_dump_maps_imm(agi):
        l1_lookup[insn_map] = {}
        for opcode in range(0, 256):
            #look in the hard-coded resolution functions
            #they are manually written for the two-immediates instructions
            if (insn_map, hex(opcode)) in _hardcoded_res_functions_imm:
                l1_fn = _hardcoded_res_functions_imm[(insn_map, hex(opcode))]
                l1_lookup[insn_map][hex(opcode)] = l1_fn
                continue
            info_list = instr_by_map_opcode.get_info_list(
                insn_map, hex(opcode))
            #get only info objects with minimum priority
            info_list = ild_info.get_min_prio_list(info_list)
            is_conflict = _is_imm_conflict(info_list, imm_dict)

            if len(info_list) > 1 and is_conflict:
                l1_fo = _resolve_conflicts(agi, info_list, imm_dict)
                if not l1_fo:
                    ildutil.ild_err(
                        'FAILED TO GENERATE L1 CONFLICT ' +
                        'RESOLUTION FUNCTION FOR IMM\n infos:\n %s' %
                        "\n".join([str(info) for info in info_list]))

                l1_resolution_fos.append(l1_fo)
                l1_fn = l1_fo.function_name
            #if map-opcode pair is undefined the lookup function ptr is NULL
            #this will happen for opcodes like 0F in 0F map - totally illegal
            #opcodes, that should never be looked up in runtime.
            elif len(info_list) == 0:
                l1_fn = _imm0_fn
            else:
                #there are no conflicts, we can use L2 function as L1
                info = info_list[0]
                l1_fn = get_l2_fn_from_info(info, imm_dict)
                if not l1_fn:
                    return None
            l1_lookup[insn_map][hex(opcode)] = l1_fn
    return l1_resolution_fos, l1_lookup
示例#3
0
def gen_getter_fn_lookup(agi, united_lookup, eosz_dict):  # NOT USED
    """Compute L1(conflict resolution) functions list and eosz 
    lookup tables dict.
    @param agi: all generators info
    
    @param united_lookup: the 2D lookup by map-opcode to info objects list.
    united_lookup['0x0']['0x78'] == [ild_info1, ild_info2, ... ]
    @type united_lookup: 
    {string(insn_map) : {string(opcode): [ild_info.ild_info_t]} }
    
    
    """
    l1_lookup = {}
    for insn_map in united_lookup.get_maps():
        l1_lookup[insn_map] = {}
        for opcode in range(0, 256):
            info_list = united_lookup.get_info_list(insn_map, hex(opcode))
            #get only info objects with minimum priority
            info_list = ild_info.get_min_prio_list(info_list)
            is_conflict = False
            if len(info_list) > 1:
                is_conflict = is_eosz_conflict(info_list)

            if is_conflict:
                genutil.msg("EOSZ CONFLICT MAP/OPCODE:{}/{}".format(
                    insn_map, opcode))
                #                l1_fo = _resolve_conflicts(agi, info_list, nt_dict)
                #                if not l1_fo:
                #                    ildutil.ild_err('FAILED TO GENERATE CONFLICT ' +
                #                    'RESOLUTION FUNCTION FOR EOSZ\n infos:\n %s' %
                #                    "\n".join([str(info) for info in info_list]))
                #
                #                l1_resolution_fos.append(l1_fo)
                #                l1_fn = l1_fo.function_name
                l1_fn = None
            #if map-opcode pair is undefined the lookup function ptr is NULL
            #this will happen for opcodes like 0F in 0F map - totally illegal
            #opcodes, that should never be looked up in runtime.
            elif len(info_list) == 0:
                l1_fn = '(%s)0' % (ildutil.l1_ptr_typename)
            else:
                #there are no conflicts, we can use the eosz_nt_seq
                #function
                info = info_list[0]
                l1_fn = ild_nt.get_lufn(info.eosz_nt_seq, _eosz_token)
            l1_lookup[insn_map][hex(opcode)] = l1_fn
    return l1_lookup
示例#4
0
def gen_getter_fn_lookup(agi, united_lookup, easz_dict):  # NOT USED
    """Compute L1(conflict resolution) functions list and easz 
    lookup tables dict.
    @param agi: all generators info
    
    @param united_lookup: the 2D lookup by map-opcode to info objects list.
    united_lookup['0x0']['0x78'] == [ild_info1, ild_info2, ... ]
    @type united_lookup: 
    {string(insn_map) : {string(opcode): [ild_info.ild_info_t]} }
    
    
    """
    l1_lookup = {}
    for insn_map in united_lookup.get_maps():
        l1_lookup[insn_map] = {}
        for opcode in range(0, 256):
            info_list = united_lookup.get_info_list(insn_map, hex(opcode))
            #get only info objects with minimum priority
            info_list = ild_info.get_min_prio_list(info_list)
            is_conflict = False
            if len(info_list) > 1:
                is_conflict = is_easz_conflict(info_list)

            if is_conflict:
                l1_fn = None
            #if map-opcode pair is undefined the lookup function ptr is NULL
            #this will happen for opcodes like 0F in 0F map - totally illegal
            #opcodes, that should never be looked up in runtime.
            elif len(info_list) == 0:
                l1_fn = '(%s)0' % (ildutil.l1_ptr_typename)
            else:
                #there are no conflicts, we can use the eosz_nt_seq
                #function
                info = info_list[0]
                l1_fn = ild_nt.get_lufn(info.easz_nt_seq, _easz_token)
            l1_lookup[insn_map][hex(opcode)] = l1_fn
    return l1_lookup
示例#5
0
def gen_l1_functions_and_lookup(agi, united_lookup, disp_dict):
    """Compute L1(conflict resolution) functions list and disp_bytes lookup 
    tables dict.
    @param agi: all generators info
    
    @param united_lookup: the 2D lookup by map-opcode to info objects list.
    united_lookup['0x0']['0x78'] == [ild_info1, ild_info2, ... ]
    @type united_lookup: 
    {string(insn_map) : {string(opcode): [ild_info.ild_info_t]} }
    
    
    """
    #list of L1 function objects that resolve conflicts in map-opcodes
    #functions. This list will be dumped to xed_ild_imm_l1.h
    l1_resolution_fos = []

    #dictionary l1_lookup[insn_map][opcode] = l1_function_name
    #this dictionary will be used to dump the has_imm lookup tables
    l1_lookup = {}

    #dictionary from function body(as string) to list of function objects
    #with that body.
    #This dict will be used to bucket identical functions in order to
    #not define same functions more than once.
    l1_bucket_dict = collections.defaultdict(list)

    for insn_map in ild_info.get_maps(united_lookup.is_amd):
        l1_lookup[insn_map] = {}
        for opcode in range(0, 256):
            #look in the hardcoded resolution functions
            if (insn_map, hex(opcode)) in harcoded_res_functions:
                l1_fn = harcoded_res_functions[(insn_map, hex(opcode))]
                l1_lookup[insn_map][hex(opcode)] = l1_fn
                continue
            info_list = united_lookup.get_info_list(insn_map, hex(opcode))
            #get only info objects with minimum priority
            info_list = ild_info.get_min_prio_list(info_list)
            is_conflict = _is_disp_conflict(info_list, disp_dict)
            if len(info_list) > 1 and is_conflict:
                l1_fo = _resolve_conflicts(agi, info_list, disp_dict)
                if not l1_fo:
                    ildutil.ild_err(
                        'FAILED TO GENERATE L1 CONFLICT ' +
                        'RESOLUTION FUNCTION FOR DISP\n infos: %s' %
                        "\n".join([str(info) for info in info_list]))
                l1_bucket_dict[l1_fo.emit_body()].append(l1_fo)
                l1_fn = l1_fo.function_name

            elif len(info_list) == 0:
                #if map-opcode pair is undefined the lookup function ptr is
                #NULL.
                #This will happen for opcodes like 0F in 0F map - totally
                #illegal opcodes, that should never be looked up in runtime.
                #We define NULL pointer for such map-opcodes
                l1_fn = '(%s)0' % (ildutil.l1_ptr_typename)
            else:
                #there are no conflicts, we can use L2 function as L1
                info = info_list[0]
                l1_fn = get_l2_fn_from_info(info, disp_dict)
            l1_lookup[insn_map][hex(opcode)] = l1_fn

    #there are 18 L1 functions with same body (currently, may change
    #in future)
    #we are going to bucket L1 functions with identical body but different
    #names in order to have only one function for each unique body
    #FIXME: the bucketed function name is not self descriptive
    bucket_name = 'xed_lookup_function_DISP_BUCKET_%s_l1'
    cur_bucket = 0
    for res_fun_list in list(l1_bucket_dict.values()):
        if len(res_fun_list) == 1:
            #only one such function - we should define it as is
            l1_resolution_fos.append(res_fun_list[0])
        else:
            #more than one L1 function with identical body
            #we should define L1 function with that body
            #and fix references in the lookup table

            #the function name
            cur_buck_name = bucket_name % cur_bucket
            cur_bucket += 1

            #fix references in the lookup table
            for res_fun in res_fun_list:
                for insn_map in list(l1_lookup.keys()):
                    for opcode in list(l1_lookup[insn_map].keys()):
                        cur_fn = l1_lookup[insn_map][opcode]
                        if cur_fn == res_fun.function_name:
                            l1_lookup[insn_map][opcode] = cur_buck_name
            #define the L1 function and add it to the list of L1 functions
            #to dump
            buck_fo = res_fun_list[0]
            buck_fo.function_name = cur_buck_name
            l1_resolution_fos.append(buck_fo)

    return l1_resolution_fos, l1_lookup