angr 9.2.101__py3-none-win_amd64.whl → 9.2.103__py3-none-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of angr might be problematic. Click here for more details.

Files changed (240) hide show
  1. angr/__init__.py +1 -1
  2. angr/analyses/analysis.py +7 -6
  3. angr/analyses/calling_convention.py +33 -35
  4. angr/analyses/cdg.py +2 -4
  5. angr/analyses/cfg/cfb.py +4 -3
  6. angr/analyses/cfg/cfg_base.py +14 -14
  7. angr/analyses/cfg/cfg_emulated.py +3 -4
  8. angr/analyses/cfg/cfg_fast.py +46 -46
  9. angr/analyses/cfg/cfg_fast_soot.py +1 -2
  10. angr/analyses/cfg/cfg_job_base.py +2 -2
  11. angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +14 -13
  12. angr/analyses/cfg/indirect_jump_resolvers/mips_elf_fast.py +5 -5
  13. angr/analyses/cfg_slice_to_sink/cfg_slice_to_sink.py +3 -3
  14. angr/analyses/complete_calling_conventions.py +13 -12
  15. angr/analyses/data_dep/data_dependency_analysis.py +24 -24
  16. angr/analyses/data_dep/dep_nodes.py +3 -3
  17. angr/analyses/ddg.py +1 -2
  18. angr/analyses/decompiler/ail_simplifier.py +35 -34
  19. angr/analyses/decompiler/block_io_finder.py +20 -20
  20. angr/analyses/decompiler/block_similarity.py +4 -6
  21. angr/analyses/decompiler/block_simplifier.py +17 -16
  22. angr/analyses/decompiler/callsite_maker.py +25 -10
  23. angr/analyses/decompiler/ccall_rewriters/amd64_ccalls.py +1 -3
  24. angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +2 -4
  25. angr/analyses/decompiler/clinic.py +250 -45
  26. angr/analyses/decompiler/condition_processor.py +15 -8
  27. angr/analyses/decompiler/decompilation_cache.py +7 -7
  28. angr/analyses/decompiler/decompilation_options.py +4 -4
  29. angr/analyses/decompiler/decompiler.py +19 -15
  30. angr/analyses/decompiler/expression_counters.py +10 -9
  31. angr/analyses/decompiler/goto_manager.py +2 -4
  32. angr/analyses/decompiler/graph_region.py +9 -9
  33. angr/analyses/decompiler/jump_target_collector.py +1 -2
  34. angr/analyses/decompiler/optimization_passes/__init__.py +4 -3
  35. angr/analyses/decompiler/optimization_passes/code_motion.py +5 -6
  36. angr/analyses/decompiler/optimization_passes/const_derefs.py +4 -4
  37. angr/analyses/decompiler/optimization_passes/deadblock_remover.py +73 -0
  38. angr/analyses/decompiler/optimization_passes/engine_base.py +25 -3
  39. angr/analyses/decompiler/optimization_passes/expr_op_swapper.py +6 -5
  40. angr/analyses/decompiler/optimization_passes/flip_boolean_cmp.py +2 -2
  41. angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +3 -0
  42. angr/analyses/decompiler/optimization_passes/ite_expr_converter.py +2 -2
  43. angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +17 -17
  44. angr/analyses/decompiler/optimization_passes/optimization_pass.py +12 -13
  45. angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py +25 -21
  46. angr/analyses/decompiler/optimization_passes/ret_addr_save_simplifier.py +3 -3
  47. angr/analyses/decompiler/optimization_passes/ret_deduplicator.py +1 -2
  48. angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +7 -7
  49. angr/analyses/decompiler/optimization_passes/spilled_register_finder.py +18 -0
  50. angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +2 -3
  51. angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +1 -2
  52. angr/analyses/decompiler/optimization_passes/x86_gcc_getpc_simplifier.py +2 -2
  53. angr/analyses/decompiler/peephole_optimizations/__init__.py +4 -3
  54. angr/analyses/decompiler/peephole_optimizations/base.py +13 -15
  55. angr/analyses/decompiler/peephole_optimizations/bswap.py +1 -3
  56. angr/analyses/decompiler/peephole_optimizations/cmpord_rewriter.py +72 -0
  57. angr/analyses/decompiler/peephole_optimizations/const_mull_a_shift.py +1 -2
  58. angr/analyses/decompiler/peephole_optimizations/eager_eval.py +1 -1
  59. angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py +5 -10
  60. angr/analyses/decompiler/peephole_optimizations/inlined_strcpy_consolidation.py +3 -4
  61. angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy.py +7 -10
  62. angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +2 -3
  63. angr/analyses/decompiler/peephole_optimizations/sar_to_signed_div.py +1 -2
  64. angr/analyses/decompiler/peephole_optimizations/tidy_stack_addr.py +4 -4
  65. angr/analyses/decompiler/redundant_label_remover.py +4 -5
  66. angr/analyses/decompiler/region_identifier.py +4 -5
  67. angr/analyses/decompiler/region_simplifiers/cascading_cond_transformer.py +1 -2
  68. angr/analyses/decompiler/region_simplifiers/expr_folding.py +19 -20
  69. angr/analyses/decompiler/region_simplifiers/goto.py +2 -3
  70. angr/analyses/decompiler/region_simplifiers/loop.py +1 -2
  71. angr/analyses/decompiler/region_simplifiers/node_address_finder.py +1 -2
  72. angr/analyses/decompiler/region_simplifiers/region_simplifier.py +1 -3
  73. angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +19 -19
  74. angr/analyses/decompiler/return_maker.py +1 -2
  75. angr/analyses/decompiler/structured_codegen/base.py +5 -6
  76. angr/analyses/decompiler/structured_codegen/c.py +39 -38
  77. angr/analyses/decompiler/structuring/__init__.py +1 -1
  78. angr/analyses/decompiler/structuring/dream.py +17 -16
  79. angr/analyses/decompiler/structuring/phoenix.py +45 -46
  80. angr/analyses/decompiler/structuring/recursive_structurer.py +4 -4
  81. angr/analyses/decompiler/structuring/structurer_base.py +16 -15
  82. angr/analyses/decompiler/structuring/structurer_nodes.py +10 -9
  83. angr/analyses/decompiler/utils.py +17 -16
  84. angr/analyses/disassembly.py +7 -6
  85. angr/analyses/flirt.py +9 -9
  86. angr/analyses/forward_analysis/forward_analysis.py +15 -14
  87. angr/analyses/forward_analysis/visitors/function_graph.py +1 -2
  88. angr/analyses/forward_analysis/visitors/graph.py +16 -15
  89. angr/analyses/propagator/engine_ail.py +30 -26
  90. angr/analyses/propagator/outdated_definition_walker.py +8 -7
  91. angr/analyses/propagator/propagator.py +11 -13
  92. angr/analyses/proximity_graph.py +21 -21
  93. angr/analyses/reaching_definitions/__init__.py +3 -3
  94. angr/analyses/reaching_definitions/call_trace.py +3 -6
  95. angr/analyses/reaching_definitions/dep_graph.py +41 -48
  96. angr/analyses/reaching_definitions/engine_ail.py +11 -5
  97. angr/analyses/reaching_definitions/engine_vex.py +9 -8
  98. angr/analyses/reaching_definitions/function_handler.py +51 -34
  99. angr/analyses/reaching_definitions/heap_allocator.py +3 -4
  100. angr/analyses/reaching_definitions/rd_initializer.py +8 -8
  101. angr/analyses/reaching_definitions/rd_state.py +57 -58
  102. angr/analyses/reaching_definitions/reaching_definitions.py +18 -17
  103. angr/analyses/reaching_definitions/subject.py +2 -3
  104. angr/analyses/stack_pointer_tracker.py +15 -6
  105. angr/analyses/typehoon/dfa.py +4 -4
  106. angr/analyses/typehoon/simple_solver.py +48 -52
  107. angr/analyses/typehoon/translator.py +3 -6
  108. angr/analyses/typehoon/typeconsts.py +13 -14
  109. angr/analyses/typehoon/typehoon.py +9 -9
  110. angr/analyses/typehoon/typevars.py +18 -17
  111. angr/analyses/variable_recovery/engine_ail.py +5 -5
  112. angr/analyses/variable_recovery/engine_base.py +25 -21
  113. angr/analyses/variable_recovery/irsb_scanner.py +8 -9
  114. angr/analyses/variable_recovery/variable_recovery.py +1 -2
  115. angr/analyses/variable_recovery/variable_recovery_base.py +14 -13
  116. angr/analyses/variable_recovery/variable_recovery_fast.py +8 -8
  117. angr/analyses/veritesting.py +1 -2
  118. angr/analyses/vfg.py +57 -56
  119. angr/analyses/xrefs.py +1 -2
  120. angr/angrdb/db.py +7 -7
  121. angr/angrdb/serializers/kb.py +16 -13
  122. angr/angrdb/serializers/loader.py +1 -2
  123. angr/angrdb/serializers/structured_code.py +2 -2
  124. angr/annocfg.py +1 -2
  125. angr/block.py +16 -6
  126. angr/calling_conventions.py +27 -27
  127. angr/code_location.py +8 -8
  128. angr/codenode.py +1 -2
  129. angr/concretization_strategies/max.py +1 -3
  130. angr/distributed/server.py +1 -3
  131. angr/distributed/worker.py +1 -2
  132. angr/engines/engine.py +2 -3
  133. angr/engines/light/engine.py +4 -4
  134. angr/engines/pcode/behavior.py +20 -2
  135. angr/engines/pcode/emulate.py +1 -1
  136. angr/engines/pcode/engine.py +7 -7
  137. angr/engines/pcode/lifter.py +78 -77
  138. angr/engines/vex/claripy/ccall.py +1 -2
  139. angr/engines/vex/claripy/datalayer.py +1 -2
  140. angr/engines/vex/light/light.py +1 -2
  141. angr/exploration_techniques/tracer.py +4 -4
  142. angr/factory.py +12 -15
  143. angr/flirt/__init__.py +8 -8
  144. angr/flirt/build_sig.py +2 -3
  145. angr/keyed_region.py +2 -2
  146. angr/knowledge_base/knowledge_base.py +3 -3
  147. angr/knowledge_plugins/callsite_prototypes.py +4 -6
  148. angr/knowledge_plugins/cfg/cfg_manager.py +19 -6
  149. angr/knowledge_plugins/cfg/cfg_model.py +26 -27
  150. angr/knowledge_plugins/cfg/cfg_node.py +2 -2
  151. angr/knowledge_plugins/cfg/indirect_jump.py +6 -8
  152. angr/knowledge_plugins/cfg/memory_data.py +8 -9
  153. angr/knowledge_plugins/custom_strings.py +1 -3
  154. angr/knowledge_plugins/debug_variables.py +2 -2
  155. angr/knowledge_plugins/functions/function.py +21 -22
  156. angr/knowledge_plugins/functions/function_manager.py +5 -5
  157. angr/knowledge_plugins/indirect_jumps.py +1 -3
  158. angr/knowledge_plugins/key_definitions/atoms.py +7 -7
  159. angr/knowledge_plugins/key_definitions/definition.py +14 -14
  160. angr/knowledge_plugins/key_definitions/environment.py +5 -7
  161. angr/knowledge_plugins/key_definitions/heap_address.py +1 -3
  162. angr/knowledge_plugins/key_definitions/key_definition_manager.py +3 -2
  163. angr/knowledge_plugins/key_definitions/live_definitions.py +60 -59
  164. angr/knowledge_plugins/key_definitions/liveness.py +16 -16
  165. angr/knowledge_plugins/key_definitions/rd_model.py +15 -15
  166. angr/knowledge_plugins/key_definitions/uses.py +11 -11
  167. angr/knowledge_plugins/patches.py +4 -8
  168. angr/knowledge_plugins/propagations/prop_value.py +10 -9
  169. angr/knowledge_plugins/propagations/propagation_manager.py +3 -5
  170. angr/knowledge_plugins/propagations/propagation_model.py +9 -9
  171. angr/knowledge_plugins/propagations/states.py +52 -22
  172. angr/knowledge_plugins/structured_code/manager.py +2 -2
  173. angr/knowledge_plugins/sync/sync_controller.py +3 -3
  174. angr/knowledge_plugins/variables/variable_access.py +4 -4
  175. angr/knowledge_plugins/variables/variable_manager.py +56 -39
  176. angr/knowledge_plugins/xrefs/xref.py +9 -11
  177. angr/knowledge_plugins/xrefs/xref_manager.py +3 -4
  178. angr/lib/angr_native.dll +0 -0
  179. angr/misc/ansi.py +1 -2
  180. angr/misc/autoimport.py +3 -3
  181. angr/misc/plugins.py +9 -9
  182. angr/procedures/definitions/__init__.py +16 -16
  183. angr/procedures/definitions/linux_kernel.py +1 -1
  184. angr/procedures/definitions/parse_win32json.py +1 -1
  185. angr/procedures/java_jni/__init__.py +1 -1
  186. angr/procedures/java_jni/array_operations.py +1 -2
  187. angr/procedures/java_jni/method_calls.py +1 -2
  188. angr/procedures/posix/inet_ntoa.py +1 -2
  189. angr/procedures/stubs/format_parser.py +3 -3
  190. angr/project.py +13 -11
  191. angr/sim_manager.py +12 -12
  192. angr/sim_procedure.py +7 -3
  193. angr/sim_state.py +2 -2
  194. angr/sim_type.py +60 -45
  195. angr/sim_variable.py +5 -5
  196. angr/simos/simos.py +1 -2
  197. angr/simos/userland.py +1 -2
  198. angr/state_plugins/callstack.py +3 -2
  199. angr/state_plugins/history.py +1 -2
  200. angr/state_plugins/solver.py +34 -34
  201. angr/storage/memory_mixins/__init__.py +4 -3
  202. angr/storage/memory_mixins/actions_mixin.py +1 -3
  203. angr/storage/memory_mixins/address_concretization_mixin.py +1 -3
  204. angr/storage/memory_mixins/convenient_mappings_mixin.py +3 -4
  205. angr/storage/memory_mixins/default_filler_mixin.py +1 -1
  206. angr/storage/memory_mixins/label_merger_mixin.py +2 -2
  207. angr/storage/memory_mixins/multi_value_merger_mixin.py +4 -3
  208. angr/storage/memory_mixins/paged_memory/page_backer_mixins.py +9 -8
  209. angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +12 -11
  210. angr/storage/memory_mixins/paged_memory/pages/cooperation.py +8 -8
  211. angr/storage/memory_mixins/paged_memory/pages/history_tracking_mixin.py +2 -3
  212. angr/storage/memory_mixins/paged_memory/pages/list_page.py +10 -11
  213. angr/storage/memory_mixins/paged_memory/pages/multi_values.py +11 -10
  214. angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +18 -17
  215. angr/storage/memory_mixins/paged_memory/pages/ultra_page.py +12 -11
  216. angr/storage/memory_mixins/regioned_memory/abstract_address_descriptor.py +3 -3
  217. angr/storage/memory_mixins/regioned_memory/abstract_merger_mixin.py +3 -2
  218. angr/storage/memory_mixins/regioned_memory/region_data.py +1 -2
  219. angr/storage/memory_mixins/regioned_memory/region_meta_mixin.py +2 -2
  220. angr/storage/memory_mixins/regioned_memory/regioned_address_concretization_mixin.py +3 -3
  221. angr/storage/memory_mixins/regioned_memory/regioned_memory_mixin.py +18 -21
  222. angr/storage/memory_mixins/size_resolution_mixin.py +1 -2
  223. angr/storage/memory_mixins/symbolic_merger_mixin.py +3 -2
  224. angr/storage/memory_mixins/top_merger_mixin.py +3 -2
  225. angr/storage/memory_object.py +2 -4
  226. angr/utils/algo.py +3 -2
  227. angr/utils/dynamic_dictlist.py +5 -5
  228. angr/utils/formatting.py +4 -4
  229. angr/utils/funcid.py +1 -2
  230. angr/utils/graph.py +5 -6
  231. angr/utils/library.py +5 -5
  232. angr/utils/mp.py +5 -4
  233. angr/utils/segment_list.py +3 -4
  234. angr/utils/typing.py +3 -2
  235. {angr-9.2.101.dist-info → angr-9.2.103.dist-info}/METADATA +9 -11
  236. {angr-9.2.101.dist-info → angr-9.2.103.dist-info}/RECORD +240 -237
  237. {angr-9.2.101.dist-info → angr-9.2.103.dist-info}/LICENSE +0 -0
  238. {angr-9.2.101.dist-info → angr-9.2.103.dist-info}/WHEEL +0 -0
  239. {angr-9.2.101.dist-info → angr-9.2.103.dist-info}/entry_points.txt +0 -0
  240. {angr-9.2.101.dist-info → angr-9.2.103.dist-info}/top_level.txt +0 -0
angr/project.py CHANGED
@@ -6,7 +6,7 @@ import pickle
6
6
  import string
7
7
  from collections import defaultdict
8
8
  from pathlib import Path
9
- from typing import Dict, Any, Optional, Union, cast
9
+ from typing import Any, cast
10
10
 
11
11
  import archinfo
12
12
  from archinfo.arch_soot import SootAddressDescriptor, ArchSoot
@@ -19,7 +19,7 @@ from .errors import AngrNoPluginError
19
19
  l = logging.getLogger(name=__name__)
20
20
 
21
21
 
22
- def load_shellcode(shellcode: Union[bytes, str], arch, start_offset=0, load_address=0, thumb=False, **kwargs):
22
+ def load_shellcode(shellcode: bytes | str, arch, start_offset=0, load_address=0, thumb=False, **kwargs):
23
23
  """
24
24
  Load a new project based on a snippet of assembly or bytecode.
25
25
 
@@ -107,10 +107,10 @@ class Project:
107
107
  arch=None,
108
108
  simos=None,
109
109
  engine=None,
110
- load_options: Optional[Dict[str, Any]] = None,
110
+ load_options: dict[str, Any] | None = None,
111
111
  translation_cache=True,
112
112
  selfmodifying_code: bool = False,
113
- support_selfmodifying_code: Optional[bool] = None, # deprecated. use selfmodifying_code instead
113
+ support_selfmodifying_code: bool | None = None, # deprecated. use selfmodifying_code instead
114
114
  store_function=None,
115
115
  load_function=None,
116
116
  analyses_preset=None,
@@ -461,7 +461,7 @@ class Project:
461
461
  #
462
462
 
463
463
  # pylint: disable=inconsistent-return-statements
464
- def hook(self, addr, hook=None, length=0, kwargs=None, replace: Optional[bool] = False):
464
+ def hook(self, addr, hook=None, length=0, kwargs=None, replace: bool | None = False):
465
465
  """
466
466
  Hook a section of code with a custom function. This is used internally to provide symbolic
467
467
  summaries of library functions, and can be used to instrument execution or to modify
@@ -491,7 +491,7 @@ class Project:
491
491
  """
492
492
  if hook is None:
493
493
  # if we haven't been passed a thing to hook with, assume we're being used as a decorator
494
- return self._hook_decorator(addr, length=length, kwargs=kwargs)
494
+ return self._hook_decorator(addr, length=length, kwargs=kwargs, replace=replace)
495
495
 
496
496
  if kwargs is None:
497
497
  kwargs = {}
@@ -534,7 +534,7 @@ class Project:
534
534
  """
535
535
  return addr in self._sim_procedures
536
536
 
537
- def hooked_by(self, addr) -> Optional[SimProcedure]:
537
+ def hooked_by(self, addr) -> SimProcedure | None:
538
538
  """
539
539
  Returns the current hook for `addr`.
540
540
 
@@ -561,7 +561,7 @@ class Project:
561
561
 
562
562
  del self._sim_procedures[addr]
563
563
 
564
- def hook_symbol(self, symbol_name, simproc, kwargs=None, replace: Optional[bool] = None):
564
+ def hook_symbol(self, symbol_name, simproc, kwargs=None, replace: bool | None = None):
565
565
  """
566
566
  Resolve a dependency in a binary. Looks up the address of the given symbol, and then hooks that
567
567
  address. If the symbol was not available in the loaded libraries, this address may be provided
@@ -612,7 +612,7 @@ class Project:
612
612
  self.hook(hook_addr, simproc, kwargs=kwargs, replace=replace)
613
613
  return hook_addr
614
614
 
615
- def symbol_hooked_by(self, symbol_name) -> Optional[SimProcedure]:
615
+ def symbol_hooked_by(self, symbol_name) -> SimProcedure | None:
616
616
  """
617
617
  Return the SimProcedure, if it exists, for the given symbol name.
618
618
 
@@ -625,6 +625,8 @@ class Project:
625
625
  l.warning("Could not find symbol %s", symbol_name)
626
626
  return None
627
627
  hook_addr, _ = self.simos.prepare_function_symbol(symbol_name, basic_addr=sym.rebased_addr)
628
+ if not self.is_hooked(hook_addr):
629
+ return None
628
630
  return self.hooked_by(hook_addr)
629
631
 
630
632
  def is_symbol_hooked(self, symbol_name):
@@ -726,7 +728,7 @@ class Project:
726
728
  # Private methods related to hooking
727
729
  #
728
730
 
729
- def _hook_decorator(self, addr, length=0, kwargs=None):
731
+ def _hook_decorator(self, addr, length=0, kwargs=None, replace=False):
730
732
  """
731
733
  Return a function decorator that allows easy hooking. Please refer to hook() for its usage.
732
734
 
@@ -734,7 +736,7 @@ class Project:
734
736
  """
735
737
 
736
738
  def hook_decorator(func):
737
- self.hook(addr, func, length=length, kwargs=kwargs)
739
+ self.hook(addr, func, length=length, kwargs=kwargs, replace=replace)
738
740
  return func
739
741
 
740
742
  return hook_decorator
angr/sim_manager.py CHANGED
@@ -2,7 +2,7 @@ import sys
2
2
  import itertools
3
3
  import types
4
4
  from collections import defaultdict
5
- from typing import List, Tuple, DefaultDict
5
+ from typing import DefaultDict
6
6
  import logging
7
7
 
8
8
  import claripy
@@ -65,7 +65,7 @@ class SimulationManager:
65
65
  ALL = "_ALL"
66
66
  DROP = "_DROP"
67
67
 
68
- _integral_stashes: Tuple[str] = ("active", "stashed", "pruned", "unsat", "errored", "deadended", "unconstrained")
68
+ _integral_stashes: tuple[str] = ("active", "stashed", "pruned", "unsat", "errored", "deadended", "unconstrained")
69
69
 
70
70
  def __init__(
71
71
  self,
@@ -91,7 +91,7 @@ class SimulationManager:
91
91
 
92
92
  if stashes is None:
93
93
  stashes = self._create_integral_stashes()
94
- self._stashes: DefaultDict[str, List["SimState"]] = stashes
94
+ self._stashes: DefaultDict[str, list["SimState"]] = stashes
95
95
  self._hierarchy = StateHierarchy() if hierarchy is None else hierarchy
96
96
  self._save_unsat = save_unsat
97
97
  self._auto_drop = {
@@ -164,13 +164,13 @@ class SimulationManager:
164
164
  except AttributeError:
165
165
  return SimulationManager._fetch_states(self, stash=item)
166
166
 
167
- active: List[SimState]
168
- stashed: List[SimState]
169
- pruned: List[SimState]
170
- unsat: List[SimState]
171
- deadended: List[SimState]
172
- unconstrained: List[SimState]
173
- found: List[SimState]
167
+ active: list[SimState]
168
+ stashed: list[SimState]
169
+ pruned: list[SimState]
170
+ unsat: list[SimState]
171
+ deadended: list[SimState]
172
+ unconstrained: list[SimState]
173
+ found: list[SimState]
174
174
  one_active: SimState
175
175
  one_stashed: SimState
176
176
  one_pruned: SimState
@@ -193,7 +193,7 @@ class SimulationManager:
193
193
  return self._errored
194
194
 
195
195
  @property
196
- def stashes(self) -> DefaultDict[str, List["SimState"]]:
196
+ def stashes(self) -> DefaultDict[str, list["SimState"]]:
197
197
  return self._stashes
198
198
 
199
199
  def mulpyplex(self, *stashes):
@@ -894,7 +894,7 @@ class SimulationManager:
894
894
  # ...
895
895
  #
896
896
 
897
- def _create_integral_stashes(self) -> DefaultDict[str, List["SimState"]]:
897
+ def _create_integral_stashes(self) -> DefaultDict[str, list["SimState"]]:
898
898
  stashes = defaultdict(list)
899
899
  stashes.update({name: [] for name in self._integral_stashes})
900
900
  return stashes
angr/sim_procedure.py CHANGED
@@ -2,7 +2,7 @@ import inspect
2
2
  import copy
3
3
  import itertools
4
4
  import logging
5
- from typing import TYPE_CHECKING, Union, Tuple
5
+ from typing import TYPE_CHECKING
6
6
 
7
7
  import claripy
8
8
  from cle import SymbolType
@@ -165,7 +165,7 @@ class SimProcedure:
165
165
  self.ret_expr = None
166
166
  self.call_ret_expr = None
167
167
  self.inhibit_autoret = None
168
- self.arg_session: Union[None, ArgSession, int] = None
168
+ self.arg_session: None | ArgSession | int = None
169
169
 
170
170
  def __repr__(self):
171
171
  return "<SimProcedure %s%s%s%s%s>" % self._describe_me()
@@ -321,7 +321,7 @@ class SimProcedure:
321
321
  IS_FUNCTION = True
322
322
  ARGS_MISMATCH = False
323
323
  ALT_NAMES = None # alternative names
324
- local_vars: Tuple[str, ...] = ()
324
+ local_vars: tuple[str, ...] = ()
325
325
 
326
326
  def run(self, *args, **kwargs): # pylint: disable=unused-argument
327
327
  """
@@ -520,6 +520,10 @@ class SimProcedure:
520
520
 
521
521
  self._exit_action(call_state, addr)
522
522
  self.successors.add_successor(call_state, addr, call_state.solver.true, jumpkind)
523
+ if jumpkind != "Ijk_Call":
524
+ call_state.callstack.call(
525
+ self.state.addr, addr, retn_target=ret_addr, stack_pointer=call_state.regs.sp.concrete_value
526
+ )
523
527
 
524
528
  if o.DO_RET_EMULATION in self.state.options:
525
529
  # we need to set up the call because the continuation will try to tear it down
angr/sim_state.py CHANGED
@@ -5,7 +5,7 @@ import weakref
5
5
 
6
6
  import logging
7
7
 
8
- from typing import Type, TypeVar, TYPE_CHECKING
8
+ from typing import TypeVar, TYPE_CHECKING
9
9
 
10
10
  from archinfo import Arch
11
11
 
@@ -429,7 +429,7 @@ class SimState(PluginHub):
429
429
  self._set_plugin_state(plugin, inhibit_init=inhibit_init)
430
430
  return super().register_plugin(name, plugin)
431
431
 
432
- def _init_plugin(self, plugin_cls: Type[SimStatePlugin]) -> SimStatePlugin:
432
+ def _init_plugin(self, plugin_cls: type[SimStatePlugin]) -> SimStatePlugin:
433
433
  plugin = plugin_cls()
434
434
  self._set_plugin_state(plugin)
435
435
  return plugin
angr/sim_type.py CHANGED
@@ -1,8 +1,10 @@
1
1
  # pylint:disable=abstract-method,line-too-long,missing-class-docstring
2
+ from __future__ import annotations
3
+
2
4
  from collections import OrderedDict, defaultdict, ChainMap
3
5
  import copy
4
6
  import re
5
- from typing import Optional, Dict, Any, Tuple, List, Union, Type, TYPE_CHECKING
7
+ from typing import Any, TYPE_CHECKING
6
8
  import logging
7
9
 
8
10
  try:
@@ -50,6 +52,14 @@ class SimType:
50
52
  """
51
53
  self.label = label
52
54
 
55
+ @staticmethod
56
+ def _simtype_eq(self_type: SimType, other: SimType, avoid: dict[str, set[SimType]] | None) -> bool:
57
+ if self_type is other:
58
+ return True
59
+ if avoid is not None and self_type in avoid["self"] and other in avoid["other"]:
60
+ return True
61
+ return self_type.__eq__(other, avoid=avoid) # pylint:disable=unnecessary-dunder-call
62
+
53
63
  def __eq__(self, other, avoid=None):
54
64
  if type(self) != type(other):
55
65
  return False
@@ -60,12 +70,18 @@ class SimType:
60
70
  attr_self = getattr(self, attr)
61
71
  attr_other = getattr(other, attr)
62
72
  if isinstance(attr_self, SimType):
63
- if attr_other is attr_self:
64
- return True
65
- if avoid is not None and attr_self in avoid["self"] and attr_other in avoid["other"]:
66
- continue
67
- if not attr_self.__eq__(attr_other, avoid=avoid):
73
+ if not SimType._simtype_eq(attr_self, attr_other, avoid):
74
+ return False
75
+ elif isinstance(attr_self, (list, tuple)) and isinstance(attr_other, (list, tuple)):
76
+ if len(attr_self) != len(attr_other):
68
77
  return False
78
+ for a, b in zip(attr_self, attr_other):
79
+ if isinstance(a, SimType) and isinstance(b, SimType):
80
+ if SimType._simtype_eq(a, b, avoid) is False:
81
+ return False
82
+ else:
83
+ if a != b:
84
+ return False
69
85
  else:
70
86
  if attr_self != attr_other:
71
87
  return False
@@ -125,7 +141,7 @@ class SimType:
125
141
  def _init_str(self):
126
142
  return f"NotImplemented({self.__class__.__name__})"
127
143
 
128
- def c_repr(self, name=None, full=0, memo=None, indent=0):
144
+ def c_repr(self, name=None, full=0, memo=None, indent=0): # pylint:disable=unused-argument
129
145
  if name is None:
130
146
  return repr(self)
131
147
  else:
@@ -210,7 +226,7 @@ class NamedTypeMixin:
210
226
  unqualified name of the type.
211
227
  """
212
228
 
213
- def __init__(self, *args, name: Optional[str] = None, **kwargs):
229
+ def __init__(self, *args, name: str | None = None, **kwargs):
214
230
  super().__init__(*args, **kwargs)
215
231
  self._name = name
216
232
 
@@ -239,9 +255,6 @@ class SimTypeBottom(SimType):
239
255
 
240
256
  _base_name = "bot"
241
257
 
242
- def __init__(self, label=None):
243
- super().__init__(label)
244
-
245
258
  def __repr__(self):
246
259
  return self.label or "BOT"
247
260
 
@@ -413,8 +426,8 @@ class SimTypeInt(SimTypeReg):
413
426
  raise ValueError("Can't tell my size without an arch!")
414
427
  try:
415
428
  return self._arch.sizeof[self._base_name]
416
- except KeyError:
417
- raise ValueError(f"Arch {self._arch.name} doesn't have its {self._base_name} type defined!")
429
+ except KeyError as ex:
430
+ raise ValueError(f"Arch {self._arch.name} doesn't have its {self._base_name} type defined!") from ex
418
431
 
419
432
  def extract(self, state, addr, concrete=False):
420
433
  out = state.memory.load(addr, self.size // state.arch.byte_width, endness=state.arch.memory_endness)
@@ -723,7 +736,7 @@ class SimTypeArray(SimType):
723
736
  """
724
737
  super().__init__(label=label)
725
738
  self.elem_type: SimType = elem_type
726
- self.length: Optional[int] = length
739
+ self.length: int | None = length
727
740
 
728
741
  def __repr__(self):
729
742
  return "{}[{}]".format(self.elem_type, "" if self.length is None else self.length)
@@ -790,7 +803,7 @@ class SimTypeString(NamedTypeMixin, SimTypeArray):
790
803
 
791
804
  _fields = SimTypeArray._fields + ("length",)
792
805
 
793
- def __init__(self, length=None, label=None, name: Optional[str] = None):
806
+ def __init__(self, length=None, label=None, name: str | None = None):
794
807
  """
795
808
  :param label: The type label.
796
809
  :param length: An expression of the length of the string, if known.
@@ -800,7 +813,7 @@ class SimTypeString(NamedTypeMixin, SimTypeArray):
800
813
  def __repr__(self):
801
814
  return "string_t"
802
815
 
803
- def extract(self, state: "SimState", addr, concrete=False):
816
+ def extract(self, state: SimState, addr, concrete=False):
804
817
  if self.length is None:
805
818
  out = None
806
819
  last_byte = state.memory.load(addr, size=1)
@@ -848,7 +861,7 @@ class SimTypeWString(NamedTypeMixin, SimTypeArray):
848
861
 
849
862
  _fields = SimTypeArray._fields + ("length",)
850
863
 
851
- def __init__(self, length=None, label=None, name: Optional[str] = None):
864
+ def __init__(self, length=None, label=None, name: str | None = None):
852
865
  super().__init__(SimTypeNum(16, False), label=label, length=length, name=name)
853
866
 
854
867
  def __repr__(self):
@@ -909,7 +922,7 @@ class SimTypeFunction(SimType):
909
922
  _fields = ("args", "returnty")
910
923
  base = False
911
924
 
912
- def __init__(self, args: List[SimType], returnty: Optional[SimType], label=None, arg_names=None, variadic=False):
925
+ def __init__(self, args: list[SimType], returnty: SimType | None, label=None, arg_names=None, variadic=False):
913
926
  """
914
927
  :param label: The type label
915
928
  :param args: A tuple of types representing the arguments to the function
@@ -917,8 +930,8 @@ class SimTypeFunction(SimType):
917
930
  :param variadic: Whether the function accepts varargs
918
931
  """
919
932
  super().__init__(label=label)
920
- self.args: List[SimType] = args
921
- self.returnty: Optional[SimType] = returnty
933
+ self.args: list[SimType] = args
934
+ self.returnty: SimType | None = returnty
922
935
  self.arg_names = arg_names if arg_names else ()
923
936
  self.variadic = variadic
924
937
 
@@ -931,14 +944,18 @@ class SimTypeFunction(SimType):
931
944
  argstrs.append("...")
932
945
  return "({}) -> {}".format(", ".join(argstrs), self.returnty)
933
946
 
934
- def c_repr(self, name=None, full=0, memo=None, indent=0):
947
+ def c_repr(self, name=None, full=0, memo=None, indent=0, name_parens: bool = True):
935
948
  formatted_args = [
936
949
  a.c_repr(n, full - 1, memo, indent)
937
950
  for a, n in zip(self.args, self.arg_names if self.arg_names and full else (None,) * len(self.args))
938
951
  ]
939
952
  if self.variadic:
940
953
  formatted_args.append("...")
941
- proto = f"({name or ''})({', '.join(formatted_args)})"
954
+ if name_parens:
955
+ name_str = f"({name or ''})"
956
+ else:
957
+ name_str = name or ""
958
+ proto = f"{name_str}({', '.join(formatted_args)})"
942
959
  return f"void {proto}" if self.returnty is None else self.returnty.c_repr(proto, full, memo, indent)
943
960
 
944
961
  @property
@@ -988,7 +1005,7 @@ class SimTypeCppFunction(SimTypeFunction):
988
1005
  """
989
1006
 
990
1007
  def __init__(
991
- self, args, returnty, label=None, arg_names: Tuple[str] = None, ctor: bool = False, dtor: bool = False
1008
+ self, args, returnty, label=None, arg_names: tuple[str] = None, ctor: bool = False, dtor: bool = False
992
1009
  ):
993
1010
  super().__init__(args, returnty, label=label, arg_names=arg_names, variadic=False)
994
1011
  self.ctor = ctor
@@ -1121,7 +1138,7 @@ class SimTypeDouble(SimTypeFloat):
1121
1138
  class SimStruct(NamedTypeMixin, SimType):
1122
1139
  _fields = ("name", "fields")
1123
1140
 
1124
- def __init__(self, fields: Union[Dict[str, SimType], OrderedDict], name=None, pack=False, align=None):
1141
+ def __init__(self, fields: dict[str, SimType] | OrderedDict, name=None, pack=False, align=None):
1125
1142
  super().__init__(None, name="<anon>" if name is None else name)
1126
1143
 
1127
1144
  self._pack = pack
@@ -1135,7 +1152,7 @@ class SimStruct(NamedTypeMixin, SimType):
1135
1152
  return self._pack
1136
1153
 
1137
1154
  @property
1138
- def offsets(self) -> Dict[str, int]:
1155
+ def offsets(self) -> dict[str, int]:
1139
1156
  offsets = {}
1140
1157
  offset_so_far = 0
1141
1158
  for name, ty in self.fields.items():
@@ -1273,7 +1290,7 @@ class SimStruct(NamedTypeMixin, SimType):
1273
1290
  def copy(self):
1274
1291
  return SimStruct(dict(self.fields), name=self.name, pack=self._pack, align=self._align)
1275
1292
 
1276
- def __eq__(self, other, avoid=None):
1293
+ def __eq__(self, other, avoid: dict[str, set[SimType]] | None = None):
1277
1294
  if not isinstance(other, SimStruct):
1278
1295
  return False
1279
1296
  if not (
@@ -1298,6 +1315,8 @@ class SimStruct(NamedTypeMixin, SimType):
1298
1315
  field_other = other.fields[key]
1299
1316
  if field_self in avoid["self"] and field_other in avoid["other"]:
1300
1317
  continue
1318
+ avoid["self"].add(field_self)
1319
+ avoid["other"].add(field_other)
1301
1320
  if not field_self.__eq__(field_other, avoid=avoid):
1302
1321
  return False
1303
1322
  return True
@@ -1352,8 +1371,7 @@ class SimStructValue:
1352
1371
  return f[k]
1353
1372
  except KeyError:
1354
1373
  continue
1355
- else:
1356
- return self._values[k]
1374
+ return self._values[k]
1357
1375
 
1358
1376
  return self._values[k]
1359
1377
 
@@ -1490,10 +1508,10 @@ class SimUnionValue:
1490
1508
  class SimCppClass(SimStruct):
1491
1509
  def __init__(
1492
1510
  self,
1493
- members: Optional[Dict[str, SimType]] = None,
1494
- function_members: Optional[Dict[str, SimTypeCppFunction]] = None,
1511
+ members: dict[str, SimType] | None = None,
1512
+ function_members: dict[str, SimTypeCppFunction] | None = None,
1495
1513
  vtable_ptrs=None,
1496
- name: Optional[str] = None,
1514
+ name: str | None = None,
1497
1515
  pack: bool = False,
1498
1516
  align=None,
1499
1517
  ):
@@ -1606,10 +1624,7 @@ class SimTypeNumOffset(SimTypeNum):
1606
1624
  super().__init__(size, signed, label)
1607
1625
  self.offset = offset
1608
1626
 
1609
- def __repr__(self):
1610
- return super().__repr__()
1611
-
1612
- def extract(self, state: "SimState", addr, concrete=False):
1627
+ def extract(self, state: SimState, addr, concrete=False):
1613
1628
  if state.arch.memory_endness != Endness.LE:
1614
1629
  raise NotImplementedError("This has only been implemented and tested with Little Endian arches so far")
1615
1630
  minimum_load_size = self.offset + self.size # because we start from a byte aligned offset _before_ the value
@@ -1639,7 +1654,7 @@ class SimTypeRef(SimType):
1639
1654
  SimTypeRef is not SimTypeReference.
1640
1655
  """
1641
1656
 
1642
- def __init__(self, name, original_type: Type[SimStruct]):
1657
+ def __init__(self, name, original_type: type[SimStruct]):
1643
1658
  super().__init__(label=name)
1644
1659
  self.original_type = original_type
1645
1660
 
@@ -2812,7 +2827,7 @@ def parse_types(defn, preprocess=True, predefined_types=None, arch=None):
2812
2827
  _include_re = re.compile(r"^\s*#include")
2813
2828
 
2814
2829
 
2815
- def parse_file(defn, preprocess=True, predefined_types: Optional[Dict[Any, SimType]] = None, arch=None):
2830
+ def parse_file(defn, preprocess=True, predefined_types: dict[Any, SimType] | None = None, arch=None):
2816
2831
  """
2817
2832
  Parse a series of C definitions, returns a tuple of two type mappings, one for variable
2818
2833
  definitions and one for type definitions.
@@ -2862,7 +2877,7 @@ def parse_file(defn, preprocess=True, predefined_types: Optional[Dict[Any, SimTy
2862
2877
  _type_parser_singleton = None
2863
2878
 
2864
2879
 
2865
- def type_parser_singleton() -> Optional[pycparser.CParser]:
2880
+ def type_parser_singleton() -> pycparser.CParser | None:
2866
2881
  global _type_parser_singleton # pylint:disable=global-statement
2867
2882
  if pycparser is not None:
2868
2883
  if _type_parser_singleton is None:
@@ -2887,7 +2902,7 @@ def parse_type(defn, preprocess=True, predefined_types=None, arch=None): # pyli
2887
2902
 
2888
2903
 
2889
2904
  def parse_type_with_name(
2890
- defn, preprocess=True, predefined_types: Optional[Dict[Any, SimType]] = None, arch=None
2905
+ defn, preprocess=True, predefined_types: dict[Any, SimType] | None = None, arch=None
2891
2906
  ): # pylint:disable=unused-argument
2892
2907
  """
2893
2908
  Parse a simple type expression into a SimType, returning a tuple of the type object and any associated name
@@ -3119,7 +3134,7 @@ def _parse_const(c, arch=None, extra_types=None):
3119
3134
  raise ValueError(c)
3120
3135
 
3121
3136
 
3122
- def _cpp_decl_to_type(decl: Any, extra_types: Dict[str, SimType], opaque_classes=True):
3137
+ def _cpp_decl_to_type(decl: Any, extra_types: dict[str, SimType], opaque_classes=True):
3123
3138
  if isinstance(decl, CppHeaderParser.CppMethod):
3124
3139
  the_func = decl
3125
3140
  func_name = the_func["name"]
@@ -3131,7 +3146,7 @@ def _cpp_decl_to_type(decl: Any, extra_types: Dict[str, SimType], opaque_classes
3131
3146
  the_func["destructor"] = True
3132
3147
  # translate parameters
3133
3148
  args = []
3134
- arg_names: List[str] = []
3149
+ arg_names: list[str] = []
3135
3150
  for param in the_func["parameters"]:
3136
3151
  arg_type = param["type"]
3137
3152
  args.append(_cpp_decl_to_type(arg_type, extra_types, opaque_classes=opaque_classes))
@@ -3139,7 +3154,7 @@ def _cpp_decl_to_type(decl: Any, extra_types: Dict[str, SimType], opaque_classes
3139
3154
  arg_names.append(arg_name)
3140
3155
 
3141
3156
  args = tuple(args)
3142
- arg_names: Tuple[str] = tuple(arg_names)
3157
+ arg_names: tuple[str] = tuple(arg_names)
3143
3158
  # returns
3144
3159
  if not the_func["returns"].strip():
3145
3160
  returnty = SimTypeBottom()
@@ -3252,10 +3267,10 @@ def parse_cpp_file(cpp_decl, with_param_names: bool = False):
3252
3267
  if not h.functions:
3253
3268
  return None, None
3254
3269
 
3255
- func_decls: Dict[str, SimTypeCppFunction] = {}
3270
+ func_decls: dict[str, SimTypeCppFunction] = {}
3256
3271
  for the_func in h.functions:
3257
3272
  # FIXME: We always assume that there is a "this" pointer but it is not the case for static methods.
3258
- proto: Optional[SimTypeCppFunction] = _cpp_decl_to_type(the_func, {}, opaque_classes=True)
3273
+ proto: SimTypeCppFunction | None = _cpp_decl_to_type(the_func, {}, opaque_classes=True)
3259
3274
  if proto is not None and the_func["class"]:
3260
3275
  func_name = the_func["class"] + "::" + the_func["name"]
3261
3276
  proto.args = (
@@ -3270,7 +3285,7 @@ def parse_cpp_file(cpp_decl, with_param_names: bool = False):
3270
3285
 
3271
3286
 
3272
3287
  def dereference_simtype(
3273
- t: SimType, type_collections: List["SimTypeCollection"], memo: Optional[Dict[str, SimType]] = None
3288
+ t: SimType, type_collections: list[SimTypeCollection], memo: dict[str, SimType] | None = None
3274
3289
  ) -> SimType:
3275
3290
  if memo is None:
3276
3291
  memo = {}
angr/sim_variable.py CHANGED
@@ -1,6 +1,6 @@
1
1
  import collections.abc
2
2
  import claripy
3
- from typing import Optional, TYPE_CHECKING
3
+ from typing import TYPE_CHECKING
4
4
 
5
5
  from .protos import variables_pb2 as pb2
6
6
  from .serializable import Serializable
@@ -20,15 +20,15 @@ class SimVariable(Serializable):
20
20
  "size",
21
21
  ]
22
22
 
23
- def __init__(self, ident=None, name=None, region: Optional[int] = None, category=None, size: Optional[int] = None):
23
+ def __init__(self, ident=None, name=None, region: int | None = None, category=None, size: int | None = None):
24
24
  """
25
25
  :param ident: A unique identifier provided by user or the program. Usually a string.
26
26
  :param str name: Name of this variable.
27
27
  """
28
28
  self.ident = ident
29
29
  self.name = name
30
- self.region: Optional[int] = region
31
- self.category: Optional[str] = category
30
+ self.region: int | None = region
31
+ self.category: str | None = category
32
32
  self.renamed = False
33
33
  self.candidate_names = None
34
34
  self.size = size
@@ -175,7 +175,7 @@ class SimRegisterVariable(SimVariable):
175
175
  SimVariable.__init__(self, ident=ident, name=name, region=region, category=category, size=size)
176
176
 
177
177
  self.reg: int = reg_offset
178
- self._hash: Optional[int] = None
178
+ self._hash: int | None = None
179
179
 
180
180
  @property
181
181
  def bits(self):
angr/simos/simos.py CHANGED
@@ -1,6 +1,5 @@
1
1
  import logging
2
2
  import struct
3
- from typing import Optional
4
3
 
5
4
  import angr # for types
6
5
 
@@ -344,7 +343,7 @@ class SimOS:
344
343
  def syscall_abi(self, state) -> str:
345
344
  return None
346
345
 
347
- def syscall_cc(self, state) -> Optional[angr.calling_conventions.SimCCSyscall]:
346
+ def syscall_cc(self, state) -> angr.calling_conventions.SimCCSyscall | None:
348
347
  raise NotImplementedError()
349
348
 
350
349
  def is_syscall_addr(self, addr):
angr/simos/userland.py CHANGED
@@ -1,5 +1,4 @@
1
1
  import logging
2
- from typing import Dict, Tuple
3
2
 
4
3
  from ..calling_conventions import SYSCALL_CC, SimCCSyscall
5
4
  from ..errors import AngrUnsupportedSyscallError, SimSolverError
@@ -23,7 +22,7 @@ class SimUserland(SimOS):
23
22
  self.syscall_addr_alignment = syscall_addr_alignment
24
23
  self.kernel_base = None
25
24
  self.unknown_syscall_number = None
26
- self.syscall_abis: Dict[str, Tuple[int, int, int]] = {}
25
+ self.syscall_abis: dict[str, tuple[int, int, int]] = {}
27
26
  # syscall_abis is a dict of tuples {name: (base_number, min_number, max_number)}
28
27
  # min_number and max_number are just cached from SimSyscallLibrary.{min,max}imum_sysall_number
29
28
  # base_number is used to map the syscalls into the syscall address space - it's a "base address"
@@ -1,7 +1,8 @@
1
1
  import collections
2
2
  from itertools import dropwhile
3
3
  import logging
4
- from typing import Iterator, Optional, Tuple, Union
4
+ from typing import Optional
5
+ from collections.abc import Iterator
5
6
 
6
7
  from .plugin import SimStatePlugin
7
8
  from ..errors import AngrError, SimEmptyCallStackError
@@ -327,7 +328,7 @@ class CallStack(SimStatePlugin):
327
328
 
328
329
  return "\n".join(stack)
329
330
 
330
- def stack_suffix(self, context_sensitivity_level) -> Tuple[Union[int, None], ...]:
331
+ def stack_suffix(self, context_sensitivity_level) -> tuple[int | None, ...]:
331
332
  """
332
333
  Generate the stack suffix. A stack suffix can be used as the key to a SimRun in CFG recovery.
333
334
 
@@ -2,7 +2,6 @@ import operator
2
2
  import logging
3
3
  import itertools
4
4
  import contextlib
5
- from typing import Optional
6
5
 
7
6
  import claripy
8
7
  from claripy.ast.bv import BV
@@ -40,7 +39,7 @@ class SimStateHistory(SimStatePlugin):
40
39
  self.jump_target = None if clone is None else clone.jump_target
41
40
  self.jump_source = None if clone is None else clone.jump_source
42
41
  self.jump_avoidable = None if clone is None else clone.jump_avoidable
43
- self.jump_guard: Optional[BV] = None if clone is None else clone.jump_guard
42
+ self.jump_guard: BV | None = None if clone is None else clone.jump_guard
44
43
  self.jumpkind = None if clone is None else clone.jumpkind
45
44
 
46
45
  # the execution log for this history