Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pyvex/lifting/zerodivision.py: 25%
20 statements
« prev ^ index » next coverage.py v7.3.1, created at 2023-09-25 06:15 +0000
« prev ^ index » next coverage.py v7.3.1, created at 2023-09-25 06:15 +0000
1import copy
3from pyvex import const, expr, stmt
5from .post_processor import Postprocessor
8class ZeroDivisionPostProcessor(Postprocessor):
9 """
10 A postprocessor for adding zero-division checks to VEX.
12 For "div rcx", will turn:
14 00 | ------ IMark(0x8000, 3, 0) ------
15 01 | t0 = GET:I64(rcx)
16 02 | t1 = GET:I64(rax)
17 03 | t2 = GET:I64(rdx)
18 04 | t3 = 64HLto128(t2,t1)
19 05 | t4 = DivModU128to64(t3,t0)
20 06 | t5 = 128to64(t4)
21 07 | PUT(rax) = t5
22 08 | t6 = 128HIto64(t4)
23 09 | PUT(rdx) = t6
24 NEXT: PUT(rip) = 0x0000000000008003; Ijk_Boring
26 into:
28 00 | ------ IMark(0x8000, 3, 0) ------
29 01 | t0 = GET:I64(rcx)
30 02 | t4 = GET:I64(rax)
31 03 | t5 = GET:I64(rdx)
32 04 | t3 = 64HLto128(t5,t4)
33 05 | t9 = CmpEQ(t0,0x0000000000000000)
34 06 | if (t9) { PUT(pc) = 0x8000; Ijk_SigFPE_IntDiv }
35 07 | t2 = DivModU128to64(t3,t0)
36 08 | t6 = 128to64(t2)
37 09 | PUT(rax) = t6
38 10 | t7 = 128HIto64(t2)
39 11 | PUT(rdx) = t7
40 NEXT: PUT(rip) = 0x0000000000008003; Ijk_Boring
41 """
43 def postprocess(self):
44 if self.irsb.statements is None:
45 # This is an optimized IRSB. We cannot really post-process it.
46 return
48 insertions = []
49 last_ip = 0
50 for i, s in enumerate(self.irsb.statements):
51 if s.tag == "Ist_IMark":
52 last_ip = s.addr
53 if s.tag == "Ist_WrTmp" and s.data.tag == "Iex_Binop" and ("Div" in s.data.op or "Mod" in s.data.op):
54 arg_size = s.data.args[1].result_size(self.irsb.tyenv)
55 cmp_args = [copy.copy(s.data.args[1]), expr.Const(const.vex_int_class(arg_size)(0))]
56 cmp_tmp = self.irsb.tyenv.add("Ity_I1")
57 insertions.append((i, stmt.WrTmp(cmp_tmp, expr.Binop("Iop_CmpEQ%d" % arg_size, cmp_args))))
58 insertions.append(
59 (
60 i,
61 stmt.Exit(
62 expr.RdTmp.get_instance(cmp_tmp),
63 const.vex_int_class(self.irsb.arch.bits)(last_ip),
64 "Ijk_SigFPE_IntDiv",
65 self.irsb.offsIP,
66 ),
67 )
68 )
70 for i, s in reversed(insertions):
71 self.irsb.statements.insert(i, s)