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
def emit_gen_info_lookup(agi, ptrn_list, is_3dnow, debug): debug.write("DUMPING ILD STORAGE\n") f = codegen.xed_file_emitter_t(agi.common.options.xeddir, agi.common.options.xeddir, storage_fn, shell_file=True) storage = get_info_storage(ptrn_list, ild_info.storage_priority, is_3dnow) #list_name = "info_lookup['%s']['%s']" list_name = 'info_list' indent = ' ' * 4 f.start() f.add_code("import ild_info") f.add_code("import ild_storage\n\n\n") f.add_code("#GENERATED FILE - DO NOT EDIT\n\n\n") f.write("def gen_ild_info():\n") f.write(indent + "storage = ild_storage.ild_storage_t(is_amd=%s)\n" % is_3dnow) for insn_map in ild_info.get_dump_maps(): for op in range(0, 256): for info in storage.get_info_list(insn_map, hex(op)): f.write("%s#MAP:%s OPCODE:%s\n" % (indent, info.insn_map, info.opcode)) f.write("%sinfo_list = storage.get_info_list('%s','%s')\n" % (indent, insn_map, hex(op))) emit_add_info_call(info, list_name, f, indent) f.write(indent + "return storage\n") f.close()
def gen_l1_functions_and_lookup(agi, united_lookup, imm_dict): """Compute L1(conflict resolution) functions list and imm_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]} } """ l1_resolution_fos = [] l1_lookup = {} for insn_map in ild_info.get_dump_maps(): 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 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_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 = '(%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, imm_dict) if not l1_fn: return None l1_lookup[insn_map][hex(opcode)] = l1_fn return l1_resolution_fos, l1_lookup