Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pyvex/lifting/libvex.py: 93%

58 statements  

« prev     ^ index     » next       coverage.py v7.3.1, created at 2023-09-25 06:15 +0000

1import logging 

2import threading 

3 

4from pyvex.errors import LiftingException 

5from pyvex.native import ffi, pvc 

6 

7from .lift_function import Lifter 

8 

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

10 

11_libvex_lock = threading.Lock() 

12 

13LIBVEX_SUPPORTED_ARCHES = { 

14 "X86", 

15 "AMD64", 

16 "MIPS32", 

17 "MIPS64", 

18 "ARM", 

19 "ARMEL", 

20 "ARMHF", 

21 "ARMCortexM", 

22 "AARCH64", 

23 "PPC32", 

24 "PPC64", 

25 "S390X", 

26 "RISCV64", 

27} 

28 

29VEX_MAX_INSTRUCTIONS = 99 

30VEX_MAX_BYTES = 5000 

31 

32 

33class VexRegisterUpdates: 

34 VexRegUpd_INVALID = 0x700 

35 VexRegUpdSpAtMemAccess = 0x701 

36 VexRegUpdUnwindregsAtMemAccess = 0x702 

37 VexRegUpdAllregsAtMemAccess = 0x703 

38 VexRegUpdAllregsAtEachInsn = 0x704 

39 VexRegUpdLdAllregsAtEachInsn = 0x705 

40 

41 

42class LibVEXLifter(Lifter): 

43 __slots__ = () 

44 

45 REQUIRE_DATA_C = True 

46 

47 @staticmethod 

48 def get_vex_log(): 

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

50 

51 def _lift(self): 

52 try: 

53 _libvex_lock.acquire() 

54 

55 pvc.log_level = log.getEffectiveLevel() 

56 vex_arch = getattr(pvc, self.irsb.arch.vex_arch) 

57 

58 if self.bytes_offset is None: 

59 self.bytes_offset = 0 

60 

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

62 max_bytes = VEX_MAX_BYTES 

63 else: 

64 max_bytes = self.max_bytes 

65 

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

67 max_inst = VEX_MAX_INSTRUCTIONS 

68 else: 

69 max_inst = self.max_inst 

70 

71 strict_block_end = self.strict_block_end 

72 if strict_block_end is None: 

73 strict_block_end = True 

74 

75 collect_data_refs = 1 if self.collect_data_refs else 0 

76 if collect_data_refs != 0 and self.load_from_ro_regions: 

77 collect_data_refs |= 2 # the second bit stores load_from_ro_regions 

78 

79 if self.cross_insn_opt: 

80 px_control = VexRegisterUpdates.VexRegUpdUnwindregsAtMemAccess 

81 else: 

82 px_control = VexRegisterUpdates.VexRegUpdLdAllregsAtEachInsn 

83 

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

85 lift_r = pvc.vex_lift( 

86 vex_arch, 

87 self.irsb.arch.vex_archinfo, 

88 self.data + self.bytes_offset, 

89 self.irsb.addr, 

90 max_inst, 

91 max_bytes, 

92 self.opt_level, 

93 self.traceflags, 

94 self.allow_arch_optimizations, 

95 strict_block_end, 

96 collect_data_refs, 

97 px_control, 

98 self.bytes_offset, 

99 ) 

100 log_str = self.get_vex_log() 

101 if lift_r == ffi.NULL: 

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

103 else: 

104 if log_str is not None: 

105 log.debug(log_str) 

106 

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

108 if self.irsb.size == 0: 

109 log.debug("raising lifting exception") 

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

111 finally: 

112 _libvex_lock.release() 

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