Ejemplo n.º 1
0
parse.Transfs('''

applicable =
	ir.path.Applicable(
		ir.path.projectSelection => Function(_, _, _, _)
	)

input =
	ir.path.Input2(
		ir.path.projectSelection => Function(_, name, _, _) ;
		ui.Str(!"Add Function Argument", !"Argument Symbol?") => arg ;
		![name, arg]
	)

apply =
	[root, [name, arg]] -> root ;
	type := !Int(32,Signed) ;
	~Module(<
		One(
			~Function(_, ?name, <Concat(id,![Arg(type,arg)])>, _)
		)
	>) ;
	BottomUp(Try(
		~Call(Sym(?name), <Concat(id,![Sym(arg)])>)
	))

testApply =
	![
		Module([
			Function(Void,"main",[],[
				Assign(Int(32,Signed),Sym("eax"),Lit(Int(32,Signed),1)),
				Ret(Void,NoExpr)
			]),
		]),
		["main", "eax"]
	] ;
	apply ;
	?Module([
		Function(Void,"main",[Arg(Int(32,Signed),"eax")],[
			Assign(Int(32,Signed),Sym("eax"),Lit(Int(32,Signed),1)),
			Ret(Void,NoExpr)
		]),
	])

''')
Ejemplo n.º 2
0
parse.Transfs('''

#######################################################################
# Types

ppSign =
	Signed -> H([ <kw "signed">, " " ])
|	Unsigned -> H([ <kw "unsigned"> , " " ])
|	NoSign -> ""

ppSize =
	switch id
	case 8:
		!<kw "char">
	case 16:
		!H([ <kw "short">, " ", <kw "int"> ])
	case 32:
		!<kw "int">
	case 64:
		!H([ <kw "long">, " ", <kw "int"> ])
	else
		!H([ "int", <strings.tostr> ])
	end

ppType =
	Void
		-> <kw "void">
|	Bool
		-> <kw "bool">
|	Int(size, sign)
		-> H([ <ppSign sign>, <ppSize size> ])
|	Float(32)
		-> <kw "float">
|	Float(64)
		-> <kw "double">
|	Char(8)
		-> <kw "char">
|	Char(16)
		-> <kw "wchar_t">
|	Pointer(type)
		-> H([ <ppType type>, " ", <ppOp "*"> ])
|	Array(type)
		-> H([ <ppType type>, "[", "]" ])
|	Blob(size)
		-> H([ "blob", <strings.tostr size> ])
|	_ -> "???"


#######################################################################
# Operator precendence.
#
# See http://www.difranco.net/cop2220/op-prec.htm

precUnaryOp =
	Not -> 1
|	Neg -> 1

precBinaryOp =
	And(Bool) -> 10
|	Or(Bool) -> 11
|	And(_) -> 7
|	Or(_) -> 9
|	Xor(_) -> 8
|	LShift -> 4
|	RShift -> 4
|	Plus -> 4 # force parenthesis inside shifts (was 3)
|	Minus -> 4 # force parenthesis inside shifts (was 3)
|	Mult -> 2
|	Div -> 2
|	Mod -> 2
|	Eq -> 6
|	NotEq -> 6
|	Lt -> 5
|	LtEq -> 5
|	Gt -> 5
|	GtEq -> 5

precExpr =
	Lit(_, _) -> 0
|	Sym(_) -> 0
|	Cast(_, _) -> 1
|	Addr(_) -> 1
|	Ref(_) -> 1
|	Unary(op, _) -> <precUnaryOp op>
|	Binary(op, _, _) -> <precBinaryOp op>
|	Cond(_, _, _) -> 13
|	Call(_, _) -> 0


#######################################################################
# Expressions

ppUnaryOp =
	Not(Bool) -> "!"
|	Not(_) -> "~"
|	Neg -> "-"

ppBinaryOp =
	And(Bool) -> "&&"
|	Or(Bool) -> "||"
|	And(_) -> "&"
|	Or(_) -> "|"
|	Xor(_) -> "^"
|	LShift -> "<<"
|	RShift -> ">>"
|	Plus -> "+"
|	Minus -> "-"
|	Mult -> "*"
|	Div -> "/"
|	Mod -> "%"
|	Eq -> "=="
|	NotEq -> "!="
|	Lt -> "<"
|	LtEq -> "<="
|	Gt -> ">"
|	GtEq -> ">="


SubExpr(Cmp) =
	?[pprec, rest] ;
	prec := precExpr rest ;
	if Cmp(!prec, !pprec) then
		!H([ "(", <exprKern [prec,rest]>, ")" ])
	else
		exprKern [prec,rest]
	end


subExpr = SubExpr(arith.Gt)
subExprEq = SubExpr(arith.Geq)

exprKern =
	( [prec,rest] -> rest ) ;
	Path((
	Lit(Int(_,_), value)
		-> <intlit value>
|	Lit(Pointer(Char(8)), value)
		-> <strlit value>
|	Lit(type, value)
		-> <lit value>
|	Sym(name)
		-> <sym name>
|	Cast(type, expr)
		-> H([ "(", <ppType type>, ")", " ", <subExpr [prec,expr]> ])
|	Unary(op, expr)
		-> H([ <ppUnaryOp op>, <subExpr [prec,expr]> ])
|	Binary(op, lexpr, rexpr)
		-> H([ <subExpr [prec,lexpr]>, " ", <ppBinaryOp op>, " ", <subExprEq [prec,rexpr]> ])
|	Cond(cond, texpr, fexpr)
		-> H([ <subExpr [prec,cond]>, " ", <ppOp "?">, " ", <subExpr [prec,texpr]>, " ", <ppOp ":">, " ", <subExpr [prec,fexpr]> ])
|	Call(addr, args)
		-> H([ <subExpr [prec,addr]>, "(", <(Map(subExpr [prec,<id>]); commas) args>, ")" ])
|	Addr(addr)
		-> H([ <ppOp "&">, <subExpr [prec,addr]> ])
|	Ref(expr)
		-> H([ <ppOp "*">, <subExpr [prec,expr]> ])
))

ppExpr =
	exprKern [<precExpr>,<id>]


#######################################################################
# Statements

ppArg =
	Arg(type, name)
		-> H([ <ppType type>, " ", name ])

ppStmts =
	!V( <Map(ppStmt)> )


stmtKern =
	Assign(Void, NoExpr, src)
		-> H([ <ppExpr src> ])
|	Assign(_, dst, src)
		-> H([ <ppExpr dst>, " ", <ppOp "=">, " ", <ppExpr src> ])
|	If(cond, _, _)
		-> H([ <kw "if">, "(", <ppExpr cond>, ")" ])
|	While(cond, _)
		-> H([ <kw "while">, "(", <ppExpr cond>, ")" ])
|	DoWhile(cond, _)
		-> H([ <kw "while">, "(", <ppExpr cond>, ")" ])
|	Var(type, name, NoExpr)
		-> H([ <ppType type>, " ", name ])
|	Var(type, name, val)
		-> H([ <ppType type>, " ", name, " = ", <ppExpr val> ])
|	Function(type, name, args, stmts)
		-> H([ <ppType type>, " ", name, "(", <(Map(ppArg);commas) args>, ")" ])
|	Label(name)
		-> H([ name, ":" ])
|	GoTo(label)
		-> H([ <kw "goto">, " ", <ppExpr label> ])
|	Ret(_, NoExpr)
		-> H([ <kw "return"> ])
|	Ret(_, value)
		-> H([ <kw "return">, " ", <ppExpr value> ])
|	NoStmt
		-> ""
|	Asm(opcode, operands)
		-> H([ <kw "asm">, "(", <commas [<lit opcode>, *<Map(ppExpr) operands>]>, ")" ])

ppLabel =
	Label
		-> D( <stmtKern> )

ppBlock =
	Block( stmts )
		-> V([
			D("{"),
				<ppStmts stmts>,
			D("}")
		])

ppIf =
	If(_, true, NoStmt)
		-> V([
			<stmtKern>,
				I( <ppStmt true> )
		])
|	If(_, true, false)
		-> V([
			<stmtKern>,
				I( <ppStmt true> ),
			H([ <kw "else"> ]),
				I( <ppStmt false> )
		])

ppWhile =
	While(_, body)
		-> V([
			<stmtKern>,
				I( <ppStmt body> )
		])

ppDoWhile =
	DoWhile(_, body)
		-> V([
			H([ <kw "do"> ]),
				I( <ppStmt body> ),
			!H([ <stmtKern>, ";" ])
		])

ppFunction =
	Function(_, _, _, stmts)
		-> D(V([
			<stmtKern>,
			"{",
				I(V([ <ppStmts stmts> ])),
			"}"
		]))

ppDefault =
	!H([ <stmtKern>, ";" ])

ppStmt = Path(
	switch project.name
		case "Label": ppLabel
		case "Block": ppBlock
		case "If": ppIf
		case "While": ppWhile
		case "DoWhile": ppDoWhile
		case "Function": ppFunction
		else ppDefault
	end
)

module = Path((
	Module(stmts)
		-> V([
			I( <ppStmts stmts> )
		])
))

''')
Ejemplo n.º 3
0
parse.Transfs('''

asmJMPL =
	[Ref(addr)] -> [GoTo(addr)]

asmJMP = asmJMPL


AsmJcc(cond) =
	[Ref(addr)] -> [If(<cond>,GoTo(addr),NoStmt)]

asmJA    = AsmJcc(ccA   )
asmJAE   = AsmJcc(ccAE  )
asmJB    = AsmJcc(ccB   )
asmJBE   = AsmJcc(ccBE  )
asmJC    = AsmJcc(ccC   )
asmJCXZ  = AsmJcc(ccCXZ )
asmJECXZ = AsmJcc(ccECXZ)
asmJE    = AsmJcc(ccE   )
asmJG    = AsmJcc(ccG   )
asmJGE   = AsmJcc(ccGE  )
asmJL    = AsmJcc(ccL   )
asmJLE   = AsmJcc(ccLE  )
asmJNA   = AsmJcc(ccNA  )
asmJNAE  = AsmJcc(ccNAE )
asmJNB   = AsmJcc(ccNB  )
asmJNBE  = AsmJcc(ccNBE )
asmJNC   = AsmJcc(ccNC  )
asmJNE   = AsmJcc(ccNE  )
asmJNG   = AsmJcc(ccNG  )
asmJNGE  = AsmJcc(ccNGE )
asmJNL   = AsmJcc(ccNL  )
asmJNLE  = AsmJcc(ccNLE )
asmJNO   = AsmJcc(ccNO  )
asmJNP   = AsmJcc(ccNP  )
asmJNS   = AsmJcc(ccNS  )
asmJNZ   = AsmJcc(ccNZ  )
asmJO    = AsmJcc(ccO   )
asmJP    = AsmJcc(ccP   )
asmJPE   = AsmJcc(ccPE  )
asmJPO   = AsmJcc(ccPO  )
asmJS    = AsmJcc(ccS   )
asmJZ    = AsmJcc(ccZ   )


AsmLOOP(size, counter) =
	[Ref(addr)] -> [
		Assign(type, <counter>, Binary(Minus(type),<counter>, Lit(type,1))),
		If(Binary(Eq(type),<counter>,Lit(type,0)), GoTo(addr), NoStmt)
	] where type := UWord(size)

asmLOOPW = AsmLOOP(!16, cx)
asmLOOPL = AsmLOOP(!16, ecx)


AsmLOOPcc(size, counter, cc) =
	[Ref(addr)] -> [
		Assign(type, <counter>, Binary(Minus(type),<counter>, Lit(type,1))),
		If(Binary(And(Bool), Binary(Eq(type),<counter>,Lit(type,0)), <cc>),
			GoTo(addr),
			NoStmt
		)
	] where type := UWord(size)

asmLOOPEW  = AsmLOOPcc(!16, cx, ccE )
asmLOOPZW  = AsmLOOPcc(!16, cx, ccZ )
asmLOOPNEW = AsmLOOPcc(!16, cx, ccNE)
asmLOOPNZW = AsmLOOPcc(!16, cx, ccNZ)

asmLOOPEL  = AsmLOOPcc(!32, ecx, ccE )
asmLOOPZL  = AsmLOOPcc(!32, ecx, ccZ )
asmLOOPNEL = AsmLOOPcc(!32, ecx, ccNE)
asmLOOPNZL = AsmLOOPcc(!32, ecx, ccNZ)


asmCALLL =
	[Ref(addr)] -> [Assign(Void, NoExpr, Call(addr,[]))]

asmCALL = asmCALLL


asmRETL =
	[] -> [Ret(Void, NoExpr)] |
	[size] -> [Ret(Void, NoExpr)]

asmRET = asmRETL


# FIXME: INT
# FIXME: IRET
# FIXME: INT
# FIXME: INTO

# FIXME: BOUND


# FIXME: deal with level
asmENTERL =
	[size, level] -> [
		*<AsmPUSH(!32) [<ebp>]>,
		Assign(type, <ebp>, <esp>),
		Assign(type, <esp>, Binary(Minus(type), <esp>, size))
	] where type := UWord(!32)

asmENTER = asmENTERL


asmLEAVEL =
	[] -> [
		Assign(type, <esp>, <ebp>),
		*<AsmPOP(!32) [<ebp>]>
	] where type := UWord(!32)

asmLEAVE = asmLEAVEL

''')
Ejemplo n.º 4
0
parse.Transfs('''

applicable =
	ir.path.Applicable(
		ir.path.projectSelection => Function(Void, _, _, _)
	)

input =
	ir.path.Input2(
		ir.path.projectSelection => Function(_, name, _, _) ;
		ui.Str(!"Set Function Return", !"Return Symbol?") => ret ;
		![name, ret]
	)

apply =
		( [root, [name, ret]] -> root ) ;
		~Module(<
			One(
				~Function(!type, ?name, _, <
					AllTD(~Ret(!type, !Sym(ret)))
				>)
			)
		>) ;
		ir.traverse.AllStmtsBU(Try(
			?Assign(Void, NoExpr, Call(Sym(?name), _)) ;
			~Assign(!type, !Sym(ret), _)
		))
	where
		type := !Int(32,Signed)


testApply =
	!Module([
		Function(Void,"main",[],[
			Assign(Int(32,Signed),Sym("eax"),Lit(Int(32,Signed),1)),
			Ret(Void,NoExpr)
		]),
	]) ;
	apply [<id>, ["main","eax"] ] ;
	?Module([
		Function(Int(32,Signed),"main",[],[
			Assign(Int(32,Signed),Sym("eax"),Lit(Int(32,Signed),1)),
			Ret(Int(32,Signed),Sym("eax"))
		]),
	])

''')
Ejemplo n.º 5
0
parse.Transfs('''
applName =
	?Rule(Appl(Str(_), Ident), _)  +
	?Anon(Rule(Appl(Str(_), Ident), _))


applNames =
	?Choice(<Map(applName)>)

simplifyRule =
	Rule(Appl(Str(name), Undef), build) ->
		SwitchCase([Str(name)], Build(build))
|	Anon(Rule(Appl(Str(name), Undef), build)) ->
		SwitchCase([Str(name)], Build(build))


simplifyChoice =
	Choice(rules) ->
		Switch(
			Transf("project.name"),
			<Filter(simplifyRule) rules>,
			Choice(<Filter(Not(simplifyRule)) rules>)
		)
		#if Some(simplifyRule) rules


simplify = BottomUp(Try(simplifyChoice))

''',
              simplify=False)
Ejemplo n.º 6
0
parse.Transfs('''

Goto(label) =
	ir.path.inSelection ;
	?GoTo(Sym(label))

doReturn =
	with label, rest in
		Where(
			ir.path.projectSelection ;
			?GoTo(Sym(label))
		) ;
		OnceTD(
			AtSuffix(
				Where(
					~[Label(label), *<AtSuffix(~[?Ret, *<![]>])>] ;
					Filter(Not(?Label)) ;
					Map(?Assign + ?Ret) ;
					? rest
				)
			)
		) ;
		OnceTD(Goto(label); !Block(rest))
	end


gotoSelected =
	Where(
		ir.path.projectSelection => GoTo(Sym(_))
	)

functionSelected =
	Where(
		ir.path.projectSelection => Function
	)

common = doReturn

applicable =
	ir.path.Applicable(
		gotoSelected ;
		common
	)

input =
	ir.path.Input(
		![]
	)

apply =
	ir.path.Apply(
		[root,[]] -> root ;
		common ;
		dle
	)
''')
Ejemplo n.º 7
0
parse.Transfs(r'''

simplify =
	Binary(Eq(t),Binary(Minus(t),x,y),Lit(t,0))
		-> Binary(Eq(t),x,y) |
	Unary(Not(Bool),Binary(Eq(t),x,y))
		-> Binary(NotEq(t),x,y) |
	Binary(And(_),x,x)
		-> x

applicable =
	ir.path.Applicable(
		ir.path.projectSelection ;
		ir.match.expr ;
		OnceTD(simplify)
	)

input =
	ir.path.Input(
		![]
	)

apply =
	ir.path.Apply(
		[root,[]] -> root ;
		OnceTD(
			ir.path.isSelected ;
			InnerMost(simplify)
		)
	)


testAnd =
	simplify Binary(And(Int(32,Signed)),Sym("x"),Sym("x")) => Sym("x")

''')
Ejemplo n.º 8
0
parse.Transfs('''

BitMask(size, offset) =
	!Binary(LShift(type), Lit(type,1),
		Binary(Mod(type), <offset>, Lit(type,<size>)))
	where
		type := Word(size)

Bit(size, base, offset) =
	!Binary(And(type), <base>, <BitMask(size, offset)>)
	where
		type := Word(size)


AsmBT(size) =
	[dst, src] -> [Assign(Bool,<cf>,<Bit(size,!dst,!src)>)]

asmBTW = AsmBT(!16)
asmBTL = AsmBT(!32)


AsmBTS(size) =
	[dst, src] -> [
		Assign(Bool,<cf>,<Bit(size,!dst,!src)>),
		Assign(type,dst,Binary(Or(type),dst,<BitMask(size,!src)>))
	] where
		type := Word(size)

asmBTSW = AsmBTS(!16)
asmBTSL = AsmBTS(!32)


AsmBTR(size) =
	[dst, src] -> [
		Assign(Bool,<cf>,<Bit(size,!dst,!src)>),
		Assign(type,dst,
			Binary(And(type),dst,
				Unary(Not(type),<BitMask(size,!src)>)))
	] where
		type := Word(size)

asmBTRW = AsmBTR(!16)
asmBTRL = AsmBTR(!32)


AsmBTC(size) =
	[dst, src] -> [
		Assign(Bool,<cf>,<Bit(size,!dst,!src)>),
		Assign(type,dst,Binary(Xor(type),dst,<BitMask(size,!src)>))
	] where
		type := Word(size)

asmBTCW = AsmBTC(!16)
asmBTCL = AsmBTC(!32)


AsmBS(size, builtin) =
	[dst, src] -> [
		Assign(Bool, <zf>, Binary(Eq(type), src, Lit(type,0))),
		Assign(type, dst, Call(Sym(<builtin>){Builtin},[src])),
	] where
		type := Word(size)

AsmBSF(size) = AsmBS(size, !"_bit_scan_reverse")
AsmBSR(size) = AsmBS(size, !"_bit_scan_forward")

asmBSFW = AsmBSF(!16)
asmBSFL = AsmBSF(!32)

asmBSRW = AsmBSR(!16)
asmBSRL = AsmBSR(!32)


AsmSETcc(cc) =
	[dst] -> [
		Assign(type, dst, Cond(<cc>, Lit(type,1), Lit(type,0)))
	] where
		type := Word(!8)

asmSETA   = AsmSETcc(ccA  )
asmSETAE  = AsmSETcc(ccAE )
asmSETB   = AsmSETcc(ccB  )
asmSETBE  = AsmSETcc(ccBE )
asmSETC   = AsmSETcc(ccC  )
asmSETE   = AsmSETcc(ccE  )
asmSETG   = AsmSETcc(ccG  )
asmSETGE  = AsmSETcc(ccGE )
asmSETL   = AsmSETcc(ccL  )
asmSETLE  = AsmSETcc(ccLE )
asmSETNA  = AsmSETcc(ccNA )
asmSETNAE = AsmSETcc(ccNAE)
asmSETNB  = AsmSETcc(ccNB )
asmSETNBE = AsmSETcc(ccNBE)
asmSETNC  = AsmSETcc(ccNC )
asmSETNE  = AsmSETcc(ccNE )
asmSETNG  = AsmSETcc(ccNG )
asmSETNGE = AsmSETcc(ccNGE)
asmSETNL  = AsmSETcc(ccNL )
asmSETNLE = AsmSETcc(ccNLE)
asmSETNO  = AsmSETcc(ccNO )
asmSETNP  = AsmSETcc(ccNP )
asmSETNS  = AsmSETcc(ccNS )
asmSETNZ  = AsmSETcc(ccNZ )
asmSETO   = AsmSETcc(ccO  )
asmSETP   = AsmSETcc(ccP  )
asmSETPE  = AsmSETcc(ccPE )
asmSETPO  = AsmSETcc(ccPO )
asmSETS   = AsmSETcc(ccS  )
asmSETZ   = AsmSETcc(ccZ  )


AsmTEST(size) =
	[dst, src] -> [
		Assign(type, tmp, Binary(And(type), dst, src)),
		*<LogFlags(size, !tmp)>
	]
	where
		type := Word(size) ;
		tmp := temp

asmTESTB = AsmTEST(!8)
asmTESTW = AsmTEST(!16)
asmTESTL = AsmTEST(!32)


''')
Ejemplo n.º 9
0
parse.Transfs('''

LogFlags(size,res) =
	![
		<ZeroFlag(size, res)>,
		<SignFlag(size, res)>,
		Assign(Bool, <cf>, <false>),
		Assign(Bool, <of>, <false>)
	]

AsmLog(size, op) =
	[dst,src] -> [
		Assign(<Word(size)>, dst, Binary(<op>,dst,src)),
		*<LogFlags(size, !dst)>
	]

AsmAnd(size) = AsmLog(size, !And(<Word(size)>))
AsmOr(size) = AsmLog(size, !Or(<Word(size)>))
AsmXor(size) = AsmLog(size, !Xor(<Word(size)>))

asmANDB = AsmAnd(!8)
asmANDW = AsmAnd(!16)
asmANDL = AsmAnd(!32)

asmORB = AsmOr(!8)
asmORW = AsmOr(!16)
asmORL = AsmOr(!32)

asmXORB = AsmXor(!8)
asmXORW = AsmXor(!16)
asmXORL = AsmXor(!32)


AsmNOT(size) =
	[dst] -> [Assign(type,dst,Unary(Not(type),dst))]
	where
		type := Word(size)

asmNOTB = AsmNOT(!8)
asmNOTW = AsmNOT(!16)
asmNOTL = AsmNOT(!32)


''')
Ejemplo n.º 10
0
parse.Transfs('''


Goto(label) =
	ir.path.inSelection ;
	?GoTo(Sym(label))


liftLoop =
		with label, rest in
			~[Label(label), *<AtSuffix(
				?[<Goto(label)>, *rest] ;
				![]
			) ;
			![While(Lit(Bool,1), Block(<id>)), *rest]
			>]
		end


gotoSelected =
	Where(
		ir.path.projectSelection => GoTo(Sym(_))
	)

functionSelected =
	Where(
		ir.path.projectSelection => Function
	)

common = OnceTD(AtSuffix(liftLoop))

applicable =
	ir.path.Applicable(
		gotoSelected ;
		common
	)

input =
	ir.path.Input(
		![]
	)

apply =
	ir.path.Apply(
		[root,[]] -> root ;
		common ;
		dle
	)


testApply =
	!Module([
		Label("next"),
		Assign(Int(32,Signed), Sym("a"), Sym("b")),
		GoTo(Sym("next"))
	]) ;
	ir.path.annotate ;
	apply [<id>, [[2,0]]] ;
	?Module([
		While(Lit(Bool,1),
			Assign(Int(32,Signed), Sym("a"), Sym("b"))
		)
	])

''')
Ejemplo n.º 11
0
parse.Transfs('''


#######################################################################
# Labels

shared needed_label as table

updateNeededLabels =
	Where(
		?GoTo(Sym(label)) ;
		needed_label.set [label,label]
	)

#######################################################################
# Statements

dleLabel =
	Try(
		?Label(<Not(~needed_label)>) ;
		!NoStmt
	)

elimBlock =
	Block([]) -> NoStmt |
	Block([stmt]) -> stmt

dleBlock =
	~Block(<dleStmts>) ;
	Try(elimBlock)

elimIf =
	If(cond,NoStmt,NoStmt) -> Assign(Void,NoExpr,cond) |
	If(cond,NoStmt,false) -> If(Unary(Not,cond),false,NoStmt)

dleIf =
	~If(_, <dleStmt>, <dleStmt>) ;
	Try(elimIf)

elimWhile =
	While(cond,NoStmt) -> Assign(Void,NoExpr,cond)

dleWhile =
	~While(_, <dleStmt>) ;
	Try(elimWhile)

elimDoWhile =
	DoWhile(cond,NoStmt) -> Assign(Void,NoExpr,cond)

dleDoWhile =
	~DoWhile(_, <dleStmt>) ;
	Try(elimDoWhile)

dleFunction =
	{needed_label:
		AllTD(updateNeededLabels) ;
		~Function(_, _, _, <dleStmts>)
	}

# If none of the above applies, assume all vars are needed
dleDefault =
	id

dleStmt =
	?Label & dleLabel +
	?Block & dleBlock +
	?If & dleIf +
	?While & dleWhile +
	?DoWhile & dleDoWhile +
	?Function & dleFunction +
	id

dleStmts =
	MapR(dleStmt) ;
	Filter(Not(?NoStmt))

dleModule =
	~Module(<dleStmts>)

dle =
	{needed_label:
		AllTD(updateNeededLabels) ;
		dleModule
	}


testUnusedLabel =
    !Module([
    	Label("A")
    ]) ;
    dle ;
    ?Module([])

testUsedLabel =
    !Module([
    	GoTo(Sym("A")),
    	Label("A")
    ]) ;
    dle ;
    ?Module([
    	GoTo(Sym("A")),
    	Label("A")
    ])

''')
Ejemplo n.º 12
0
Archivo: misc.py Proyecto: uxmal/idc
'''Miscellaneous instructions.'''

from transf import parse
from machine.pentium.common import *

parse.Transfs('''


AsmLEA(size) =
	[dst,src] -> [Assign(<Word(size)>,dst,Addr(src))]

asmLEAW = AsmLEA(!8)
asmLEAL = AsmLEA(!16)


asmNOP =
	[] -> [NoStmt]


# FIXME: UD2
# FIXME: XLAT/XLATB
# FIXME: CPUID


''')
Ejemplo n.º 13
0
parse.Transfs('''


Goto(label) =
	ir.path.inSelection ;
	?GoTo(Sym(label))

liftIfElse =
		with
			cond, false_stmts,
			true_label, true_stmts,
			rest_label, rest_stmts
		in
			~[If(cond, <ir.path.inSelection;?GoTo(Sym(true_label))>, NoStmt), *<AtSuffix(
				~[GoTo(Sym(rest_label)), Label(true_label), *<AtSuffix(
					?[Label(rest_label), *] => rest_stmts ;
					![]
				)>] ; project.tail => true_stmts ;
				![]
			)>] ; project.tail => false_stmts ;
			![If(cond, Block(true_stmts), Block(false_stmts)), *rest_stmts]
		end

gotoSelected =
	Where(
		ir.path.projectSelection => GoTo(Sym(_))
	)

functionSelected =
	Where(
		ir.path.projectSelection => Function
	)

common = OnceTD(AtSuffix(liftIfElse))

applicable =
	ir.path.Applicable(
		gotoSelected ;
		common
	)

input =
	ir.path.Input(
		![]
	)

apply =
	ir.path.Apply(
		[root,[]] -> root ;
		common ;
		dle
	)

''')
Ejemplo n.º 14
0
parse.Transfs('''


AddFlags(size, op1, op2, res) =
	![
		<ZeroFlag(size, res)>,
		<SignFlag(size, res)>,
		Assign(Bool, <cf>,
			Binary(Or(Bool),
				Binary(And(Bool),<HsbOne(size,op1)>,<HsbOne(size,op2)>),
				Binary(And(Bool),
					<HsbZero(size,res)>,
					Binary(Or(Bool),<HsbOne(size,op1)>,<HsbOne(size,op2)>)
				)
			)
		),
		Assign(Bool, <of>,
			Binary(Or(Bool),
				Binary(And(Bool),
					Binary(And(Bool),<Negative(size,op1)>,<Negative(size,op2)>),
					<NonNegative(size,res)>
				),
				Binary(And(Bool),
					Binary(And(Bool),<NonNegative(size,op1)>,<NonNegative(size,op2)>),
					<Negative(size,res)>
				)
			)
		)
	]

SubFlags(size, op1, op2, res) =
	![
		<ZeroFlag(size, res)>,
		<SignFlag(size, res)>,
		Assign(Bool, <cf>,
			Binary(Or(Bool),
				Binary(And(Bool),<HsbZero(size,op1)>,<HsbOne(size,op2)>),
				Binary(And(Bool),
					<HsbZero(size,res)>,
					Binary(Or(Bool),<HsbZero(size,op1)>,<HsbOne(size,op2)>)
				)
			)
		),
		Assign(Bool, <of>,
			Binary(Or(Bool),
				Binary(And(Bool),
					Binary(And(Bool),<NonNegative(size,op1)>,<Negative(size,op2)>),
					<NonNegative(size,res)>
				),
				Binary(And(Bool),
					Binary(And(Bool),<Negative(size,op1)>,<NonNegative(size,op2)>),
					<Negative(size,res)>
				)
			)
		)
	]

AsmAdd(size) =
		[dst, src] -> [
			Assign(type, tmp, dst),
			Assign(type, dst, Binary(Plus(type), dst, src)),
			*<AddFlags(size, !tmp, !src, !dst)>
		]
	where
		type := Word(size) ;
		tmp := temp


asmADDB = AsmAdd(!8)
asmADDW = AsmAdd(!16)
asmADDL = AsmAdd(!32)


AsmADC(size) =
		[dst, src] -> [
			Assign(type, tmp, dst),
			Assign(type, dst,
				Binary(Plus(type),dst,
					Binary(Plus(type),src,
						Cond(<cf>,Lit(type,1),Lit(type,0))))),
			*<AddFlags(size, !tmp, !src, !dst)>
		]
	where
		type := Word(size) ;
		tmp := temp


asmADCB = AsmADC(!8)
asmADCW = AsmADC(!16)
asmADCL = AsmADC(!32)


AsmSub(size) =
		[dst, src] -> [
			Assign(type, tmp, dst),
			Assign(type, dst, Binary(Minus(type), dst, src)),
			*<SubFlags(size, !tmp, !src, !dst)>
		]
	where
		type := Word(size) ;
		tmp := temp

asmSUBB = AsmSub(!8)
asmSUBW = AsmSub(!16)
asmSUBL = AsmSub(!32)


AsmSBB(size) =
		[dst, src] -> [
			Assign(type, tmp, dst),
			Assign(type, dst,
				Binary(Minus(type),dst,
					Binary(Plus(type),src,
						Cond(<cf>,Lit(type,1),Lit(type,0))))),
			*<SubFlags(size, !tmp, !src, !dst)>
		]
	where
		type := Word(size) ;
		tmp := temp

asmSBBB = AsmSBB(!8)
asmSBBW = AsmSBB(!16)
asmSBBL = AsmSBB(!32)


AsmInc(size) =
		[dst] -> [
			Assign(type, tmp, dst),
			Assign(type, dst, Binary(Plus(type), dst, Lit(type,1))),
			*<AddFlags(size, !tmp, !Lit(type,1), !dst)>
		]
	where
		type := Word(size) ;
		tmp := temp

asmINCB = AsmInc(!8)
asmINCW = AsmInc(!16)
asmINCL = AsmInc(!32)

AsmDec(size) =
		[dst] -> [
			Assign(type, tmp, dst),
			Assign(type, dst, Binary(Minus(type), dst, Lit(type,1))),
			*<SubFlags(size, !tmp, !Lit(type,1), !dst)>
		]
	where
		type := Word(size) ;
		tmp := temp

asmDECB = AsmDec(!8)
asmDECW = AsmDec(!16)
asmDECL = AsmDec(!32)


HighLow(size) =
	switch size
		case 8: ![<ah>,<al>]
		case 16: ![<dx>,<ax>]
		case 32: ![<edx>,<eax>]
	end

AsmMUL(size) =
		[src] -> <
		HighLow(size); ?[high,low] ;
		![
			Assign(type2, tmp, Binary(Mult(type2),Cast(type2,low),Cast(type2,src))),
			Assign(type, low, Cast(type,tmp)),
			Assign(type, high, Cast(type,Binary(RShift(type),tmp,Lit(type2,<size>)))),
			Assign(Bool, <cf>, Binary(NotEq(type),high,Lit(type2,0))),
			Assign(Bool, <of>, Binary(NotEq(type),high,Lit(type2,0)))
		]>
	where
		type := Word(size) ;
		type2 := Word(arith.MulInt(size,!2)) ;
		tmp := temp

asmMULB = AsmMUL(!8)
asmMULW = AsmMUL(!16)
asmMULL = AsmMUL(!32)


AsmIMUL1(size,src) =
		HighLow(size); ?[high,low] ;
		![
			Assign(type2, tmp, Binary(Mult(type2),Cast(type2,low),Cast(type2,<src>))),
			Assign(type, low, Cast(type,tmp)),
			Assign(type, high, Cast(type,Binary(RShift(type),tmp,Lit(type2,<size>)))),
			Assign(Bool, <cf>, Binary(And(Bool),Binary(NotEq(type),high,Lit(type2,0)),Binary(NotEq(type),high,Lit(type2,-1)))),
			Assign(Bool, <of>, Binary(And(Bool),Binary(NotEq(type),high,Lit(type2,0)),Binary(NotEq(type),high,Lit(type2,-1))))
		]
	where
		type := SWord(size) ;
		type2 := SWord(arith.MulInt(size,!2)) ;
		tmp := temp

AsmIMUL23(size,dst,src1,src2) =
		![
			Assign(type2, tmp, Binary(Mult(type2),Cast(type2,<src1>),Cast(type2,<src2>))),
			Assign(type, <dst>, Binary(Mult(type),<src1>,<src2>)),
			Assign(Bool, <cf>, Binary(NotEq(type2),tmp,Cast(type2,<dst>))),
			Assign(Bool, <of>, Binary(NotEq(type2),tmp,Cast(type2,<dst>)))
		]
	where
		type := SWord(size) ;
		type2 := SWord(arith.MulInt(size,!2)) ;
		tmp := temp

AsmIMUL(size) =
	[op1] -> <AsmIMUL1(size,!op1)> |
	[op1,op2] -> <AsmIMUL23(size,!op1,!op1,!op2)> |
	[op1,op2,op3] -> <AsmIMUL23(size,!op1,!op2,!op3)>

asmIMULB = AsmIMUL(!8)
asmIMULW = AsmIMUL(!16)
asmIMULL = AsmIMUL(!32)

# FIXME: handle 8 bit specially


AsmDIV(size) =
		[src] -> <
		HighLow(size); ?[high,low] ;
		![
			Assign(type2, tmp1,
				Binary(And(type2),
					Cast(type2,low),
					Binary(LShift(type2),Cast(type2,high),Lit(type2,<size>))
				)
			),
			Assign(type, tmp2, src),
			Assign(type, low, Cast(type,Binary(Div(type2),tmp1,Cast(type2,tmp2)))),
			Assign(type, high, Cast(type,Binary(Mod(type2),tmp1,Cast(type2,tmp2))))
			# FIXME: undefine flags
		]>
	where
		type := Word(size) ;
		type2 := Word(arith.MulInt(size,!2)) ;
		tmp1 := temp ;
		tmp2 := temp

asmDIVB = AsmDIV(!8)
asmDIVW = AsmDIV(!16)
asmDIVL = AsmDIV(!32)


AsmIDIV(size) =
		[src] -> <
		HighLow(size); ?[high,low] ;
		![
			Assign(type2, tmp1,
				Binary(And(type2),
					Cast(type2,low),
					Binary(LShift(type2),Cast(type2,high),Lit(type2,<size>))
				)
			),
			Assign(type, tmp2, src),
			Assign(type, low, Cast(type,Binary(Div(type2),tmp1,Cast(type2,tmp2)))),
			Assign(type, high, Cast(type,Binary(Mod(type2),tmp1,Cast(type2,tmp2))))
			# FIXME: undefine flags
		]>
	where
		type := SWord(size) ;
		type2 := SWord(arith.MulInt(size,!2)) ;
		tmp1 := temp ;
		tmp2 := temp

asmIDIVB = AsmIDIV(!8)
asmIDIVW = AsmIDIV(!16)
asmIDIVL = AsmIDIV(!32)


AsmNEG(size) =
		[dst] -> [
			Assign(type, tmp, dst),
			Assign(type, dst, Unary(Neg(type), dst)),
			*<SubFlags(size, !Lit(type,0), !tmp, !dst)>
		]
	where
		type := Word(size) ;
		tmp := temp

asmNEGB = AsmNEG(!8)
asmNEGW = AsmNEG(!16)
asmNEGL = AsmNEG(!32)


AsmCmp(size) =
		[dst, src] -> [
			Assign(type, tmp, Binary(Minus(type), dst, src)),
			*<SubFlags(size, !dst, !src, !tmp)>
		]
	where
		type := Word(size) ;
		tmp := temp

asmCMPB = AsmCmp(!8)
asmCMPW = AsmCmp(!16)
asmCMPL = AsmCmp(!32)

''')
Ejemplo n.º 15
0
Archivo: flag.py Proyecto: uxmal/idc
parse.Transfs('''


asmSTC = [] -> [Assign(Bool, <cf>, Lit(Bool,1))]
asmCLC = [] -> [Assign(Bool, <cf>, Lit(Bool,0))]
asmCMC = [] -> [Assign(Bool, <cf>, Unary(Not(Bool),<cf>))]


asmSTD = [] -> [Assign(Bool, <df>, Lit(Bool,1))]
asmCLD = [] -> [Assign(Bool, <df>, Lit(Bool,0))]


asmLAHF = [] -> [
		Assign(type, <ah>,
			Binary(Or(type), Cond(<cf>, Lit(type,0x01), Lit(type,0)),
			Binary(Or(type), Lit(type,0x02),
			Binary(Or(type), Cond(<pf>, Lit(type,0x04), Lit(type,0)),
			Binary(Or(type), Cond(<af>, Lit(type,0x10), Lit(type,0)),
			Binary(Or(type), Cond(<zf>, Lit(type,0x40), Lit(type,0)),
				Cond(<sf>, Lit(type,0x80), Lit(type,0))
		))))))
	] where
		type := UWord(!8)


asmSAHF = [] -> [
		Assign(type, <cf>, Binary(And(type), <ah>, Lit(type,0x01))),
		Assign(type, <pf>, Binary(And(type), <ah>, Lit(type,0x04))),
		Assign(type, <af>, Binary(And(type), <ah>, Lit(type,0x10))),
		Assign(type, <zf>, Binary(And(type), <ah>, Lit(type,0x40))),
		Assign(type, <sf>, Binary(And(type), <ah>, Lit(type,0x80)))
	] where
		type := UWord(!8)


asmPUSHFL = [] -> [
		Binary(Or(type), Cond(<cf>, Lit(type,0x01), Lit(type,0)),
		Binary(Or(type), Lit(type,0x02),
		Binary(Or(type), Cond(<pf>, Lit(type,0x04), Lit(type,0)),
		Binary(Or(type), Cond(<af>, Lit(type,0x10), Lit(type,0)),
		Binary(Or(type), Cond(<zf>, Lit(type,0x40), Lit(type,0)),
			Cond(<sf>, Lit(type,0x80), Lit(type,0)))))))
		# FIXME: incomplete
	] ; asmPUSHL
		where type := UWord(!32)


asmPOPFL = [] -> [
		<asmPOPL [tmp] >,
		Assign(type, <cf>, Binary(And(type), tmp, Lit(type,0x01))),
		Assign(type, <pf>, Binary(And(type), tmp, Lit(type,0x04))),
		Assign(type, <af>, Binary(And(type), tmp, Lit(type,0x10))),
		Assign(type, <zf>, Binary(And(type), tmp, Lit(type,0x40))),
		Assign(type, <sf>, Binary(And(type), tmp, Lit(type,0x80)))
		# FIXME: incomplete
	] where
		type := UWord(!32) ;
		tmp := temp


asmSTI = [] -> [Assign(Bool, <if_>, Lit(Bool,1))]
asmCLI = [] -> [Assign(Bool, <if_>, Lit(Bool,0))]


''')
Ejemplo n.º 16
0
parse.Transfs(r'''

#######################################################################
# Graph Generation

shared stmtid

shared this
shared next
shared retn
shared brek
shared cont

shared nodes


getNodeId =
	Label(label) -> label & box.escape +
	Count()

makeNodeLabel =
	( If(cond,_,_)
		-> <ir.pprint.ppExpr cond>
	| While(cond,_)
		-> <ir.pprint.ppExpr cond>
	| DoWhile(cond,_)
		-> <ir.pprint.ppExpr cond>
	| _
		-> <ir.pprint.stmtKern>
	| n(*)
		-> n
	) ;
	renderBox ;
	box.escape

makeNodeShape =
	If
		-> "diamond"
|	While
		-> "diamond"
|	DoWhile
		-> "diamond"
|	Module
		-> "point"
|	Block
		-> "point"
|	NoStmt
		-> "point"
|	_
		-> "box"


makeNodeUrl =
	(path.get & box.reprz + !"" ) ;
	box.escape

makeNodeAttrs =
	![
		!Attr("label", <makeNodeLabel>),
		!Attr("shape", <makeNodeShape>),
		!Attr("URL", <makeNodeUrl>)
	]

MakeEdge(dst) =
	!Edge(<dst>, [])
MakeLabelledEdge(dst, label) =
	!Edge(<dst>, [Attr("label", <label ; box.escape>)])

AddNode(nodeid, attrs, edges) =
	Where(
		!Node(
			<nodeid>,
			<attrs>,
			<edges>
		) ;
		nodes := ![_,*nodes]
	)

GetTerminalNodeId(nodeid) =
	NegInt(nodeid)

hasTerminalNode =
	?Function

addTerminalNode =
	AddNode(
		!retn,
		![
			Attr("label", "\"\""),
			Attr("shape", "doublecircle"),
			Attr("style", "filled"),
			Attr("fillcolor", "black")
		],
		![]
	)


#######################################################################
# Flow Traversal

doStmts =
	MapR(doStmt)

MakeNode(edges) =
	AddNode(!this, makeNodeAttrs, edges)

doDefault =
	MakeNode(![<MakeEdge(!next)>]) ;
	next := !this

doIf =
	with true, false, oldnext in
		oldnext := !next ;
		?If(_,
			<with next in next := !oldnext; doStmt; true := !next end>,
			<with next in next := !oldnext; doStmt; false := !next end>
		) ;
		MakeNode(![
			<MakeLabelledEdge(!true, !"True")>,
			<MakeLabelledEdge(!false, !"False")>,
		]) ;
		next := !this
	end

doNoStmt =
	id

doWhile =
	with true in
		?While(_, <with next in next := !this; doStmt; true := !next end> );
		MakeNode(![
			<MakeLabelledEdge(!true, !"True")>,
			<MakeLabelledEdge(!next, !"False")>,
		]) ;
		next := !this
	end


doDoWhile =
	with false in
		false := !next ;
		next := !this ;
		?DoWhile(_, <doStmt> );
		MakeNode(![
			<MakeLabelledEdge(!next, !"True")>,
			<MakeLabelledEdge(!false, !"False")>,
		])
	end

doBreak =
	MakeNode(![<MakeEdge(!brek)>]) ;
	next := !this

doContinue =
	MakeNode(![<MakeEdge(!cont)>]) ;
	next := !this

doRet =
	MakeNode(![<MakeEdge(!retn)>]) ;
	next := !this

doGoTo =
	with
		label
	in
		?GoTo(Sym(label)) &
		MakeNode(![<MakeEdge(!label ; box.escape)>]) +
		MakeNode(![])
	end ;
	next := !this

doBlock =
	?Block(<doStmts>)

doFunction =
	oldnext := !next ;
	with next, retn, brek, cont in
		next := !oldnext ;
		retn := GetTerminalNodeId(!this) ;
		brek := !0 ;
		cont := !0 ;
		?Function(_, _, _, <doStmts>) ;
		MakeNode(![<MakeEdge(!next)>]) ;
		addTerminalNode
	end

doModule =
	with next, retn, brek, cont in
		next := !0 ;
		retn := !0 ;
		brek := !0 ;
		cont := !0 ;
		?Module(<doStmts>) ;
		addTerminalNode
	end

doStmt =
	with this in
		this := getNodeId ;
		switch project.name
		case "If": doIf
		case "While": doWhile
		case "DoWhile":	doDoWhile
		case "Break": doBreak
		case "GoTo": doGoTo
		case "Continue": doContinue
		case "NoStmt": doNoStmt
		case "Ret": doRet
		case "Block": doBlock
		case "Function": doFunction
		case "Module": doModule
		else doDefault
		end
	end

makeGraph =
	with nodes, stmtid in
		nodes := ![] ;
		stmtid := !0 ;
		doModule ;
		AddNode(!"edge",![Attr("fontname","Arial")],![]) ;
		AddNode(!"node",![Attr("fontname","Arial")],![]) ;
		!Graph(nodes)
	end


#######################################################################
# Graph Simplification

shared point as table

matchPointShapeAttr =
	?Attr("shape", "point")

findPointNode =
	?Node(src, <One(matchPointShapeAttr)>, [Edge(dst, _)]) ;
	point.set [src, dst]

findPointNodes =
	Map(Try(findPointNode))

replaceEdge =
	~Edge(<~point>, _)

removePointNode =
	~Node(<Not(?point)>, _, <Map(Try(replaceEdge))>)

removePointNodes =
	Filter(removePointNode)

simplifyPoints =
	with point in
		~Graph(<findPointNodes; removePointNodes>)
	end

simplifyGraph = simplifyPoints


#######################################################################

render = makeGraph ; simplifyGraph


''')
Ejemplo n.º 17
0
parse.Transfs('''

liftContinue =
	~[Label(label), <
		~While(_, < OnceTD( (GoTo(Sym(label)) -> Continue if ir.path.inSelection) ) >) +
		~DoWhile(_, < OnceTD( (GoTo(Sym(label)) -> Continue if ir.path.inSelection) ) >)
	>, *]


gotoSelected =
	Where(
		ir.path.projectSelection => GoTo(Sym(_))
	)

functionSelected =
	Where(
		ir.path.projectSelection => Function
	)

common =
	OnceTD(AtSuffix(liftContinue))

applicable =
	ir.path.Applicable(
		gotoSelected ;
		common
	)

input =
	ir.path.Input(
		![]
	)


apply =
	ir.path.Apply(
		[root,[]] -> root ;
		common ;
		dle
	)


xtestApply =
	!Module([
		Label("continue"),
		While(Lit(Bool,1), Block([
			Assign(Int(32,Signed), Sym("a"), Sym("b")),
			GoTo(Sym("continue"))
		]))
	]) ;
	ir.path.annotate ;
	apply [<id>, [[0,1,1,0,1]]] ;
	?Module([
		While(Lit(Bool,1), Block([
			Assign(Int(32,Signed), Sym("a"), Sym("b")),
			Continue
		]))
	])

''')
Ejemplo n.º 18
0
Archivo: shift.py Proyecto: uxmal/idc
parse.Transfs('''

# FIXME: truncate src

_AsmSxL(size, sign, dst, src) =
	![
		Assign(type, tmp, <dst>),
		Assign(type, <dst>, Binary(LShift(type), <dst>, <src>)),
		# FIXME: deal with zero count
		Assign(Bool, <cf>, Binary(And(type), tmp,
			Binary(LShift(type),Lit(type,1),
				Binary(Minus(type),Lit(type,<size>), <src>))
		)),
		Assign(Bool, <of>, <LNotEq(HsbOne(size,dst),cf)>)
	]
	where
		type := !Int(<size>,<sign>) ;
		tmp := temp

AsmSxL(size, sign) =
	[dst] -> <_AsmSxL(size, sign, !dst, !Lit(Int(<size>,<sign>),1))> |
	[dst,src] -> <_AsmSxL(size, sign, !dst, !src)>

asmSHLB = AsmSxL(!8, !Unsigned)
asmSHLW = AsmSxL(!16, !Unsigned)
asmSHLL = AsmSxL(!32, !Unsigned)
asmSALB = AsmSxL(!8, !Signed)
asmSALW = AsmSxL(!16, !Signed)
asmSALL = AsmSxL(!32, !Signed)

_AsmSxR(size, sign, dst, src) =
	![
		Assign(type, tmp, <dst>),
		Assign(type, <dst>, Binary(RShift(type), <dst>, <src>)),
		Assign(Bool, <cf>, Binary(And(type), tmp,
			Binary(RShift(type),Lit(type,1),
				Binary(Minus(type),<src>, Lit(type,1)))
		)),
		Assign(Bool, <of>,
			<switch sign
			case Unsigned:
				!Lit(Bool, 0)
			case Signed:
				HsbOne(size,!tmp)
			end>
		)
	]
	where
		type := !Int(<size>,<sign>) ;
		tmp := temp


AsmSxR(size, sign) =
	[dst] -> <_AsmSxR(size, sign, !dst, !Lit(Int(<size>,<sign>),1))> |
	[dst,src] -> <_AsmSxR(size, sign, !dst, !src)>

asmSHRB = AsmSxR(!8, !Unsigned)
asmSHRW = AsmSxR(!16, !Unsigned)
asmSHRL = AsmSxR(!32, !Unsigned)
asmSARB = AsmSxR(!8, !Signed)
asmSARW = AsmSxR(!16, !Signed)
asmSARL = AsmSxR(!32, !Signed)


# FIXME: SHRD
# FIXME: SHLD

# FIXME: ROR
# FIXME: ROL
# FIXME: RCR
# FIXME: RCL


''')
Ejemplo n.º 19
0
parse.Transfs('''


Goto(label) =
	ir.path.inSelection ;
	?GoTo(Sym(label))

liftDoWhile =
		with label, cond, rest in
			~[Label(label), *<AtSuffix(
				?[If(_,<Goto(label)>,NoStmt), *] ;
				?[If(cond,_,_), *rest] ;
				![]
			) ;
			![DoWhile(cond, Block(<id>)), *rest]
			>]
		end

gotoSelected =
	Where(
		ir.path.projectSelection => GoTo(Sym(_))
	)

functionSelected =
	Where(
		ir.path.projectSelection => Function
	)

common = OnceTD(AtSuffix(liftDoWhile))

applicable =
	ir.path.Applicable(
		gotoSelected ;
		common
	)

input =
	ir.path.Input(
		![]
	)

apply =
	ir.path.Apply(
		[root,[]] -> root ;
		common ;
		dle
	)


testApply =
	!Module([
		Label("next"),
		Assign(Int(32,Signed), Sym("a"), Sym("b")),
		If(Sym("a"),GoTo(Sym("next")),NoStmt)
	]) ;
	ir.path.annotate ;
	apply [_, [[1,2,0]]] ;
	?Module([
		DoWhile(Sym("a"),
			Assign(Int(32,Signed), Sym("a"), Sym("b"))
		)
	])
''')
Ejemplo n.º 20
0
parse.Transfs('''


# Equality conditions

ccZ = zf
ccNZ = LNot(zf)
ccE = ccZ
ccNE = ccNZ

ccCXZ  = LNot(cx)
ccECXZ = LNot(ecx)


# Unsigned conditions

ccA = LAnd(LNot(cf),LNot(zf))
ccAE = LNot(cf)
ccB = cf
ccBE = LOr(cf, zf)

ccNBE = ccA
ccNB = ccNC
ccNAE = ccB
ccNA = ccBE

ccC = cf
ccNC = LNot(cf)


# Signed conditions

ccG   = LOr(LNotEq(sf,of),LNot(zf))
ccGE  = LNotEq(sf,of)
ccL   = LEq(sf,of)
ccLE  = LOr(LEq(sf,of),zf)

ccNLE = ccG
ccNL  = ccGE
ccNGE = ccL
ccNG  = ccLE

ccO = of
ccNO = LNot(of)

ccS = sf
ccNS = LNot(sf)


# Miscellaneous

ccP = pf
ccNP = LNot(pf)
ccPE = ccP
ccPO = ccNP


''')
Ejemplo n.º 21
0
parse.Transfs('''

AsmMOV(size) =
	[dst,src] -> [Assign(<Word(size)>,dst,src)]

asmMOVB = AsmMOV(!8)
asmMOVW = AsmMOV(!16)
asmMOVL = AsmMOV(!32)


AsmCMOVcc(size,cond) =
	[dst,src] -> [If(<cond>,Assign(<Word(size)>,dst,src),NoStmt)]

asmCMOVAW   = AsmCMOVcc(!16, ccA   )
asmCMOVAEW  = AsmCMOVcc(!16, ccAE  )
asmCMOVBW   = AsmCMOVcc(!16, ccB   )
asmCMOVBEW  = AsmCMOVcc(!16, ccBE  )
asmCMOVCW   = AsmCMOVcc(!16, ccC   )
asmCMOVEW   = AsmCMOVcc(!16, ccE   )
asmCMOVGW   = AsmCMOVcc(!16, ccG   )
asmCMOVGEW  = AsmCMOVcc(!16, ccGE  )
asmCMOVLW   = AsmCMOVcc(!16, ccL   )
asmCMOVLEW  = AsmCMOVcc(!16, ccLE  )
asmCMOVNAW  = AsmCMOVcc(!16, ccNA  )
asmCMOVNAEW = AsmCMOVcc(!16, ccNAE )
asmCMOVNBW  = AsmCMOVcc(!16, ccNB  )
asmCMOVNBEW = AsmCMOVcc(!16, ccNBE )
asmCMOVNCW  = AsmCMOVcc(!16, ccNC  )
asmCMOVNEW  = AsmCMOVcc(!16, ccNE  )
asmCMOVNGW  = AsmCMOVcc(!16, ccNG  )
asmCMOVNGEW = AsmCMOVcc(!16, ccNGE )
asmCMOVNLW  = AsmCMOVcc(!16, ccNL  )
asmCMOVNLEW = AsmCMOVcc(!16, ccNLE )
asmCMOVNOW  = AsmCMOVcc(!16, ccNO  )
asmCMOVNPW  = AsmCMOVcc(!16, ccNP  )
asmCMOVNSW  = AsmCMOVcc(!16, ccNS  )
asmCMOVNZW  = AsmCMOVcc(!16, ccNZ  )
asmCMOVOW   = AsmCMOVcc(!16, ccO   )
asmCMOVPW   = AsmCMOVcc(!16, ccP   )
asmCMOVPEW  = AsmCMOVcc(!16, ccPE  )
asmCMOVPOW  = AsmCMOVcc(!16, ccPO  )
asmCMOVSW   = AsmCMOVcc(!16, ccS   )
asmCMOVZW   = AsmCMOVcc(!16, ccZ   )

asmCMOVAL   = AsmCMOVcc(!32, ccA   )
asmCMOVAEL  = AsmCMOVcc(!32, ccAE  )
asmCMOVBL   = AsmCMOVcc(!32, ccB   )
asmCMOVBEL  = AsmCMOVcc(!32, ccBE  )
asmCMOVCL   = AsmCMOVcc(!32, ccC   )
asmCMOVEL   = AsmCMOVcc(!32, ccE   )
asmCMOVGL   = AsmCMOVcc(!32, ccG   )
asmCMOVGEL  = AsmCMOVcc(!32, ccGE  )
asmCMOVLL   = AsmCMOVcc(!32, ccL   )
asmCMOVLEL  = AsmCMOVcc(!32, ccLE  )
asmCMOVNAL  = AsmCMOVcc(!32, ccNA  )
asmCMOVNAEL = AsmCMOVcc(!32, ccNAE )
asmCMOVNBL  = AsmCMOVcc(!32, ccNB  )
asmCMOVNBEL = AsmCMOVcc(!32, ccNBE )
asmCMOVNCL  = AsmCMOVcc(!32, ccNC  )
asmCMOVNEL  = AsmCMOVcc(!32, ccNE  )
asmCMOVNGL  = AsmCMOVcc(!32, ccNG  )
asmCMOVNGEL = AsmCMOVcc(!32, ccNGE )
asmCMOVNLL  = AsmCMOVcc(!32, ccNL  )
asmCMOVNLEL = AsmCMOVcc(!32, ccNLE )
asmCMOVNOL  = AsmCMOVcc(!32, ccNO  )
asmCMOVNPL  = AsmCMOVcc(!32, ccNP  )
asmCMOVNSL  = AsmCMOVcc(!32, ccNS  )
asmCMOVNZL  = AsmCMOVcc(!32, ccNZ  )
asmCMOVOL   = AsmCMOVcc(!32, ccO   )
asmCMOVPL   = AsmCMOVcc(!32, ccP   )
asmCMOVPEL  = AsmCMOVcc(!32, ccPE  )
asmCMOVPOL  = AsmCMOVcc(!32, ccPO  )
asmCMOVSL   = AsmCMOVcc(!32, ccS   )
asmCMOVZL   = AsmCMOVcc(!32, ccZ   )


AsmXCHG(size) =
	[dst,src] -> [
		Assign(type,tmp,dst),
		Assign(type,dst,src),
		Assign(type,src,tmp)
	]
	where
		type := Word(size) ;
		tmp := temp

asmXCHGB = AsmXCHG(!8)
asmXCHGW = AsmXCHG(!16)
asmXCHGL = AsmXCHG(!32)


# FIXME: BSWAP


AsmXADD(size) =
		[dst, src] -> [
			Assign(type, tmp, Binary(Plus(type), dst, src)),
			Assign(type, src, dst),
			Assign(type, dst, tmp),
			*<AddFlags(size, !src, !dst, !tmp)>
		]
	where
		type := Word(size) ;
		tmp := temp

asmXADDB = AsmXADD(!8)
asmXADDW = AsmXADD(!16)
asmXADDL = AsmXADD(!32)


AsmCMPXCHG(size,accum) =
		[dst, src] -> [
			Assign(type, tmp, Binary(Minus(type), <accum>, dst)),
			*<SubFlags(size, accum, !src, !tmp)>,
			If(Binary(Eq(type),<accum>,dst),
				Assign(type, dst, src),
				Assign(type, <accum>, dst)
			)
		]
	where
		type := Word(size) ;
		tmp := temp

asmCMPXCHGB = AsmCMPXCHG(!8,   al)
asmCMPXCHGW = AsmCMPXCHG(!16,  ax)
asmCMPXCHGL = AsmCMPXCHG(!32, eax)


# FIXME: CMPXCHG8B


AsmPUSH(size) =
	[src] -> [
		Assign(type, <esp>, Binary(Minus(type), <esp>, Lit(type,4))),
		Assign(type, Ref(<esp>), src)
	] where
		type := Word(size)

asmPUSHW = AsmPUSH(!16)
asmPUSHL = AsmPUSH(!32)


AsmPOP(size) =
	[dst] -> [
		Assign(type, dst, Ref(<esp>)),
		Assign(type, <esp>, Binary(Plus(type), <esp>, Lit(type,4)))
	] where
		type := Word(size)

asmPOPW = AsmPOP(!16)
asmPOPL = AsmPOP(!32)


asmPUSHAD =
	[] -> [
		Assign(<Word(!32)>, tmp, <esp>),
		*<lists.MapConcat(asmPUSHL [_]) [<eax>, <ecx>, <edx>, <ebx>, tmp , <esi>, <edi>]>
	] where
		tmp := temp

asmPOPAD =
	[] -> [
		*<lists.MapConcat(asmPOPL [_]) [<eax>, <ecx>, <edx>, <ebx>, tmp , <esi>, <edi>]>
	] where
		tmp := temp


AsmIN(size, builtin) =
	[dst, src] -> [Assign(<Word(size)>,dst,Call(Sym(<builtin>){Builtin},[src]))]

asmINB = AsmIN(!8, !"_inp")
asmINW = AsmIN(!8, !"_inpw")
asmINL = AsmIN(!8, !"_inpd")


AsmOUT(size, builtin) =
	[dst, src] -> [Assign(Void,NoExpr,Call(Sym(<builtin>){Builtin},[dst,src]))]

asmOUTB = AsmOUT(!8, !"_outp")
asmOUTW = AsmOUT(!8, !"_outpw")
asmOUTL = AsmOUT(!8, !"_outpd")


asmCWTD =
	[] -> [
		If(Binary(Lt(type),<ax>,Lit(type,0)),
			Assign(type,<dx>,Lit(type,-1)),
			Assign(type,<dx>,Lit(type,0))
		)
	] where
		type := SWord(!16)


asmCLTD =
	[] -> [
		If(Binary(Lt(type),<eax>,Lit(type,0)),
			Assign(type,<edx>,Lit(type,-1)),
			Assign(type,<edx>,Lit(type,0))
		)
	] where
		type := SWord(!32)


AsmMOVSX(size, dst, src) =
	![Assign(Int(<size>,Signed), <dst>, Cast(Int(<size>,Signed),<src>))]

asmCBTW = [] -> <AsmMOVSX(!16,ax,al)>

asmCWTL = [] -> <AsmMOVSX(!16,eax,ax)>

asmMOVSBW = [dst, src] -> <AsmMOVSX(!16, !dst, !src)>
asmMOVSBL = [dst, src] -> <AsmMOVSX(!32, !dst, !src)>
asmMOVSWL = [dst, src] -> <AsmMOVSX(!32, !dst, !src)>


AsmMOVZX(size) =
	[dst, src] -> [Assign(Int(<size>,Unsigned), dst, Cast(Int(<size>,Unsigned),src))]

asmMOVZBW = AsmMOVZX(!16)
asmMOVZBL = AsmMOVZX(!32)
asmMOVZWL = AsmMOVZX(!32)


''')
Ejemplo n.º 22
0
parse.Transfs('''


simplifyExpr =
	Not(Int(1,_)) -> Not(Bool)
|	Or(Int(1,_)) -> Or(Bool)
|	And(Int(1,_)) -> And(Bool)


simplifyStmt =
	Assign(type, dst, Cond(cond, src, dst))
		-> If(cond, Assign(type, dst, src), NoStmt)

|	Assign(type, dst, Cond(cond, src, dst))
		-> If(Unary(Not, cond), Assign(type, dst, src), NoStmt)

|	Assign(_, Sym("pc"), expr)
		-> GoTo(Addr(expr))

|	Cond(cond,Lit(Int(_,_),1),Lit(Int(_,_),0))
		-> cond
|	Cond(cond,Lit(Int(_,_),0),Lit(Int(_,_),1))
		-> Not(cond)

|	Ref(Addr(expr))
		-> expr
|	Addr(Ref(expr))
		-> expr


simplify =
	traverse.InnerMost(
		simplifyExpr +
		simplifyStmt
	)


''')
Ejemplo n.º 23
0
parse.Transfs(r'''

#######################################################################
# Path annotation

# Only annotate term applications
annotate = path.Annotate(
	match.ApplNames(`
		ir.match.stmtNames +
		ir.match.exprNames +
		ir.match.typeNames
	`)
)

deannotate = path.deannotate


#######################################################################
# Selection

shared selection

Applicable(t) =
	with selection in
		?[root, selection] ;
		!root ;
		t
	end

Input(t) =
	with selection in
		?[root, selection] ;
		!root ;
		# annotate ;
		t ;
		![selection, *<id>]
	end

Input2(t) =
	with selection in
		?[root, selection] ;
		!root ;
		# annotate ;
		t
	end

Apply(t) =
	with selection in
		?[root, [selection, *args]] ;
		![root, args] ;
		t ;
		deannotate
	end



WithSelection(s, x) = with selection in x where selection := s end



projectSelection = path.Project(!selection)

MatchSelectionTo(s) = projectSelection ; s


#######################################################################
# Selection context

getSelection = !selection

isSelected =
	Where(
		path.get ;
		path.Equals(getSelection)
	)

inSelection =
	Where(
		path.get ;
		path.Contained(getSelection)
	)

hasSelection =
	Where(
		path.get ;
		path.Contains(getSelection)
	)

''')
Ejemplo n.º 24
0
			trf = eval("asm" + opcode.upper())
		except NameError:
			sys.stderr.write("warning: don't now how to translate opcode '%s'\n" % opcode)
			raise exception.Failure

		try:
			trm = trf.apply(operands, ctx)
			for stmt in trm:
				ir.check.stmt(stmt)
			return trm
		except KeyboardInterrupt, SystemExit:
			raise
		except:
			sys.stderr.write("warning: failed to translate opcode '%s'\n" % opcode)
			traceback.print_exc()
			raise exception.Failure


parse.Transfs('''

doStmt =
	OpcodeDispatch() ; Try(simplify)
	+ ![<id>]


doModule =
	~Module(<lists.MapConcat(doStmt)>)


''')
Ejemplo n.º 25
0
parse.Transfs('''

reduceStmts =
(
	Block(stmts) -> stmts |
	If(_, true, false) -> [true, false] |
	While(_, stmt) -> [stmt] |
	DoWhile(_, stmt) -> [stmt] |
	Function(_, _, _, stmts) -> stmts |
	Module(stmts) -> stmts
) + ![]

reduceStmts =
switch Try(project.name)
case "Block":
	project.args ; project.first
case "If":
	project.args ; project.tail
case "While":
	project.args ; project.tail
case "DoWhile":
	project.args ; project.tail
case "Function":
	project.args ; project.fourth
case "Module":
	project.args ; project.first
else
	![]
end

stopStmts =
	Not(aModule + aCompoundStmt + lib.match.aList)

''')
Ejemplo n.º 26
0
parse.Transfs('''

reg32Names = ![
	"eax", "ebx", "ecx", "edx",
	"esi", "edi", "ebp", "esp"
]

reg16Names = ![
	"ax", "bx", "cx", "dx",
	"si", "di", "bp", "sp"
]

reg8Names = ![
	"ah", "bh", "ch", "dh",
	"al", "bl", "cl", "dl"
]

flagNames = ![
	"sf", "zf", "af", "pf",
	"cf", "of", "df", "if"
]

declReg32 = !Var(Int(32,NoSign),<id>,NoExpr)
declFlag = !Var(Bool,<id>,NoExpr)

stmtsPreambule =
	Concat(
		reg32Names ; Map(declReg32) ,
		flagNames ; Map(declFlag)
	)

''')
Ejemplo n.º 27
0
parse.Transfs('''

ppId = strings.tostr

ppAttr =
		Attr(name, value)
			-> H([ <ppId name>, "=", <ppId value> ])

ppAttrs =
		!H([ "[", <Map(ppAttr); box.commas>, "]" ])

ppNode =
		Node(nid, attrs, _)
			-> H([ <ppId nid>, <ppAttrs attrs> ])

ppNodes = lists.Map(ppNode)

ppNodeEdge =
		Edge(dst, attrs)
			-> H([ <ppId src>, "->", <ppId dst>, <ppAttrs attrs> ])

ppNodeEdges =
		Node(src, _, edges)
			-> <Map(ppNodeEdge) edges>

ppEdges =
	lists.MapConcat(ppNodeEdges)

ppGraph =
		Graph(nodes)
			-> V([
				H([ "digraph", " ", "{" ]),
				V( <ppNodes nodes> ),
				V( <ppEdges nodes> ),
				H([ "}" ])
			])

pprint = ppGraph

''')
Ejemplo n.º 28
0
parse.Transfs('''

Reg(reg) = !Sym(<reg>){Reg}

eax = Reg(!"eax")
ebx = Reg(!"ebx")
ecx = Reg(!"ecx")
edx = Reg(!"edx")
esi = Reg(!"esi")
edi = Reg(!"edi")
ebp = Reg(!"ebp")
esp = Reg(!"esp")

ax = Reg(!"ax")
bx = Reg(!"bx")
cx = Reg(!"cx")
dx = Reg(!"dx")
si = Reg(!"si")
di = Reg(!"di")
bp = Reg(!"bp")
sp = Reg(!"sp")

ah = Reg(!"ah")
bh = Reg(!"bh")
ch = Reg(!"ch")
dh = Reg(!"dh")
al = Reg(!"al")
bl = Reg(!"bl")
cl = Reg(!"cl")
dl = Reg(!"dl")

af = Reg(!"af")
cf = Reg(!"cf")
sf = Reg(!"sf")
of = Reg(!"of")
pf = Reg(!"pf")
zf = Reg(!"zf")
df = Reg(!"df")
if_ = Reg(!"if")

''')
Ejemplo n.º 29
0
parse.Transfs('''

applicable =
	ir.path.Applicable(
		~Module(<
			lists.One(ir.path.isSelected ; ?Label(_) )
		>)
	)

input =
	ir.path.Input2(
		ir.path.projectSelection => Label(label) ;
		![label]
	)

apply =
	[root, [label]] -> root ;
	~Module(<AtSuffix(
		{rest:
			~[Label(?label), *<AtSuffix(
				~[Ret(_,_), *<?rest ; ![]>]
			)>] ;
			![Function(Void, label, [], <project.tail>), *rest]
		}
	)>)


testApply =
	!Module([
		Asm("pre",[]),
		Label("main"),
		Assign(Int(32,Signed),Sym("eax"),Lit(Int(32,Signed),1)),
		Ret(Int(32,Signed),Sym("eax")),
		Asm("post",[]),
	]) ;
	apply [<id>, ["main"]] ;
	?Module([
		Asm("pre",[]),
		Function(Void,"main",[],[
			Assign(Int(32,Signed),Sym("eax"),Lit(Int(32,Signed),1)),
			Ret(Int(32,Signed),Sym("eax"))
		]),
		Asm("post",[]),
	])

''')
Ejemplo n.º 30
0
parse.Transfs('''

#######################################################################
# Local variable table

shared local as table

# TODO: detect local variables from scope rules
isReg = annotation.Has(?Reg)
isTmp = annotation.Has(?Tmp)

isLocalVar =
	ir.match.aSym ;
	(isReg + isTmp)

updateLocalVar =
	isLocalVar ;
	Where(local.set [_,_] )

updateLocalVars =
	local.clear ;
	traverse.AllTD(updateLocalVar)

EnterFunction(operand) =
	with local in
		updateLocalVars ;
		operand
	end

EnterModule(operand) = EnterFunction(operand)

''')