node/lib/metasm/metasm/cpu/ia32/parse.rb
# check if the argument matches the opcode's argument spec
check if the argument matches the opcode's argument spec
check if the argument matches the opcode ' s argument spec
def parse_arg_valid?(o, spec, arg)
		if o.name ==  'movsx' or o.name == 'movzx'
			if not arg.kind_of?(Reg) and not arg.kind_of?(ModRM)
				return
			elsif not arg.sz
				puts "ambiguous arg size for indirection in #{o.name}" if $VERBOSE
				return
			elsif spec == :reg	
				return (arg.kind_of?(Reg) and arg.sz >= 16)
			elsif o.props[:argsz]
				return arg.sz == o.props[:argsz]
			else
				return arg.sz == 16
			end
		elsif o.name == 'crc32'
			if not arg.kind_of?(Reg) and not arg.kind_of?(ModRM)
				return
			elsif not arg.sz
				puts "ambiguous arg size for indirection in #{o.name}" if $VERBOSE
				return
			elsif spec == :reg
				return (arg.kind_of?(Reg) and arg.sz >= 32)
			elsif o.props[:argsz]
				return arg.sz == o.props[:argsz]
			else
				return arg.sz >= 16
			end
		end
		return false if arg.kind_of? ModRM and arg.adsz and o.props[:adsz] and arg.adsz != o.props[:adsz]
		cond = true
		if s = o.props[:argsz] and (arg.kind_of? Reg or arg.kind_of? ModRM)
			cond = (!arg.sz or arg.sz == s or spec == :reg_dx)
		end
		cond and
		case spec
		when :reg; arg.kind_of? Reg and (arg.sz >= 16 or o.props[:argsz])
		when :modrm; (arg.kind_of? ModRM or arg.kind_of? Reg) and (!arg.sz or arg.sz >= 16 or o.props[:argsz]) and (!o.props[:modrmA] or arg.kind_of? ModRM) and (!o.props[:modrmR] or arg.kind_of? Reg)
		when :i;        arg.kind_of? Expression
		when :imm_val1; arg.kind_of? Expression and arg.reduce == 1
		when :imm_val3; arg.kind_of? Expression and arg.reduce == 3
		when :reg_eax;  arg.kind_of? Reg     and arg.val == 0
		when :reg_cl;   arg.kind_of? Reg     and arg.val == 1 and arg.sz == 8
		when :reg_dx;   arg.kind_of? Reg     and arg.val == 2 and arg.sz == 16
		when :seg3;     arg.kind_of? SegReg
		when :seg3A;    arg.kind_of? SegReg  and arg.val > 3
		when :seg2;     arg.kind_of? SegReg  and arg.val < 4
		when :seg2A;    arg.kind_of? SegReg  and arg.val < 4 and arg.val != 1
		when :eeec;     arg.kind_of? CtrlReg
		when :eeed;     arg.kind_of? DbgReg
		when :eeet;     arg.kind_of? TstReg
		when :mrm_imm;  arg.kind_of? ModRM   and not arg.s and not arg.i and not arg.b
		when :farptr;   arg.kind_of? Farptr
		when :regfp;    arg.kind_of? FpReg
		when :regfp0;   arg.kind_of? FpReg   and (arg.val == nil or arg.val == 0)
		when :modrmmmx; arg.kind_of? ModRM   or (arg.kind_of? SimdReg and (arg.sz == 64 or (arg.sz == 128 and o.props[:xmmx]))) and (!o.props[:modrmA] or arg.kind_of? ModRM) and (!o.props[:modrmR] or arg.kind_of? SimdReg)
		when :regmmx;   arg.kind_of? SimdReg and (arg.sz == 64 or (arg.sz == 128 and o.props[:xmmx]))
		when :modrmxmm; arg.kind_of? ModRM   or (arg.kind_of? SimdReg and arg.sz == 128) and (!o.props[:modrmA] or arg.kind_of? ModRM) and (!o.props[:modrmR] or arg.kind_of? SimdReg)
		when :regxmm;   arg.kind_of? SimdReg and arg.sz == 128
		when :modrmymm; arg.kind_of? ModRM   or (arg.kind_of? SimdReg and arg.sz == 256) and (!o.props[:modrmA] or arg.kind_of? ModRM) and (!o.props[:modrmR] or arg.kind_of? SimdReg)
		when :regymm;   arg.kind_of? SimdReg and arg.sz == 256
		when :vexvreg;  arg.kind_of? Reg and arg.sz == @size
		when :vexvxmm, :i4xmm;  arg.kind_of? SimdReg and arg.sz == 128
		when :vexvymm, :i4ymm;  arg.kind_of? SimdReg and arg.sz == 256
		when :i8, :u8, :u16
			arg.kind_of? Expression and
			(o.props[:setip] or Expression.in_range?(arg, spec) != false)	
		else raise EncodeError, "Internal error: unknown argument specification #{spec.inspect}"
		end
	end
def parse_arg_valid? ( o , spec , arg ) if o . name == 'movsx' or o . name == 'movzx' if not arg . kind_of? ( Reg ) and not arg . kind_of? ( ModRM ) return elsif not arg . sz puts "ambiguous arg size for indirection in #{o.name}" if $VERBOSE return elsif spec == :reg return ( arg . kind_of? ( Reg ) and arg . sz >= 16 ) elsif o . props [ :argsz ] return arg . sz == o . props [ :argsz ] else return arg . sz == 16 end elsif o . name == 'crc32' if not arg . kind_of? ( Reg ) and not arg . kind_of? ( ModRM ) return elsif not arg . sz puts "ambiguous arg size for indirection in #{o.name}" if $VERBOSE return elsif spec == :reg return ( arg . kind_of? ( Reg ) and arg . sz >= 32 ) elsif o . props [ :argsz ] return arg . sz == o . props [ :argsz ] else return arg . sz >= 16 end end return false if arg . kind_of? ModRM and arg . adsz and o . props [ :adsz ] and arg . adsz != o . props [ :adsz ] cond = true if s = o . props [ :argsz ] and ( arg . kind_of? Reg or arg . kind_of? ModRM ) cond = ( ! arg . sz or arg . sz == s or spec == :reg_dx ) end cond and case spec when :reg ; arg . kind_of? Reg and ( arg . sz >= 16 or o . props [ :argsz ] ) when :modrm ; ( arg . kind_of? ModRM or arg . kind_of? Reg ) and ( ! arg . sz or arg . sz >= 16 or o . props [ :argsz ] ) and ( ! o . props [ :modrmA ] or arg . kind_of? ModRM ) and ( ! o . props [ :modrmR ] or arg . kind_of? Reg ) when :i ; arg . kind_of? Expression when :imm_val1 ; arg . kind_of? Expression and arg . reduce == 1 when :imm_val3 ; arg . kind_of? Expression and arg . reduce == 3 when :reg_eax ; arg . kind_of? Reg and arg . val == 0 when :reg_cl ; arg . kind_of? Reg and arg . val == 1 and arg . sz == 8 when :reg_dx ; arg . kind_of? Reg and arg . val == 2 and arg . sz == 16 when :seg3 ; arg . kind_of? SegReg when :seg3A ; arg . kind_of? SegReg and arg . val > 3 when :seg2 ; arg . kind_of? SegReg and arg . val < 4 when :seg2A ; arg . kind_of? SegReg and arg . val < 4 and arg . val != 1 when :eeec ; arg . kind_of? CtrlReg when :eeed ; arg . kind_of? DbgReg when :eeet ; arg . kind_of? TstReg when :mrm_imm ; arg . kind_of? ModRM and not arg . s and not arg . i and not arg . b when :farptr ; arg . kind_of? Farptr when :regfp ; arg . kind_of? FpReg when :regfp0 ; arg . kind_of? FpReg and ( arg . val == nil or arg . val == 0 ) when :modrmmmx ; arg . kind_of? ModRM or ( arg . kind_of? SimdReg and ( arg . sz == 64 or ( arg . sz == 128 and o . props [ :xmmx ] ) ) ) and ( ! o . props [ :modrmA ] or arg . kind_of? ModRM ) and ( ! o . props [ :modrmR ] or arg . kind_of? SimdReg ) when :regmmx ; arg . kind_of? SimdReg and ( arg . sz == 64 or ( arg . sz == 128 and o . props [ :xmmx ] ) ) when :modrmxmm ; arg . kind_of? ModRM or ( arg . kind_of? SimdReg and arg . sz == 128 ) and ( ! o . props [ :modrmA ] or arg . kind_of? ModRM ) and ( ! o . props [ :modrmR ] or arg . kind_of? SimdReg ) when :regxmm ; arg . kind_of? SimdReg and arg . sz == 128 when :modrmymm ; arg . kind_of? ModRM or ( arg . kind_of? SimdReg and arg . sz == 256 ) and ( ! o . props [ :modrmA ] or arg . kind_of? ModRM ) and ( ! o . props [ :modrmR ] or arg . kind_of? SimdReg ) when :regymm ; arg . kind_of? SimdReg and arg . sz == 256 when :vexvreg ; arg . kind_of? Reg and arg . sz == @size when :vexvxmm , :i4xmm ; arg . kind_of? SimdReg and arg . sz == 128 when :vexvymm , :i4ymm ; arg . kind_of? SimdReg and arg . sz == 256 when :i8 , :u8 , :u16 arg . kind_of? Expression and ( o . props [ :setip ] or Expression . in_range? ( arg , spec ) != false ) else raise EncodeError , "Internal error: unknown argument specification #{spec.inspect}" end end
check if the argument matches the opcode's argument spec
check if the argument matches the opcode ' s argument spec
# reg=dst, modrm=src (smaller) # true or nil allowed # jz 0x28282828 may fit in :i8 depending on instr addr
o
spec
arg