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

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

64 statements  

1import logging 

2import threading 

3from typing import TYPE_CHECKING 

4 

5from pyvex.errors import LiftingException 

6from pyvex.native import ffi, pvc 

7from pyvex.types import CLiftSource, LibvexArch 

8 

9from .lift_function import Lifter 

10 

11log = logging.getLogger("pyvex.lifting.libvex") 

12 

13_libvex_lock = threading.Lock() 

14 

15LIBVEX_SUPPORTED_ARCHES = { 

16 "X86", 

17 "AMD64", 

18 "MIPS32", 

19 "MIPS64", 

20 "ARM", 

21 "ARMEL", 

22 "ARMHF", 

23 "ARMCortexM", 

24 "AARCH64", 

25 "PPC32", 

26 "PPC64", 

27 "S390X", 

28 "RISCV64", 

29} 

30 

31VEX_MAX_INSTRUCTIONS = 99 

32VEX_MAX_BYTES = 5000 

33 

34 

35class VexRegisterUpdates: 

36 VexRegUpd_INVALID = 0x700 

37 VexRegUpdSpAtMemAccess = 0x701 

38 VexRegUpdUnwindregsAtMemAccess = 0x702 

39 VexRegUpdAllregsAtMemAccess = 0x703 

40 VexRegUpdAllregsAtEachInsn = 0x704 

41 VexRegUpdLdAllregsAtEachInsn = 0x705 

42 

43 

44class LibVEXLifter(Lifter): 

45 __slots__ = () 

46 

47 REQUIRE_DATA_C = True 

48 

49 @staticmethod 

50 def get_vex_log(): 

51 return bytes(ffi.buffer(pvc.msg_buffer, pvc.msg_current_size)).decode() if pvc.msg_buffer != ffi.NULL else None 

52 

53 def _lift(self): 

54 if TYPE_CHECKING: 

55 assert isinstance(self.irsb.arch, LibvexArch) 

56 assert isinstance(self.data, CLiftSource) 

57 try: 

58 _libvex_lock.acquire() 

59 

60 pvc.log_level = log.getEffectiveLevel() 

61 vex_arch = getattr(pvc, self.irsb.arch.vex_arch, None) 

62 assert vex_arch is not None 

63 

64 if self.bytes_offset is None: 

65 self.bytes_offset = 0 

66 

67 if self.max_bytes is None or self.max_bytes > VEX_MAX_BYTES: 

68 max_bytes = VEX_MAX_BYTES 

69 else: 

70 max_bytes = self.max_bytes 

71 

72 if self.max_inst is None or self.max_inst > VEX_MAX_INSTRUCTIONS: 

73 max_inst = VEX_MAX_INSTRUCTIONS 

74 else: 

75 max_inst = self.max_inst 

76 

77 strict_block_end = self.strict_block_end 

78 if strict_block_end is None: 

79 strict_block_end = True 

80 

81 collect_data_refs = 1 if self.collect_data_refs else 0 

82 if collect_data_refs != 0 and self.load_from_ro_regions: 

83 collect_data_refs |= 2 # the second bit stores load_from_ro_regions 

84 

85 if self.cross_insn_opt: 

86 px_control = VexRegisterUpdates.VexRegUpdUnwindregsAtMemAccess 

87 else: 

88 px_control = VexRegisterUpdates.VexRegUpdLdAllregsAtEachInsn 

89 

90 self.irsb.arch.vex_archinfo["hwcache_info"]["caches"] = ffi.NULL 

91 lift_r = pvc.vex_lift( 

92 vex_arch, 

93 self.irsb.arch.vex_archinfo, 

94 self.data + self.bytes_offset, 

95 self.irsb.addr, 

96 max_inst, 

97 max_bytes, 

98 self.opt_level, 

99 self.traceflags, 

100 self.allow_arch_optimizations, 

101 strict_block_end, 

102 collect_data_refs, 

103 px_control, 

104 self.bytes_offset, 

105 ) 

106 log_str = self.get_vex_log() 

107 if lift_r == ffi.NULL: 

108 raise LiftingException("libvex: unknown error" if log_str is None else log_str) 

109 else: 

110 if log_str is not None: 

111 log.debug(log_str) 

112 

113 self.irsb._from_c(lift_r, skip_stmts=self.skip_stmts) 

114 if self.irsb.size == 0: 

115 log.debug("raising lifting exception") 

116 raise LiftingException("libvex: could not decode any instructions @ 0x%x" % self.addr) 

117 finally: 

118 _libvex_lock.release() 

119 self.irsb.arch.vex_archinfo["hwcache_info"]["caches"] = None