def action_instr(toks): i = instruction(b"") i.mnemonic = toks[0].upper() # Remove prefixes if i.mnemonic in ("REP", "REPZ", "REPNZ", "REPE", "REPNE", "LOCK"): if i.mnemonic in ("REP", "REPZ", "REPE"): i.misc.update({"pfx": ["rep", None, None, None], "rep": True}) if i.mnemonic in ("REPNZ", "REPNE"): i.misc.update({ "pfx": ["repne", None, None, None], "repne": True }) if i.mnemonic in ("LOCK", ): i.misc.update({ "pfx": ["lock", None, None, None], "lock": True }) del toks[0] # toks.pop(0) is broken for pyparsing 2.0.2 # https://bugs.launchpad.net/ubuntu/+source/pyparsing/+bug/1381564 i.mnemonic = toks[0].upper() # Get operands if len(toks) > 1: i.operands = list(reversed(toks[1][0:])) # Convert mnemonics, set operand sizes if i.mnemonic in ( "CALLL", "CALLQ", "JMPL", "JMPQ", "RETL", "RETQ", "BSWAPL", "BSWAPQ", "FUCOMPI", ): # clang on MacOS X if i.mnemonic[-1] in ("L", "Q"): i.mnemonic = i.mnemonic[:-1] else: i.mnemonic = "FUCOMIP" mnemo = i.mnemonic.lower() if i.mnemonic in ("CALL", "JMP"): if len(i.operands) == 2 and i.operands[1] == "*": i.operands.pop() if not i.operands[0]._is_mem and not i.operands[0]._is_reg: i.operands[0] = expressions.mem(i.operands[0], cpu_addrsize) else: if i.operands[0]._is_mem: i.operands[0] = i.operands[0].a.base + i.operands[0].a.disp elif i.mnemonic.startswith(("J", "SET", "CMOV")): for pfx in ("J", "SET", "CMOV"): if i.mnemonic.startswith(pfx): break for i.cond in CONDITION_CODES.values(): if i.mnemonic[len(pfx):] in i.cond[0].split("/"): break else: if pfx == "CMOV" and i.mnemonic[-1] in ("W", "L", "Q"): # clang on MacOS X for i.cond in CONDITION_CODES.values(): if i.mnemonic[len(pfx):-1] in i.cond[0].split("/"): break else: NEVER elif pfx == "SET" and i.mnemonic[-1] == "B": # gcc 3.2.3 for i.cond in CONDITION_CODES.values(): if i.mnemonic[len(pfx):-1] in i.cond[0].split("/"): break else: NEVER else: NEVER i.mnemonic = pfx + "cc" if pfx == "J": i.operands[0] = i.operands[0].a.base + i.operands[0].a.disp if pfx == "CMOV": if i.operands[0]._is_mem: i.operands[0].size = i.operands[1].size if i.operands[1]._is_mem: i.operands[1].size = i.operands[0].size elif mnemo in att_mnemo_correspondance: i.mnemonic = att_mnemo_correspondance[mnemo].upper() if i.mnemonic in ("CBW", "CWD", "IRET"): i.misc.update({ "opdsz": 16, "pfx": [None, None, "opdsz", None] }) elif mnemo[-1] == "w" and mnemo[:-1] in mnemo_string_rep: i.misc.update({"opdsz": 16, "pfx": [None, None, "opdsz", None]}) elif i.mnemonic == "CMPSD" and len(i.operands) == 0: # String cmpsd, different from the SSE cmp*sd, has no arguments pass elif i.mnemonic == "MOVSL": # String movsd, different from the SSE movsd # Has no arguments i.mnemonic = "MOVSD" assert len(i.operands) == 0 elif i.mnemonic[:-2] in ("MOVS", "MOVZ"): i.misc["opdsz"], sz = { "BW": (8, 16), "BL": (8, 32), "BQ": (8, 64), "WL": (16, 32), "WQ": (16, 64), "LQ": (32, 64), }[i.mnemonic[-2:]] if i.operands[1]._is_mem: i.operands[1].size = i.misc["opdsz"] assert i.operands[0].size == sz i.mnemonic = i.mnemonic[:-2] + "X" elif i.mnemonic == "MOVD": pass elif i.mnemonic in ( "FLDCW", "FSTCW", "FNSTCW", ): assert i.operands[0]._is_mem i.operands[0].size = 16 elif i.mnemonic == "CMPXCHG": if i.operands[0]._is_mem: i.operands[0].size = i.operands[1].size elif i.mnemonic == "CMPXCHG8B": if i.operands[0]._is_mem: i.operands[0].size = 64 elif i.mnemonic == "CMPXCHG16B": if i.operands[0]._is_mem: i.operands[0].size = 128 elif i.mnemonic in mmx_with_suffix2 and len(i.operands): if i.mnemonic.endswith("SS"): if i.operands[1]._is_mem: i.operands[1].size = 32 elif i.mnemonic.endswith("SD"): if i.operands[0]._is_mem: i.operands[0].size = 64 if i.operands[1]._is_mem: i.operands[1].size = 64 else: if i.operands[1]._is_mem: i.operands[1].size = 128 elif i.mnemonic in ( "CVTSI2SS", "CVTSI2SD", "CVTTSS2SI", "CVTTSS2SIL", "CVTTSS2SIQ", ): if i.operands[1]._is_mem: i.operands[1].size = 32 # gcc 4.9.2 generates cvttss2siq %xmm0, %r15 # which is useless, because the size of the output is # determined by the output register if i.mnemonic[-1] in "LQ": i.mnemonic = i.mnemonic[:-1] elif i.mnemonic in ( "MOVLPD", "MOVLPS", "MOVHPD", "MOVHPS", "MOVDDUP", "PSHUFW", "CVTSD2SS", "CVTSD2SI", "CVTTSD2SI", "CVTTSD2SIL", "CVTTSD2SIQ", "CVTPI2PD", "CVTPI2PS", "CVTPS2PI", "CVTPS2PD", "CVTDQ2PD", ): if i.operands[0]._is_mem: i.operands[0].size = 64 if i.operands[1]._is_mem: i.operands[1].size = 64 if i.mnemonic[-1] in "LQ": i.mnemonic = i.mnemonic[:-1] elif i.mnemonic in ( "PSHUFD", "PSHUFLW", "PSHUFHW", "MOVDQA", "MOVDQU", "MOVSLDUP", "MOVSHDUP", "MOVAPD", "MOVAPS", "MOVUPD", "MOVUPS", "CVTPD2PS", "CVTPD2PI", "CVTPD2DQ", "CVTTPD2DQ", "CVTTPD2PI", "CVTPS2DQ", "CVTTPS2PI", "CVTTPS2DQ", "CVTDQ2PS", "PUNPCKHQDQ", ): if i.operands[0]._is_mem: i.operands[0].size = 128 if i.operands[1]._is_mem: i.operands[1].size = 128 elif i.mnemonic in mmx_with_suffix1 or i.mnemonic in ( "PSHUFB", "PAND", "PANDN", "POR", "PXOR", ): if i.operands[1]._is_mem: i.operands[1].size = i.operands[0].size elif i.mnemonic == "MOVABSQ": # gcc generates 'movabsq $cst, %reg' instead of 'movq $cst, %reg' i.mnemonic = "MOV" for _ in i.operands: if _._is_mem: _.size = 64 if _._is_cst: _.size = 64 _.v &= _.mask if _._is_lab: _.size = 64 else: for _ in att_mnemo_suffix_one_ptr: if mnemo[:-1] != _: continue # Detect MMX MOVQ instruction, not 64-bit register MOV for x64 if (i.mnemonic == "MOVQ" and i.operands[1]._is_reg and "mm" in i.operands[1].ref): if i.operands[0]._is_mem: i.operands[0].size = 64 break if (i.mnemonic == "MOVQ" and i.operands[0]._is_reg and "mm" in i.operands[0].ref): if i.operands[1]._is_mem: i.operands[1].size = 64 break i.mnemonic = _.upper() sz = {"b": 8, "w": 16, "l": 32, "q": 64}[mnemo[-1]] if "q" == mnemo[-1]: i.misc.update({"REX": (1, 0, 0, 0)}) if "w" == mnemo[-1]: i.misc.update({ "opdsz": 16, "pfx": [None, None, "opdsz", None] }) def set_size(e, sz): if e._is_mem: e.size = sz if e._is_cst: e.size = sz e.v &= e.mask if e._is_lab: e.size = sz if e._is_eqn: e.size = sz if e.l is not None: set_size(e.l, sz) set_size(e.r, sz) for _ in i.operands: set_size(_, sz) for _ in att_mnemo_suffix_one_iflt: if mnemo[:-1] != _: continue i.mnemonic = _.upper() sz = {"s": 16, "l": 32, "q": 64}[mnemo[-1]] for _ in i.operands: if _._is_mem: _.size = sz if mnemo[-2:] == "ll" and mnemo[:-2] in att_mnemo_suffix_one_iflt: # clang on MacOS X i.mnemonic = mnemo[:-2].upper() for _ in i.operands: if _._is_mem: _.size = 64 for _ in att_mnemo_float_optional_suffix: if mnemo[:-1] != _: continue if mnemo[-1] in ("i", "p", "r", "z", "1"): continue i.mnemonic = _.upper() sz = {"s": 32, "l": 64, "t": 80}[mnemo[-1]] for _ in i.operands: if _._is_mem: _.size = sz # Implicit operands if i.mnemonic in ("AAD", "AAM"): if len(i.operands) == 0: i.operands.append(expressions.cst(10, 8)) else: i.operands[0].size = 8 elif (i.mnemonic in ("SAL", "SAR", "SHL", "SHR", "ROR", "ROL") and len(i.operands) == 1): i.operands.append(expressions.cst(1, 32)) elif i.mnemonic in ("SHLD", "SHRD") and len(i.operands) == 2: i.operands.append(env.__dict__["cl"]) elif (i.mnemonic.startswith("CMP") and i.mnemonic.endswith( ("PS", "PD", "SD", "SS")) and len(i.operands)): idx = mnemo_sse_cmp_predicate.index(i.mnemonic[3:-2].lower()) i.operands.append(expressions.cst(idx)) i.mnemonic = i.mnemonic[:3] + i.mnemonic[-2:] elif (i.mnemonic in ( "FADD", "FSUB", "FSUBR", "FMUL", "FDIV", "FDIVR", "FCOMI", "FCOMIP", "FUCOMI", "FUCOMIP", ) and len(i.operands) == 1 and not i.operands[0]._is_mem): i.operands.insert(0, env.st(0)) elif (i.mnemonic in ( "FADDP", "FSUBP", "FSUBRP", "FMULP", "FDIVP", "FDIVRP", ) and len(i.operands) == 1 and not i.operands[0]._is_mem): i.operands.append(env.st(0)) elif (i.mnemonic in ( "FCOM", "FCOMP", "FUCOM", "FUCOMP", ) and len(i.operands) == 0): i.operands.append(env.st(1)) return i
def action_instr(toks): i = instruction('') i.mnemonic = toks[0].upper() # Remove prefixes if i.mnemonic in ('REP','REPZ','REPNZ','REPE','REPNE'): if i.mnemonic in ('REP','REPZ','REPE'): i.misc.update({'pfx':['rep', None,None,None], 'rep':True}) if i.mnemonic in ('REPNZ','REPNE'): i.misc.update({'pfx':['repne',None,None, None], 'repne':True}) toks.pop(0) i.mnemonic = toks[0].upper() # Get operands if len(toks) > 1: i.operands = list(reversed(toks[1][0:])) # Convert mnemonics, set operand sizes if i.mnemonic in ('CALLL','CALLQ','JMPL','JMPQ','RETL','RETQ', 'BSWAPL','FUCOMPI'): # clang on MacOS X if i.mnemonic[-1] in ('L','Q'): i.mnemonic = i.mnemonic[:-1] else: i.mnemonic = 'FUCOMIP' mnemo = i.mnemonic.lower() if i.mnemonic in ('CALL','JMP'): if len(i.operands) == 2 and i.operands[1] == '*': i.operands.pop() if not i.operands[0]._is_mem and \ not i.operands[0]._is_reg: i.operands[0] = expressions.mem(i.operands[0],att_syntax.cpu_addrsize) else: if i.operands[0]._is_mem: i.operands[0] = i.operands[0].a.base + i.operands[0].a.disp elif i.mnemonic.startswith(('J','SET','CMOV')): for pfx in ('J','SET','CMOV'): if i.mnemonic.startswith(pfx): break for i.cond in att_syntax.CONDITION_CODES.values(): if i.mnemonic[len(pfx):] in i.cond[0].split('/'): break else: if pfx == 'CMOV' and i.mnemonic[-1] in ('W','L','Q'): # clang on MacOS X for i.cond in att_syntax.CONDITION_CODES.values(): if i.mnemonic[len(pfx):-1] in i.cond[0].split('/'): break else: NEVER elif pfx == 'SET' and i.mnemonic[-1] == 'B': # gcc 3.2.3 for i.cond in att_syntax.CONDITION_CODES.values(): if i.mnemonic[len(pfx):-1] in i.cond[0].split('/'): break else: NEVER else: NEVER i.mnemonic = pfx+'cc' if pfx == 'J': i.operands[0] = i.operands[0].a.base + i.operands[0].a.disp if pfx == 'CMOV': if i.operands[0]._is_mem: i.operands[0].size = i.operands[1].size if i.operands[1]._is_mem: i.operands[1].size = i.operands[0].size elif mnemo in att_mnemo_correspondance: i.mnemonic = att_mnemo_correspondance[mnemo].upper() if i.mnemonic in ('CBW','CWD','IRET'): i.misc.update({'opdsz':16, 'pfx':[None, None, 'opdsz', None]}) elif mnemo[-1] == 'w' and mnemo[:-1] in mnemo_string_rep: i.misc.update({'opdsz':16, 'pfx':[None, None, 'opdsz', None]}) elif i.mnemonic == 'CMPSD' and len(i.operands) == 0: # String cmpsd, different from the SSE cmp*sd, has no arguments pass elif i.mnemonic == 'MOVSL': # String movsd, different from the SSE movsd # Has no arguments i.mnemonic = 'MOVSD' assert len(i.operands) == 0 elif i.mnemonic[:-2] in ('MOVS','MOVZ'): i.misc['opdsz'], sz = { 'BW': ( 8,16), 'BL': ( 8,32), 'BQ': ( 8,64), 'WL': (16,32), 'WQ': (16,64), 'LQ': (32,64), }[i.mnemonic[-2:]] if i.operands[1]._is_mem: i.operands[1].size = i.misc['opdsz'] assert i.operands[0].size == sz i.mnemonic = i.mnemonic[:-2] + 'X' elif i.mnemonic == 'MOVD': pass elif i.mnemonic in ( 'FLDCW', 'FSTCW', 'FNSTCW', ): assert i.operands[0]._is_mem i.operands[0].size = 16 elif i.mnemonic in att_syntax.mmx_with_suffix2 and len(i.operands): if i.mnemonic.endswith('SS'): if i.operands[1]._is_mem: i.operands[1].size = 32 elif i.mnemonic.endswith('SD'): if i.operands[0]._is_mem: i.operands[0].size = 64 if i.operands[1]._is_mem: i.operands[1].size = 64 else: if i.operands[1]._is_mem: i.operands[1].size = 128 elif i.mnemonic in ( 'CVTSI2SS', ): if i.operands[1]._is_mem: i.operands[1].size = 32 elif i.mnemonic in ( 'MOVLPD','MOVLPS','MOVHPD','MOVHPS', 'MOVDDUP', 'PSHUFW', 'CVTSD2SS','CVTSD2SI','CVTTSD2SI', 'CVTPI2PD','CVTPI2PS','CVTPS2PI','CVTPS2PD','CVTDQ2PD', ): if i.operands[0]._is_mem: i.operands[0].size = 64 if i.operands[1]._is_mem: i.operands[1].size = 64 elif i.mnemonic in ( 'PSHUFD','PSHUFLW','PSHUFHW', 'MOVDQA','MOVDQU','MOVSLDUP','MOVSHDUP', 'MOVAPD','MOVAPS','MOVUPD','MOVUPS', 'CVTPD2PS','CVTPD2PI','CVTPD2DQ','CVTTPD2DQ','CVTTPD2PI', 'CVTPS2DQ','CVTTPS2PI','CVTTPS2DQ','CVTDQ2PS', 'PUNPCKHQDQ', ): if i.operands[0]._is_mem: i.operands[0].size = 128 if i.operands[1]._is_mem: i.operands[1].size = 128 elif i.mnemonic in att_syntax.mmx_with_suffix1 or i.mnemonic in ( 'PSHUFB', 'PAND','PANDN','POR','PXOR', ): if i.operands[1]._is_mem: i.operands[1].size = i.operands[0].size elif i.mnemonic == 'MOVABSQ': # gcc generates 'movabsq $cst, %reg' instead of 'movq $cst, %reg' i.mnemonic = 'MOV' for _ in i.operands: if _._is_mem: _.size = 64 if _._is_cst: _.size = 64; _.v &= _.mask if _._is_lab: _.size = 64 else: for _ in att_mnemo_suffix_one_ptr: if mnemo[:-1] != _: continue # Detect MMX MOVQ instruction, not 64-bit register MOV for x64 if i.mnemonic == 'MOVQ' \ and i.operands[1]._is_reg \ and 'mm' in i.operands[1].ref: if i.operands[0]._is_mem: i.operands[0].size = 64 break if i.mnemonic == 'MOVQ' \ and i.operands[0]._is_reg \ and 'mm' in i.operands[0].ref: if i.operands[1]._is_mem: i.operands[1].size = 64 break i.mnemonic = _.upper() sz = {'b':8, 'w':16, 'l':32, 'q':64}[mnemo[-1]] for _ in i.operands: if _._is_mem: _.size = sz if _._is_cst: _.size = sz; _.v &= _.mask if _._is_lab: _.size = sz for _ in att_mnemo_suffix_one_iflt: if mnemo[:-1] != _: continue i.mnemonic = _.upper() sz = {'s':16, 'l':32, 'q':64}[mnemo[-1]] for _ in i.operands: if _._is_mem: _.size = sz if mnemo[-2:] == 'll' and mnemo[:-2] in att_mnemo_suffix_one_iflt: # clang on MacOS X i.mnemonic = mnemo[:-2].upper() for _ in i.operands: if _._is_mem: _.size = 64 for _ in att_mnemo_float_optional_suffix: if mnemo[:-1] != _: continue if mnemo[-1] in ('p','r','z','1'): continue i.mnemonic = _.upper() sz = {'s':32, 'l':64, 't':80}[mnemo[-1]] for _ in i.operands: if _._is_mem: _.size = sz # Implicit operands if i.mnemonic in ('AAD','AAM'): if len(i.operands) == 0: i.operands.append(expressions.cst(10,8)) else: i.operands[0].size = 8 elif i.mnemonic in ('SAL','SAR','SHL','SHR','ROR','ROL') \ and len(i.operands) == 1: i.operands.append(expressions.cst(1,32)) elif i.mnemonic.startswith('CMP') \ and i.mnemonic.endswith(('PS','PD','SD','SS')) \ and len(i.operands): idx = mnemo_sse_cmp_predicate.index(i.mnemonic[3:-2].lower()) i.operands.append(expressions.cst(idx)) i.mnemonic = i.mnemonic[:3] + i.mnemonic[-2:] return i
def action_instr(toks): i = instruction(b'') i.mnemonic = toks[0].upper() # Remove prefixes if i.mnemonic in ('REP', 'REPZ', 'REPNZ', 'REPE', 'REPNE', 'LOCK'): if i.mnemonic in ('REP', 'REPZ', 'REPE'): i.misc.update({'pfx': ['rep', None, None, None], 'rep': True}) if i.mnemonic in ('REPNZ', 'REPNE'): i.misc.update({ 'pfx': ['repne', None, None, None], 'repne': True }) if i.mnemonic in ('LOCK', ): i.misc.update({ 'pfx': ['lock', None, None, None], 'lock': True }) del toks[0] # toks.pop(0) is broken for pyparsing 2.0.2 # https://bugs.launchpad.net/ubuntu/+source/pyparsing/+bug/1381564 i.mnemonic = toks[0].upper() # Get operands if len(toks) > 1: i.operands = list(reversed(toks[1][0:])) # Convert mnemonics, set operand sizes if i.mnemonic in ('CALLL', 'CALLQ', 'JMPL', 'JMPQ', 'RETL', 'RETQ', 'BSWAPL', 'BSWAPQ', 'FUCOMPI'): # clang on MacOS X if i.mnemonic[-1] in ('L', 'Q'): i.mnemonic = i.mnemonic[:-1] else: i.mnemonic = 'FUCOMIP' mnemo = i.mnemonic.lower() if i.mnemonic in ('CALL', 'JMP'): if len(i.operands) == 2 and i.operands[1] == '*': i.operands.pop() if not i.operands[0]._is_mem and \ not i.operands[0]._is_reg: i.operands[0] = expressions.mem(i.operands[0], cpu_addrsize) else: if i.operands[0]._is_mem: i.operands[0] = i.operands[0].a.base + i.operands[0].a.disp elif i.mnemonic.startswith(('J', 'SET', 'CMOV')): for pfx in ('J', 'SET', 'CMOV'): if i.mnemonic.startswith(pfx): break for i.cond in CONDITION_CODES.values(): if i.mnemonic[len(pfx):] in i.cond[0].split('/'): break else: if pfx == 'CMOV' and i.mnemonic[-1] in ('W', 'L', 'Q'): # clang on MacOS X for i.cond in CONDITION_CODES.values(): if i.mnemonic[len(pfx):-1] in i.cond[0].split('/'): break else: NEVER elif pfx == 'SET' and i.mnemonic[-1] == 'B': # gcc 3.2.3 for i.cond in CONDITION_CODES.values(): if i.mnemonic[len(pfx):-1] in i.cond[0].split('/'): break else: NEVER else: NEVER i.mnemonic = pfx + 'cc' if pfx == 'J': i.operands[0] = i.operands[0].a.base + i.operands[0].a.disp if pfx == 'CMOV': if i.operands[0]._is_mem: i.operands[0].size = i.operands[1].size if i.operands[1]._is_mem: i.operands[1].size = i.operands[0].size elif mnemo in att_mnemo_correspondance: i.mnemonic = att_mnemo_correspondance[mnemo].upper() if i.mnemonic in ('CBW', 'CWD', 'IRET'): i.misc.update({ 'opdsz': 16, 'pfx': [None, None, 'opdsz', None] }) elif mnemo[-1] == 'w' and mnemo[:-1] in mnemo_string_rep: i.misc.update({'opdsz': 16, 'pfx': [None, None, 'opdsz', None]}) elif i.mnemonic == 'CMPSD' and len(i.operands) == 0: # String cmpsd, different from the SSE cmp*sd, has no arguments pass elif i.mnemonic == 'MOVSL': # String movsd, different from the SSE movsd # Has no arguments i.mnemonic = 'MOVSD' assert len(i.operands) == 0 elif i.mnemonic[:-2] in ('MOVS', 'MOVZ'): i.misc['opdsz'], sz = { 'BW': (8, 16), 'BL': (8, 32), 'BQ': (8, 64), 'WL': (16, 32), 'WQ': (16, 64), 'LQ': (32, 64), }[i.mnemonic[-2:]] if i.operands[1]._is_mem: i.operands[1].size = i.misc['opdsz'] assert i.operands[0].size == sz i.mnemonic = i.mnemonic[:-2] + 'X' elif i.mnemonic == 'MOVD': pass elif i.mnemonic in ( 'FLDCW', 'FSTCW', 'FNSTCW', ): assert i.operands[0]._is_mem i.operands[0].size = 16 elif i.mnemonic == 'CMPXCHG': if i.operands[0]._is_mem: i.operands[0].size = i.operands[1].size elif i.mnemonic == 'CMPXCHG8B': if i.operands[0]._is_mem: i.operands[0].size = 64 elif i.mnemonic == 'CMPXCHG16B': if i.operands[0]._is_mem: i.operands[0].size = 128 elif i.mnemonic in mmx_with_suffix2 and len(i.operands): if i.mnemonic.endswith('SS'): if i.operands[1]._is_mem: i.operands[1].size = 32 elif i.mnemonic.endswith('SD'): if i.operands[0]._is_mem: i.operands[0].size = 64 if i.operands[1]._is_mem: i.operands[1].size = 64 else: if i.operands[1]._is_mem: i.operands[1].size = 128 elif i.mnemonic in ( 'CVTSI2SS', 'CVTSI2SD', 'CVTTSS2SI', 'CVTTSS2SIL', 'CVTTSS2SIQ', ): if i.operands[1]._is_mem: i.operands[1].size = 32 # gcc 4.9.2 generates cvttss2siq %xmm0, %r15 # which is useless, because the size of the output is # determined by the output register if i.mnemonic[-1] in 'LQ': i.mnemonic = i.mnemonic[:-1] elif i.mnemonic in ( 'MOVLPD', 'MOVLPS', 'MOVHPD', 'MOVHPS', 'MOVDDUP', 'PSHUFW', 'CVTSD2SS', 'CVTSD2SI', 'CVTTSD2SI', 'CVTTSD2SIL', 'CVTTSD2SIQ', 'CVTPI2PD', 'CVTPI2PS', 'CVTPS2PI', 'CVTPS2PD', 'CVTDQ2PD', ): if i.operands[0]._is_mem: i.operands[0].size = 64 if i.operands[1]._is_mem: i.operands[1].size = 64 if i.mnemonic[-1] in 'LQ': i.mnemonic = i.mnemonic[:-1] elif i.mnemonic in ( 'PSHUFD', 'PSHUFLW', 'PSHUFHW', 'MOVDQA', 'MOVDQU', 'MOVSLDUP', 'MOVSHDUP', 'MOVAPD', 'MOVAPS', 'MOVUPD', 'MOVUPS', 'CVTPD2PS', 'CVTPD2PI', 'CVTPD2DQ', 'CVTTPD2DQ', 'CVTTPD2PI', 'CVTPS2DQ', 'CVTTPS2PI', 'CVTTPS2DQ', 'CVTDQ2PS', 'PUNPCKHQDQ', ): if i.operands[0]._is_mem: i.operands[0].size = 128 if i.operands[1]._is_mem: i.operands[1].size = 128 elif i.mnemonic in mmx_with_suffix1 or i.mnemonic in ( 'PSHUFB', 'PAND', 'PANDN', 'POR', 'PXOR', ): if i.operands[1]._is_mem: i.operands[1].size = i.operands[0].size elif i.mnemonic == 'MOVABSQ': # gcc generates 'movabsq $cst, %reg' instead of 'movq $cst, %reg' i.mnemonic = 'MOV' for _ in i.operands: if _._is_mem: _.size = 64 if _._is_cst: _.size = 64 _.v &= _.mask if _._is_lab: _.size = 64 else: for _ in att_mnemo_suffix_one_ptr: if mnemo[:-1] != _: continue # Detect MMX MOVQ instruction, not 64-bit register MOV for x64 if i.mnemonic == 'MOVQ' \ and i.operands[1]._is_reg \ and 'mm' in i.operands[1].ref: if i.operands[0]._is_mem: i.operands[0].size = 64 break if i.mnemonic == 'MOVQ' \ and i.operands[0]._is_reg \ and 'mm' in i.operands[0].ref: if i.operands[1]._is_mem: i.operands[1].size = 64 break i.mnemonic = _.upper() sz = {'b': 8, 'w': 16, 'l': 32, 'q': 64}[mnemo[-1]] if 'q' == mnemo[-1]: i.misc.update({'REX': (1, 0, 0, 0)}) if 'w' == mnemo[-1]: i.misc.update({ 'opdsz': 16, 'pfx': [None, None, 'opdsz', None] }) def set_size(e, sz): if e._is_mem: e.size = sz if e._is_cst: e.size = sz e.v &= e.mask if e._is_lab: e.size = sz if e._is_eqn: e.size = sz if e.l is not None: set_size(e.l, sz) set_size(e.r, sz) for _ in i.operands: set_size(_, sz) for _ in att_mnemo_suffix_one_iflt: if mnemo[:-1] != _: continue i.mnemonic = _.upper() sz = {'s': 16, 'l': 32, 'q': 64}[mnemo[-1]] for _ in i.operands: if _._is_mem: _.size = sz if mnemo[-2:] == 'll' and mnemo[:-2] in att_mnemo_suffix_one_iflt: # clang on MacOS X i.mnemonic = mnemo[:-2].upper() for _ in i.operands: if _._is_mem: _.size = 64 for _ in att_mnemo_float_optional_suffix: if mnemo[:-1] != _: continue if mnemo[-1] in ('i', 'p', 'r', 'z', '1'): continue i.mnemonic = _.upper() sz = {'s': 32, 'l': 64, 't': 80}[mnemo[-1]] for _ in i.operands: if _._is_mem: _.size = sz # Implicit operands if i.mnemonic in ('AAD', 'AAM'): if len(i.operands) == 0: i.operands.append(expressions.cst(10, 8)) else: i.operands[0].size = 8 elif i.mnemonic in ('SAL','SAR','SHL','SHR','ROR','ROL') \ and len(i.operands) == 1: i.operands.append(expressions.cst(1, 32)) elif i.mnemonic in ('SHLD','SHRD') \ and len(i.operands) == 2: i.operands.append(env.__dict__['cl']) elif i.mnemonic.startswith('CMP') \ and i.mnemonic.endswith(('PS','PD','SD','SS')) \ and len(i.operands): idx = mnemo_sse_cmp_predicate.index(i.mnemonic[3:-2].lower()) i.operands.append(expressions.cst(idx)) i.mnemonic = i.mnemonic[:3] + i.mnemonic[-2:] elif i.mnemonic in ('FADD','FSUB','FSUBR', 'FMUL','FDIV','FDIVR', 'FCOMI','FCOMIP','FUCOMI','FUCOMIP', ) \ and len(i.operands) == 1 \ and not i.operands[0]._is_mem: i.operands.insert(0, env.st(0)) elif i.mnemonic in ('FADDP','FSUBP','FSUBRP', 'FMULP','FDIVP','FDIVRP', ) \ and len(i.operands) == 1 \ and not i.operands[0]._is_mem: i.operands.append(env.st(0)) elif i.mnemonic in ('FCOM','FCOMP','FUCOM','FUCOMP', ) \ and len(i.operands) == 0: i.operands.append(env.st(1)) return i