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('') i.mnemonic = toks[0] if len(toks) > 1: i.operands = toks[1][0:] return asmhelper(i)
def action_instr(toks): i = instruction('') i.mnemonic = toks[0] if len(toks)>1: i.operands = toks[1][0:] return asmhelper(i)