Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.9/dist-packages/pyvex/lifting/zerodivision.py: 25%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

20 statements  

1import copy 

2 

3from pyvex import const, expr, stmt 

4 

5from .post_processor import Postprocessor 

6 

7 

8class ZeroDivisionPostProcessor(Postprocessor): 

9 """ 

10 A postprocessor for adding zero-division checks to VEX. 

11 

12 For "div rcx", will turn: 

13 

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 

25 

26 into: 

27 

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 """ 

42 

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 

47 

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 ) 

69 

70 for i, s in reversed(insertions): 

71 self.irsb.statements.insert(i, s)