angr 9.2.116__py3-none-manylinux2014_aarch64.whl → 9.2.118__py3-none-manylinux2014_aarch64.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 (1316) hide show
  1. angr/__init__.py +2 -1
  2. angr/__main__.py +21 -1
  3. angr/analyses/__init__.py +4 -0
  4. angr/analyses/analysis.py +45 -45
  5. angr/analyses/backward_slice.py +15 -18
  6. angr/analyses/binary_optimizer.py +29 -34
  7. angr/analyses/bindiff.py +35 -44
  8. angr/analyses/boyscout.py +1 -0
  9. angr/analyses/callee_cleanup_finder.py +3 -4
  10. angr/analyses/calling_convention.py +98 -98
  11. angr/analyses/cdg.py +5 -12
  12. angr/analyses/cfg/__init__.py +1 -0
  13. angr/analyses/cfg/cfb.py +14 -20
  14. angr/analyses/cfg/cfg.py +2 -1
  15. angr/analyses/cfg/cfg_arch_options.py +4 -1
  16. angr/analyses/cfg/cfg_base.py +122 -165
  17. angr/analyses/cfg/cfg_emulated.py +64 -96
  18. angr/analyses/cfg/cfg_fast.py +273 -314
  19. angr/analyses/cfg/cfg_fast_soot.py +10 -17
  20. angr/analyses/cfg/cfg_job_base.py +6 -7
  21. angr/analyses/cfg/indirect_jump_resolvers/__init__.py +1 -0
  22. angr/analyses/cfg/indirect_jump_resolvers/amd64_elf_got.py +2 -3
  23. angr/analyses/cfg/indirect_jump_resolvers/amd64_pe_iat.py +2 -3
  24. angr/analyses/cfg/indirect_jump_resolvers/arm_elf_fast.py +6 -8
  25. angr/analyses/cfg/indirect_jump_resolvers/const_resolver.py +3 -5
  26. angr/analyses/cfg/indirect_jump_resolvers/default_resolvers.py +1 -0
  27. angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +104 -119
  28. angr/analyses/cfg/indirect_jump_resolvers/mips_elf_fast.py +29 -34
  29. angr/analyses/cfg/indirect_jump_resolvers/propagator_utils.py +1 -0
  30. angr/analyses/cfg/indirect_jump_resolvers/resolver.py +7 -7
  31. angr/analyses/cfg/indirect_jump_resolvers/x86_elf_pic_plt.py +3 -8
  32. angr/analyses/cfg/indirect_jump_resolvers/x86_pe_iat.py +2 -3
  33. angr/analyses/cfg_slice_to_sink/__init__.py +1 -0
  34. angr/analyses/cfg_slice_to_sink/cfg_slice_to_sink.py +4 -4
  35. angr/analyses/cfg_slice_to_sink/graph.py +4 -1
  36. angr/analyses/cfg_slice_to_sink/transitions.py +4 -2
  37. angr/analyses/class_identifier.py +1 -0
  38. angr/analyses/code_tagging.py +9 -9
  39. angr/analyses/complete_calling_conventions.py +28 -36
  40. angr/analyses/congruency_check.py +6 -11
  41. angr/analyses/data_dep/__init__.py +1 -0
  42. angr/analyses/data_dep/data_dependency_analysis.py +38 -48
  43. angr/analyses/data_dep/dep_nodes.py +13 -12
  44. angr/analyses/data_dep/sim_act_location.py +3 -0
  45. angr/analyses/datagraph_meta.py +7 -7
  46. angr/analyses/ddg.py +48 -69
  47. angr/analyses/decompiler/__init__.py +3 -0
  48. angr/analyses/decompiler/ail_simplifier.py +929 -400
  49. angr/analyses/decompiler/ailgraph_walker.py +1 -0
  50. angr/analyses/decompiler/block_io_finder.py +13 -4
  51. angr/analyses/decompiler/block_similarity.py +28 -18
  52. angr/analyses/decompiler/block_simplifier.py +40 -104
  53. angr/analyses/decompiler/callsite_maker.py +124 -82
  54. angr/analyses/decompiler/ccall_rewriters/__init__.py +1 -0
  55. angr/analyses/decompiler/ccall_rewriters/amd64_ccalls.py +115 -105
  56. angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +2 -1
  57. angr/analyses/decompiler/clinic.py +348 -172
  58. angr/analyses/decompiler/condition_processor.py +86 -100
  59. angr/analyses/decompiler/counters/__init__.py +5 -0
  60. angr/analyses/decompiler/counters/boolean_counter.py +27 -0
  61. angr/analyses/decompiler/{call_counter.py → counters/call_counter.py} +5 -4
  62. angr/analyses/decompiler/{expression_counters.py → counters/expression_counters.py} +5 -4
  63. angr/analyses/decompiler/counters/seq_cf_structure_counter.py +63 -0
  64. angr/analyses/decompiler/decompilation_cache.py +2 -1
  65. angr/analyses/decompiler/decompilation_options.py +1 -0
  66. angr/analyses/decompiler/decompiler.py +47 -27
  67. angr/analyses/decompiler/dephication/__init__.py +6 -0
  68. angr/analyses/decompiler/dephication/dephication_base.py +87 -0
  69. angr/analyses/decompiler/dephication/graph_dephication.py +63 -0
  70. angr/analyses/decompiler/dephication/graph_rewriting.py +116 -0
  71. angr/analyses/decompiler/dephication/graph_vvar_mapping.py +313 -0
  72. angr/analyses/decompiler/dephication/rewriting_engine.py +247 -0
  73. angr/analyses/decompiler/dephication/seqnode_dephication.py +106 -0
  74. angr/analyses/decompiler/empty_node_remover.py +1 -0
  75. angr/analyses/decompiler/expression_narrower.py +12 -17
  76. angr/analyses/decompiler/goto_manager.py +43 -4
  77. angr/analyses/decompiler/graph_region.py +19 -31
  78. angr/analyses/decompiler/jump_target_collector.py +1 -0
  79. angr/analyses/decompiler/jumptable_entry_condition_rewriter.py +1 -0
  80. angr/analyses/decompiler/optimization_passes/__init__.py +7 -3
  81. angr/analyses/decompiler/optimization_passes/base_ptr_save_simplifier.py +23 -18
  82. angr/analyses/decompiler/optimization_passes/call_stmt_rewriter.py +46 -0
  83. angr/analyses/decompiler/optimization_passes/code_motion.py +4 -2
  84. angr/analyses/decompiler/optimization_passes/const_derefs.py +36 -36
  85. angr/analyses/decompiler/optimization_passes/const_prop_reverter.py +6 -9
  86. angr/analyses/decompiler/optimization_passes/cross_jump_reverter.py +4 -3
  87. angr/analyses/decompiler/optimization_passes/deadblock_remover.py +1 -0
  88. angr/analyses/decompiler/optimization_passes/div_simplifier.py +78 -72
  89. angr/analyses/decompiler/optimization_passes/duplication_reverter/__init__.py +2 -0
  90. angr/analyses/decompiler/optimization_passes/duplication_reverter/ail_merge_graph.py +500 -0
  91. angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +1211 -0
  92. angr/analyses/decompiler/optimization_passes/duplication_reverter/errors.py +16 -0
  93. angr/analyses/decompiler/optimization_passes/duplication_reverter/similarity.py +126 -0
  94. angr/analyses/decompiler/optimization_passes/duplication_reverter/utils.py +169 -0
  95. angr/analyses/decompiler/optimization_passes/engine_base.py +60 -63
  96. angr/analyses/decompiler/optimization_passes/expr_op_swapper.py +6 -7
  97. angr/analyses/decompiler/optimization_passes/flip_boolean_cmp.py +1 -0
  98. angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +88 -23
  99. angr/analyses/decompiler/optimization_passes/ite_expr_converter.py +8 -10
  100. angr/analyses/decompiler/optimization_passes/ite_region_converter.py +128 -18
  101. angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +142 -145
  102. angr/analyses/decompiler/optimization_passes/mod_simplifier.py +27 -23
  103. angr/analyses/decompiler/optimization_passes/multi_simplifier.py +30 -34
  104. angr/analyses/decompiler/optimization_passes/optimization_pass.py +108 -47
  105. angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py +10 -3
  106. angr/analyses/decompiler/optimization_passes/ret_addr_save_simplifier.py +5 -6
  107. angr/analyses/decompiler/optimization_passes/ret_deduplicator.py +3 -2
  108. angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +125 -13
  109. angr/analyses/decompiler/optimization_passes/return_duplicator_high.py +1 -0
  110. angr/analyses/decompiler/optimization_passes/return_duplicator_low.py +3 -2
  111. angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +52 -21
  112. angr/analyses/decompiler/optimization_passes/switch_default_case_duplicator.py +3 -2
  113. angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +47 -36
  114. angr/analyses/decompiler/optimization_passes/x86_gcc_getpc_simplifier.py +2 -1
  115. angr/analyses/decompiler/peephole_optimizations/__init__.py +2 -0
  116. angr/analyses/decompiler/peephole_optimizations/a_div_const_add_a_mul_n_div_const.py +26 -22
  117. angr/analyses/decompiler/peephole_optimizations/a_mul_const_div_shr_const.py +2 -2
  118. angr/analyses/decompiler/peephole_optimizations/a_shl_const_sub_a.py +1 -0
  119. angr/analyses/decompiler/peephole_optimizations/a_sub_a_div.py +2 -2
  120. angr/analyses/decompiler/peephole_optimizations/a_sub_a_div_const_mul_const.py +1 -0
  121. angr/analyses/decompiler/peephole_optimizations/a_sub_a_sub_n.py +8 -4
  122. angr/analyses/decompiler/peephole_optimizations/arm_cmpf.py +28 -27
  123. angr/analyses/decompiler/peephole_optimizations/base.py +17 -20
  124. angr/analyses/decompiler/peephole_optimizations/basepointeroffset_add_n.py +1 -0
  125. angr/analyses/decompiler/peephole_optimizations/basepointeroffset_and_mask.py +1 -0
  126. angr/analyses/decompiler/peephole_optimizations/bitwise_or_to_logical_or.py +2 -2
  127. angr/analyses/decompiler/peephole_optimizations/bool_expr_xor_1.py +2 -2
  128. angr/analyses/decompiler/peephole_optimizations/bswap.py +29 -22
  129. angr/analyses/decompiler/peephole_optimizations/cmpord_rewriter.py +3 -4
  130. angr/analyses/decompiler/peephole_optimizations/coalesce_adjacent_shrs.py +39 -0
  131. angr/analyses/decompiler/peephole_optimizations/coalesce_same_cascading_ifs.py +2 -1
  132. angr/analyses/decompiler/peephole_optimizations/const_mull_a_shift.py +94 -29
  133. angr/analyses/decompiler/peephole_optimizations/constant_derefs.py +1 -0
  134. angr/analyses/decompiler/peephole_optimizations/conv_a_sub0_shr_and.py +48 -49
  135. angr/analyses/decompiler/peephole_optimizations/conv_shl_shr.py +1 -0
  136. angr/analyses/decompiler/peephole_optimizations/eager_eval.py +41 -34
  137. angr/analyses/decompiler/peephole_optimizations/extended_byte_and_mask.py +2 -1
  138. angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py +28 -18
  139. angr/analyses/decompiler/peephole_optimizations/inlined_strcpy_consolidation.py +8 -4
  140. angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy.py +28 -18
  141. angr/analyses/decompiler/peephole_optimizations/invert_negated_logical_conjuction_disjunction.py +32 -32
  142. angr/analyses/decompiler/peephole_optimizations/one_sub_bool.py +2 -2
  143. angr/analyses/decompiler/peephole_optimizations/remove_cascading_conversions.py +23 -3
  144. angr/analyses/decompiler/peephole_optimizations/remove_empty_if_body.py +2 -1
  145. angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +4 -0
  146. angr/analyses/decompiler/peephole_optimizations/remove_redundant_bitmasks.py +1 -0
  147. angr/analyses/decompiler/peephole_optimizations/remove_redundant_conversions.py +4 -6
  148. angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_branch.py +14 -13
  149. angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_comparisons.py +2 -2
  150. angr/analyses/decompiler/peephole_optimizations/remove_redundant_nots.py +1 -0
  151. angr/analyses/decompiler/peephole_optimizations/remove_redundant_reinterprets.py +3 -2
  152. angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts.py +2 -2
  153. angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts_around_comparators.py +20 -16
  154. angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +3 -3
  155. angr/analyses/decompiler/peephole_optimizations/rewrite_mips_gp_loads.py +4 -2
  156. angr/analyses/decompiler/peephole_optimizations/rol_ror.py +66 -40
  157. angr/analyses/decompiler/peephole_optimizations/sar_to_signed_div.py +64 -57
  158. angr/analyses/decompiler/peephole_optimizations/simplify_pc_relative_loads.py +14 -14
  159. angr/analyses/decompiler/peephole_optimizations/single_bit_cond_to_boolexpr.py +1 -0
  160. angr/analyses/decompiler/peephole_optimizations/single_bit_xor.py +8 -5
  161. angr/analyses/decompiler/peephole_optimizations/tidy_stack_addr.py +4 -6
  162. angr/analyses/decompiler/redundant_label_remover.py +20 -19
  163. angr/analyses/decompiler/region_identifier.py +64 -77
  164. angr/analyses/decompiler/region_simplifiers/__init__.py +1 -0
  165. angr/analyses/decompiler/region_simplifiers/cascading_cond_transformer.py +2 -1
  166. angr/analyses/decompiler/region_simplifiers/cascading_ifs.py +1 -0
  167. angr/analyses/decompiler/region_simplifiers/expr_folding.py +43 -29
  168. angr/analyses/decompiler/region_simplifiers/goto.py +1 -0
  169. angr/analyses/decompiler/region_simplifiers/if_.py +29 -36
  170. angr/analyses/decompiler/region_simplifiers/ifelse.py +1 -0
  171. angr/analyses/decompiler/region_simplifiers/loop.py +27 -13
  172. angr/analyses/decompiler/region_simplifiers/node_address_finder.py +1 -0
  173. angr/analyses/decompiler/region_simplifiers/region_simplifier.py +1 -0
  174. angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +12 -16
  175. angr/analyses/decompiler/region_simplifiers/switch_expr_simplifier.py +36 -32
  176. angr/analyses/decompiler/region_walker.py +1 -0
  177. angr/analyses/decompiler/return_maker.py +1 -0
  178. angr/analyses/decompiler/seq_to_blocks.py +1 -0
  179. angr/analyses/decompiler/sequence_walker.py +5 -10
  180. angr/analyses/decompiler/ssailification/__init__.py +4 -0
  181. angr/analyses/decompiler/ssailification/rewriting.py +325 -0
  182. angr/analyses/decompiler/ssailification/rewriting_engine.py +601 -0
  183. angr/analyses/decompiler/ssailification/rewriting_state.py +60 -0
  184. angr/analyses/decompiler/ssailification/ssailification.py +213 -0
  185. angr/analyses/decompiler/ssailification/traversal.py +97 -0
  186. angr/analyses/decompiler/ssailification/traversal_engine.py +131 -0
  187. angr/analyses/decompiler/ssailification/traversal_state.py +42 -0
  188. angr/analyses/decompiler/structured_codegen/__init__.py +1 -0
  189. angr/analyses/decompiler/structured_codegen/base.py +2 -2
  190. angr/analyses/decompiler/structured_codegen/c.py +163 -158
  191. angr/analyses/decompiler/structured_codegen/dummy.py +1 -0
  192. angr/analyses/decompiler/structured_codegen/dwarf_import.py +1 -0
  193. angr/analyses/decompiler/structuring/__init__.py +1 -0
  194. angr/analyses/decompiler/structuring/dream.py +19 -36
  195. angr/analyses/decompiler/structuring/phoenix.py +199 -199
  196. angr/analyses/decompiler/structuring/recursive_structurer.py +4 -3
  197. angr/analyses/decompiler/structuring/sailr.py +5 -4
  198. angr/analyses/decompiler/structuring/structurer_base.py +26 -23
  199. angr/analyses/decompiler/structuring/structurer_nodes.py +14 -24
  200. angr/analyses/decompiler/utils.py +112 -52
  201. angr/analyses/disassembly.py +75 -77
  202. angr/analyses/disassembly_utils.py +10 -13
  203. angr/analyses/dominance_frontier.py +25 -7
  204. angr/analyses/find_objects_static.py +3 -2
  205. angr/analyses/flirt.py +7 -10
  206. angr/analyses/forward_analysis/__init__.py +1 -0
  207. angr/analyses/forward_analysis/forward_analysis.py +9 -6
  208. angr/analyses/forward_analysis/job_info.py +3 -3
  209. angr/analyses/forward_analysis/visitors/__init__.py +1 -0
  210. angr/analyses/forward_analysis/visitors/call_graph.py +1 -0
  211. angr/analyses/forward_analysis/visitors/function_graph.py +3 -2
  212. angr/analyses/forward_analysis/visitors/graph.py +9 -9
  213. angr/analyses/forward_analysis/visitors/loop.py +1 -0
  214. angr/analyses/forward_analysis/visitors/single_node_graph.py +2 -2
  215. angr/analyses/identifier/__init__.py +1 -0
  216. angr/analyses/identifier/custom_callable.py +2 -2
  217. angr/analyses/identifier/errors.py +1 -0
  218. angr/analyses/identifier/func.py +6 -3
  219. angr/analyses/identifier/functions/__init__.py +2 -1
  220. angr/analyses/identifier/functions/atoi.py +2 -4
  221. angr/analyses/identifier/functions/based_atoi.py +3 -6
  222. angr/analyses/identifier/functions/fdprintf.py +1 -0
  223. angr/analyses/identifier/functions/free.py +6 -6
  224. angr/analyses/identifier/functions/int2str.py +11 -26
  225. angr/analyses/identifier/functions/malloc.py +4 -6
  226. angr/analyses/identifier/functions/memcmp.py +2 -4
  227. angr/analyses/identifier/functions/memcpy.py +2 -2
  228. angr/analyses/identifier/functions/memset.py +2 -2
  229. angr/analyses/identifier/functions/printf.py +1 -0
  230. angr/analyses/identifier/functions/recv_until.py +3 -6
  231. angr/analyses/identifier/functions/skip_calloc.py +2 -1
  232. angr/analyses/identifier/functions/skip_realloc.py +4 -6
  233. angr/analyses/identifier/functions/skip_recv_n.py +4 -6
  234. angr/analyses/identifier/functions/snprintf.py +2 -4
  235. angr/analyses/identifier/functions/sprintf.py +1 -0
  236. angr/analyses/identifier/functions/strcasecmp.py +1 -0
  237. angr/analyses/identifier/functions/strcmp.py +2 -1
  238. angr/analyses/identifier/functions/strcpy.py +2 -2
  239. angr/analyses/identifier/functions/strlen.py +1 -0
  240. angr/analyses/identifier/functions/strncmp.py +2 -1
  241. angr/analyses/identifier/functions/strncpy.py +2 -2
  242. angr/analyses/identifier/functions/strtol.py +2 -4
  243. angr/analyses/identifier/identify.py +46 -67
  244. angr/analyses/identifier/runner.py +8 -7
  245. angr/analyses/init_finder.py +17 -17
  246. angr/analyses/loop_analysis.py +10 -14
  247. angr/analyses/loopfinder.py +9 -13
  248. angr/analyses/propagator/__init__.py +1 -0
  249. angr/analyses/propagator/engine_ail.py +159 -165
  250. angr/analyses/propagator/engine_base.py +3 -2
  251. angr/analyses/propagator/engine_vex.py +47 -48
  252. angr/analyses/propagator/outdated_definition_walker.py +18 -23
  253. angr/analyses/propagator/propagator.py +8 -12
  254. angr/analyses/propagator/tmpvar_finder.py +1 -0
  255. angr/analyses/propagator/top_checker_mixin.py +2 -4
  256. angr/analyses/propagator/values.py +1 -0
  257. angr/analyses/propagator/vex_vars.py +3 -2
  258. angr/analyses/proximity_graph.py +12 -20
  259. angr/analyses/reaching_definitions/__init__.py +5 -4
  260. angr/analyses/reaching_definitions/call_trace.py +7 -6
  261. angr/analyses/reaching_definitions/dep_graph.py +18 -23
  262. angr/analyses/reaching_definitions/engine_ail.py +89 -121
  263. angr/analyses/reaching_definitions/engine_vex.py +20 -32
  264. angr/analyses/reaching_definitions/function_handler.py +32 -33
  265. angr/analyses/reaching_definitions/function_handler_library/__init__.py +1 -0
  266. angr/analyses/reaching_definitions/function_handler_library/stdio.py +4 -6
  267. angr/analyses/reaching_definitions/function_handler_library/stdlib.py +1 -2
  268. angr/analyses/reaching_definitions/function_handler_library/string.py +2 -4
  269. angr/analyses/reaching_definitions/function_handler_library/unistd.py +1 -0
  270. angr/analyses/reaching_definitions/heap_allocator.py +7 -6
  271. angr/analyses/reaching_definitions/rd_initializer.py +27 -25
  272. angr/analyses/reaching_definitions/rd_state.py +14 -16
  273. angr/analyses/reaching_definitions/reaching_definitions.py +27 -36
  274. angr/analyses/reaching_definitions/subject.py +3 -2
  275. angr/analyses/reassembler.py +189 -253
  276. angr/analyses/s_liveness/__init__.py +2 -0
  277. angr/analyses/s_liveness/s_liveness.py +153 -0
  278. angr/analyses/s_propagator/__init__.py +2 -0
  279. angr/analyses/s_propagator/s_propagator.py +250 -0
  280. angr/analyses/s_reaching_definitions/__init__.py +2 -0
  281. angr/analyses/s_reaching_definitions/s_rda.py +479 -0
  282. angr/analyses/soot_class_hierarchy.py +15 -24
  283. angr/analyses/stack_pointer_tracker.py +83 -93
  284. angr/analyses/static_hooker.py +3 -2
  285. angr/analyses/typehoon/__init__.py +1 -0
  286. angr/analyses/typehoon/dfa.py +5 -5
  287. angr/analyses/typehoon/lifter.py +5 -4
  288. angr/analyses/typehoon/simple_solver.py +80 -64
  289. angr/analyses/typehoon/translator.py +7 -14
  290. angr/analyses/typehoon/typeconsts.py +14 -12
  291. angr/analyses/typehoon/typehoon.py +8 -10
  292. angr/analyses/typehoon/typevars.py +37 -49
  293. angr/analyses/typehoon/variance.py +1 -0
  294. angr/analyses/variable_recovery/__init__.py +1 -0
  295. angr/analyses/variable_recovery/annotations.py +1 -0
  296. angr/analyses/variable_recovery/engine_ail.py +78 -32
  297. angr/analyses/variable_recovery/engine_base.py +233 -59
  298. angr/analyses/variable_recovery/engine_vex.py +10 -11
  299. angr/analyses/variable_recovery/irsb_scanner.py +1 -0
  300. angr/analyses/variable_recovery/variable_recovery.py +14 -16
  301. angr/analyses/variable_recovery/variable_recovery_base.py +12 -14
  302. angr/analyses/variable_recovery/variable_recovery_fast.py +67 -47
  303. angr/analyses/veritesting.py +10 -16
  304. angr/analyses/vfg.py +105 -151
  305. angr/analyses/vsa_ddg.py +3 -5
  306. angr/analyses/vtable.py +6 -6
  307. angr/analyses/xrefs.py +9 -13
  308. angr/angrdb/__init__.py +4 -2
  309. angr/angrdb/db.py +51 -53
  310. angr/angrdb/models.py +1 -0
  311. angr/angrdb/serializers/__init__.py +1 -0
  312. angr/angrdb/serializers/cfg_model.py +2 -2
  313. angr/angrdb/serializers/comments.py +1 -0
  314. angr/angrdb/serializers/funcs.py +4 -3
  315. angr/angrdb/serializers/kb.py +3 -2
  316. angr/angrdb/serializers/labels.py +1 -0
  317. angr/angrdb/serializers/structured_code.py +5 -10
  318. angr/angrdb/serializers/variables.py +6 -6
  319. angr/angrdb/serializers/xrefs.py +2 -2
  320. angr/annocfg.py +17 -25
  321. angr/blade.py +19 -23
  322. angr/block.py +11 -13
  323. angr/callable.py +4 -3
  324. angr/calling_conventions.py +80 -123
  325. angr/code_location.py +12 -13
  326. angr/codenode.py +2 -1
  327. angr/concretization_strategies/__init__.py +6 -6
  328. angr/concretization_strategies/any.py +5 -4
  329. angr/concretization_strategies/any_named.py +4 -1
  330. angr/concretization_strategies/controlled_data.py +5 -2
  331. angr/concretization_strategies/eval.py +2 -2
  332. angr/concretization_strategies/logging.py +1 -0
  333. angr/concretization_strategies/max.py +6 -6
  334. angr/concretization_strategies/nonzero.py +1 -0
  335. angr/concretization_strategies/nonzero_range.py +4 -3
  336. angr/concretization_strategies/norepeats.py +2 -1
  337. angr/concretization_strategies/norepeats_range.py +1 -0
  338. angr/concretization_strategies/range.py +1 -0
  339. angr/concretization_strategies/signed_add.py +15 -9
  340. angr/concretization_strategies/single.py +2 -0
  341. angr/concretization_strategies/solutions.py +1 -0
  342. angr/concretization_strategies/unlimited_range.py +1 -0
  343. angr/distributed/__init__.py +1 -0
  344. angr/distributed/server.py +2 -2
  345. angr/distributed/worker.py +3 -3
  346. angr/engines/__init__.py +1 -0
  347. angr/engines/concrete.py +4 -1
  348. angr/engines/engine.py +4 -6
  349. angr/engines/failure.py +2 -1
  350. angr/engines/hook.py +1 -0
  351. angr/engines/light/__init__.py +1 -0
  352. angr/engines/light/data.py +221 -255
  353. angr/engines/light/engine.py +66 -74
  354. angr/engines/pcode/__init__.py +1 -0
  355. angr/engines/pcode/behavior.py +5 -3
  356. angr/engines/pcode/cc.py +1 -0
  357. angr/engines/pcode/emulate.py +16 -19
  358. angr/engines/pcode/engine.py +8 -10
  359. angr/engines/pcode/lifter.py +62 -79
  360. angr/engines/procedure.py +1 -0
  361. angr/engines/soot/__init__.py +1 -0
  362. angr/engines/soot/engine.py +48 -53
  363. angr/engines/soot/exceptions.py +3 -0
  364. angr/engines/soot/expressions/__init__.py +1 -0
  365. angr/engines/soot/expressions/arrayref.py +1 -0
  366. angr/engines/soot/expressions/base.py +4 -5
  367. angr/engines/soot/expressions/binop.py +1 -0
  368. angr/engines/soot/expressions/cast.py +1 -0
  369. angr/engines/soot/expressions/condition.py +1 -0
  370. angr/engines/soot/expressions/constants.py +7 -5
  371. angr/engines/soot/expressions/instanceOf.py +1 -0
  372. angr/engines/soot/expressions/instancefieldref.py +1 -0
  373. angr/engines/soot/expressions/invoke.py +7 -9
  374. angr/engines/soot/expressions/length.py +1 -0
  375. angr/engines/soot/expressions/local.py +1 -0
  376. angr/engines/soot/expressions/new.py +1 -0
  377. angr/engines/soot/expressions/newArray.py +4 -1
  378. angr/engines/soot/expressions/newMultiArray.py +6 -4
  379. angr/engines/soot/expressions/paramref.py +1 -0
  380. angr/engines/soot/expressions/phi.py +1 -0
  381. angr/engines/soot/expressions/staticfieldref.py +1 -0
  382. angr/engines/soot/expressions/thisref.py +1 -0
  383. angr/engines/soot/expressions/unsupported.py +1 -0
  384. angr/engines/soot/field_dispatcher.py +5 -8
  385. angr/engines/soot/method_dispatcher.py +4 -7
  386. angr/engines/soot/statements/__init__.py +4 -4
  387. angr/engines/soot/statements/assign.py +1 -0
  388. angr/engines/soot/statements/base.py +6 -7
  389. angr/engines/soot/statements/goto.py +4 -1
  390. angr/engines/soot/statements/identity.py +1 -0
  391. angr/engines/soot/statements/if_.py +4 -1
  392. angr/engines/soot/statements/invoke.py +1 -0
  393. angr/engines/soot/statements/return_.py +1 -0
  394. angr/engines/soot/statements/switch.py +4 -1
  395. angr/engines/soot/statements/throw.py +5 -2
  396. angr/engines/soot/values/__init__.py +4 -2
  397. angr/engines/soot/values/arrayref.py +13 -15
  398. angr/engines/soot/values/base.py +4 -1
  399. angr/engines/soot/values/constants.py +1 -0
  400. angr/engines/soot/values/instancefieldref.py +1 -0
  401. angr/engines/soot/values/local.py +1 -0
  402. angr/engines/soot/values/paramref.py +1 -0
  403. angr/engines/soot/values/staticfieldref.py +1 -0
  404. angr/engines/soot/values/strref.py +3 -2
  405. angr/engines/soot/values/thisref.py +1 -0
  406. angr/engines/successors.py +20 -23
  407. angr/engines/syscall.py +9 -9
  408. angr/engines/unicorn.py +20 -14
  409. angr/engines/vex/__init__.py +1 -0
  410. angr/engines/vex/claripy/__init__.py +1 -0
  411. angr/engines/vex/claripy/ccall.py +86 -112
  412. angr/engines/vex/claripy/datalayer.py +12 -16
  413. angr/engines/vex/claripy/irop.py +85 -104
  414. angr/engines/vex/heavy/__init__.py +1 -0
  415. angr/engines/vex/heavy/actions.py +1 -0
  416. angr/engines/vex/heavy/concretizers.py +14 -15
  417. angr/engines/vex/heavy/dirty.py +20 -21
  418. angr/engines/vex/heavy/heavy.py +17 -20
  419. angr/engines/vex/heavy/inspect.py +1 -0
  420. angr/engines/vex/heavy/resilience.py +2 -2
  421. angr/engines/vex/heavy/super_fastpath.py +2 -2
  422. angr/engines/vex/lifter.py +28 -35
  423. angr/engines/vex/light/__init__.py +1 -0
  424. angr/engines/vex/light/light.py +2 -4
  425. angr/engines/vex/light/resilience.py +1 -0
  426. angr/engines/vex/light/slicing.py +1 -0
  427. angr/errors.py +2 -1
  428. angr/exploration_techniques/__init__.py +3 -2
  429. angr/exploration_techniques/bucketizer.py +2 -3
  430. angr/exploration_techniques/common.py +3 -3
  431. angr/exploration_techniques/dfs.py +1 -0
  432. angr/exploration_techniques/director.py +18 -20
  433. angr/exploration_techniques/driller_core.py +5 -6
  434. angr/exploration_techniques/explorer.py +7 -3
  435. angr/exploration_techniques/lengthlimiter.py +1 -0
  436. angr/exploration_techniques/local_loop_seer.py +2 -2
  437. angr/exploration_techniques/loop_seer.py +11 -14
  438. angr/exploration_techniques/manual_mergepoint.py +3 -2
  439. angr/exploration_techniques/memory_watcher.py +1 -0
  440. angr/exploration_techniques/oppologist.py +4 -4
  441. angr/exploration_techniques/slicecutor.py +1 -0
  442. angr/exploration_techniques/spiller.py +8 -8
  443. angr/exploration_techniques/spiller_db.py +1 -0
  444. angr/exploration_techniques/stochastic.py +3 -4
  445. angr/exploration_techniques/stub_stasher.py +1 -0
  446. angr/exploration_techniques/suggestions.py +3 -2
  447. angr/exploration_techniques/symbion.py +1 -0
  448. angr/exploration_techniques/tech_builder.py +1 -0
  449. angr/exploration_techniques/threading.py +1 -0
  450. angr/exploration_techniques/timeout.py +1 -0
  451. angr/exploration_techniques/tracer.py +36 -40
  452. angr/exploration_techniques/unique.py +1 -0
  453. angr/exploration_techniques/veritesting.py +1 -0
  454. angr/factory.py +9 -9
  455. angr/flirt/__init__.py +1 -0
  456. angr/flirt/build_sig.py +8 -12
  457. angr/keyed_region.py +10 -17
  458. angr/knowledge_base/__init__.py +1 -0
  459. angr/knowledge_base/knowledge_base.py +17 -17
  460. angr/knowledge_plugins/__init__.py +1 -0
  461. angr/knowledge_plugins/callsite_prototypes.py +1 -0
  462. angr/knowledge_plugins/cfg/__init__.py +2 -0
  463. angr/knowledge_plugins/cfg/cfg_manager.py +2 -1
  464. angr/knowledge_plugins/cfg/cfg_model.py +25 -42
  465. angr/knowledge_plugins/cfg/cfg_node.py +8 -19
  466. angr/knowledge_plugins/cfg/indirect_jump.py +3 -5
  467. angr/knowledge_plugins/cfg/memory_data.py +3 -3
  468. angr/knowledge_plugins/comments.py +1 -0
  469. angr/knowledge_plugins/custom_strings.py +1 -0
  470. angr/knowledge_plugins/data.py +1 -0
  471. angr/knowledge_plugins/debug_variables.py +18 -23
  472. angr/knowledge_plugins/functions/__init__.py +1 -0
  473. angr/knowledge_plugins/functions/function.py +49 -53
  474. angr/knowledge_plugins/functions/function_manager.py +14 -14
  475. angr/knowledge_plugins/functions/function_parser.py +38 -42
  476. angr/knowledge_plugins/functions/soot_function.py +5 -6
  477. angr/knowledge_plugins/indirect_jumps.py +1 -0
  478. angr/knowledge_plugins/key_definitions/__init__.py +1 -0
  479. angr/knowledge_plugins/key_definitions/atoms.py +65 -17
  480. angr/knowledge_plugins/key_definitions/constants.py +6 -0
  481. angr/knowledge_plugins/key_definitions/definition.py +22 -25
  482. angr/knowledge_plugins/key_definitions/environment.py +18 -14
  483. angr/knowledge_plugins/key_definitions/heap_address.py +4 -3
  484. angr/knowledge_plugins/key_definitions/key_definition_manager.py +5 -4
  485. angr/knowledge_plugins/key_definitions/live_definitions.py +36 -45
  486. angr/knowledge_plugins/key_definitions/liveness.py +18 -23
  487. angr/knowledge_plugins/key_definitions/rd_model.py +29 -34
  488. angr/knowledge_plugins/key_definitions/tag.py +7 -6
  489. angr/knowledge_plugins/key_definitions/undefined.py +3 -0
  490. angr/knowledge_plugins/key_definitions/unknown_size.py +3 -0
  491. angr/knowledge_plugins/key_definitions/uses.py +21 -23
  492. angr/knowledge_plugins/labels.py +3 -2
  493. angr/knowledge_plugins/patches.py +2 -1
  494. angr/knowledge_plugins/plugin.py +2 -1
  495. angr/knowledge_plugins/propagations/__init__.py +1 -0
  496. angr/knowledge_plugins/propagations/prop_value.py +25 -27
  497. angr/knowledge_plugins/propagations/propagation_manager.py +2 -2
  498. angr/knowledge_plugins/propagations/propagation_model.py +5 -4
  499. angr/knowledge_plugins/propagations/states.py +71 -81
  500. angr/knowledge_plugins/structured_code/__init__.py +1 -0
  501. angr/knowledge_plugins/structured_code/manager.py +5 -4
  502. angr/knowledge_plugins/sync/__init__.py +1 -0
  503. angr/knowledge_plugins/sync/sync_controller.py +10 -15
  504. angr/knowledge_plugins/types.py +1 -0
  505. angr/knowledge_plugins/variables/__init__.py +1 -0
  506. angr/knowledge_plugins/variables/variable_access.py +9 -10
  507. angr/knowledge_plugins/variables/variable_manager.py +84 -55
  508. angr/knowledge_plugins/xrefs/__init__.py +1 -0
  509. angr/knowledge_plugins/xrefs/xref.py +7 -11
  510. angr/knowledge_plugins/xrefs/xref_manager.py +1 -0
  511. angr/knowledge_plugins/xrefs/xref_types.py +3 -0
  512. angr/misc/__init__.py +1 -0
  513. angr/misc/ansi.py +1 -0
  514. angr/misc/autoimport.py +3 -2
  515. angr/misc/bug_report.py +6 -5
  516. angr/misc/hookset.py +3 -2
  517. angr/misc/loggers.py +2 -2
  518. angr/misc/picklable_lock.py +1 -0
  519. angr/misc/plugins.py +11 -13
  520. angr/misc/range.py +3 -0
  521. angr/misc/testing.py +2 -1
  522. angr/misc/ux.py +5 -5
  523. angr/misc/weakpatch.py +1 -0
  524. angr/procedures/__init__.py +1 -0
  525. angr/procedures/cgc/_terminate.py +1 -0
  526. angr/procedures/cgc/allocate.py +9 -10
  527. angr/procedures/cgc/deallocate.py +11 -3
  528. angr/procedures/cgc/fdwait.py +16 -13
  529. angr/procedures/cgc/random.py +12 -5
  530. angr/procedures/cgc/receive.py +30 -28
  531. angr/procedures/cgc/transmit.py +6 -4
  532. angr/procedures/definitions/__init__.py +9 -10
  533. angr/procedures/definitions/cgc.py +1 -0
  534. angr/procedures/definitions/glibc.py +1 -0
  535. angr/procedures/definitions/gnulib.py +1 -0
  536. angr/procedures/definitions/libstdcpp.py +1 -0
  537. angr/procedures/definitions/linux_kernel.py +1 -0
  538. angr/procedures/definitions/linux_loader.py +1 -0
  539. angr/procedures/definitions/msvcr.py +1 -0
  540. angr/procedures/definitions/parse_syscalls_from_local_system.py +2 -1
  541. angr/procedures/definitions/parse_win32json.py +27 -30
  542. angr/procedures/definitions/types_win32.py +1 -0
  543. angr/procedures/definitions/wdk_api-ms-win-dx-d3dkmt-l1-1-4.py +1 -0
  544. angr/procedures/definitions/wdk_api-ms-win-dx-d3dkmt-l1-1-6.py +1 -0
  545. angr/procedures/definitions/wdk_clfs.py +1 -0
  546. angr/procedures/definitions/wdk_fltmgr.py +1 -0
  547. angr/procedures/definitions/wdk_fwpkclnt.py +1 -0
  548. angr/procedures/definitions/wdk_fwpuclnt.py +1 -0
  549. angr/procedures/definitions/wdk_gdi32.py +1 -0
  550. angr/procedures/definitions/wdk_hal.py +1 -0
  551. angr/procedures/definitions/wdk_ksecdd.py +1 -0
  552. angr/procedures/definitions/wdk_ndis.py +1 -0
  553. angr/procedures/definitions/wdk_ntoskrnl.py +1 -0
  554. angr/procedures/definitions/wdk_offreg.py +1 -0
  555. angr/procedures/definitions/wdk_pshed.py +1 -0
  556. angr/procedures/definitions/wdk_secur32.py +1 -0
  557. angr/procedures/definitions/wdk_vhfum.py +1 -0
  558. angr/procedures/definitions/win32_aclui.py +1 -0
  559. angr/procedures/definitions/win32_activeds.py +1 -0
  560. angr/procedures/definitions/win32_advapi32.py +1 -0
  561. angr/procedures/definitions/win32_advpack.py +1 -0
  562. angr/procedures/definitions/win32_amsi.py +1 -0
  563. angr/procedures/definitions/win32_api-ms-win-appmodel-runtime-l1-1-1.py +1 -0
  564. angr/procedures/definitions/win32_api-ms-win-appmodel-runtime-l1-1-3.py +1 -0
  565. angr/procedures/definitions/win32_api-ms-win-appmodel-runtime-l1-1-6.py +1 -0
  566. angr/procedures/definitions/win32_api-ms-win-core-apiquery-l2-1-0.py +1 -0
  567. angr/procedures/definitions/win32_api-ms-win-core-backgroundtask-l1-1-0.py +1 -0
  568. angr/procedures/definitions/win32_api-ms-win-core-comm-l1-1-1.py +1 -0
  569. angr/procedures/definitions/win32_api-ms-win-core-comm-l1-1-2.py +1 -0
  570. angr/procedures/definitions/win32_api-ms-win-core-enclave-l1-1-1.py +1 -0
  571. angr/procedures/definitions/win32_api-ms-win-core-errorhandling-l1-1-3.py +1 -0
  572. angr/procedures/definitions/win32_api-ms-win-core-featurestaging-l1-1-0.py +1 -0
  573. angr/procedures/definitions/win32_api-ms-win-core-featurestaging-l1-1-1.py +1 -0
  574. angr/procedures/definitions/win32_api-ms-win-core-file-fromapp-l1-1-0.py +1 -0
  575. angr/procedures/definitions/win32_api-ms-win-core-handle-l1-1-0.py +1 -0
  576. angr/procedures/definitions/win32_api-ms-win-core-ioring-l1-1-0.py +1 -0
  577. angr/procedures/definitions/win32_api-ms-win-core-marshal-l1-1-0.py +1 -0
  578. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-3.py +1 -0
  579. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-4.py +1 -0
  580. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-5.py +1 -0
  581. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-6.py +1 -0
  582. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-7.py +1 -0
  583. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-8.py +1 -0
  584. angr/procedures/definitions/win32_api-ms-win-core-path-l1-1-0.py +1 -0
  585. angr/procedures/definitions/win32_api-ms-win-core-psm-appnotify-l1-1-0.py +1 -0
  586. angr/procedures/definitions/win32_api-ms-win-core-psm-appnotify-l1-1-1.py +1 -0
  587. angr/procedures/definitions/win32_api-ms-win-core-realtime-l1-1-1.py +1 -0
  588. angr/procedures/definitions/win32_api-ms-win-core-realtime-l1-1-2.py +1 -0
  589. angr/procedures/definitions/win32_api-ms-win-core-slapi-l1-1-0.py +1 -0
  590. angr/procedures/definitions/win32_api-ms-win-core-state-helpers-l1-1-0.py +1 -0
  591. angr/procedures/definitions/win32_api-ms-win-core-synch-l1-2-0.py +1 -0
  592. angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-0.py +1 -0
  593. angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-3.py +1 -0
  594. angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-4.py +1 -0
  595. angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-6.py +1 -0
  596. angr/procedures/definitions/win32_api-ms-win-core-util-l1-1-1.py +1 -0
  597. angr/procedures/definitions/win32_api-ms-win-core-winrt-error-l1-1-0.py +1 -0
  598. angr/procedures/definitions/win32_api-ms-win-core-winrt-error-l1-1-1.py +1 -0
  599. angr/procedures/definitions/win32_api-ms-win-core-winrt-l1-1-0.py +1 -0
  600. angr/procedures/definitions/win32_api-ms-win-core-winrt-registration-l1-1-0.py +1 -0
  601. angr/procedures/definitions/win32_api-ms-win-core-winrt-robuffer-l1-1-0.py +1 -0
  602. angr/procedures/definitions/win32_api-ms-win-core-winrt-roparameterizediid-l1-1-0.py +1 -0
  603. angr/procedures/definitions/win32_api-ms-win-core-winrt-string-l1-1-0.py +1 -0
  604. angr/procedures/definitions/win32_api-ms-win-core-winrt-string-l1-1-1.py +1 -0
  605. angr/procedures/definitions/win32_api-ms-win-core-wow64-l1-1-1.py +1 -0
  606. angr/procedures/definitions/win32_api-ms-win-devices-query-l1-1-0.py +1 -0
  607. angr/procedures/definitions/win32_api-ms-win-devices-query-l1-1-1.py +1 -0
  608. angr/procedures/definitions/win32_api-ms-win-dx-d3dkmt-l1-1-0.py +1 -0
  609. angr/procedures/definitions/win32_api-ms-win-gaming-deviceinformation-l1-1-0.py +1 -0
  610. angr/procedures/definitions/win32_api-ms-win-gaming-expandedresources-l1-1-0.py +1 -0
  611. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-0.py +1 -0
  612. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-1.py +1 -0
  613. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-2.py +1 -0
  614. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-3.py +1 -0
  615. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-4.py +1 -0
  616. angr/procedures/definitions/win32_api-ms-win-mm-misc-l1-1-1.py +1 -0
  617. angr/procedures/definitions/win32_api-ms-win-net-isolation-l1-1-0.py +1 -0
  618. angr/procedures/definitions/win32_api-ms-win-security-base-l1-2-2.py +1 -0
  619. angr/procedures/definitions/win32_api-ms-win-security-isolatedcontainer-l1-1-0.py +1 -0
  620. angr/procedures/definitions/win32_api-ms-win-security-isolatedcontainer-l1-1-1.py +1 -0
  621. angr/procedures/definitions/win32_api-ms-win-service-core-l1-1-3.py +1 -0
  622. angr/procedures/definitions/win32_api-ms-win-service-core-l1-1-4.py +1 -0
  623. angr/procedures/definitions/win32_api-ms-win-service-core-l1-1-5.py +1 -0
  624. angr/procedures/definitions/win32_api-ms-win-shcore-scaling-l1-1-0.py +1 -0
  625. angr/procedures/definitions/win32_api-ms-win-shcore-scaling-l1-1-1.py +1 -0
  626. angr/procedures/definitions/win32_api-ms-win-shcore-scaling-l1-1-2.py +1 -0
  627. angr/procedures/definitions/win32_api-ms-win-shcore-stream-winrt-l1-1-0.py +1 -0
  628. angr/procedures/definitions/win32_api-ms-win-wsl-api-l1-1-0.py +1 -0
  629. angr/procedures/definitions/win32_apphelp.py +1 -0
  630. angr/procedures/definitions/win32_authz.py +1 -0
  631. angr/procedures/definitions/win32_avicap32.py +1 -0
  632. angr/procedures/definitions/win32_avifil32.py +1 -0
  633. angr/procedures/definitions/win32_avrt.py +1 -0
  634. angr/procedures/definitions/win32_bcp47mrm.py +1 -0
  635. angr/procedures/definitions/win32_bcrypt.py +1 -0
  636. angr/procedures/definitions/win32_bcryptprimitives.py +1 -0
  637. angr/procedures/definitions/win32_bluetoothapis.py +1 -0
  638. angr/procedures/definitions/win32_bthprops.py +1 -0
  639. angr/procedures/definitions/win32_bthprops_cpl.py +1 -0
  640. angr/procedures/definitions/win32_cabinet.py +1 -0
  641. angr/procedures/definitions/win32_certadm.py +1 -0
  642. angr/procedures/definitions/win32_certpoleng.py +1 -0
  643. angr/procedures/definitions/win32_cfgmgr32.py +1 -0
  644. angr/procedures/definitions/win32_chakra.py +1 -0
  645. angr/procedures/definitions/win32_cldapi.py +1 -0
  646. angr/procedures/definitions/win32_clfsw32.py +1 -0
  647. angr/procedures/definitions/win32_clusapi.py +1 -0
  648. angr/procedures/definitions/win32_comctl32.py +1 -0
  649. angr/procedures/definitions/win32_comdlg32.py +1 -0
  650. angr/procedures/definitions/win32_compstui.py +1 -0
  651. angr/procedures/definitions/win32_computecore.py +1 -0
  652. angr/procedures/definitions/win32_computenetwork.py +1 -0
  653. angr/procedures/definitions/win32_computestorage.py +1 -0
  654. angr/procedures/definitions/win32_comsvcs.py +1 -0
  655. angr/procedures/definitions/win32_coremessaging.py +1 -0
  656. angr/procedures/definitions/win32_credui.py +1 -0
  657. angr/procedures/definitions/win32_crypt32.py +1 -0
  658. angr/procedures/definitions/win32_cryptnet.py +1 -0
  659. angr/procedures/definitions/win32_cryptui.py +1 -0
  660. angr/procedures/definitions/win32_cryptxml.py +1 -0
  661. angr/procedures/definitions/win32_cscapi.py +1 -0
  662. angr/procedures/definitions/win32_d2d1.py +1 -0
  663. angr/procedures/definitions/win32_d3d10.py +1 -0
  664. angr/procedures/definitions/win32_d3d10_1.py +1 -0
  665. angr/procedures/definitions/win32_d3d11.py +1 -0
  666. angr/procedures/definitions/win32_d3d12.py +1 -0
  667. angr/procedures/definitions/win32_d3d9.py +1 -0
  668. angr/procedures/definitions/win32_d3dcompiler_47.py +1 -0
  669. angr/procedures/definitions/win32_d3dcsx.py +1 -0
  670. angr/procedures/definitions/win32_davclnt.py +1 -0
  671. angr/procedures/definitions/win32_dbgeng.py +1 -0
  672. angr/procedures/definitions/win32_dbghelp.py +1 -0
  673. angr/procedures/definitions/win32_dbgmodel.py +1 -0
  674. angr/procedures/definitions/win32_dciman32.py +1 -0
  675. angr/procedures/definitions/win32_dcomp.py +1 -0
  676. angr/procedures/definitions/win32_ddraw.py +1 -0
  677. angr/procedures/definitions/win32_deviceaccess.py +1 -0
  678. angr/procedures/definitions/win32_dflayout.py +1 -0
  679. angr/procedures/definitions/win32_dhcpcsvc.py +1 -0
  680. angr/procedures/definitions/win32_dhcpcsvc6.py +1 -0
  681. angr/procedures/definitions/win32_dhcpsapi.py +1 -0
  682. angr/procedures/definitions/win32_diagnosticdataquery.py +1 -0
  683. angr/procedures/definitions/win32_dinput8.py +1 -0
  684. angr/procedures/definitions/win32_directml.py +1 -0
  685. angr/procedures/definitions/win32_dmprocessxmlfiltered.py +1 -0
  686. angr/procedures/definitions/win32_dnsapi.py +1 -0
  687. angr/procedures/definitions/win32_drt.py +1 -0
  688. angr/procedures/definitions/win32_drtprov.py +1 -0
  689. angr/procedures/definitions/win32_drttransport.py +1 -0
  690. angr/procedures/definitions/win32_dsound.py +1 -0
  691. angr/procedures/definitions/win32_dsparse.py +1 -0
  692. angr/procedures/definitions/win32_dsprop.py +1 -0
  693. angr/procedures/definitions/win32_dssec.py +1 -0
  694. angr/procedures/definitions/win32_dsuiext.py +1 -0
  695. angr/procedures/definitions/win32_dwmapi.py +1 -0
  696. angr/procedures/definitions/win32_dwrite.py +1 -0
  697. angr/procedures/definitions/win32_dxcompiler.py +1 -0
  698. angr/procedures/definitions/win32_dxcore.py +1 -0
  699. angr/procedures/definitions/win32_dxgi.py +1 -0
  700. angr/procedures/definitions/win32_dxva2.py +1 -0
  701. angr/procedures/definitions/win32_eappcfg.py +1 -0
  702. angr/procedures/definitions/win32_eappprxy.py +1 -0
  703. angr/procedures/definitions/win32_efswrt.py +1 -0
  704. angr/procedures/definitions/win32_elscore.py +1 -0
  705. angr/procedures/definitions/win32_esent.py +1 -0
  706. angr/procedures/definitions/win32_evr.py +1 -0
  707. angr/procedures/definitions/win32_faultrep.py +1 -0
  708. angr/procedures/definitions/win32_fhsvcctl.py +1 -0
  709. angr/procedures/definitions/win32_firewallapi.py +1 -0
  710. angr/procedures/definitions/win32_fltlib.py +1 -0
  711. angr/procedures/definitions/win32_fontsub.py +1 -0
  712. angr/procedures/definitions/win32_forceinline.py +1 -0
  713. angr/procedures/definitions/win32_fwpuclnt.py +1 -0
  714. angr/procedures/definitions/win32_fxsutility.py +1 -0
  715. angr/procedures/definitions/win32_gdi32.py +1 -0
  716. angr/procedures/definitions/win32_gdiplus.py +1 -0
  717. angr/procedures/definitions/win32_glu32.py +1 -0
  718. angr/procedures/definitions/win32_gpedit.py +1 -0
  719. angr/procedures/definitions/win32_hhctrl_ocx.py +1 -0
  720. angr/procedures/definitions/win32_hid.py +1 -0
  721. angr/procedures/definitions/win32_hlink.py +1 -0
  722. angr/procedures/definitions/win32_hrtfapo.py +1 -0
  723. angr/procedures/definitions/win32_httpapi.py +1 -0
  724. angr/procedures/definitions/win32_icm32.py +1 -0
  725. angr/procedures/definitions/win32_icmui.py +1 -0
  726. angr/procedures/definitions/win32_icu.py +1 -0
  727. angr/procedures/definitions/win32_ieframe.py +1 -0
  728. angr/procedures/definitions/win32_imagehlp.py +1 -0
  729. angr/procedures/definitions/win32_imgutil.py +1 -0
  730. angr/procedures/definitions/win32_imm32.py +1 -0
  731. angr/procedures/definitions/win32_infocardapi.py +1 -0
  732. angr/procedures/definitions/win32_inkobjcore.py +1 -0
  733. angr/procedures/definitions/win32_iphlpapi.py +1 -0
  734. angr/procedures/definitions/win32_iscsidsc.py +1 -0
  735. angr/procedures/definitions/win32_isolatedwindowsenvironmentutils.py +1 -0
  736. angr/procedures/definitions/win32_kernel32.py +1 -0
  737. angr/procedures/definitions/win32_kernelbase.py +1 -0
  738. angr/procedures/definitions/win32_keycredmgr.py +1 -0
  739. angr/procedures/definitions/win32_ksproxy_ax.py +1 -0
  740. angr/procedures/definitions/win32_ksuser.py +1 -0
  741. angr/procedures/definitions/win32_ktmw32.py +1 -0
  742. angr/procedures/definitions/win32_licenseprotection.py +1 -0
  743. angr/procedures/definitions/win32_loadperf.py +1 -0
  744. angr/procedures/definitions/win32_magnification.py +1 -0
  745. angr/procedures/definitions/win32_mapi32.py +1 -0
  746. angr/procedures/definitions/win32_mdmlocalmanagement.py +1 -0
  747. angr/procedures/definitions/win32_mdmregistration.py +1 -0
  748. angr/procedures/definitions/win32_mf.py +1 -0
  749. angr/procedures/definitions/win32_mfcore.py +1 -0
  750. angr/procedures/definitions/win32_mfplat.py +1 -0
  751. angr/procedures/definitions/win32_mfplay.py +1 -0
  752. angr/procedures/definitions/win32_mfreadwrite.py +1 -0
  753. angr/procedures/definitions/win32_mfsensorgroup.py +1 -0
  754. angr/procedures/definitions/win32_mfsrcsnk.py +1 -0
  755. angr/procedures/definitions/win32_mgmtapi.py +1 -0
  756. angr/procedures/definitions/win32_mi.py +1 -0
  757. angr/procedures/definitions/win32_mmdevapi.py +1 -0
  758. angr/procedures/definitions/win32_mpr.py +1 -0
  759. angr/procedures/definitions/win32_mprapi.py +1 -0
  760. angr/procedures/definitions/win32_mqrt.py +1 -0
  761. angr/procedures/definitions/win32_mrmsupport.py +1 -0
  762. angr/procedures/definitions/win32_msacm32.py +1 -0
  763. angr/procedures/definitions/win32_msajapi.py +1 -0
  764. angr/procedures/definitions/win32_mscms.py +1 -0
  765. angr/procedures/definitions/win32_mscoree.py +1 -0
  766. angr/procedures/definitions/win32_msctfmonitor.py +1 -0
  767. angr/procedures/definitions/win32_msdelta.py +1 -0
  768. angr/procedures/definitions/win32_msdmo.py +1 -0
  769. angr/procedures/definitions/win32_msdrm.py +1 -0
  770. angr/procedures/definitions/win32_msi.py +1 -0
  771. angr/procedures/definitions/win32_msimg32.py +1 -0
  772. angr/procedures/definitions/win32_mspatcha.py +1 -0
  773. angr/procedures/definitions/win32_mspatchc.py +1 -0
  774. angr/procedures/definitions/win32_msports.py +1 -0
  775. angr/procedures/definitions/win32_msrating.py +1 -0
  776. angr/procedures/definitions/win32_mssign32.py +1 -0
  777. angr/procedures/definitions/win32_mstask.py +1 -0
  778. angr/procedures/definitions/win32_msvfw32.py +1 -0
  779. angr/procedures/definitions/win32_mswsock.py +1 -0
  780. angr/procedures/definitions/win32_mtxdm.py +1 -0
  781. angr/procedures/definitions/win32_ncrypt.py +1 -0
  782. angr/procedures/definitions/win32_ndfapi.py +1 -0
  783. angr/procedures/definitions/win32_netapi32.py +1 -0
  784. angr/procedures/definitions/win32_netsh.py +1 -0
  785. angr/procedures/definitions/win32_netshell.py +1 -0
  786. angr/procedures/definitions/win32_newdev.py +1 -0
  787. angr/procedures/definitions/win32_ninput.py +1 -0
  788. angr/procedures/definitions/win32_normaliz.py +1 -0
  789. angr/procedures/definitions/win32_ntdll.py +1 -0
  790. angr/procedures/definitions/win32_ntdllk.py +1 -0
  791. angr/procedures/definitions/win32_ntdsapi.py +1 -0
  792. angr/procedures/definitions/win32_ntlanman.py +1 -0
  793. angr/procedures/definitions/win32_odbc32.py +1 -0
  794. angr/procedures/definitions/win32_odbcbcp.py +1 -0
  795. angr/procedures/definitions/win32_ole32.py +1 -0
  796. angr/procedures/definitions/win32_oleacc.py +1 -0
  797. angr/procedures/definitions/win32_oleaut32.py +1 -0
  798. angr/procedures/definitions/win32_oledlg.py +1 -0
  799. angr/procedures/definitions/win32_ondemandconnroutehelper.py +1 -0
  800. angr/procedures/definitions/win32_opengl32.py +1 -0
  801. angr/procedures/definitions/win32_opmxbox.py +1 -0
  802. angr/procedures/definitions/win32_p2p.py +1 -0
  803. angr/procedures/definitions/win32_p2pgraph.py +1 -0
  804. angr/procedures/definitions/win32_pdh.py +1 -0
  805. angr/procedures/definitions/win32_peerdist.py +1 -0
  806. angr/procedures/definitions/win32_powrprof.py +1 -0
  807. angr/procedures/definitions/win32_prntvpt.py +1 -0
  808. angr/procedures/definitions/win32_projectedfslib.py +1 -0
  809. angr/procedures/definitions/win32_propsys.py +1 -0
  810. angr/procedures/definitions/win32_psapi.py +1 -0
  811. angr/procedures/definitions/win32_quartz.py +1 -0
  812. angr/procedures/definitions/win32_query.py +1 -0
  813. angr/procedures/definitions/win32_qwave.py +1 -0
  814. angr/procedures/definitions/win32_rasapi32.py +1 -0
  815. angr/procedures/definitions/win32_rasdlg.py +1 -0
  816. angr/procedures/definitions/win32_resutils.py +1 -0
  817. angr/procedures/definitions/win32_rometadata.py +1 -0
  818. angr/procedures/definitions/win32_rpcns4.py +1 -0
  819. angr/procedures/definitions/win32_rpcproxy.py +1 -0
  820. angr/procedures/definitions/win32_rpcrt4.py +1 -0
  821. angr/procedures/definitions/win32_rstrtmgr.py +1 -0
  822. angr/procedures/definitions/win32_rtm.py +1 -0
  823. angr/procedures/definitions/win32_rtutils.py +1 -0
  824. angr/procedures/definitions/win32_rtworkq.py +1 -0
  825. angr/procedures/definitions/win32_sas.py +1 -0
  826. angr/procedures/definitions/win32_scarddlg.py +1 -0
  827. angr/procedures/definitions/win32_schannel.py +1 -0
  828. angr/procedures/definitions/win32_sechost.py +1 -0
  829. angr/procedures/definitions/win32_secur32.py +1 -0
  830. angr/procedures/definitions/win32_sensapi.py +1 -0
  831. angr/procedures/definitions/win32_sensorsutilsv2.py +1 -0
  832. angr/procedures/definitions/win32_setupapi.py +1 -0
  833. angr/procedures/definitions/win32_sfc.py +1 -0
  834. angr/procedures/definitions/win32_shdocvw.py +1 -0
  835. angr/procedures/definitions/win32_shell32.py +1 -0
  836. angr/procedures/definitions/win32_shlwapi.py +1 -0
  837. angr/procedures/definitions/win32_slc.py +1 -0
  838. angr/procedures/definitions/win32_slcext.py +1 -0
  839. angr/procedures/definitions/win32_slwga.py +1 -0
  840. angr/procedures/definitions/win32_snmpapi.py +1 -0
  841. angr/procedures/definitions/win32_spoolss.py +1 -0
  842. angr/procedures/definitions/win32_srclient.py +1 -0
  843. angr/procedures/definitions/win32_srpapi.py +1 -0
  844. angr/procedures/definitions/win32_sspicli.py +1 -0
  845. angr/procedures/definitions/win32_sti.py +1 -0
  846. angr/procedures/definitions/win32_t2embed.py +1 -0
  847. angr/procedures/definitions/win32_tapi32.py +1 -0
  848. angr/procedures/definitions/win32_tbs.py +1 -0
  849. angr/procedures/definitions/win32_tdh.py +1 -0
  850. angr/procedures/definitions/win32_tokenbinding.py +1 -0
  851. angr/procedures/definitions/win32_traffic.py +1 -0
  852. angr/procedures/definitions/win32_txfw32.py +1 -0
  853. angr/procedures/definitions/win32_ualapi.py +1 -0
  854. angr/procedures/definitions/win32_uiautomationcore.py +1 -0
  855. angr/procedures/definitions/win32_urlmon.py +1 -0
  856. angr/procedures/definitions/win32_user32.py +1 -0
  857. angr/procedures/definitions/win32_userenv.py +1 -0
  858. angr/procedures/definitions/win32_usp10.py +1 -0
  859. angr/procedures/definitions/win32_uxtheme.py +1 -0
  860. angr/procedures/definitions/win32_verifier.py +1 -0
  861. angr/procedures/definitions/win32_version.py +1 -0
  862. angr/procedures/definitions/win32_vertdll.py +1 -0
  863. angr/procedures/definitions/win32_virtdisk.py +1 -0
  864. angr/procedures/definitions/win32_vmdevicehost.py +1 -0
  865. angr/procedures/definitions/win32_vmsavedstatedumpprovider.py +1 -0
  866. angr/procedures/definitions/win32_vssapi.py +1 -0
  867. angr/procedures/definitions/win32_wcmapi.py +1 -0
  868. angr/procedures/definitions/win32_wdsbp.py +1 -0
  869. angr/procedures/definitions/win32_wdsclientapi.py +1 -0
  870. angr/procedures/definitions/win32_wdsmc.py +1 -0
  871. angr/procedures/definitions/win32_wdspxe.py +1 -0
  872. angr/procedures/definitions/win32_wdstptc.py +1 -0
  873. angr/procedures/definitions/win32_webauthn.py +1 -0
  874. angr/procedures/definitions/win32_webservices.py +1 -0
  875. angr/procedures/definitions/win32_websocket.py +1 -0
  876. angr/procedures/definitions/win32_wecapi.py +1 -0
  877. angr/procedures/definitions/win32_wer.py +1 -0
  878. angr/procedures/definitions/win32_wevtapi.py +1 -0
  879. angr/procedures/definitions/win32_winbio.py +1 -0
  880. angr/procedures/definitions/win32_windows_ai_machinelearning.py +1 -0
  881. angr/procedures/definitions/win32_windows_data_pdf.py +1 -0
  882. angr/procedures/definitions/win32_windows_media_mediacontrol.py +1 -0
  883. angr/procedures/definitions/win32_windows_networking.py +1 -0
  884. angr/procedures/definitions/win32_windows_ui_xaml.py +1 -0
  885. angr/procedures/definitions/win32_windowscodecs.py +1 -0
  886. angr/procedures/definitions/win32_winfax.py +1 -0
  887. angr/procedures/definitions/win32_winhttp.py +1 -0
  888. angr/procedures/definitions/win32_winhvemulation.py +1 -0
  889. angr/procedures/definitions/win32_winhvplatform.py +1 -0
  890. angr/procedures/definitions/win32_wininet.py +1 -0
  891. angr/procedures/definitions/win32_winml.py +1 -0
  892. angr/procedures/definitions/win32_winmm.py +1 -0
  893. angr/procedures/definitions/win32_winscard.py +1 -0
  894. angr/procedures/definitions/win32_winspool.py +1 -0
  895. angr/procedures/definitions/win32_winspool_drv.py +1 -0
  896. angr/procedures/definitions/win32_wintrust.py +1 -0
  897. angr/procedures/definitions/win32_winusb.py +1 -0
  898. angr/procedures/definitions/win32_wlanapi.py +1 -0
  899. angr/procedures/definitions/win32_wlanui.py +1 -0
  900. angr/procedures/definitions/win32_wldap32.py +1 -0
  901. angr/procedures/definitions/win32_wldp.py +1 -0
  902. angr/procedures/definitions/win32_wmvcore.py +1 -0
  903. angr/procedures/definitions/win32_wnvapi.py +1 -0
  904. angr/procedures/definitions/win32_wofutil.py +1 -0
  905. angr/procedures/definitions/win32_ws2_32.py +1 -0
  906. angr/procedures/definitions/win32_wscapi.py +1 -0
  907. angr/procedures/definitions/win32_wsclient.py +1 -0
  908. angr/procedures/definitions/win32_wsdapi.py +1 -0
  909. angr/procedures/definitions/win32_wsmsvc.py +1 -0
  910. angr/procedures/definitions/win32_wsnmp32.py +1 -0
  911. angr/procedures/definitions/win32_wtsapi32.py +1 -0
  912. angr/procedures/definitions/win32_xaudio2_8.py +1 -0
  913. angr/procedures/definitions/win32_xinput1_4.py +1 -0
  914. angr/procedures/definitions/win32_xinputuap.py +1 -0
  915. angr/procedures/definitions/win32_xmllite.py +1 -0
  916. angr/procedures/definitions/win32_xolehlp.py +1 -0
  917. angr/procedures/definitions/win32_xpsprint.py +1 -0
  918. angr/procedures/glibc/__ctype_b_loc.py +2 -3
  919. angr/procedures/glibc/__ctype_tolower_loc.py +2 -3
  920. angr/procedures/glibc/__ctype_toupper_loc.py +2 -3
  921. angr/procedures/glibc/__errno_location.py +1 -0
  922. angr/procedures/glibc/__libc_init.py +1 -0
  923. angr/procedures/glibc/__libc_start_main.py +7 -7
  924. angr/procedures/glibc/dynamic_loading.py +1 -0
  925. angr/procedures/glibc/scanf.py +1 -0
  926. angr/procedures/glibc/sscanf.py +1 -0
  927. angr/procedures/gnulib/xalloc_die.py +1 -0
  928. angr/procedures/gnulib/xstrtol_fatal.py +1 -0
  929. angr/procedures/java/__init__.py +1 -0
  930. angr/procedures/java/unconstrained.py +3 -2
  931. angr/procedures/java_io/read.py +1 -0
  932. angr/procedures/java_io/write.py +1 -0
  933. angr/procedures/java_jni/__init__.py +8 -9
  934. angr/procedures/java_jni/array_operations.py +4 -1
  935. angr/procedures/java_jni/class_and_interface_operations.py +3 -3
  936. angr/procedures/java_jni/field_access.py +3 -6
  937. angr/procedures/java_jni/global_and_local_refs.py +1 -0
  938. angr/procedures/java_jni/method_calls.py +3 -2
  939. angr/procedures/java_jni/not_implemented.py +2 -1
  940. angr/procedures/java_jni/object_operations.py +3 -4
  941. angr/procedures/java_jni/string_operations.py +1 -0
  942. angr/procedures/java_jni/version_information.py +1 -0
  943. angr/procedures/java_lang/character.py +2 -3
  944. angr/procedures/java_lang/double.py +2 -2
  945. angr/procedures/java_lang/exit.py +1 -0
  946. angr/procedures/java_lang/getsimplename.py +2 -2
  947. angr/procedures/java_lang/integer.py +1 -0
  948. angr/procedures/java_lang/load_library.py +1 -0
  949. angr/procedures/java_lang/math.py +1 -0
  950. angr/procedures/java_lang/string.py +3 -3
  951. angr/procedures/java_lang/stringbuilder.py +1 -0
  952. angr/procedures/java_lang/system.py +1 -0
  953. angr/procedures/java_util/collection.py +1 -0
  954. angr/procedures/java_util/iterator.py +1 -0
  955. angr/procedures/java_util/list.py +1 -0
  956. angr/procedures/java_util/map.py +3 -4
  957. angr/procedures/java_util/random.py +4 -1
  958. angr/procedures/java_util/scanner_nextline.py +1 -0
  959. angr/procedures/libc/abort.py +1 -0
  960. angr/procedures/libc/access.py +5 -2
  961. angr/procedures/libc/atoi.py +2 -2
  962. angr/procedures/libc/atol.py +1 -0
  963. angr/procedures/libc/calloc.py +1 -0
  964. angr/procedures/libc/closelog.py +1 -0
  965. angr/procedures/libc/err.py +1 -0
  966. angr/procedures/libc/error.py +2 -3
  967. angr/procedures/libc/exit.py +1 -0
  968. angr/procedures/libc/fclose.py +2 -3
  969. angr/procedures/libc/feof.py +5 -3
  970. angr/procedures/libc/fflush.py +1 -0
  971. angr/procedures/libc/fgetc.py +4 -1
  972. angr/procedures/libc/fgets.py +22 -22
  973. angr/procedures/libc/fopen.py +9 -10
  974. angr/procedures/libc/fprintf.py +1 -0
  975. angr/procedures/libc/fputc.py +1 -0
  976. angr/procedures/libc/fputs.py +1 -0
  977. angr/procedures/libc/fread.py +5 -3
  978. angr/procedures/libc/free.py +1 -0
  979. angr/procedures/libc/fscanf.py +2 -2
  980. angr/procedures/libc/fseek.py +7 -5
  981. angr/procedures/libc/ftell.py +1 -0
  982. angr/procedures/libc/fwrite.py +1 -0
  983. angr/procedures/libc/getchar.py +2 -2
  984. angr/procedures/libc/getdelim.py +30 -27
  985. angr/procedures/libc/getegid.py +1 -0
  986. angr/procedures/libc/geteuid.py +1 -0
  987. angr/procedures/libc/getgid.py +1 -0
  988. angr/procedures/libc/gets.py +20 -18
  989. angr/procedures/libc/getuid.py +1 -0
  990. angr/procedures/libc/malloc.py +1 -0
  991. angr/procedures/libc/memcmp.py +21 -21
  992. angr/procedures/libc/memcpy.py +1 -0
  993. angr/procedures/libc/memset.py +10 -7
  994. angr/procedures/libc/openlog.py +1 -0
  995. angr/procedures/libc/perror.py +1 -0
  996. angr/procedures/libc/printf.py +1 -0
  997. angr/procedures/libc/putchar.py +1 -0
  998. angr/procedures/libc/puts.py +4 -1
  999. angr/procedures/libc/rand.py +1 -0
  1000. angr/procedures/libc/realloc.py +1 -0
  1001. angr/procedures/libc/rewind.py +2 -1
  1002. angr/procedures/libc/scanf.py +2 -2
  1003. angr/procedures/libc/setbuf.py +1 -0
  1004. angr/procedures/libc/setvbuf.py +1 -0
  1005. angr/procedures/libc/snprintf.py +5 -2
  1006. angr/procedures/libc/sprintf.py +4 -1
  1007. angr/procedures/libc/srand.py +1 -0
  1008. angr/procedures/libc/sscanf.py +2 -2
  1009. angr/procedures/libc/stpcpy.py +2 -2
  1010. angr/procedures/libc/strcat.py +1 -0
  1011. angr/procedures/libc/strchr.py +7 -3
  1012. angr/procedures/libc/strcmp.py +6 -3
  1013. angr/procedures/libc/strcpy.py +2 -2
  1014. angr/procedures/libc/strlen.py +38 -34
  1015. angr/procedures/libc/strncat.py +1 -0
  1016. angr/procedures/libc/strncmp.py +34 -36
  1017. angr/procedures/libc/strncpy.py +6 -2
  1018. angr/procedures/libc/strnlen.py +2 -2
  1019. angr/procedures/libc/strstr.py +17 -10
  1020. angr/procedures/libc/strtol.py +39 -41
  1021. angr/procedures/libc/strtoul.py +2 -2
  1022. angr/procedures/libc/system.py +1 -0
  1023. angr/procedures/libc/time.py +2 -2
  1024. angr/procedures/libc/tmpnam.py +1 -0
  1025. angr/procedures/libc/tolower.py +4 -1
  1026. angr/procedures/libc/toupper.py +4 -1
  1027. angr/procedures/libc/ungetc.py +1 -0
  1028. angr/procedures/libc/vsnprintf.py +1 -0
  1029. angr/procedures/libc/wchar.py +1 -0
  1030. angr/procedures/libstdcpp/_unwind_resume.py +1 -0
  1031. angr/procedures/libstdcpp/std____throw_bad_alloc.py +1 -0
  1032. angr/procedures/libstdcpp/std____throw_bad_cast.py +1 -0
  1033. angr/procedures/libstdcpp/std____throw_length_error.py +1 -0
  1034. angr/procedures/libstdcpp/std____throw_logic_error.py +1 -0
  1035. angr/procedures/libstdcpp/std__terminate.py +1 -0
  1036. angr/procedures/linux_kernel/access.py +1 -0
  1037. angr/procedures/linux_kernel/arch_prctl.py +1 -0
  1038. angr/procedures/linux_kernel/arm_user_helpers.py +1 -0
  1039. angr/procedures/linux_kernel/brk.py +1 -0
  1040. angr/procedures/linux_kernel/cwd.py +1 -0
  1041. angr/procedures/linux_kernel/fstat.py +15 -14
  1042. angr/procedures/linux_kernel/fstat64.py +17 -16
  1043. angr/procedures/linux_kernel/futex.py +3 -3
  1044. angr/procedures/linux_kernel/getegid.py +1 -0
  1045. angr/procedures/linux_kernel/geteuid.py +1 -0
  1046. angr/procedures/linux_kernel/getgid.py +1 -0
  1047. angr/procedures/linux_kernel/getpid.py +1 -0
  1048. angr/procedures/linux_kernel/getrlimit.py +3 -3
  1049. angr/procedures/linux_kernel/gettid.py +1 -0
  1050. angr/procedures/linux_kernel/getuid.py +1 -0
  1051. angr/procedures/linux_kernel/iovec.py +1 -0
  1052. angr/procedures/linux_kernel/lseek.py +6 -3
  1053. angr/procedures/linux_kernel/mmap.py +1 -0
  1054. angr/procedures/linux_kernel/mprotect.py +7 -6
  1055. angr/procedures/linux_kernel/munmap.py +1 -0
  1056. angr/procedures/linux_kernel/openat.py +3 -5
  1057. angr/procedures/linux_kernel/set_tid_address.py +1 -0
  1058. angr/procedures/linux_kernel/sigaction.py +5 -2
  1059. angr/procedures/linux_kernel/sigprocmask.py +6 -3
  1060. angr/procedures/linux_kernel/stat.py +3 -2
  1061. angr/procedures/linux_kernel/sysinfo.py +1 -0
  1062. angr/procedures/linux_kernel/tgkill.py +4 -1
  1063. angr/procedures/linux_kernel/time.py +7 -3
  1064. angr/procedures/linux_kernel/uid.py +1 -0
  1065. angr/procedures/linux_kernel/uname.py +1 -0
  1066. angr/procedures/linux_kernel/unlink.py +2 -2
  1067. angr/procedures/linux_kernel/vsyscall.py +1 -0
  1068. angr/procedures/linux_loader/_dl_initial_error_catch_tsd.py +1 -0
  1069. angr/procedures/linux_loader/_dl_rtld_lock.py +1 -0
  1070. angr/procedures/linux_loader/sim_loader.py +1 -0
  1071. angr/procedures/linux_loader/tls.py +2 -2
  1072. angr/procedures/msvcr/__getmainargs.py +1 -0
  1073. angr/procedures/msvcr/_initterm.py +1 -0
  1074. angr/procedures/msvcr/fmode.py +4 -1
  1075. angr/procedures/ntdll/exceptions.py +7 -4
  1076. angr/procedures/posix/accept.py +2 -2
  1077. angr/procedures/posix/bind.py +1 -0
  1078. angr/procedures/posix/bzero.py +4 -1
  1079. angr/procedures/posix/chroot.py +1 -0
  1080. angr/procedures/posix/close.py +2 -2
  1081. angr/procedures/posix/closedir.py +1 -0
  1082. angr/procedures/posix/dup.py +4 -3
  1083. angr/procedures/posix/fcntl.py +1 -0
  1084. angr/procedures/posix/fdopen.py +19 -20
  1085. angr/procedures/posix/fileno.py +1 -0
  1086. angr/procedures/posix/fork.py +7 -4
  1087. angr/procedures/posix/getenv.py +1 -0
  1088. angr/procedures/posix/gethostbyname.py +1 -0
  1089. angr/procedures/posix/getpass.py +1 -0
  1090. angr/procedures/posix/getsockopt.py +1 -0
  1091. angr/procedures/posix/htonl.py +2 -2
  1092. angr/procedures/posix/htons.py +2 -2
  1093. angr/procedures/posix/inet_ntoa.py +3 -5
  1094. angr/procedures/posix/listen.py +1 -0
  1095. angr/procedures/posix/mmap.py +8 -4
  1096. angr/procedures/posix/open.py +1 -0
  1097. angr/procedures/posix/opendir.py +1 -0
  1098. angr/procedures/posix/poll.py +8 -7
  1099. angr/procedures/posix/pread64.py +1 -0
  1100. angr/procedures/posix/pthread.py +3 -3
  1101. angr/procedures/posix/pwrite64.py +1 -0
  1102. angr/procedures/posix/read.py +1 -0
  1103. angr/procedures/posix/readdir.py +11 -8
  1104. angr/procedures/posix/recv.py +1 -0
  1105. angr/procedures/posix/recvfrom.py +1 -0
  1106. angr/procedures/posix/select.py +10 -8
  1107. angr/procedures/posix/send.py +6 -5
  1108. angr/procedures/posix/setsockopt.py +1 -0
  1109. angr/procedures/posix/sigaction.py +5 -2
  1110. angr/procedures/posix/sim_time.py +4 -1
  1111. angr/procedures/posix/sleep.py +1 -0
  1112. angr/procedures/posix/socket.py +2 -2
  1113. angr/procedures/posix/strcasecmp.py +4 -1
  1114. angr/procedures/posix/strdup.py +1 -0
  1115. angr/procedures/posix/strtok_r.py +38 -39
  1116. angr/procedures/posix/syslog.py +1 -0
  1117. angr/procedures/posix/tz.py +1 -0
  1118. angr/procedures/posix/unlink.py +1 -0
  1119. angr/procedures/posix/usleep.py +1 -0
  1120. angr/procedures/posix/write.py +1 -0
  1121. angr/procedures/procedure_dict.py +1 -0
  1122. angr/procedures/stubs/CallReturn.py +1 -0
  1123. angr/procedures/stubs/NoReturnUnconstrained.py +1 -0
  1124. angr/procedures/stubs/Nop.py +1 -0
  1125. angr/procedures/stubs/PathTerminator.py +1 -0
  1126. angr/procedures/stubs/Redirect.py +5 -2
  1127. angr/procedures/stubs/ReturnChar.py +4 -3
  1128. angr/procedures/stubs/ReturnUnconstrained.py +2 -1
  1129. angr/procedures/stubs/UnresolvableCallTarget.py +1 -0
  1130. angr/procedures/stubs/UnresolvableJumpTarget.py +1 -0
  1131. angr/procedures/stubs/UserHook.py +4 -1
  1132. angr/procedures/stubs/b64_decode.py +4 -1
  1133. angr/procedures/stubs/caller.py +1 -0
  1134. angr/procedures/stubs/crazy_scanf.py +7 -4
  1135. angr/procedures/stubs/format_parser.py +24 -30
  1136. angr/procedures/stubs/syscall_stub.py +6 -7
  1137. angr/procedures/testing/manyargs.py +1 -0
  1138. angr/procedures/testing/retreg.py +2 -2
  1139. angr/procedures/tracer/random.py +1 -0
  1140. angr/procedures/tracer/receive.py +6 -4
  1141. angr/procedures/tracer/transmit.py +6 -4
  1142. angr/procedures/uclibc/__uClibc_main.py +1 -0
  1143. angr/procedures/win32/EncodePointer.py +1 -0
  1144. angr/procedures/win32/ExitProcess.py +1 -0
  1145. angr/procedures/win32/GetCommandLine.py +1 -0
  1146. angr/procedures/win32/GetCurrentProcessId.py +1 -0
  1147. angr/procedures/win32/GetCurrentThreadId.py +1 -0
  1148. angr/procedures/win32/GetLastInputInfo.py +5 -2
  1149. angr/procedures/win32/GetModuleHandle.py +3 -4
  1150. angr/procedures/win32/GetProcessAffinityMask.py +5 -2
  1151. angr/procedures/win32/InterlockedExchange.py +2 -1
  1152. angr/procedures/win32/IsProcessorFeaturePresent.py +1 -0
  1153. angr/procedures/win32/VirtualAlloc.py +2 -1
  1154. angr/procedures/win32/VirtualProtect.py +1 -0
  1155. angr/procedures/win32/critical_section.py +1 -0
  1156. angr/procedures/win32/dynamic_loading.py +2 -1
  1157. angr/procedures/win32/file_handles.py +4 -4
  1158. angr/procedures/win32/gethostbyname.py +5 -3
  1159. angr/procedures/win32/heap.py +4 -1
  1160. angr/procedures/win32/is_bad_ptr.py +1 -0
  1161. angr/procedures/win32/local_storage.py +11 -8
  1162. angr/procedures/win32/mutex.py +1 -0
  1163. angr/procedures/win32/sim_time.py +9 -9
  1164. angr/procedures/win32/system_paths.py +5 -4
  1165. angr/procedures/win32_kernel/ExAllocatePool.py +1 -0
  1166. angr/procedures/win32_kernel/ExFreePoolWithTag.py +1 -0
  1167. angr/procedures/win_user32/chars.py +5 -2
  1168. angr/procedures/win_user32/keyboard.py +1 -0
  1169. angr/procedures/win_user32/messagebox.py +5 -5
  1170. angr/project.py +15 -22
  1171. angr/protos/__init__.py +1 -0
  1172. angr/serializable.py +6 -3
  1173. angr/sim_manager.py +18 -18
  1174. angr/sim_options.py +5 -7
  1175. angr/sim_procedure.py +18 -17
  1176. angr/sim_state.py +48 -59
  1177. angr/sim_state_options.py +9 -15
  1178. angr/sim_type.py +96 -126
  1179. angr/sim_variable.py +23 -38
  1180. angr/simos/__init__.py +3 -1
  1181. angr/simos/cgc.py +4 -3
  1182. angr/simos/javavm.py +77 -83
  1183. angr/simos/linux.py +53 -63
  1184. angr/simos/simos.py +16 -24
  1185. angr/simos/snimmuc_nxp.py +3 -6
  1186. angr/simos/userland.py +6 -6
  1187. angr/simos/windows.py +18 -15
  1188. angr/slicer.py +13 -11
  1189. angr/state_hierarchy.py +3 -3
  1190. angr/state_plugins/__init__.py +1 -0
  1191. angr/state_plugins/callstack.py +19 -18
  1192. angr/state_plugins/cgc.py +5 -4
  1193. angr/state_plugins/concrete.py +7 -8
  1194. angr/state_plugins/debug_variables.py +15 -17
  1195. angr/state_plugins/filesystem.py +13 -19
  1196. angr/state_plugins/gdb.py +3 -2
  1197. angr/state_plugins/globals.py +5 -1
  1198. angr/state_plugins/heap/__init__.py +1 -0
  1199. angr/state_plugins/heap/heap_base.py +1 -0
  1200. angr/state_plugins/heap/heap_brk.py +14 -9
  1201. angr/state_plugins/heap/heap_freelist.py +12 -9
  1202. angr/state_plugins/heap/heap_libc.py +1 -0
  1203. angr/state_plugins/heap/heap_ptmalloc.py +32 -40
  1204. angr/state_plugins/heap/utils.py +1 -0
  1205. angr/state_plugins/history.py +14 -15
  1206. angr/state_plugins/inspect.py +1 -0
  1207. angr/state_plugins/javavm_classloader.py +3 -2
  1208. angr/state_plugins/jni_references.py +2 -1
  1209. angr/state_plugins/libc.py +4 -4
  1210. angr/state_plugins/light_registers.py +8 -10
  1211. angr/state_plugins/log.py +1 -0
  1212. angr/state_plugins/loop_data.py +1 -0
  1213. angr/state_plugins/plugin.py +9 -10
  1214. angr/state_plugins/posix.py +39 -45
  1215. angr/state_plugins/preconstrainer.py +4 -2
  1216. angr/state_plugins/scratch.py +5 -4
  1217. angr/state_plugins/sim_action.py +15 -20
  1218. angr/state_plugins/sim_action_object.py +205 -82
  1219. angr/state_plugins/sim_event.py +1 -0
  1220. angr/state_plugins/solver.py +73 -117
  1221. angr/state_plugins/symbolizer.py +5 -6
  1222. angr/state_plugins/trace_additions.py +33 -47
  1223. angr/state_plugins/uc_manager.py +20 -11
  1224. angr/state_plugins/unicorn_engine.py +22 -38
  1225. angr/state_plugins/view.py +21 -20
  1226. angr/storage/__init__.py +1 -0
  1227. angr/storage/file.py +40 -47
  1228. angr/storage/memory_mixins/__init__.py +12 -15
  1229. angr/storage/memory_mixins/__init__.pyi +13 -14
  1230. angr/storage/memory_mixins/actions_mixin.py +5 -2
  1231. angr/storage/memory_mixins/address_concretization_mixin.py +13 -17
  1232. angr/storage/memory_mixins/bvv_conversion_mixin.py +10 -11
  1233. angr/storage/memory_mixins/clouseau_mixin.py +1 -0
  1234. angr/storage/memory_mixins/conditional_store_mixin.py +1 -0
  1235. angr/storage/memory_mixins/convenient_mappings_mixin.py +1 -0
  1236. angr/storage/memory_mixins/default_filler_mixin.py +16 -16
  1237. angr/storage/memory_mixins/dirty_addrs_mixin.py +1 -0
  1238. angr/storage/memory_mixins/hex_dumper_mixin.py +6 -9
  1239. angr/storage/memory_mixins/javavm_memory/__init__.py +1 -0
  1240. angr/storage/memory_mixins/javavm_memory/javavm_memory_mixin.py +23 -28
  1241. angr/storage/memory_mixins/keyvalue_memory/__init__.py +1 -0
  1242. angr/storage/memory_mixins/keyvalue_memory/keyvalue_memory_mixin.py +2 -1
  1243. angr/storage/memory_mixins/label_merger_mixin.py +2 -2
  1244. angr/storage/memory_mixins/multi_value_merger_mixin.py +1 -0
  1245. angr/storage/memory_mixins/name_resolution_mixin.py +12 -15
  1246. angr/storage/memory_mixins/paged_memory/page_backer_mixins.py +6 -6
  1247. angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +23 -37
  1248. angr/storage/memory_mixins/paged_memory/paged_memory_multivalue_mixin.py +1 -0
  1249. angr/storage/memory_mixins/paged_memory/pages/__init__.py +1 -2
  1250. angr/storage/memory_mixins/paged_memory/pages/cooperation.py +4 -3
  1251. angr/storage/memory_mixins/paged_memory/pages/history_tracking_mixin.py +4 -4
  1252. angr/storage/memory_mixins/paged_memory/pages/ispo_mixin.py +1 -0
  1253. angr/storage/memory_mixins/paged_memory/pages/list_page.py +12 -20
  1254. angr/storage/memory_mixins/paged_memory/pages/multi_values.py +14 -19
  1255. angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +26 -32
  1256. angr/storage/memory_mixins/paged_memory/pages/permissions_mixin.py +1 -0
  1257. angr/storage/memory_mixins/paged_memory/pages/refcount_mixin.py +2 -2
  1258. angr/storage/memory_mixins/paged_memory/pages/ultra_page.py +37 -41
  1259. angr/storage/memory_mixins/paged_memory/privileged_mixin.py +1 -0
  1260. angr/storage/memory_mixins/paged_memory/stack_allocation_mixin.py +1 -0
  1261. angr/storage/memory_mixins/regioned_memory/__init__.py +1 -0
  1262. angr/storage/memory_mixins/regioned_memory/abstract_address_descriptor.py +5 -4
  1263. angr/storage/memory_mixins/regioned_memory/abstract_merger_mixin.py +6 -21
  1264. angr/storage/memory_mixins/regioned_memory/region_category_mixin.py +1 -0
  1265. angr/storage/memory_mixins/regioned_memory/region_data.py +7 -6
  1266. angr/storage/memory_mixins/regioned_memory/region_meta_mixin.py +130 -14
  1267. angr/storage/memory_mixins/regioned_memory/regioned_address_concretization_mixin.py +2 -1
  1268. angr/storage/memory_mixins/regioned_memory/regioned_memory_mixin.py +38 -47
  1269. angr/storage/memory_mixins/regioned_memory/static_find_mixin.py +7 -9
  1270. angr/storage/memory_mixins/simple_interface_mixin.py +10 -13
  1271. angr/storage/memory_mixins/simplification_mixin.py +1 -0
  1272. angr/storage/memory_mixins/size_resolution_mixin.py +7 -4
  1273. angr/storage/memory_mixins/slotted_memory.py +4 -4
  1274. angr/storage/memory_mixins/smart_find_mixin.py +3 -2
  1275. angr/storage/memory_mixins/symbolic_merger_mixin.py +6 -3
  1276. angr/storage/memory_mixins/top_merger_mixin.py +2 -2
  1277. angr/storage/memory_mixins/underconstrained_mixin.py +12 -14
  1278. angr/storage/memory_mixins/unwrapper_mixin.py +1 -0
  1279. angr/storage/memory_object.py +30 -28
  1280. angr/storage/pcap.py +3 -3
  1281. angr/tablespecs.py +4 -3
  1282. angr/utils/__init__.py +1 -0
  1283. angr/utils/ail.py +30 -0
  1284. angr/utils/algo.py +1 -0
  1285. angr/utils/bits.py +12 -0
  1286. angr/utils/constants.py +2 -0
  1287. angr/utils/cowdict.py +3 -4
  1288. angr/utils/dynamic_dictlist.py +4 -7
  1289. angr/utils/endness.py +1 -0
  1290. angr/utils/enums_conv.py +1 -0
  1291. angr/utils/env.py +1 -0
  1292. angr/utils/formatting.py +1 -0
  1293. angr/utils/funcid.py +15 -14
  1294. angr/utils/graph.py +52 -19
  1295. angr/utils/lazy_import.py +1 -0
  1296. angr/utils/library.py +10 -13
  1297. angr/utils/loader.py +6 -6
  1298. angr/utils/mp.py +4 -3
  1299. angr/utils/orderedset.py +1 -0
  1300. angr/utils/segment_list.py +7 -9
  1301. angr/utils/ssa/__init__.py +198 -0
  1302. angr/utils/ssa/tmp_uses_collector.py +23 -0
  1303. angr/utils/ssa/vvar_uses_collector.py +37 -0
  1304. angr/utils/timing.py +2 -2
  1305. angr/utils/typing.py +1 -0
  1306. angr/vaults.py +7 -8
  1307. {angr-9.2.116.dist-info → angr-9.2.118.dist-info}/METADATA +7 -8
  1308. angr-9.2.118.dist-info/RECORD +1344 -0
  1309. {angr-9.2.116.dist-info → angr-9.2.118.dist-info}/WHEEL +1 -1
  1310. angr/analyses/decompiler/optimization_passes/spilled_register_finder.py +0 -18
  1311. angr/analyses/decompiler/seq_cf_structure_counter.py +0 -37
  1312. angr/service.py +0 -35
  1313. angr-9.2.116.dist-info/RECORD +0 -1310
  1314. {angr-9.2.116.dist-info → angr-9.2.118.dist-info}/LICENSE +0 -0
  1315. {angr-9.2.116.dist-info → angr-9.2.118.dist-info}/entry_points.txt +0 -0
  1316. {angr-9.2.116.dist-info → angr-9.2.118.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,12 @@
1
- # pylint:disable=too-many-boolean-expressions
2
- from typing import Any, Optional, TYPE_CHECKING
1
+ # pylint:disable=too-many-boolean-expressions,consider-using-enumerate
2
+ from __future__ import annotations
3
+ from typing import Any, TYPE_CHECKING
4
+ from collections.abc import Iterable
3
5
  from collections import defaultdict
4
6
  import logging
5
7
 
8
+ import networkx
9
+
6
10
  from ailment import AILBlockWalker
7
11
  from ailment.block import Block
8
12
  from ailment.statement import Statement, Assignment, Store, Call, ConditionalJump, DirtyStatement
@@ -17,14 +21,16 @@ from ailment.expression import (
17
21
  Tmp,
18
22
  Const,
19
23
  BinaryOp,
24
+ VirtualVariable,
25
+ Phi,
20
26
  )
21
27
 
22
- from ...engines.light import SpOffset
28
+ from angr.analyses.s_reaching_definitions import SRDAModel
29
+ from angr.utils.ail import is_phi_assignment, HasExprWalker
23
30
  from ...code_location import CodeLocation, ExternalCodeLocation
24
- from ...sim_variable import SimStackVariable, SimMemoryVariable
31
+ from ...sim_variable import SimStackVariable, SimMemoryVariable, SimVariable
25
32
  from ...knowledge_plugins.propagations.states import Equivalence
26
33
  from ...knowledge_plugins.key_definitions import atoms
27
- from ...knowledge_plugins.key_definitions.atoms import Register as RegisterAtom
28
34
  from ...knowledge_plugins.key_definitions.definition import Definition
29
35
  from ...knowledge_plugins.key_definitions.constants import OP_BEFORE
30
36
  from ...errors import AngrRuntimeError
@@ -33,11 +39,10 @@ from .ailgraph_walker import AILGraphWalker
33
39
  from .expression_narrower import ExpressionNarrowingWalker
34
40
  from .block_simplifier import BlockSimplifier
35
41
  from .ccall_rewriters import CCALL_REWRITERS
36
- from .expression_counters import SingleExpressionCounter
42
+ from .counters.expression_counters import SingleExpressionCounter
37
43
 
38
44
  if TYPE_CHECKING:
39
45
  from ailment.manager import Manager
40
- from angr.analyses.reaching_definitions import ReachingDefinitionsModel
41
46
 
42
47
 
43
48
  _l = logging.getLogger(__name__)
@@ -49,6 +54,12 @@ class HasCallNotification(Exception):
49
54
  """
50
55
 
51
56
 
57
+ class HasVVarNotification(Exception):
58
+ """
59
+ Notifies the existence of a VirtualVariable.
60
+ """
61
+
62
+
52
63
  class AILBlockTempCollector(AILBlockWalker):
53
64
  """
54
65
  Collects any temporaries used in a block.
@@ -65,6 +76,26 @@ class AILBlockTempCollector(AILBlockWalker):
65
76
  self.temps.add(expr)
66
77
 
67
78
 
79
+ class ExprNarrowingInfo:
80
+ """
81
+ Stores the analysis result of _narrowing_needed().
82
+ """
83
+
84
+ __slots__ = ("narrowable", "to_size", "use_exprs", "phi_vars")
85
+
86
+ def __init__(
87
+ self,
88
+ narrowable: bool,
89
+ to_size: int | None = None,
90
+ use_exprs: list[tuple[atoms.VirtualVariable, CodeLocation, tuple[str, tuple[Expression, ...]]]] | None = None,
91
+ phi_vars: set[atoms.VirtualVariable] | None = None,
92
+ ):
93
+ self.narrowable = narrowable
94
+ self.to_size = to_size
95
+ self.use_exprs = use_exprs
96
+ self.phi_vars = phi_vars
97
+
98
+
68
99
  class AILSimplifier(Analysis):
69
100
  """
70
101
  Perform function-level simplifications.
@@ -77,29 +108,33 @@ class AILSimplifier(Analysis):
77
108
  remove_dead_memdefs=False,
78
109
  stack_arg_offsets: set[tuple[int, int]] | None = None,
79
110
  unify_variables=False,
80
- ail_manager: Optional["Manager"] = None,
111
+ ail_manager: Manager | None = None,
81
112
  gp: int | None = None,
82
113
  narrow_expressions=False,
83
114
  only_consts=False,
84
115
  fold_callexprs_into_conditions=False,
85
116
  use_callee_saved_regs_at_return=True,
86
117
  rewrite_ccalls=True,
118
+ removed_vvar_ids: set[int] | None = None,
119
+ arg_vvars: dict[int, tuple[VirtualVariable, SimVariable]] | None = None,
87
120
  ):
88
121
  self.func = func
89
122
  self.func_graph = func_graph if func_graph is not None else func.graph
90
- self._reaching_definitions: Optional["ReachingDefinitionsModel"] = None
123
+ self._reaching_definitions: SRDAModel | None = None
91
124
  self._propagator = None
92
125
 
93
126
  self._remove_dead_memdefs = remove_dead_memdefs
94
127
  self._stack_arg_offsets = stack_arg_offsets
95
128
  self._unify_vars = unify_variables
96
- self._ail_manager = ail_manager
129
+ self._ail_manager: Manager | None = ail_manager
97
130
  self._gp = gp
98
131
  self._narrow_expressions = narrow_expressions
99
132
  self._only_consts = only_consts
100
133
  self._fold_callexprs_into_conditions = fold_callexprs_into_conditions
101
134
  self._use_callee_saved_regs_at_return = use_callee_saved_regs_at_return
102
135
  self._should_rewrite_ccalls = rewrite_ccalls
136
+ self._removed_vvar_ids = removed_vvar_ids if removed_vvar_ids is not None else set()
137
+ self._arg_vvars = arg_vvars
103
138
 
104
139
  self._calls_to_remove: set[CodeLocation] = set()
105
140
  self._assignments_to_remove: set[CodeLocation] = set()
@@ -110,6 +145,14 @@ class AILSimplifier(Analysis):
110
145
 
111
146
  def _simplify(self):
112
147
  if self._narrow_expressions:
148
+ _l.debug("Removing dead assignments before narrowing expressions")
149
+ r = self._remove_dead_assignments()
150
+ if r:
151
+ _l.debug("... dead assignments removed")
152
+ self.simplified = True
153
+ self._rebuild_func_graph()
154
+ self._clear_cache()
155
+
113
156
  _l.debug("Narrowing expressions")
114
157
  narrowed_exprs = self._narrow_exprs()
115
158
  self.simplified |= narrowed_exprs
@@ -162,6 +205,7 @@ class AILSimplifier(Analysis):
162
205
  _l.debug("... call expressions folded")
163
206
  self.simplified = True
164
207
  self._rebuild_func_graph()
208
+ self._clear_cache()
165
209
 
166
210
  _l.debug("Removing dead assignments")
167
211
  r = self._remove_dead_assignments()
@@ -177,18 +221,15 @@ class AILSimplifier(Analysis):
177
221
  AILGraphWalker(self.func_graph, _handler, replace_nodes=True).walk()
178
222
  self.blocks = {}
179
223
 
180
- def _compute_reaching_definitions(self) -> "ReachingDefinitionsModel":
224
+ def _compute_reaching_definitions(self) -> SRDAModel:
181
225
  # Computing reaching definitions or return the cached one
182
226
  if self._reaching_definitions is not None:
183
227
  return self._reaching_definitions
184
- rd = self.project.analyses.ReachingDefinitions(
228
+ rd = self.project.analyses.SReachingDefinitions(
185
229
  subject=self.func,
186
230
  func_graph=self.func_graph,
187
- # init_context=(), <-- in case of fire break glass
188
- observe_all=False,
189
- use_callee_saved_regs_at_return=self._use_callee_saved_regs_at_return,
190
- track_tmps=True,
191
- element_limit=1,
231
+ # use_callee_saved_regs_at_return=self._use_callee_saved_regs_at_return,
232
+ # track_tmps=True,
192
233
  ).model
193
234
  self._reaching_definitions = rd
194
235
  return rd
@@ -197,17 +238,47 @@ class AILSimplifier(Analysis):
197
238
  # Propagate expressions or return the existing result
198
239
  if self._propagator is not None:
199
240
  return self._propagator
200
- prop = self.project.analyses.Propagator(
201
- func=self.func,
241
+ prop = self.project.analyses.SPropagator(
242
+ subject=self.func,
202
243
  func_graph=self.func_graph,
203
- gp=self._gp,
244
+ # gp=self._gp,
204
245
  only_consts=self._only_consts,
205
- reaching_definitions=self._compute_reaching_definitions(),
206
246
  immediate_stmt_removal=immediate_stmt_removal,
207
247
  )
208
248
  self._propagator = prop
209
249
  return prop
210
250
 
251
+ def _compute_equivalence(self) -> set[Equivalence]:
252
+ equivalence = set()
253
+ for block in self.func_graph:
254
+ for stmt_idx, stmt in enumerate(block.statements):
255
+ if isinstance(stmt, Assignment):
256
+ if isinstance(stmt.dst, VirtualVariable) and isinstance(
257
+ stmt.src, (VirtualVariable, Tmp, Call, Convert)
258
+ ):
259
+ codeloc = CodeLocation(block.addr, stmt_idx, block_idx=block.idx, ins_addr=stmt.ins_addr)
260
+ equivalence.add(Equivalence(codeloc, stmt.dst, stmt.src))
261
+ elif isinstance(stmt, Call):
262
+ if isinstance(stmt.ret_expr, (VirtualVariable, Load)):
263
+ codeloc = CodeLocation(block.addr, stmt_idx, block_idx=block.idx, ins_addr=stmt.ins_addr)
264
+ equivalence.add(Equivalence(codeloc, stmt.ret_expr, stmt))
265
+ elif (
266
+ isinstance(stmt, Store)
267
+ and isinstance(stmt.size, int)
268
+ and isinstance(stmt.data, (VirtualVariable, Tmp, Call, Convert))
269
+ ):
270
+ if isinstance(stmt.addr, StackBaseOffset) and isinstance(stmt.addr.offset, int):
271
+ # stack variable
272
+ atom = SimStackVariable(stmt.addr.offset, stmt.size)
273
+ codeloc = CodeLocation(block.addr, stmt_idx, block_idx=block.idx, ins_addr=stmt.ins_addr)
274
+ equivalence.add(Equivalence(codeloc, atom, stmt.data))
275
+ elif isinstance(stmt.addr, Const):
276
+ # global variable
277
+ atom = SimMemoryVariable(stmt.addr.value, stmt.size)
278
+ codeloc = CodeLocation(block.addr, stmt_idx, block_idx=block.idx, ins_addr=stmt.ins_addr)
279
+ equivalence.add(Equivalence(codeloc, atom, stmt.data))
280
+ return equivalence
281
+
211
282
  def _clear_cache(self) -> None:
212
283
  self._propagator = None
213
284
  self._reaching_definitions = None
@@ -237,8 +308,9 @@ class AILSimplifier(Analysis):
237
308
 
238
309
  rd = self._compute_reaching_definitions()
239
310
  sorted_defs = sorted(rd.all_definitions, key=lambda d: d.codeloc, reverse=True)
311
+ narrowing_candidates: dict[int, tuple[Definition, ExprNarrowingInfo]] = {}
240
312
  for def_ in (d_ for d_ in sorted_defs if d_.codeloc.context is None):
241
- if isinstance(def_.atom, atoms.Register):
313
+ if isinstance(def_.atom, atoms.VirtualVariable) and (def_.atom.was_reg or def_.atom.was_parameter):
242
314
  # only do this for general purpose register
243
315
  skip_def = False
244
316
  for reg in self.project.arch.register_list:
@@ -249,250 +321,511 @@ class AILSimplifier(Analysis):
249
321
  if skip_def:
250
322
  continue
251
323
 
252
- needs_narrowing, to_size, use_exprs = self._narrowing_needed(def_, rd, addr_and_idx_to_block)
253
- if needs_narrowing:
254
- # replace the definition
255
- if not isinstance(def_.codeloc, ExternalCodeLocation):
256
- old_block = addr_and_idx_to_block.get((def_.codeloc.block_addr, def_.codeloc.block_idx))
257
- if old_block is None:
258
- # this definition might be inside a callee function, which is why the block does not exist
259
- # ignore it
260
- continue
324
+ narrow = self._narrowing_needed(def_, rd, addr_and_idx_to_block)
325
+ if narrow.narrowable:
326
+ # we cannot narrow it immediately because any definition that is used by phi variables must be
327
+ # narrowed together with all other definitions that can reach the phi variables.
328
+ # so we record the information and decide if we are going to narrow these expressions or not at the
329
+ # end of the loop.
330
+ narrowing_candidates[def_.atom.varid] = def_, narrow
331
+
332
+ # first, determine which phi vars need to be narrowed and can be narrowed.
333
+ # a phi var can only be narrowed if all its source vvars are narrowable
334
+ vvar_to_narrowing_size = {}
335
+ for def_varid, (_, narrow_info) in narrowing_candidates.items():
336
+ vvar_to_narrowing_size[def_varid] = narrow_info.to_size
337
+
338
+ blacklist_varids = set()
339
+ while True:
340
+ repeat, narrowables = self._compute_narrowables_once(
341
+ rd, narrowing_candidates, vvar_to_narrowing_size, blacklist_varids
342
+ )
343
+ if not repeat:
344
+ break
261
345
 
262
- the_block = self.blocks.get(old_block, old_block)
263
- stmt = the_block.statements[def_.codeloc.stmt_idx]
264
- r, new_block = False, None
265
- if isinstance(stmt, Assignment) and isinstance(stmt.dst, Register):
266
- tags = dict(stmt.dst.tags)
267
- tags["reg_name"] = self.project.arch.translate_register_name(
268
- def_.atom.reg_offset, size=to_size
269
- )
270
- tags["write_size"] = stmt.dst.size
271
- new_assignment_dst = Register(
272
- stmt.dst.idx,
273
- None,
274
- def_.atom.reg_offset,
275
- to_size * self.project.arch.byte_width,
276
- **tags,
277
- )
278
- new_assignment_src = Convert(
279
- stmt.src.idx, # FIXME: This is a hack
280
- stmt.src.bits,
281
- to_size * self.project.arch.byte_width,
282
- False,
283
- stmt.src,
284
- **stmt.src.tags,
285
- )
286
- r, new_block = BlockSimplifier._replace_and_build(
287
- the_block,
288
- {
289
- def_.codeloc: {
290
- stmt.dst: new_assignment_dst,
291
- stmt.src: new_assignment_src,
292
- }
293
- },
294
- replace_assignment_dsts=True,
295
- replace_loads=True,
296
- )
297
- elif isinstance(stmt, Call):
298
- if stmt.ret_expr is not None:
299
- tags = dict(stmt.ret_expr.tags)
300
- tags["reg_name"] = self.project.arch.translate_register_name(
301
- def_.atom.reg_offset, size=to_size
302
- )
303
- new_retexpr = Register(
304
- stmt.ret_expr.idx,
305
- None,
306
- def_.atom.reg_offset,
307
- to_size * self.project.arch.byte_width,
308
- **tags,
309
- )
310
- r, new_block = BlockSimplifier._replace_and_build(
311
- the_block, {def_.codeloc: {stmt.ret_expr: new_retexpr}}
312
- )
313
- if not r:
314
- # couldn't replace the definition...
315
- continue
316
- self.blocks[old_block] = new_block
346
+ replaced_vvar_ids = set()
317
347
 
318
- # replace all uses if necessary
319
- for use_loc, (use_type, use_expr_tpl) in use_exprs:
320
- if isinstance(use_expr_tpl[0], Register) and to_size == use_expr_tpl[0].size:
321
- # don't replace registers to the same registers
322
- continue
348
+ # let's narrow them (finally)
349
+ for def_, narrow_info in narrowables:
323
350
 
324
- old_block = addr_and_idx_to_block.get((use_loc.block_addr, use_loc.block_idx))
325
- the_block = self.blocks.get(old_block, old_block)
351
+ # does any uses involve a previously replaced expressions? if so, we have to skip this one because the use
352
+ # expression may no longer exist.
353
+ should_skip = False
354
+ for _, _, (use_type, use_expr_tpl) in narrow_info.use_exprs:
355
+ if use_type == "binop-convert" and self._exprs_contain_vvar(use_expr_tpl, replaced_vvar_ids):
356
+ should_skip = True
357
+ break
358
+ if should_skip:
359
+ continue
326
360
 
327
- if use_type in {"expr", "mask", "convert"}:
328
- # the first used expr
329
- use_expr_0 = use_expr_tpl[0]
330
- tags = dict(use_expr_0.tags)
331
- tags["reg_name"] = self.project.arch.translate_register_name(
332
- def_.atom.reg_offset, size=to_size
361
+ # replace the definition
362
+ if not isinstance(def_.codeloc, ExternalCodeLocation):
363
+ old_block = addr_and_idx_to_block.get((def_.codeloc.block_addr, def_.codeloc.block_idx))
364
+ if old_block is None:
365
+ # this definition might be inside a callee function, which is why the block does not exist
366
+ # ignore it
367
+ continue
368
+
369
+ the_block = self.blocks.get(old_block, old_block)
370
+ stmt = the_block.statements[def_.codeloc.stmt_idx]
371
+ r, new_block = False, None
372
+ replaced_vvar: VirtualVariable | None = None
373
+ if is_phi_assignment(stmt):
374
+ new_assignment_dst = VirtualVariable(
375
+ stmt.dst.idx,
376
+ stmt.dst.varid,
377
+ narrow_info.to_size * self.project.arch.byte_width,
378
+ category=def_.atom.category,
379
+ oident=def_.atom.oident,
380
+ **stmt.dst.tags,
381
+ )
382
+ new_src_and_vvars = []
383
+ for src, vvar in stmt.src.src_and_vvars:
384
+ if vvar is not None and vvar.varid == stmt.dst.varid:
385
+ new_vvar = VirtualVariable(
386
+ vvar.idx,
387
+ vvar.varid,
388
+ narrow_info.to_size * self.project.arch.byte_width,
389
+ category=vvar.category,
390
+ oident=vvar.oident,
391
+ **vvar.tags,
333
392
  )
334
- new_use_expr_0 = Register(
335
- use_expr_0.idx,
393
+ else:
394
+ new_vvar = vvar
395
+ new_src_and_vvars.append((src, new_vvar))
396
+ new_assignment_src = Phi(
397
+ stmt.src.idx,
398
+ narrow_info.to_size * self.project.arch.byte_width,
399
+ new_src_and_vvars,
400
+ **stmt.src.tags,
401
+ )
402
+ replaced_vvar = stmt.dst
403
+ r, new_block = BlockSimplifier._replace_and_build(
404
+ the_block,
405
+ {
406
+ def_.codeloc: {
407
+ stmt.dst: new_assignment_dst,
408
+ stmt.src: new_assignment_src,
409
+ }
410
+ },
411
+ replace_assignment_dsts=True,
412
+ replace_loads=True,
413
+ )
414
+ elif isinstance(stmt, Assignment) and isinstance(stmt.dst, VirtualVariable) and stmt.dst.was_reg:
415
+ new_assignment_dst = VirtualVariable(
416
+ stmt.dst.idx,
417
+ stmt.dst.varid,
418
+ narrow_info.to_size * self.project.arch.byte_width,
419
+ category=def_.atom.category,
420
+ oident=def_.atom.oident,
421
+ **stmt.dst.tags,
422
+ )
423
+ new_assignment_src = Convert(
424
+ stmt.src.idx, # FIXME: This is a hack
425
+ stmt.src.bits,
426
+ narrow_info.to_size * self.project.arch.byte_width,
427
+ False,
428
+ stmt.src,
429
+ **stmt.src.tags,
430
+ )
431
+ replaced_vvar = stmt.dst
432
+ r, new_block = BlockSimplifier._replace_and_build(
433
+ the_block,
434
+ {
435
+ def_.codeloc: {
436
+ stmt.dst: new_assignment_dst,
437
+ stmt.src: new_assignment_src,
438
+ }
439
+ },
440
+ replace_assignment_dsts=True,
441
+ replace_loads=True,
442
+ )
443
+ elif isinstance(stmt, Call):
444
+ if stmt.ret_expr is not None:
445
+ tags = dict(stmt.ret_expr.tags)
446
+ tags["reg_name"] = self.project.arch.translate_register_name(
447
+ def_.atom.reg_offset, size=narrow_info.to_size
448
+ )
449
+ replaced_vvar = stmt.ret_expr
450
+ new_retexpr = VirtualVariable(
451
+ stmt.ret_expr.idx,
452
+ stmt.ret_expr.varid,
453
+ narrow_info.to_size * self.project.arch.byte_width,
454
+ category=def_.atom.category,
455
+ oident=def_.atom.oident,
456
+ **stmt.ret_expr.tags,
457
+ )
458
+ r, new_block = BlockSimplifier._replace_and_build(
459
+ the_block, {def_.codeloc: {stmt.ret_expr: new_retexpr}}
460
+ )
461
+ if not r:
462
+ # couldn't replace the definition...
463
+ continue
464
+ self.blocks[old_block] = new_block
465
+ if replaced_vvar is not None:
466
+ replaced_vvar_ids.add(replaced_vvar.varid)
467
+
468
+ use_exprs = list(narrow_info.use_exprs)
469
+ if narrow_info.phi_vars:
470
+ for phi_var in narrow_info.phi_vars:
471
+ loc = rd.all_vvar_definitions[phi_var]
472
+ old_block = addr_and_idx_to_block.get((loc.block_addr, loc.block_idx))
473
+ the_block = self.blocks.get(old_block, old_block)
474
+ stmt = the_block.statements[loc.stmt_idx]
475
+ assert is_phi_assignment(stmt)
476
+
477
+ for _, vvar in stmt.src.src_and_vvars:
478
+ if vvar.varid == def_.atom.varid:
479
+ use_exprs.append((vvar, loc, ("phi-src-expr", (vvar,))))
480
+
481
+ # replace all uses if necessary
482
+ for use_atom, use_loc, (use_type, use_expr_tpl) in use_exprs:
483
+ if (
484
+ isinstance(use_expr_tpl[0], VirtualVariable)
485
+ and use_expr_tpl[0].was_reg
486
+ and narrow_info.to_size == use_expr_tpl[0].size
487
+ ):
488
+ # don't replace registers to the same registers
489
+ continue
490
+ if use_atom.varid != def_.atom.varid:
491
+ # don't replace this use - it will be replaced later
492
+ continue
493
+
494
+ old_block = addr_and_idx_to_block.get((use_loc.block_addr, use_loc.block_idx))
495
+ the_block = self.blocks.get(old_block, old_block)
496
+
497
+ if use_type in {"expr", "mask", "convert"}:
498
+ # the first used expr
499
+ use_expr_0 = use_expr_tpl[0]
500
+ new_use_expr_0 = VirtualVariable(
501
+ use_expr_0.idx,
502
+ def_.atom.varid,
503
+ narrow_info.to_size * self.project.arch.byte_width,
504
+ category=def_.atom.category,
505
+ oident=def_.atom.oident,
506
+ **use_expr_0.tags,
507
+ )
508
+ new_use_expr = new_use_expr_0
509
+
510
+ # the second used expr (if it exists)
511
+ if len(use_expr_tpl) == 2:
512
+ use_expr_1 = use_expr_tpl[1]
513
+ assert isinstance(use_expr_1, BinaryOp)
514
+ con = use_expr_1.operands[1]
515
+ assert isinstance(con, Const)
516
+ new_use_expr_1 = BinaryOp(
517
+ use_expr_1.idx,
518
+ use_expr_1.op,
519
+ [
520
+ new_use_expr_0,
521
+ Const(con.idx, con.variable, con.value, new_use_expr_0.bits, **con.tags),
522
+ ],
523
+ use_expr_1.signed,
524
+ floating_point=use_expr_1.floating_point,
525
+ rounding_mode=use_expr_1.rounding_mode,
526
+ **use_expr_1.tags,
527
+ )
528
+
529
+ if use_expr_1.size > new_use_expr_1.size:
530
+ new_use_expr_1 = Convert(
336
531
  None,
337
- def_.atom.reg_offset,
338
- to_size * self.project.arch.byte_width,
339
- **tags,
532
+ new_use_expr_1.bits,
533
+ use_expr_1.bits,
534
+ False,
535
+ new_use_expr_1,
536
+ **new_use_expr_1.tags,
340
537
  )
341
538
 
342
- # the second used expr (if it exists)
343
- if len(use_expr_tpl) == 2:
344
- use_expr_1 = use_expr_tpl[1]
345
- assert isinstance(use_expr_1, BinaryOp)
346
- con = use_expr_1.operands[1]
347
- assert isinstance(con, Const)
348
- new_use_expr_1 = BinaryOp(
349
- use_expr_1.idx,
350
- use_expr_1.op,
351
- [
352
- new_use_expr_0,
353
- Const(con.idx, con.variable, con.value, new_use_expr_0.bits, **con.tags),
354
- ],
355
- use_expr_1.signed,
356
- floating_point=use_expr_1.floating_point,
357
- rounding_mode=use_expr_1.rounding_mode,
358
- **use_expr_1.tags,
359
- )
360
-
361
- if use_expr_1.size > new_use_expr_1.size:
362
- new_use_expr_1 = Convert(
363
- None,
364
- new_use_expr_1.bits,
365
- use_expr_1.bits,
366
- False,
367
- new_use_expr_1,
368
- **new_use_expr_1.tags,
369
- )
370
-
371
- r, new_block = BlockSimplifier._replace_and_build(
372
- the_block, {use_loc: {use_expr_1: new_use_expr_1}}
373
- )
374
- elif len(use_expr_tpl) == 1:
375
- if use_expr_0.size > new_use_expr_0.size:
376
- new_use_expr_0 = Convert(
377
- None,
378
- new_use_expr_0.bits,
379
- use_expr_0.bits,
380
- False,
381
- new_use_expr_0,
382
- **new_use_expr_0.tags,
383
- )
384
-
385
- r, new_block = BlockSimplifier._replace_and_build(
386
- the_block, {use_loc: {use_expr_0: new_use_expr_0}}
387
- )
388
- else:
389
- _l.warning("Nothing to replace at %s.", use_loc)
390
- r = False
391
- new_block = None
392
- elif use_type == "binop-convert":
393
- use_expr_0 = use_expr_tpl[0]
394
- tags = dict(use_expr_0.tags)
395
- tags["reg_name"] = self.project.arch.translate_register_name(
396
- def_.atom.reg_offset, size=to_size
397
- )
398
- new_use_expr_0 = Register(
399
- use_expr_0.idx,
539
+ r, new_block = BlockSimplifier._replace_and_build(
540
+ the_block, {use_loc: {use_expr_1: new_use_expr_1}}
541
+ )
542
+ elif len(use_expr_tpl) == 1:
543
+ if use_expr_0.size > new_use_expr_0.size:
544
+ new_use_expr_0 = Convert(
400
545
  None,
401
- def_.atom.reg_offset,
402
- to_size * self.project.arch.byte_width,
403
- **tags,
546
+ new_use_expr_0.bits,
547
+ use_expr_0.bits,
548
+ False,
549
+ new_use_expr_0,
550
+ **new_use_expr_0.tags,
404
551
  )
405
552
 
406
- use_expr_1: BinaryOp = use_expr_tpl[1]
407
- # build the new use_expr_1
408
- new_use_expr_1_operands = {}
409
- if use_expr_1.operands[0] is use_expr_0:
410
- new_use_expr_1_operands[0] = new_use_expr_0
411
- other_operand = use_expr_1.operands[1]
412
- else:
413
- new_use_expr_1_operands[1] = new_use_expr_0
414
- other_operand = use_expr_1.operands[0]
415
- use_expr_2: Convert = use_expr_tpl[2]
416
- if other_operand.bits == use_expr_2.from_bits:
417
- new_other_operand = Convert(
418
- None, use_expr_2.from_bits, use_expr_2.to_bits, False, other_operand
419
- )
420
- else:
421
- # Some operations, like Sar and Shl, have operands with different sizes
422
- new_other_operand = other_operand
423
-
424
- if 0 in new_use_expr_1_operands:
425
- new_use_expr_1_operands[1] = new_other_operand
426
- else:
427
- new_use_expr_1_operands[0] = new_other_operand
428
-
429
- # build new use_expr_1
430
- new_use_expr_1 = BinaryOp(
431
- use_expr_1.idx,
432
- use_expr_1.op,
433
- [new_use_expr_1_operands[0], new_use_expr_1_operands[1]],
434
- use_expr_1.signed,
435
- bits=to_size * 8,
436
- floating_point=use_expr_1.floating_point,
437
- rounding_mode=use_expr_1.rounding_mode,
438
- **use_expr_1.tags,
439
- )
553
+ r, new_block = BlockSimplifier._replace_and_build(
554
+ the_block, {use_loc: {use_expr_0: new_use_expr_0}}
555
+ )
556
+ else:
557
+ _l.warning("Nothing to replace at %s.", use_loc)
558
+ r = False
559
+ new_block = None
560
+
561
+ elif use_type == "phi-src-expr":
562
+ # the size of the replaced variable will be different from its original size, and it's expected
563
+ use_expr = use_expr_tpl[0]
564
+ new_use_expr = VirtualVariable(
565
+ use_expr.idx,
566
+ def_.atom.varid,
567
+ narrow_info.to_size * self.project.arch.byte_width,
568
+ category=def_.atom.category,
569
+ oident=def_.atom.oident,
570
+ **use_expr.tags,
571
+ )
572
+ r, new_block = BlockSimplifier._replace_and_build(the_block, {use_loc: {use_expr: new_use_expr}})
573
+
574
+ elif use_type == "binop-convert":
575
+ use_expr_0 = use_expr_tpl[0]
576
+ new_use_expr_0 = VirtualVariable(
577
+ use_expr_0.idx,
578
+ def_.atom.varid,
579
+ narrow_info.to_size * self.project.arch.byte_width,
580
+ category=def_.atom.category,
581
+ oident=def_.atom.oident,
582
+ **use_expr_0.tags,
583
+ )
584
+ new_use_expr = new_use_expr_0
585
+
586
+ use_expr_1: BinaryOp = use_expr_tpl[1]
587
+ # build the new use_expr_1
588
+ new_use_expr_1_operands = {}
589
+ if use_expr_1.operands[0] is use_expr_0:
590
+ new_use_expr_1_operands[0] = new_use_expr_0
591
+ other_operand = use_expr_1.operands[1]
592
+ else:
593
+ new_use_expr_1_operands[1] = new_use_expr_0
594
+ other_operand = use_expr_1.operands[0]
595
+ use_expr_2: Convert = use_expr_tpl[2]
596
+ if other_operand.bits == use_expr_2.from_bits:
597
+ new_other_operand = Convert(
598
+ None, use_expr_2.from_bits, use_expr_2.to_bits, False, other_operand
599
+ )
600
+ else:
601
+ # Some operations, like Sar and Shl, have operands with different sizes
602
+ new_other_operand = other_operand
440
603
 
441
- # first remove the old conversion
442
- r, new_block = BlockSimplifier._replace_and_build(
443
- the_block, {use_loc: {use_expr_2: use_expr_2.operand}}
444
- )
445
- # then replace use_expr_1
446
- if r:
447
- r, new_block = BlockSimplifier._replace_and_build(
448
- new_block, {use_loc: {use_expr_1: new_use_expr_1}}
449
- )
450
- else:
451
- raise TypeError(f'Unsupported use_type value "{use_type}"')
604
+ if 0 in new_use_expr_1_operands:
605
+ new_use_expr_1_operands[1] = new_other_operand
606
+ else:
607
+ new_use_expr_1_operands[0] = new_other_operand
608
+
609
+ # build new use_expr_1
610
+ new_use_expr_1 = BinaryOp(
611
+ use_expr_1.idx,
612
+ use_expr_1.op,
613
+ [new_use_expr_1_operands[0], new_use_expr_1_operands[1]],
614
+ use_expr_1.signed,
615
+ bits=narrow_info.to_size * 8,
616
+ floating_point=use_expr_1.floating_point,
617
+ rounding_mode=use_expr_1.rounding_mode,
618
+ **use_expr_1.tags,
619
+ )
452
620
 
453
- if not r:
454
- _l.warning("Failed to replace use-expr at %s.", use_loc)
455
- else:
456
- self.blocks[old_block] = new_block
621
+ # first remove the old conversion
622
+ r, new_block = BlockSimplifier._replace_and_build(
623
+ the_block, {use_loc: {use_expr_2: use_expr_2.operand}}
624
+ )
625
+ # then replace use_expr_1
626
+ if r:
627
+ r, new_block = BlockSimplifier._replace_and_build(
628
+ new_block, {use_loc: {use_expr_1: new_use_expr_1}}
629
+ )
630
+ else:
631
+ raise TypeError(f'Unsupported use_type value "{use_type}"')
457
632
 
458
- narrowed = True
633
+ if not r:
634
+ _l.warning("Failed to replace use-expr at %s.", use_loc)
635
+ else:
636
+ # update self._arg_vvars if necessary
637
+ if new_use_expr is not None and new_use_expr.was_parameter and self._arg_vvars:
638
+ for func_arg_idx in list(self._arg_vvars):
639
+ vvar, simvar = self._arg_vvars[func_arg_idx]
640
+ if vvar.varid == new_use_expr.varid:
641
+ simvar_new = simvar.copy()
642
+ simvar_new._hash = None
643
+ simvar_new.size = new_use_expr.size
644
+ self._arg_vvars[func_arg_idx] = new_use_expr, simvar_new
645
+
646
+ self.blocks[old_block] = new_block
647
+
648
+ narrowed = True
459
649
 
460
650
  return narrowed
461
651
 
462
- def _narrowing_needed(
463
- self, def_, rd, addr_and_idx_to_block
464
- ) -> tuple[bool, int | None, list[tuple[CodeLocation, tuple[str, tuple[Expression, ...]]]] | None]:
652
+ @staticmethod
653
+ def _compute_narrowables_once(
654
+ rd, narrowing_candidates: dict, vvar_to_narrowing_size: dict[int, int], blacklist_varids: set
655
+ ):
656
+ repeat = False
657
+ narrowable_phivarids = set()
658
+ for def_vvarid, (_, narrow_info) in narrowing_candidates.items():
659
+ if def_vvarid in blacklist_varids:
660
+ continue
661
+ if def_vvarid in rd.phi_vvar_ids:
662
+ narrowing_sizes = set()
663
+ src_vvarids = rd.phivarid_to_varids[def_vvarid]
664
+ for vvarid in src_vvarids:
665
+ if vvarid in blacklist_varids:
666
+ narrowing_sizes.add(None)
667
+ else:
668
+ narrowing_sizes.add(vvar_to_narrowing_size.get(vvarid))
669
+ if len(narrowing_sizes) == 1 and None not in narrowing_sizes:
670
+ # we can narrow this phi vvar!
671
+ narrowable_phivarids.add(def_vvarid)
672
+
673
+ # now determine what to narrow!
674
+ narrowables = []
675
+
676
+ for def_, narrow_info in narrowing_candidates.values():
677
+ if def_.atom.varid in blacklist_varids:
678
+ continue
679
+ if not narrow_info.phi_vars:
680
+ # not used by any other phi variables. good!
681
+ narrowables.append((def_, narrow_info))
682
+ else:
683
+ if {phivar.varid for phivar in narrow_info.phi_vars}.issubset(narrowable_phivarids):
684
+ # all phi vvars that use this definition can be narrowed
685
+ narrowables.append((def_, narrow_info))
686
+ else:
687
+ # this vvar cannot be narrowed
688
+ # note that all phi variables that relies on this vvar also cannot be narrowed! we must analyze
689
+ # again
690
+ repeat = True
691
+ blacklist_varids.add(def_.atom.varid)
692
+ blacklist_varids |= {phivar.varid for phivar in narrow_info.phi_vars}
693
+
694
+ return repeat, narrowables
695
+
696
+ def _narrowing_needed(self, def_, rd: SRDAModel, addr_and_idx_to_block) -> ExprNarrowingInfo:
697
+
465
698
  def_size = def_.size
466
699
  # find its uses
467
- use_and_exprs = rd.all_uses.get_uses_with_expr(def_)
700
+ # some use locations are phi assignments. we keep tracking the uses of phi variables and update the dictionary
701
+ result = self._get_vvar_use_and_exprs_recursive(def_.atom, rd, addr_and_idx_to_block)
702
+ if result is None:
703
+ return ExprNarrowingInfo(False)
704
+ use_and_exprs, phi_vars = result
468
705
 
469
706
  all_used_sizes = set()
470
- used_by: list[tuple[CodeLocation, tuple[str, tuple[Expression, ...]]]] = []
707
+ used_by: list[tuple[atoms.VirtualVariable, CodeLocation, tuple[str, tuple[Expression, ...]]]] = []
708
+ used_by_loc = defaultdict(list)
471
709
 
472
- for loc, expr in use_and_exprs:
710
+ for atom, loc, expr in use_and_exprs:
473
711
  old_block = addr_and_idx_to_block.get((loc.block_addr, loc.block_idx), None)
474
712
  if old_block is None:
475
713
  # missing a block for whatever reason
476
- return False, None, None
714
+ return ExprNarrowingInfo(False)
477
715
 
478
716
  block = self.blocks.get(old_block, old_block)
479
717
  if loc.stmt_idx >= len(block.statements):
480
718
  # missing a statement for whatever reason
481
- return False, None, None
719
+ return ExprNarrowingInfo(False)
482
720
  stmt = block.statements[loc.stmt_idx]
483
721
 
722
+ # special case: if the statement is a Call statement and expr is None, it means we have not been able to
723
+ # determine if the expression is really used by the call or not. skip it in this case
724
+ if isinstance(stmt, Call) and expr is None:
725
+ continue
726
+ # special case: if the statement is a phi statement, we ignore it
727
+ if is_phi_assignment(stmt):
728
+ continue
729
+
484
730
  expr_size, used_by_exprs = self._extract_expression_effective_size(stmt, expr)
485
731
  if expr_size is None:
486
732
  # it's probably used in full width
487
- return False, None, None
733
+ return ExprNarrowingInfo(False)
488
734
 
489
735
  all_used_sizes.add(expr_size)
490
- used_by.append((loc, used_by_exprs))
736
+ used_by_loc[loc].append((atom, used_by_exprs))
491
737
 
492
738
  if len(all_used_sizes) == 1 and next(iter(all_used_sizes)) < def_size:
493
- return True, next(iter(all_used_sizes)), used_by
739
+ for loc, atom_expr_pairs in used_by_loc.items():
740
+ if len(atom_expr_pairs) == 1:
741
+ atom, used_by_exprs = atom_expr_pairs[0]
742
+ used_by.append((atom, loc, used_by_exprs))
743
+ else:
744
+ # the order matters - we must replace the outer expressions first, then replace the inner
745
+ # expressions. replacing in the wrong order will lead to expressions that are not replaced in the
746
+ # end.
747
+ ordered = []
748
+ for atom, used_by_exprs in atom_expr_pairs:
749
+ last_inclusion = len(ordered) - 1 # by default we append at the end of the list
750
+ for idx in range(len(ordered)):
751
+ if self._is_expr0_included_in_expr1(ordered[idx][1], used_by_exprs):
752
+ # this element must be inserted before idx
753
+ ordered.insert(idx, (atom, used_by_exprs))
754
+ break
755
+ if self._is_expr0_included_in_expr1(used_by_exprs, ordered[idx][1]):
756
+ # this element can be inserted after this element. record the index
757
+ last_inclusion = idx
758
+ else:
759
+ ordered.insert(last_inclusion + 1, (atom, used_by_exprs))
494
760
 
495
- return False, None, None
761
+ for atom, used_by_exprs in ordered:
762
+ used_by.append((atom, loc, used_by_exprs))
763
+
764
+ return ExprNarrowingInfo(True, to_size=next(iter(all_used_sizes)), use_exprs=used_by, phi_vars=phi_vars)
765
+
766
+ return ExprNarrowingInfo(False)
767
+
768
+ @staticmethod
769
+ def _exprs_from_used_by_exprs(used_by_exprs) -> set[Expression]:
770
+ use_type, expr_tuple = used_by_exprs
771
+ match use_type:
772
+ case "expr" | "mask" | "convert":
773
+ return {expr_tuple[1]} if len(expr_tuple) == 2 else {expr_tuple[0]}
774
+ case "phi-src-expr":
775
+ return {expr_tuple[0]}
776
+ case "binop-convert":
777
+ return {expr_tuple[0], expr_tuple[1]}
778
+ case _:
779
+ return set()
780
+
781
+ def _is_expr0_included_in_expr1(self, used_by_exprs0, used_by_exprs1) -> bool:
782
+ # extract expressions
783
+ exprs0 = self._exprs_from_used_by_exprs(used_by_exprs0)
784
+ exprs1 = self._exprs_from_used_by_exprs(used_by_exprs1)
785
+
786
+ # test for inclusion
787
+ for expr1 in exprs1:
788
+ walker = HasExprWalker(exprs0)
789
+ walker.walk_expression(expr1)
790
+ if walker.contains_exprs:
791
+ return True
792
+ return False
793
+
794
+ def _get_vvar_use_and_exprs_recursive(
795
+ self, initial_atom: atoms.VirtualVariable, rd, block_dict: dict[tuple[int, int | None], Block]
796
+ ) -> tuple[list[tuple[atoms.VirtualVariable, CodeLocation, Expression]], set[VirtualVariable]] | None:
797
+ result = []
798
+ atom_queue = [initial_atom]
799
+ phi_vars = set()
800
+ seen = set()
801
+ while atom_queue:
802
+ atom = atom_queue.pop(0)
803
+ seen.add(atom)
804
+
805
+ use_and_exprs = rd.get_vvar_uses_with_expr(atom)
806
+
807
+ for loc, expr in use_and_exprs:
808
+ old_block = block_dict.get((loc.block_addr, loc.block_idx), None)
809
+ if old_block is None:
810
+ # missing a block for whatever reason
811
+ return None
812
+
813
+ block: Block = self.blocks.get(old_block, old_block)
814
+ if loc.stmt_idx >= len(block.statements):
815
+ # missing a statement for whatever reason
816
+ return None
817
+ stmt = block.statements[loc.stmt_idx]
818
+
819
+ if is_phi_assignment(stmt):
820
+ phi_vars.add(stmt.dst)
821
+ new_atom = atoms.VirtualVariable(
822
+ stmt.dst.varid, stmt.dst.size, stmt.dst.category, oident=stmt.dst.oident
823
+ )
824
+ if new_atom not in seen:
825
+ atom_queue.append(new_atom)
826
+ else:
827
+ result.append((atom, loc, expr))
828
+ return result, phi_vars
496
829
 
497
830
  def _extract_expression_effective_size(
498
831
  self, statement, expr
@@ -509,10 +842,9 @@ class AILSimplifier(Analysis):
509
842
  return expr.size, ("expr", (expr,))
510
843
 
511
844
  first_op = walker.operations[0]
512
- if isinstance(first_op, Convert):
513
- if first_op.to_bits >= self.project.arch.byte_width:
514
- # we need at least one byte!
515
- return first_op.to_bits // self.project.arch.byte_width, ("convert", (first_op,))
845
+ if isinstance(first_op, Convert) and first_op.to_bits >= self.project.arch.byte_width:
846
+ # we need at least one byte!
847
+ return first_op.to_bits // self.project.arch.byte_width, ("convert", (first_op,))
516
848
  if isinstance(first_op, BinaryOp):
517
849
  second_op = None
518
850
  if len(walker.operations) >= 2:
@@ -551,7 +883,7 @@ class AILSimplifier(Analysis):
551
883
 
552
884
  def _fold_exprs(self):
553
885
  """
554
- Fold expressions: Fold assigned expressions that are only used once.
886
+ Fold expressions: Fold assigned expressions that are constant or only used once.
555
887
  """
556
888
 
557
889
  # propagator
@@ -603,8 +935,8 @@ class AILSimplifier(Analysis):
603
935
 
604
936
  simplified = False
605
937
 
606
- prop = self._compute_propagation()
607
- if not prop.model.equivalence:
938
+ equivalence = self._compute_equivalence()
939
+ if not equivalence:
608
940
  return simplified
609
941
 
610
942
  addr_and_idx_to_block: dict[tuple[int, int], Block] = {}
@@ -613,7 +945,7 @@ class AILSimplifier(Analysis):
613
945
 
614
946
  equivalences: dict[Any, set[Equivalence]] = defaultdict(set)
615
947
  atom_by_loc = set()
616
- for eq in prop.model.equivalence:
948
+ for eq in equivalence:
617
949
  equivalences[eq.atom1].add(eq)
618
950
  atom_by_loc.add((eq.codeloc, eq.atom1))
619
951
 
@@ -637,20 +969,37 @@ class AILSimplifier(Analysis):
637
969
  # Equivalence is generally created at assignment sites. Therefore, eq.atom0 is the definition and
638
970
  # eq.atom1 is the use.
639
971
  the_def = None
640
- if isinstance(eq.atom0, SimMemoryVariable): # covers both Stack and Global variables
641
- if isinstance(eq.atom1, Register):
972
+ if (isinstance(eq.atom0, VirtualVariable) and eq.atom0.was_stack) or (
973
+ isinstance(eq.atom0, SimMemoryVariable)
974
+ and not isinstance(eq.atom0, SimStackVariable)
975
+ and isinstance(eq.atom0.addr, int)
976
+ ):
977
+ if isinstance(eq.atom1, VirtualVariable) and eq.atom1.was_reg:
642
978
  # stack_var == register or global_var == register
643
979
  to_replace = eq.atom1
644
980
  to_replace_is_def = False
645
- elif isinstance(eq.atom1, Convert) and isinstance(eq.atom1.operand, Register):
981
+ elif (
982
+ isinstance(eq.atom0, VirtualVariable)
983
+ and eq.atom0.was_stack
984
+ and isinstance(eq.atom1, VirtualVariable)
985
+ and eq.atom1.was_parameter
986
+ ):
987
+ # stack_var == parameter
988
+ to_replace = eq.atom0
989
+ to_replace_is_def = True
990
+ elif (
991
+ isinstance(eq.atom1, Convert)
992
+ and isinstance(eq.atom1.operand, VirtualVariable)
993
+ and eq.atom1.operand.was_reg
994
+ ):
646
995
  # stack_var == Conv(register, M->N)
647
996
  to_replace = eq.atom1.operand
648
997
  to_replace_is_def = False
649
998
  else:
650
999
  continue
651
1000
 
652
- elif isinstance(eq.atom0, Register):
653
- if isinstance(eq.atom1, Register):
1001
+ elif isinstance(eq.atom0, VirtualVariable) and eq.atom0.was_reg:
1002
+ if isinstance(eq.atom1, VirtualVariable) and (eq.atom1.was_reg or eq.atom1.was_parameter):
654
1003
  # register == register
655
1004
  if self.project.arch.is_artificial_register(eq.atom0.reg_offset, eq.atom0.size):
656
1005
  to_replace = eq.atom0
@@ -664,44 +1013,46 @@ class AILSimplifier(Analysis):
664
1013
  else:
665
1014
  continue
666
1015
 
667
- # find the definition of this register
1016
+ assert isinstance(to_replace, VirtualVariable)
1017
+
1018
+ # find the definition of this virtual register
668
1019
  rd = self._compute_reaching_definitions()
669
1020
  if to_replace_is_def:
670
1021
  # find defs
671
1022
  defs = []
672
1023
  for def_ in rd.all_definitions:
673
- if def_.codeloc == eq.codeloc:
674
- if isinstance(to_replace, SimStackVariable):
675
- if isinstance(def_.atom, atoms.MemoryLocation) and isinstance(
676
- def_.atom.addr, atoms.SpOffset
677
- ):
678
- if to_replace.offset == def_.atom.addr.offset:
679
- defs.append(def_)
680
- elif isinstance(to_replace, Register):
681
- if isinstance(def_.atom, atoms.Register) and to_replace.reg_offset == def_.atom.reg_offset:
682
- defs.append(def_)
1024
+ if def_.atom.varid == to_replace.varid:
1025
+ defs.append(def_)
683
1026
  if len(defs) != 1:
684
1027
  continue
685
1028
  the_def = defs[0]
686
1029
  else:
687
1030
  # find uses
688
- defs = rd.all_uses.get_uses_by_location(eq.codeloc)
1031
+ defs = rd.get_uses_by_location(eq.codeloc)
689
1032
  if len(defs) != 1:
690
1033
  # there are multiple defs for this register - we do not support replacing all of them
691
1034
  continue
692
1035
  for def_ in defs:
693
1036
  def_: Definition
694
- if isinstance(def_.atom, atoms.Register) and def_.atom.reg_offset == to_replace.reg_offset:
1037
+ if (
1038
+ isinstance(def_.atom, atoms.VirtualVariable)
1039
+ and def_.atom.category == to_replace.category
1040
+ and def_.atom.oident == to_replace.oident
1041
+ ):
695
1042
  # found it!
696
1043
  the_def = def_
697
1044
  break
698
1045
  if the_def is None:
699
1046
  continue
700
- if the_def.codeloc.context:
1047
+ if the_def.codeloc.context: # FIXME: now the_def.codeloc.context is never filled in
701
1048
  # the definition is in a callee function
702
1049
  continue
703
1050
 
704
- if isinstance(the_def.codeloc, ExternalCodeLocation):
1051
+ if (
1052
+ isinstance(the_def.codeloc, ExternalCodeLocation)
1053
+ or isinstance(eq.atom1, VirtualVariable)
1054
+ and eq.atom1.was_parameter
1055
+ ):
705
1056
  # this is a function argument. we enter a slightly different logic and try to eliminate copies of this
706
1057
  # argument if
707
1058
  # (a) the on-stack or in-register copy of it has never been modified in this function
@@ -715,32 +1066,37 @@ class AILSimplifier(Analysis):
715
1066
  if defs and len(defs) == 1:
716
1067
  arg_copy_def = defs[0]
717
1068
  if (
718
- isinstance(arg_copy_def.atom, atoms.MemoryLocation)
719
- and isinstance(arg_copy_def.atom.addr, SpOffset)
720
- or isinstance(arg_copy_def.atom, atoms.Register)
1069
+ isinstance(arg_copy_def.atom, atoms.VirtualVariable)
1070
+ and arg_copy_def.atom.was_stack
1071
+ or (isinstance(arg_copy_def.atom, atoms.VirtualVariable) and arg_copy_def.atom.was_reg)
721
1072
  ):
722
1073
  # found the copied definition (either a stack variable or a register variable)
723
1074
 
724
1075
  # Make sure there is no other write to this stack location if the copy is a stack variable
725
- if isinstance(arg_copy_def.atom, atoms.MemoryLocation):
726
- if any(
727
- (def_ != arg_copy_def and def_.atom == arg_copy_def.atom)
1076
+ if (
1077
+ isinstance(arg_copy_def.atom, atoms.VirtualVariable)
1078
+ and arg_copy_def.atom.was_stack
1079
+ and any(
1080
+ (def_ != arg_copy_def and def_.atom.stack_offset == arg_copy_def.atom.stack_offset)
728
1081
  for def_ in rd.all_definitions
729
- if isinstance(def_.atom, atoms.MemoryLocation)
730
- ):
731
- continue
1082
+ if isinstance(def_.atom, atoms.VirtualVariable) and def_.atom.was_stack
1083
+ )
1084
+ ):
1085
+ continue
732
1086
 
733
1087
  # Make sure the register is never updated across this function
734
1088
  if any(
735
1089
  (def_ != the_def and def_.atom == the_def.atom)
736
1090
  for def_ in rd.all_definitions
737
- if isinstance(def_.atom, atoms.Register) and rd.all_uses.get_uses(def_)
1091
+ if isinstance(def_.atom, atoms.VirtualVariable)
1092
+ and def_.atom.was_reg
1093
+ and rd.get_vvar_uses(def_.atom)
738
1094
  ):
739
1095
  continue
740
1096
 
741
1097
  # find all its uses
742
1098
  all_arg_copy_var_uses: set[tuple[CodeLocation, Any]] = set(
743
- rd.all_uses.get_uses_with_expr(arg_copy_def)
1099
+ rd.get_vvar_uses_with_expr(arg_copy_def.atom)
744
1100
  )
745
1101
  all_uses_with_def = set()
746
1102
 
@@ -754,8 +1110,6 @@ class AILSimplifier(Analysis):
754
1110
  if should_abort:
755
1111
  continue
756
1112
 
757
- # to_replace = Load(None, StackBaseOffset(None, self.project.arch.bits, eq.atom0.offset),
758
- # eq.atom0.size, endness=self.project.arch.memory_endness)
759
1113
  replace_with = eq.atom1
760
1114
  remove_initial_assignment = True
761
1115
 
@@ -787,15 +1141,30 @@ class AILSimplifier(Analysis):
787
1141
  ):
788
1142
  continue
789
1143
 
790
- if isinstance(eq.atom0, SimStackVariable):
791
- # create the memory loading expression
792
- new_idx = None if self._ail_manager is None else next(self._ail_manager.atom_ctr)
793
- replace_with = Load(
794
- new_idx,
795
- StackBaseOffset(None, self.project.arch.bits, eq.atom0.offset),
796
- eq.atom0.size,
797
- endness=self.project.arch.memory_endness,
798
- )
1144
+ if isinstance(eq.atom0, VirtualVariable) and eq.atom0.was_stack:
1145
+ # create the replacement expression
1146
+ if isinstance(eq.atom1, VirtualVariable) and eq.atom1.was_parameter:
1147
+ # replacing atom0
1148
+ new_idx = None if self._ail_manager is None else next(self._ail_manager.atom_ctr)
1149
+ replace_with = VirtualVariable(
1150
+ new_idx,
1151
+ eq.atom1.varid,
1152
+ eq.atom1.bits,
1153
+ category=eq.atom1.category,
1154
+ oident=eq.atom1.oident,
1155
+ **eq.atom1.tags,
1156
+ )
1157
+ else:
1158
+ # replacing atom1
1159
+ new_idx = None if self._ail_manager is None else next(self._ail_manager.atom_ctr)
1160
+ replace_with = VirtualVariable(
1161
+ new_idx,
1162
+ eq.atom0.varid,
1163
+ eq.atom0.bits,
1164
+ category=eq.atom0.category,
1165
+ oident=eq.atom0.oident,
1166
+ **eq.atom0.tags,
1167
+ )
799
1168
  elif isinstance(eq.atom0, SimMemoryVariable) and isinstance(eq.atom0.addr, int):
800
1169
  # create the memory loading expression
801
1170
  new_idx = None if self._ail_manager is None else next(self._ail_manager.atom_ctr)
@@ -805,27 +1174,27 @@ class AILSimplifier(Analysis):
805
1174
  eq.atom0.size,
806
1175
  endness=self.project.arch.memory_endness,
807
1176
  )
808
- elif isinstance(eq.atom0, Register):
809
- if isinstance(eq.atom1, Register):
1177
+ elif isinstance(eq.atom0, VirtualVariable) and eq.atom0.was_reg:
1178
+ if isinstance(eq.atom1, VirtualVariable) and eq.atom1.was_reg:
810
1179
  if self.project.arch.is_artificial_register(eq.atom0.reg_offset, eq.atom0.size):
811
1180
  replace_with = eq.atom1
812
1181
  else:
813
1182
  replace_with = eq.atom0
814
1183
  else:
815
- raise AngrRuntimeError("Unsupported atom1 type %s." % type(eq.atom1))
1184
+ raise AngrRuntimeError(f"Unsupported atom1 type {type(eq.atom1)}.")
816
1185
  else:
817
- raise AngrRuntimeError("Unsupported atom0 type %s." % type(eq.atom0))
1186
+ raise AngrRuntimeError(f"Unsupported atom0 type {type(eq.atom0)}.")
818
1187
 
819
1188
  to_replace_def = the_def
820
1189
 
821
1190
  # find all uses of this definition
822
1191
  # we make a copy of the set since we may touch the set (uses) when replacing expressions
823
- all_uses: set[tuple[CodeLocation, Any]] = set(rd.all_uses.get_uses_with_expr(to_replace_def))
1192
+ all_uses: set[tuple[CodeLocation, Any]] = set(rd.get_vvar_uses_with_expr(to_replace_def.atom))
824
1193
  # make sure none of these uses are phi nodes (depends on more than one def)
825
1194
  all_uses_with_unique_def = set()
826
1195
  for use_and_expr in all_uses:
827
1196
  use_loc, used_expr = use_and_expr
828
- defs_and_exprs = rd.all_uses.get_uses_by_location(use_loc, exprs=True)
1197
+ defs_and_exprs = rd.get_uses_by_location(use_loc, exprs=True)
829
1198
  filtered_defs = {def_ for def_, expr_ in defs_and_exprs if expr_ == used_expr}
830
1199
  if len(filtered_defs) == 1:
831
1200
  all_uses_with_unique_def.add(use_and_expr)
@@ -837,20 +1206,40 @@ class AILSimplifier(Analysis):
837
1206
  # only when all uses are determined by the same definition will we continue with the simplification
838
1207
  continue
839
1208
 
840
- # one more check: there can be at most one assignment in all these use locations
841
- assignment_ctr = 0
842
- for use_loc, used_expr in all_uses:
843
- block = addr_and_idx_to_block[(use_loc.block_addr, use_loc.block_idx)]
844
- stmt = block.statements[use_loc.stmt_idx]
845
- if isinstance(stmt, Assignment):
846
- assignment_ctr += 1
847
- if assignment_ctr > 1:
848
- continue
1209
+ # one more check: there can be at most one assignment in all these use locations if the expression is
1210
+ # not going to be replaced with a parameter. the assignment can be an Assignment statement, but may also
1211
+ # be a Store if it's a global variable (via Load) that we are replacing with
1212
+
1213
+ if not (isinstance(replace_with, VirtualVariable) and replace_with.was_parameter):
1214
+ assignment_ctr = 0
1215
+ all_use_locs = {use_loc for use_loc, _ in all_uses}
1216
+ for use_loc in all_use_locs:
1217
+ if use_loc == eq.codeloc:
1218
+ continue
1219
+ block = addr_and_idx_to_block[(use_loc.block_addr, use_loc.block_idx)]
1220
+ stmt = block.statements[use_loc.stmt_idx]
1221
+ if isinstance(stmt, Assignment) or isinstance(replace_with, Load) and isinstance(stmt, Store):
1222
+ assignment_ctr += 1
1223
+ if assignment_ctr > 1:
1224
+ continue
849
1225
 
850
1226
  all_uses_with_def = {(to_replace_def, use_and_expr) for use_and_expr in all_uses}
851
1227
 
852
1228
  remove_initial_assignment = False # expression folding will take care of it
853
1229
 
1230
+ if any(not isinstance(use_and_expr[1], VirtualVariable) for _, use_and_expr in all_uses_with_def):
1231
+ # if any of the uses are phi assignments, we skip
1232
+ used_in_phi_assignment = False
1233
+ for _, use_and_expr in all_uses_with_def:
1234
+ u = use_and_expr[0]
1235
+ block = addr_and_idx_to_block[(u.block_addr, u.block_idx)]
1236
+ stmt = block.statements[u.stmt_idx]
1237
+ if is_phi_assignment(stmt):
1238
+ used_in_phi_assignment = True
1239
+ break
1240
+ if used_in_phi_assignment:
1241
+ continue
1242
+
854
1243
  # ensure the uses we consider are all after the eq location
855
1244
  filtered_all_uses_with_def = []
856
1245
  for def_, use_and_expr in all_uses_with_def:
@@ -878,17 +1267,17 @@ class AILSimplifier(Analysis):
878
1267
  u, used_expr = use_and_expr
879
1268
 
880
1269
  use_expr_defns = []
881
- for d in rd.all_uses.get_uses_by_location(u):
1270
+ for d in rd.get_uses_by_location(u):
882
1271
  if (
883
- isinstance(d.atom, RegisterAtom)
884
- and isinstance(def_.atom, RegisterAtom)
1272
+ isinstance(d.atom, atoms.VirtualVariable)
1273
+ and d.atom.was_reg
1274
+ and isinstance(def_.atom, atoms.VirtualVariable)
1275
+ and def_.atom.was_reg
885
1276
  and d.atom.reg_offset == def_.atom.reg_offset
886
- ):
887
- use_expr_defns.append(d)
888
- elif d.atom == def_.atom:
1277
+ ) or d.atom == def_.atom:
889
1278
  use_expr_defns.append(d)
890
1279
  # you can never replace a use with dependencies from outside the checked defn
891
- if len(use_expr_defns) != 1 or list(use_expr_defns)[0] != def_:
1280
+ if len(use_expr_defns) != 1 or next(iter(use_expr_defns)) != def_:
892
1281
  if not use_expr_defns:
893
1282
  _l.warning("There was no use_expr_defns for %s, this is likely a bug", u)
894
1283
  # TODO: can you have multiple definitions which can all be eliminated?
@@ -929,7 +1318,7 @@ class AILSimplifier(Analysis):
929
1318
  )
930
1319
 
931
1320
  r, new_block = self._replace_expr_and_update_block(
932
- the_block, u.stmt_idx, stmt, def_, u, used_expr, replace_with_copy
1321
+ the_block, u.stmt_idx, stmt, used_expr, replace_with_copy
933
1322
  )
934
1323
  if r:
935
1324
  self.blocks[old_block] = new_block
@@ -1007,8 +1396,8 @@ class AILSimplifier(Analysis):
1007
1396
 
1008
1397
  simplified = False
1009
1398
 
1010
- prop = self._compute_propagation()
1011
- if not prop.model.equivalence:
1399
+ equivalence = self._compute_equivalence()
1400
+ if not equivalence:
1012
1401
  return simplified
1013
1402
 
1014
1403
  addr_and_idx_to_block: dict[tuple[int, int], Block] = {}
@@ -1018,19 +1407,17 @@ class AILSimplifier(Analysis):
1018
1407
  def_locations_to_remove: set[CodeLocation] = set()
1019
1408
  updated_use_locations: set[CodeLocation] = set()
1020
1409
 
1021
- eq: Equivalence
1022
- for eq in prop.model.equivalence:
1410
+ for eq in equivalence:
1023
1411
  # register variable == Call
1024
- if isinstance(eq.atom0, Register):
1025
- call_addr: int | None
1412
+ if isinstance(eq.atom0, VirtualVariable) and eq.atom0.was_reg:
1026
1413
  if isinstance(eq.atom1, Call):
1027
1414
  # register variable = Call
1028
1415
  call: Expression = eq.atom1
1029
- call_addr = call.target.value if isinstance(call.target, Const) else None
1416
+ # call_addr = call.target.value if isinstance(call.target, Const) else None
1030
1417
  elif isinstance(eq.atom1, Convert) and isinstance(eq.atom1.operand, Call):
1031
1418
  # register variable = Convert(Call)
1032
1419
  call = eq.atom1
1033
- call_addr = call.operand.target.value if isinstance(call.operand.target, Const) else None
1420
+ # call_addr = call.operand.target.value if isinstance(call.operand.target, Const) else None
1034
1421
  else:
1035
1422
  continue
1036
1423
 
@@ -1042,21 +1429,17 @@ class AILSimplifier(Analysis):
1042
1429
  # we must rerun Propagator to get an updated definition (and Equivalence)
1043
1430
  continue
1044
1431
 
1045
- # find the definition of this register
1432
+ # find all uses of this virtual register
1046
1433
  rd = self._compute_reaching_definitions()
1047
- defs = [
1048
- d
1049
- for d in rd.all_definitions
1050
- if d.codeloc == eq.codeloc
1051
- and isinstance(d.atom, atoms.Register)
1052
- and d.atom.reg_offset == eq.atom0.reg_offset
1053
- ]
1054
- if not defs or len(defs) > 1:
1055
- continue
1056
- the_def: Definition = defs[0]
1057
1434
 
1058
- # find all uses of this definition
1059
- all_uses: set[tuple[CodeLocation, Any]] = set(rd.all_uses.get_uses_with_expr(the_def))
1435
+ the_def: Definition = Definition(
1436
+ atoms.VirtualVariable(
1437
+ eq.atom0.varid, eq.atom0.size, category=eq.atom0.category, oident=eq.atom0.oident
1438
+ ),
1439
+ eq.codeloc,
1440
+ )
1441
+
1442
+ all_uses: set[tuple[CodeLocation, Any]] = set(rd.get_vvar_uses_with_expr(the_def.atom))
1060
1443
 
1061
1444
  if len(all_uses) != 1:
1062
1445
  continue
@@ -1084,39 +1467,40 @@ class AILSimplifier(Analysis):
1084
1467
  continue
1085
1468
 
1086
1469
  # check if the register has been overwritten by statements in between the def site and the use site
1087
- usesite_atom_defs = set(rd.get_defs(the_def.atom, u, OP_BEFORE))
1088
- if len(usesite_atom_defs) != 1:
1089
- continue
1090
- usesite_atom_def = next(iter(usesite_atom_defs))
1091
- if usesite_atom_def != the_def:
1092
- continue
1470
+ # usesite_atom_defs = set(rd.get_defs(the_def.atom, u, OP_BEFORE))
1471
+ # if len(usesite_atom_defs) != 1:
1472
+ # continue
1473
+ # usesite_atom_def = next(iter(usesite_atom_defs))
1474
+ # if usesite_atom_def != the_def:
1475
+ # continue
1093
1476
 
1094
1477
  # check if any atoms that the call relies on has been overwritten by statements in between the def site
1095
1478
  # and the use site.
1096
- defsite_all_expr_uses = set(rd.all_uses.get_uses_by_location(the_def.codeloc))
1097
- defsite_used_atoms = set()
1098
- for dd in defsite_all_expr_uses:
1099
- defsite_used_atoms.add(dd.atom)
1100
- usesite_expr_def_outdated = False
1101
- for defsite_expr_atom in defsite_used_atoms:
1102
- usesite_expr_uses = set(rd.get_defs(defsite_expr_atom, u, OP_BEFORE))
1103
- if not usesite_expr_uses:
1104
- # the atom is not defined at the use site - it's fine
1105
- continue
1106
- defsite_expr_uses = set(rd.get_defs(defsite_expr_atom, the_def.codeloc, OP_BEFORE))
1107
- if usesite_expr_uses != defsite_expr_uses:
1108
- # special case: ok if this atom is assigned to at the def site and has not been overwritten
1109
- if len(usesite_expr_uses) == 1:
1110
- usesite_expr_use = next(iter(usesite_expr_uses))
1111
- if usesite_expr_use.atom == defsite_expr_atom and (
1112
- usesite_expr_use.codeloc == the_def.codeloc
1113
- or usesite_expr_use.codeloc.block_addr == call_addr
1114
- ):
1115
- continue
1116
- usesite_expr_def_outdated = True
1117
- break
1118
- if usesite_expr_def_outdated:
1119
- continue
1479
+ # TODO: Prove non-interference
1480
+ # defsite_all_expr_uses = set(rd.all_uses.get_uses_by_location(the_def.codeloc))
1481
+ # defsite_used_atoms = set()
1482
+ # for dd in defsite_all_expr_uses:
1483
+ # defsite_used_atoms.add(dd.atom)
1484
+ # usesite_expr_def_outdated = False
1485
+ # for defsite_expr_atom in defsite_used_atoms:
1486
+ # usesite_expr_uses = set(rd.get_defs(defsite_expr_atom, u, OP_BEFORE))
1487
+ # if not usesite_expr_uses:
1488
+ # # the atom is not defined at the use site - it's fine
1489
+ # continue
1490
+ # defsite_expr_uses = set(rd.get_defs(defsite_expr_atom, the_def.codeloc, OP_BEFORE))
1491
+ # if usesite_expr_uses != defsite_expr_uses:
1492
+ # # special case: ok if this atom is assigned to at the def site and has not been overwritten
1493
+ # if len(usesite_expr_uses) == 1:
1494
+ # usesite_expr_use = next(iter(usesite_expr_uses))
1495
+ # if usesite_expr_use.atom == defsite_expr_atom and (
1496
+ # usesite_expr_use.codeloc == the_def.codeloc
1497
+ # or usesite_expr_use.codeloc.block_addr == call_addr
1498
+ # ):
1499
+ # continue
1500
+ # usesite_expr_def_outdated = True
1501
+ # break
1502
+ # if usesite_expr_def_outdated:
1503
+ # continue
1120
1504
 
1121
1505
  # check if there are any calls in between the def site and the use site
1122
1506
  if self._count_calls_in_supernodeblocks(super_node_blocks, the_def.codeloc, u) > 0:
@@ -1131,9 +1515,17 @@ class AILSimplifier(Analysis):
1131
1515
  the_block = self.blocks.get(old_block, old_block)
1132
1516
  stmt: Statement = the_block.statements[u.stmt_idx]
1133
1517
 
1134
- if isinstance(eq.atom0, Register):
1518
+ if isinstance(eq.atom0, VirtualVariable):
1135
1519
  src = used_expr
1136
- dst: Expression = call
1520
+ dst: Call | Convert = call.copy()
1521
+
1522
+ if isinstance(dst, Call) and dst.ret_expr is not None:
1523
+ dst_bits = dst.ret_expr.bits
1524
+ # clear the ret_expr and fp_ret_expr of dst, then set bits so that it can be used as an
1525
+ # expression
1526
+ dst.ret_expr = None
1527
+ dst.fp_ret_expr = None
1528
+ dst.bits = dst_bits
1137
1529
 
1138
1530
  if src.bits != dst.bits:
1139
1531
  dst = Convert(None, dst.bits, src.bits, False, dst)
@@ -1145,9 +1537,7 @@ class AILSimplifier(Analysis):
1145
1537
  if expr_ctr.count > 1:
1146
1538
  continue
1147
1539
 
1148
- replaced, new_block = self._replace_expr_and_update_block(
1149
- the_block, u.stmt_idx, stmt, the_def, u, src, dst
1150
- )
1540
+ replaced, new_block = self._replace_expr_and_update_block(the_block, u.stmt_idx, stmt, src, dst)
1151
1541
 
1152
1542
  if replaced:
1153
1543
  self.blocks[old_block] = new_block
@@ -1180,24 +1570,25 @@ class AILSimplifier(Analysis):
1180
1570
  break
1181
1571
  return lst
1182
1572
 
1183
- def _replace_expr_and_update_block(
1184
- self, block, stmt_idx, stmt, the_def, codeloc, src_expr, dst_expr
1185
- ) -> tuple[bool, Block | None]:
1573
+ @staticmethod
1574
+ def _replace_expr_and_update_block(block, stmt_idx, stmt, src_expr, dst_expr) -> tuple[bool, Block | None]:
1186
1575
  replaced, new_stmt = stmt.replace(src_expr, dst_expr)
1187
1576
  if replaced:
1188
1577
  new_block = block.copy()
1189
1578
  new_block.statements = block.statements[::]
1190
1579
  new_block.statements[stmt_idx] = new_stmt
1191
-
1192
- # update the uses
1193
- rd = self._compute_reaching_definitions()
1194
- rd.all_uses.remove_use(the_def, codeloc, expr=src_expr)
1195
1580
  return True, new_block
1196
1581
 
1197
1582
  return False, None
1198
1583
 
1199
1584
  def _remove_dead_assignments(self) -> bool:
1585
+
1586
+ # keeping tracking of statements to remove and statements (as well as dead vvars) to keep allows us to handle
1587
+ # cases where a statement defines more than one atoms, e.g., a call statement that defines both the return
1588
+ # value and the floating-point return value.
1200
1589
  stmts_to_remove_per_block: dict[tuple[int, int], set[int]] = defaultdict(set)
1590
+ stmts_to_keep_per_block: dict[tuple[int, int], set[int]] = defaultdict(set)
1591
+ dead_vvar_ids: set[int] = set()
1201
1592
 
1202
1593
  # Find all statements that should be removed
1203
1594
  mask = (1 << self.project.arch.bits) - 1
@@ -1206,36 +1597,80 @@ class AILSimplifier(Analysis):
1206
1597
  stackarg_offsets = (
1207
1598
  {(tpl[1] & mask) for tpl in self._stack_arg_offsets} if self._stack_arg_offsets is not None else None
1208
1599
  )
1209
- def_: Definition
1210
1600
  for def_ in rd.all_definitions:
1211
1601
  if def_.dummy:
1212
1602
  continue
1213
1603
  # we do not remove references to global memory regions no matter what
1214
1604
  if isinstance(def_.atom, atoms.MemoryLocation) and isinstance(def_.atom.addr, int):
1215
1605
  continue
1216
- if isinstance(def_.atom, atoms.MemoryLocation):
1217
- if not self._remove_dead_memdefs:
1218
- # we always remove definitions for stack arguments
1219
- if stackarg_offsets is not None and isinstance(def_.atom.addr, atoms.SpOffset):
1220
- if (def_.atom.addr.offset & mask) not in stackarg_offsets:
1606
+ if isinstance(def_.atom, atoms.VirtualVariable):
1607
+ if def_.atom.was_stack:
1608
+ if not self._remove_dead_memdefs:
1609
+ if rd.is_phi_vvar_id(def_.atom.varid):
1610
+ # we always remove unused phi variables
1611
+ pass
1612
+ elif stackarg_offsets is not None:
1613
+ # we always remove definitions for stack arguments
1614
+ if (def_.atom.stack_offset & mask) not in stackarg_offsets:
1615
+ continue
1616
+ else:
1221
1617
  continue
1222
- else:
1223
- continue
1618
+ uses = rd.get_vvar_uses(def_.atom)
1224
1619
 
1225
- uses = rd.all_uses.get_uses(def_)
1226
- if (
1227
- isinstance(def_.atom, atoms.Register)
1228
- and def_.atom.reg_offset in self.project.arch.artificial_registers_offsets
1229
- ):
1230
- if len(uses) == 1 and next(iter(uses)) == def_.codeloc:
1231
- # cc_ndep = amd64g_calculate_condition(..., cc_ndep)
1620
+ elif def_.atom.was_reg:
1621
+ uses = rd.get_vvar_uses(def_.atom)
1622
+ if (
1623
+ def_.atom.reg_offset in self.project.arch.artificial_registers_offsets
1624
+ and len(uses) == 1
1625
+ and next(iter(uses)) == def_.codeloc
1626
+ ):
1627
+ # TODO: Verify if we still need this hack after moving to SSA
1628
+ # cc_ndep = amd64g_calculate_condition(..., cc_ndep)
1629
+ uses = set()
1630
+
1631
+ elif def_.atom.was_parameter:
1632
+ uses = rd.get_vvar_uses(def_.atom)
1633
+
1634
+ else:
1232
1635
  uses = set()
1233
1636
 
1637
+ else:
1638
+ continue
1639
+
1234
1640
  if not uses:
1641
+ if isinstance(def_.atom, atoms.VirtualVariable):
1642
+ dead_vvar_ids.add(def_.atom.varid)
1643
+
1235
1644
  if not isinstance(def_.codeloc, ExternalCodeLocation):
1236
1645
  stmts_to_remove_per_block[(def_.codeloc.block_addr, def_.codeloc.block_idx)].add(
1237
1646
  def_.codeloc.stmt_idx
1238
1647
  )
1648
+ else:
1649
+ stmts_to_keep_per_block[(def_.codeloc.block_addr, def_.codeloc.block_idx)].add(def_.codeloc.stmt_idx)
1650
+
1651
+ # find all phi variables that rely on variables that no longer exist
1652
+ all_removed_var_ids = self._removed_vvar_ids.copy()
1653
+ removed_vvar_ids = self._removed_vvar_ids
1654
+ while True:
1655
+ new_removed_vvar_ids = set()
1656
+ for phi_varid, phi_use_varids in rd.phivarid_to_varids.items():
1657
+ if phi_varid not in all_removed_var_ids and any(
1658
+ vvarid in removed_vvar_ids for vvarid in phi_use_varids
1659
+ ):
1660
+ loc = rd.all_vvar_definitions[rd.varid_to_vvar[phi_varid]]
1661
+ stmts_to_remove_per_block[(loc.block_addr, loc.block_idx)].add(loc.stmt_idx)
1662
+ new_removed_vvar_ids.add(phi_varid)
1663
+ all_removed_var_ids.add(phi_varid)
1664
+ if not new_removed_vvar_ids:
1665
+ break
1666
+ removed_vvar_ids = new_removed_vvar_ids
1667
+
1668
+ # find all phi variables that are only ever used by other phi variables
1669
+ redundant_phi_and_dirty_varids = self._find_cyclic_dependent_phis_and_dirty_vvars(rd)
1670
+ for varid in redundant_phi_and_dirty_varids:
1671
+ loc = rd.all_vvar_definitions[rd.varid_to_vvar[varid]]
1672
+ stmts_to_remove_per_block[(loc.block_addr, loc.block_idx)].add(loc.stmt_idx)
1673
+ stmts_to_keep_per_block[(loc.block_addr, loc.block_idx)].discard(loc.stmt_idx)
1239
1674
 
1240
1675
  for codeloc in self._calls_to_remove | self._assignments_to_remove:
1241
1676
  # this call can be removed. make sure it exists in stmts_to_remove_per_block
@@ -1256,14 +1691,28 @@ class AILSimplifier(Analysis):
1256
1691
 
1257
1692
  new_statements = []
1258
1693
  stmts_to_remove = stmts_to_remove_per_block[(block.addr, block.idx)]
1694
+ stmts_to_keep = stmts_to_keep_per_block[(block.addr, block.idx)]
1259
1695
 
1260
1696
  if not stmts_to_remove:
1261
1697
  continue
1262
1698
 
1263
1699
  for idx, stmt in enumerate(block.statements):
1264
- if idx in stmts_to_remove and not isinstance(stmt, DirtyStatement):
1700
+ if idx in stmts_to_remove and idx in stmts_to_keep and isinstance(stmt, Call):
1701
+ # this statement declares more than one variable. we should handle it surgically
1702
+ # case 1: stmt.ret_expr and stmt.fp_ret_expr are both set, but one of them is not used
1703
+ if isinstance(stmt.ret_expr, VirtualVariable) and stmt.ret_expr.varid in dead_vvar_ids:
1704
+ stmt = stmt.copy()
1705
+ stmt.ret_expr = None
1706
+ simplified = True
1707
+ if isinstance(stmt.fp_ret_expr, VirtualVariable) and stmt.fp_ret_expr.varid in dead_vvar_ids:
1708
+ stmt = stmt.copy()
1709
+ stmt.fp_ret_expr = None
1710
+ simplified = True
1711
+
1712
+ if idx in stmts_to_remove and idx not in stmts_to_keep and not isinstance(stmt, DirtyStatement):
1265
1713
  if isinstance(stmt, (Assignment, Store)):
1266
- # Skip Assignment and Store statements
1714
+ # Special logic for Assignment and Store statements
1715
+
1267
1716
  # if this statement triggers a call, it should only be removed if it's in self._calls_to_remove
1268
1717
  codeloc = CodeLocation(block.addr, idx, ins_addr=stmt.ins_addr, block_idx=block.idx)
1269
1718
  if codeloc in self._assignments_to_remove:
@@ -1276,6 +1725,10 @@ class AILSimplifier(Analysis):
1276
1725
  # it has a call and must be removed
1277
1726
  simplified = True
1278
1727
  continue
1728
+ if isinstance(stmt, Assignment) and isinstance(stmt.dst, VirtualVariable):
1729
+ # no one is using the returned virtual variable. replace this assignment statement with
1730
+ # a call statement
1731
+ stmt = stmt.src
1279
1732
  else:
1280
1733
  # no calls. remove it
1281
1734
  simplified = True
@@ -1287,21 +1740,15 @@ class AILSimplifier(Analysis):
1287
1740
  simplified = True
1288
1741
  continue
1289
1742
 
1290
- if stmt.ret_expr is not None:
1291
- # the return expr is not used. it should not have return expr
1292
- if stmt.fp_ret_expr is not None:
1293
- # maybe its fp_ret_expr is used?
1294
- stmt = stmt.copy()
1295
- stmt.ret_expr = stmt.fp_ret_expr
1296
- stmt.fp_ret_expr = None
1297
- else:
1298
- # clear ret_expr
1299
- stmt = stmt.copy()
1300
- stmt.ret_expr = None
1301
- simplified = True
1743
+ if stmt.ret_expr is not None or stmt.fp_ret_expr is not None:
1744
+ # both the return expr and the fp_ret_expr are not used
1745
+ stmt = stmt.copy()
1746
+ stmt.ret_expr = None
1747
+ stmt.fp_ret_expr = None
1748
+ simplified = True
1302
1749
  else:
1303
1750
  # Should not happen!
1304
- raise NotImplementedError()
1751
+ raise NotImplementedError
1305
1752
 
1306
1753
  new_statements.append(stmt)
1307
1754
 
@@ -1311,6 +1758,74 @@ class AILSimplifier(Analysis):
1311
1758
 
1312
1759
  return simplified
1313
1760
 
1761
+ def _find_cyclic_dependent_phis_and_dirty_vvars(self, rd: SRDAModel) -> set[int]:
1762
+ blocks_dict = {(bb.addr, bb.idx): bb for bb in self.func_graph}
1763
+
1764
+ # find dirty vvars
1765
+ dirty_vvar_ids = set()
1766
+ for bb in self.func_graph:
1767
+ for stmt in bb.statements:
1768
+ if (
1769
+ isinstance(stmt, Assignment)
1770
+ and isinstance(stmt.dst, VirtualVariable)
1771
+ and stmt.dst.was_reg
1772
+ and isinstance(stmt.src, DirtyExpression)
1773
+ ):
1774
+ dirty_vvar_ids.add(stmt.dst.varid)
1775
+
1776
+ phi_and_dirty_vvar_ids = rd.phi_vvar_ids | dirty_vvar_ids
1777
+
1778
+ vvar_used_by: dict[int, set[int]] = defaultdict(set)
1779
+ for var_id in phi_and_dirty_vvar_ids:
1780
+ if var_id in rd.phivarid_to_varids:
1781
+ for used_by_varid in rd.phivarid_to_varids[var_id]:
1782
+ vvar_used_by[used_by_varid].add(var_id)
1783
+
1784
+ vvar = rd.varid_to_vvar[var_id]
1785
+ used_by = set()
1786
+ for used_vvar, loc in rd.all_vvar_uses[vvar]:
1787
+ if used_vvar is None:
1788
+ # no explicit reference
1789
+ used_by.add(None)
1790
+ else:
1791
+ stmt = blocks_dict[loc.block_addr, loc.block_idx].statements[loc.stmt_idx]
1792
+ if isinstance(stmt, Assignment) and isinstance(stmt.dst, VirtualVariable):
1793
+ used_by.add(stmt.dst.varid)
1794
+ else:
1795
+ used_by.add(None)
1796
+ vvar_used_by[var_id] |= used_by
1797
+
1798
+ g = networkx.DiGraph()
1799
+ dummy_vvar_id = -1
1800
+ for var_id, used_by_initial in vvar_used_by.items():
1801
+ for u in used_by_initial:
1802
+ if u is None:
1803
+ # we can't have None in networkx.DiGraph
1804
+ g.add_edge(var_id, dummy_vvar_id)
1805
+ else:
1806
+ g.add_edge(var_id, u)
1807
+
1808
+ cyclic_dependent_phi_varids = set()
1809
+ for scc in networkx.strongly_connected_components(g):
1810
+ if len(scc) == 1:
1811
+ continue
1812
+
1813
+ bail = False
1814
+ for varid in scc:
1815
+ # if this vvar is a phi var, ensure this vvar is not used by anything else outside the scc
1816
+ if varid in rd.phi_vvar_ids:
1817
+ succs = list(g.successors(varid))
1818
+ if any(succ_varid not in scc for succ_varid in succs):
1819
+ bail = True
1820
+ break
1821
+ if bail:
1822
+ continue
1823
+
1824
+ if all(varid in phi_and_dirty_vvar_ids for varid in scc):
1825
+ cyclic_dependent_phi_varids |= set(scc)
1826
+
1827
+ return cyclic_dependent_phi_varids
1828
+
1314
1829
  #
1315
1830
  # Rewriting ccalls
1316
1831
  #
@@ -1335,8 +1850,7 @@ class AILSimplifier(Analysis):
1335
1850
  if rewriter.result is not None:
1336
1851
  _any_update.v = True
1337
1852
  return rewriter.result
1338
- else:
1339
- return None
1853
+ return None
1340
1854
 
1341
1855
  return AILBlockWalker._handle_expr(walker, expr_idx, expr, stmt_idx, stmt, block)
1342
1856
 
@@ -1359,7 +1873,7 @@ class AILSimplifier(Analysis):
1359
1873
  @staticmethod
1360
1874
  def _statement_has_call_exprs(stmt: Statement) -> bool:
1361
1875
  def _handle_callexpr(expr_idx, expr, stmt_idx, stmt, block): # pylint:disable=unused-argument
1362
- raise HasCallNotification()
1876
+ raise HasCallNotification
1363
1877
 
1364
1878
  walker = AILBlockWalker()
1365
1879
  walker.expr_handlers[Call] = _handle_callexpr
@@ -1373,7 +1887,7 @@ class AILSimplifier(Analysis):
1373
1887
  @staticmethod
1374
1888
  def _expression_has_call_exprs(expr: Expression) -> bool:
1375
1889
  def _handle_callexpr(expr_idx, expr, stmt_idx, stmt, block): # pylint:disable=unused-argument
1376
- raise HasCallNotification()
1890
+ raise HasCallNotification
1377
1891
 
1378
1892
  walker = AILBlockWalker()
1379
1893
  walker.expr_handlers[Call] = _handle_callexpr
@@ -1400,10 +1914,25 @@ class AILSimplifier(Analysis):
1400
1914
  started = False
1401
1915
  continue
1402
1916
 
1403
- if started:
1404
- if b.statements and isinstance(b.statements[-1], Call):
1405
- calls += 1
1917
+ if started and b.statements and isinstance(b.statements[-1], Call):
1918
+ calls += 1
1406
1919
  return calls
1407
1920
 
1921
+ @staticmethod
1922
+ def _exprs_contain_vvar(exprs: Iterable[Expression], vvar_ids: set[int]) -> bool:
1923
+ def _handle_VirtualVariable(expr_idx, expr, stmt_idx, stmt, block): # pylint:disable=unused-argument
1924
+ if expr.varid in vvar_ids:
1925
+ raise HasVVarNotification
1926
+
1927
+ walker = AILBlockWalker()
1928
+ walker.expr_handlers[VirtualVariable] = _handle_VirtualVariable
1929
+
1930
+ for expr in exprs:
1931
+ try:
1932
+ walker.walk_expression(expr)
1933
+ except HasVVarNotification:
1934
+ return True
1935
+ return False
1936
+
1408
1937
 
1409
1938
  AnalysesHub.register_default("AILSimplifier", AILSimplifier)