angr 9.2.158__cp310-abi3-manylinux2014_aarch64.whl → 9.2.160__cp310-abi3-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.
- angr/__init__.py +1 -1
- angr/ailment/__init__.py +81 -0
- angr/ailment/block.py +81 -0
- angr/ailment/block_walker.py +845 -0
- angr/ailment/constant.py +3 -0
- angr/ailment/converter_common.py +11 -0
- angr/ailment/converter_pcode.py +623 -0
- angr/ailment/converter_vex.py +798 -0
- angr/ailment/expression.py +1639 -0
- angr/ailment/manager.py +33 -0
- angr/ailment/statement.py +978 -0
- angr/ailment/tagged_object.py +61 -0
- angr/ailment/utils.py +114 -0
- angr/analyses/calling_convention/calling_convention.py +6 -2
- angr/analyses/decompiler/ail_simplifier.py +5 -5
- angr/analyses/decompiler/block_io_finder.py +4 -4
- angr/analyses/decompiler/block_similarity.py +2 -2
- angr/analyses/decompiler/block_simplifier.py +4 -4
- angr/analyses/decompiler/callsite_maker.py +2 -2
- angr/analyses/decompiler/ccall_rewriters/amd64_ccalls.py +1 -1
- angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +1 -1
- angr/analyses/decompiler/ccall_rewriters/x86_ccalls.py +1 -1
- angr/analyses/decompiler/clinic.py +5 -2
- angr/analyses/decompiler/condition_processor.py +1 -1
- angr/analyses/decompiler/counters/boolean_counter.py +4 -4
- angr/analyses/decompiler/counters/call_counter.py +4 -4
- angr/analyses/decompiler/counters/expression_counters.py +5 -5
- angr/analyses/decompiler/counters/seq_cf_structure_counter.py +1 -1
- angr/analyses/decompiler/decompiler.py +17 -12
- angr/analyses/decompiler/dephication/dephication_base.py +12 -1
- angr/analyses/decompiler/dephication/graph_dephication.py +12 -5
- angr/analyses/decompiler/dephication/graph_rewriting.py +6 -10
- angr/analyses/decompiler/dephication/graph_vvar_mapping.py +109 -72
- angr/analyses/decompiler/dephication/rewriting_engine.py +32 -9
- angr/analyses/decompiler/dephication/seqnode_dephication.py +32 -10
- angr/analyses/decompiler/empty_node_remover.py +2 -2
- angr/analyses/decompiler/expression_narrower.py +6 -6
- angr/analyses/decompiler/goto_manager.py +2 -2
- angr/analyses/decompiler/jump_target_collector.py +1 -1
- angr/analyses/decompiler/label_collector.py +1 -1
- angr/analyses/decompiler/optimization_passes/base_ptr_save_simplifier.py +25 -25
- angr/analyses/decompiler/optimization_passes/call_stmt_rewriter.py +1 -1
- angr/analyses/decompiler/optimization_passes/code_motion.py +2 -2
- angr/analyses/decompiler/optimization_passes/condition_constprop.py +3 -3
- angr/analyses/decompiler/optimization_passes/const_derefs.py +3 -3
- angr/analyses/decompiler/optimization_passes/const_prop_reverter.py +4 -4
- angr/analyses/decompiler/optimization_passes/deadblock_remover.py +2 -2
- angr/analyses/decompiler/optimization_passes/determine_load_sizes.py +3 -3
- angr/analyses/decompiler/optimization_passes/div_simplifier.py +1 -1
- angr/analyses/decompiler/optimization_passes/duplication_reverter/ail_merge_graph.py +2 -2
- angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +4 -4
- angr/analyses/decompiler/optimization_passes/duplication_reverter/similarity.py +1 -1
- angr/analyses/decompiler/optimization_passes/duplication_reverter/utils.py +4 -4
- angr/analyses/decompiler/optimization_passes/eager_std_string_concatenation.py +3 -3
- angr/analyses/decompiler/optimization_passes/engine_base.py +1 -1
- angr/analyses/decompiler/optimization_passes/expr_op_swapper.py +3 -3
- angr/analyses/decompiler/optimization_passes/flip_boolean_cmp.py +2 -2
- angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +2 -2
- angr/analyses/decompiler/optimization_passes/ite_expr_converter.py +3 -3
- angr/analyses/decompiler/optimization_passes/ite_region_converter.py +3 -3
- angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +4 -4
- angr/analyses/decompiler/optimization_passes/mod_simplifier.py +1 -1
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +25 -1
- angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py +1 -1
- angr/analyses/decompiler/optimization_passes/ret_addr_save_simplifier.py +1 -1
- angr/analyses/decompiler/optimization_passes/ret_deduplicator.py +2 -2
- angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +4 -4
- angr/analyses/decompiler/optimization_passes/return_duplicator_low.py +2 -2
- angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +1 -1
- angr/analyses/decompiler/optimization_passes/switch_default_case_duplicator.py +3 -3
- angr/analyses/decompiler/optimization_passes/switch_reused_entry_rewriter.py +3 -3
- angr/analyses/decompiler/optimization_passes/tag_slicer.py +1 -1
- angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +1 -1
- angr/analyses/decompiler/optimization_passes/x86_gcc_getpc_simplifier.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/a_div_const_add_a_mul_n_div_const.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/a_mul_const_div_shr_const.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/a_mul_const_sub_a.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/a_shl_const_sub_a.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/a_sub_a_div.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/a_sub_a_div_const_mul_const.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/a_sub_a_shr_const_shr_const.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/a_sub_a_sub_n.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/arm_cmpf.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/base.py +3 -3
- angr/analyses/decompiler/peephole_optimizations/basepointeroffset_add_n.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/basepointeroffset_and_mask.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/bitwise_or_to_logical_or.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/bool_expr_xor_1.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/bswap.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/cas_intrinsics.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/cmpord_rewriter.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/coalesce_adjacent_shrs.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/coalesce_same_cascading_ifs.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/const_mull_a_shift.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/constant_derefs.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/conv_a_sub0_shr_and.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/conv_shl_shr.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/eager_eval.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/extended_byte_and_mask.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/inlined_strcpy_consolidation.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/invert_negated_logical_conjuction_disjunction.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/one_sub_bool.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/remove_cascading_conversions.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/remove_cxx_destructor_calls.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/remove_empty_if_body.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_bitmasks.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_conversions.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_branch.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_comparisons.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_nots.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_reinterprets.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts_around_comparators.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/rewrite_conv_mul.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/rewrite_cxx_operator_calls.py +3 -3
- angr/analyses/decompiler/peephole_optimizations/rewrite_mips_gp_loads.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/rol_ror.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/sar_to_signed_div.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/shl_to_mul.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/simplify_pc_relative_loads.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/single_bit_cond_to_boolexpr.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/single_bit_xor.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/tidy_stack_addr.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/utils.py +1 -1
- angr/analyses/decompiler/redundant_label_remover.py +1 -1
- angr/analyses/decompiler/region_identifier.py +4 -4
- angr/analyses/decompiler/region_simplifiers/cascading_cond_transformer.py +1 -1
- angr/analyses/decompiler/region_simplifiers/cascading_ifs.py +1 -1
- angr/analyses/decompiler/region_simplifiers/expr_folding.py +37 -8
- angr/analyses/decompiler/region_simplifiers/goto.py +1 -1
- angr/analyses/decompiler/region_simplifiers/if_.py +1 -1
- angr/analyses/decompiler/region_simplifiers/loop.py +1 -1
- angr/analyses/decompiler/region_simplifiers/node_address_finder.py +1 -1
- angr/analyses/decompiler/region_simplifiers/region_simplifier.py +14 -2
- angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +3 -3
- angr/analyses/decompiler/region_simplifiers/switch_expr_simplifier.py +1 -1
- angr/analyses/decompiler/return_maker.py +1 -1
- angr/analyses/decompiler/seq_to_blocks.py +1 -1
- angr/analyses/decompiler/sequence_walker.py +2 -2
- angr/analyses/decompiler/ssailification/rewriting.py +4 -4
- angr/analyses/decompiler/ssailification/rewriting_engine.py +4 -4
- angr/analyses/decompiler/ssailification/rewriting_state.py +3 -3
- angr/analyses/decompiler/ssailification/ssailification.py +2 -2
- angr/analyses/decompiler/ssailification/traversal.py +1 -1
- angr/analyses/decompiler/ssailification/traversal_engine.py +11 -2
- angr/analyses/decompiler/structured_codegen/c.py +3 -3
- angr/analyses/decompiler/structuring/dream.py +1 -1
- angr/analyses/decompiler/structuring/phoenix.py +3 -3
- angr/analyses/decompiler/structuring/structurer_base.py +1 -1
- angr/analyses/decompiler/structuring/structurer_nodes.py +1 -2
- angr/analyses/decompiler/utils.py +1 -1
- angr/analyses/deobfuscator/api_obf_peephole_optimizer.py +1 -1
- angr/analyses/deobfuscator/string_obf_opt_passes.py +3 -3
- angr/analyses/deobfuscator/string_obf_peephole_optimizer.py +2 -2
- angr/analyses/propagator/propagator.py +1 -1
- angr/analyses/proximity_graph.py +2 -2
- angr/analyses/reaching_definitions/engine_ail.py +1 -1
- angr/analyses/reaching_definitions/reaching_definitions.py +1 -1
- angr/analyses/reaching_definitions/subject.py +1 -1
- angr/analyses/s_liveness.py +2 -2
- angr/analyses/s_propagator.py +3 -3
- angr/analyses/s_reaching_definitions/s_rda_model.py +1 -1
- angr/analyses/s_reaching_definitions/s_rda_view.py +3 -3
- angr/analyses/s_reaching_definitions/s_reaching_definitions.py +3 -3
- angr/analyses/typehoon/simple_solver.py +231 -29
- angr/analyses/typehoon/typehoon.py +10 -2
- angr/analyses/variable_recovery/engine_ail.py +10 -22
- angr/analyses/variable_recovery/engine_base.py +1 -1
- angr/analyses/variable_recovery/variable_recovery_base.py +1 -1
- angr/analyses/variable_recovery/variable_recovery_fast.py +2 -2
- angr/engines/light/data.py +1 -1
- angr/engines/light/engine.py +1 -1
- angr/knowledge_plugins/key_definitions/atoms.py +1 -1
- angr/knowledge_plugins/propagations/prop_value.py +1 -1
- angr/knowledge_plugins/propagations/propagation_model.py +1 -1
- angr/knowledge_plugins/propagations/states.py +1 -1
- angr/knowledge_plugins/variables/variable_manager.py +1 -1
- angr/rustylib.abi3.so +0 -0
- angr/state_plugins/unicorn_engine.py +4 -4
- angr/utils/ail.py +4 -4
- angr/utils/endness.py +1 -1
- angr/utils/ssa/__init__.py +14 -4
- angr/utils/ssa/tmp_uses_collector.py +4 -4
- angr/utils/ssa/vvar_uses_collector.py +4 -4
- {angr-9.2.158.dist-info → angr-9.2.160.dist-info}/METADATA +6 -7
- {angr-9.2.158.dist-info → angr-9.2.160.dist-info}/RECORD +195 -183
- /angr/{lib/angr_native.so → unicornlib.so} +0 -0
- {angr-9.2.158.dist-info → angr-9.2.160.dist-info}/WHEEL +0 -0
- {angr-9.2.158.dist-info → angr-9.2.160.dist-info}/entry_points.txt +0 -0
- {angr-9.2.158.dist-info → angr-9.2.160.dist-info}/licenses/LICENSE +0 -0
- {angr-9.2.158.dist-info → angr-9.2.160.dist-info}/top_level.txt +0 -0
angr/ailment/constant.py
ADDED
|
@@ -0,0 +1,623 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import logging
|
|
3
|
+
|
|
4
|
+
from angr.utils.constants import DEFAULT_STATEMENT
|
|
5
|
+
from angr.engines.pcode.lifter import IRSB
|
|
6
|
+
from pypcode import OpCode, Varnode
|
|
7
|
+
import pypcode
|
|
8
|
+
|
|
9
|
+
from .block import Block
|
|
10
|
+
from .statement import Statement, Assignment, Store, Jump, ConditionalJump, Return, Call
|
|
11
|
+
from .expression import Expression, DirtyExpression, Const, Register, Tmp, UnaryOp, BinaryOp, Load, Convert
|
|
12
|
+
|
|
13
|
+
# FIXME: Convert, ITE
|
|
14
|
+
from .manager import Manager
|
|
15
|
+
from .converter_common import Converter
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
log = logging.getLogger(name=__name__)
|
|
19
|
+
|
|
20
|
+
# FIXME: Not all ops are mapped to AIL expressions!
|
|
21
|
+
opcode_to_generic_name = {
|
|
22
|
+
# OpCode.MULTIEQUAL : '',
|
|
23
|
+
# OpCode.INDIRECT : '',
|
|
24
|
+
# OpCode.PIECE : '',
|
|
25
|
+
# OpCode.SUBPIECE : '',
|
|
26
|
+
OpCode.INT_EQUAL: "CmpEQ",
|
|
27
|
+
OpCode.INT_NOTEQUAL: "CmpNE",
|
|
28
|
+
OpCode.INT_SLESS: "CmpLTs",
|
|
29
|
+
OpCode.INT_SLESSEQUAL: "CmpLEs",
|
|
30
|
+
OpCode.INT_LESS: "CmpLT",
|
|
31
|
+
OpCode.INT_LESSEQUAL: "CmpLE",
|
|
32
|
+
# OpCode.INT_ZEXT : '',
|
|
33
|
+
# OpCode.INT_SEXT : '',
|
|
34
|
+
OpCode.INT_ADD: "Add",
|
|
35
|
+
OpCode.INT_SUB: "Sub",
|
|
36
|
+
OpCode.INT_CARRY: "Carry",
|
|
37
|
+
OpCode.INT_SCARRY: "SCarry",
|
|
38
|
+
OpCode.INT_SBORROW: "SBorrow",
|
|
39
|
+
# OpCode.INT_2COMP : '',
|
|
40
|
+
OpCode.INT_NEGATE: "Neg",
|
|
41
|
+
OpCode.INT_XOR: "Xor",
|
|
42
|
+
OpCode.INT_AND: "And",
|
|
43
|
+
OpCode.INT_OR: "Or",
|
|
44
|
+
OpCode.INT_LEFT: "Shl",
|
|
45
|
+
OpCode.INT_RIGHT: "Shr",
|
|
46
|
+
OpCode.INT_SRIGHT: "Sar",
|
|
47
|
+
OpCode.INT_MULT: "Mul",
|
|
48
|
+
OpCode.INT_DIV: "Div",
|
|
49
|
+
# OpCode.INT_SDIV : '',
|
|
50
|
+
# OpCode.INT_REM : '',
|
|
51
|
+
# OpCode.INT_SREM : '',
|
|
52
|
+
OpCode.BOOL_NEGATE: "Not",
|
|
53
|
+
OpCode.BOOL_XOR: "LogicalXor",
|
|
54
|
+
OpCode.BOOL_AND: "LogicalAnd",
|
|
55
|
+
OpCode.BOOL_OR: "LogicalOr",
|
|
56
|
+
# OpCode.CAST : '',
|
|
57
|
+
# OpCode.PTRADD : '',
|
|
58
|
+
# OpCode.PTRSUB : '',
|
|
59
|
+
# OpCode.FLOAT_EQUAL : '',
|
|
60
|
+
# OpCode.FLOAT_NOTEQUAL : '',
|
|
61
|
+
# OpCode.FLOAT_LESS : '',
|
|
62
|
+
# OpCode.FLOAT_LESSEQUAL : '',
|
|
63
|
+
# OpCode.FLOAT_NAN : '',
|
|
64
|
+
# OpCode.FLOAT_ADD : '',
|
|
65
|
+
OpCode.FLOAT_DIV: "Div",
|
|
66
|
+
OpCode.FLOAT_MULT: "Mul",
|
|
67
|
+
OpCode.FLOAT_SUB: "Sub",
|
|
68
|
+
# OpCode.FLOAT_NEG : '',
|
|
69
|
+
# OpCode.FLOAT_ABS : '',
|
|
70
|
+
# OpCode.FLOAT_SQRT : '',
|
|
71
|
+
# OpCode.FLOAT_INT2FLOAT : '',
|
|
72
|
+
# OpCode.FLOAT_FLOAT2FLOAT : '',
|
|
73
|
+
# OpCode.FLOAT_TRUNC : '',
|
|
74
|
+
# OpCode.FLOAT_CEIL : '',
|
|
75
|
+
# OpCode.FLOAT_FLOOR : '',
|
|
76
|
+
# OpCode.FLOAT_ROUND : '',
|
|
77
|
+
# OpCode.SEGMENTOP : '',
|
|
78
|
+
# OpCode.CPOOLREF : '',
|
|
79
|
+
# OpCode.NEW : '',
|
|
80
|
+
# OpCode.INSERT : '',
|
|
81
|
+
# OpCode.EXTRACT : '',
|
|
82
|
+
# OpCode.POPCOUNT : '',
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class PCodeIRSBConverter(Converter):
|
|
87
|
+
"""
|
|
88
|
+
Converts a p-code IRSB to an AIL block
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
@staticmethod
|
|
92
|
+
def convert(irsb: IRSB, manager: Manager): # pylint:disable=arguments-differ
|
|
93
|
+
"""
|
|
94
|
+
Convert the given IRSB to an AIL block
|
|
95
|
+
|
|
96
|
+
:param irsb: IRSB to convert
|
|
97
|
+
:param manager: Manager to use
|
|
98
|
+
:return: Converted block
|
|
99
|
+
"""
|
|
100
|
+
return PCodeIRSBConverter(irsb, manager)._convert()
|
|
101
|
+
|
|
102
|
+
def __init__(self, irsb: IRSB, manager: Manager):
|
|
103
|
+
self._irsb = irsb
|
|
104
|
+
self._manager = manager
|
|
105
|
+
self._statements = []
|
|
106
|
+
self._current_op = None
|
|
107
|
+
self._next_ins_addr = None
|
|
108
|
+
self._current_behavior = None
|
|
109
|
+
self._statement_idx = 0
|
|
110
|
+
|
|
111
|
+
# Remap all uniques s.t. they are write-once with values starting from 0
|
|
112
|
+
self._unique_tracker: dict[int, tuple[int, int]] = {}
|
|
113
|
+
self._unique_counter = 0
|
|
114
|
+
|
|
115
|
+
self._special_op_handlers = {
|
|
116
|
+
OpCode.COPY: self._convert_copy,
|
|
117
|
+
OpCode.INT_ZEXT: self._convert_zext,
|
|
118
|
+
OpCode.INT_SEXT: self._convert_sext,
|
|
119
|
+
OpCode.LOAD: self._convert_load,
|
|
120
|
+
OpCode.STORE: self._convert_store,
|
|
121
|
+
OpCode.BRANCH: self._convert_branch,
|
|
122
|
+
OpCode.CBRANCH: self._convert_cbranch,
|
|
123
|
+
OpCode.BRANCHIND: self._convert_branchind,
|
|
124
|
+
OpCode.CALL: self._convert_call,
|
|
125
|
+
OpCode.CALLIND: self._convert_callind,
|
|
126
|
+
OpCode.CALLOTHER: self._convert_callother,
|
|
127
|
+
OpCode.RETURN: self._convert_ret,
|
|
128
|
+
OpCode.MULTIEQUAL: self._convert_multiequal,
|
|
129
|
+
OpCode.INDIRECT: self._convert_indirect,
|
|
130
|
+
OpCode.SEGMENTOP: self._convert_segment_op,
|
|
131
|
+
OpCode.CPOOLREF: self._convert_cpool_ref,
|
|
132
|
+
OpCode.NEW: self._convert_new,
|
|
133
|
+
OpCode.FLOAT_INT2FLOAT: self._convert_int2float,
|
|
134
|
+
OpCode.FLOAT_FLOAT2FLOAT: self._convert_float2float,
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
manager.tyenv = None
|
|
138
|
+
manager.block_addr = irsb.addr
|
|
139
|
+
manager.vex_stmt_idx = DEFAULT_STATEMENT # Reset after loop. Necessary?
|
|
140
|
+
|
|
141
|
+
def _convert(self) -> Block:
|
|
142
|
+
"""
|
|
143
|
+
Convert the given IRSB to an AIL Block
|
|
144
|
+
"""
|
|
145
|
+
self._statement_idx = 0
|
|
146
|
+
|
|
147
|
+
for op in self._irsb._ops:
|
|
148
|
+
self._current_op = op
|
|
149
|
+
if op.opcode == pypcode.OpCode.IMARK:
|
|
150
|
+
self._manager.ins_addr = op.inputs[0].offset
|
|
151
|
+
self._next_ins_addr = op.inputs[-1].offset + op.inputs[-1].size
|
|
152
|
+
else:
|
|
153
|
+
self._current_behavior = self._irsb.behaviors.get_behavior_for_opcode(self._current_op.opcode)
|
|
154
|
+
self._convert_current_op()
|
|
155
|
+
self._statement_idx += 1
|
|
156
|
+
|
|
157
|
+
if (
|
|
158
|
+
"sparc:" in self._irsb.arch.name
|
|
159
|
+
and self._irsb.arch.bits == 32
|
|
160
|
+
and self._current_op.opcode == OpCode.CALL
|
|
161
|
+
):
|
|
162
|
+
break
|
|
163
|
+
|
|
164
|
+
return Block(self._irsb.addr, self._irsb.size, statements=self._statements)
|
|
165
|
+
|
|
166
|
+
def _convert_current_op(self) -> None:
|
|
167
|
+
"""
|
|
168
|
+
Convert the current op to corresponding AIL statement
|
|
169
|
+
"""
|
|
170
|
+
assert self._current_behavior is not None
|
|
171
|
+
|
|
172
|
+
is_special = self._current_behavior.opcode in self._special_op_handlers
|
|
173
|
+
|
|
174
|
+
if is_special:
|
|
175
|
+
try:
|
|
176
|
+
self._special_op_handlers[self._current_behavior.opcode]()
|
|
177
|
+
except NotImplementedError as ex:
|
|
178
|
+
log.warning("Unsupported opcode: %s", ex)
|
|
179
|
+
elif self._current_behavior.is_unary:
|
|
180
|
+
self._convert_unary()
|
|
181
|
+
else:
|
|
182
|
+
self._convert_binary()
|
|
183
|
+
|
|
184
|
+
def _convert_unary(self) -> None:
|
|
185
|
+
"""
|
|
186
|
+
Convert the current unary op to corresponding AIL statement
|
|
187
|
+
"""
|
|
188
|
+
opcode = self._current_op.opcode
|
|
189
|
+
|
|
190
|
+
op = opcode_to_generic_name.get(opcode)
|
|
191
|
+
in1 = self._get_value(self._current_op.inputs[0])
|
|
192
|
+
if op is None:
|
|
193
|
+
log.warning("p-code: Unsupported opcode of type %s", opcode.__name__)
|
|
194
|
+
out = DirtyExpression(self._manager.next_atom(), opcode.__name__, [], bits=self._current_op.output.size * 8)
|
|
195
|
+
else:
|
|
196
|
+
out = UnaryOp(self._manager.next_atom(), op, in1, ins_addr=self._manager.ins_addr)
|
|
197
|
+
|
|
198
|
+
stmt = self._set_value(self._current_op.output, out)
|
|
199
|
+
self._statements.append(stmt)
|
|
200
|
+
|
|
201
|
+
def _convert_binary(self) -> None:
|
|
202
|
+
"""
|
|
203
|
+
Convert the current binary op to corresponding AIL statement
|
|
204
|
+
"""
|
|
205
|
+
opcode = self._current_op.opcode
|
|
206
|
+
op = opcode_to_generic_name.get(opcode)
|
|
207
|
+
in1 = self._get_value(self._current_op.inputs[0])
|
|
208
|
+
in2 = self._get_value(self._current_op.inputs[1])
|
|
209
|
+
signed = op in {"CmpLEs", "CmpGTs"}
|
|
210
|
+
|
|
211
|
+
if op is None:
|
|
212
|
+
log.warning("p-code: Unsupported opcode of type %s.", opcode.__name__)
|
|
213
|
+
out = DirtyExpression(self._manager.next_atom(), opcode.__name__, [], bits=self._current_op.output.size * 8)
|
|
214
|
+
else:
|
|
215
|
+
out = BinaryOp(self._manager.next_atom(), op, [in1, in2], signed, ins_addr=self._manager.ins_addr)
|
|
216
|
+
|
|
217
|
+
# Zero-extend 1-bit results
|
|
218
|
+
zextend_ops = {
|
|
219
|
+
OpCode.INT_EQUAL,
|
|
220
|
+
OpCode.INT_NOTEQUAL,
|
|
221
|
+
OpCode.INT_SLESS,
|
|
222
|
+
OpCode.INT_SLESSEQUAL,
|
|
223
|
+
OpCode.INT_LESS,
|
|
224
|
+
OpCode.INT_LESSEQUAL,
|
|
225
|
+
}
|
|
226
|
+
if opcode in zextend_ops:
|
|
227
|
+
out = Convert(self._manager.next_atom(), 1, self._current_op.output.size * 8, False, out)
|
|
228
|
+
|
|
229
|
+
stmt = self._set_value(self._current_op.output, out)
|
|
230
|
+
self._statements.append(stmt)
|
|
231
|
+
|
|
232
|
+
def _map_register_name(self, varnode: Varnode) -> int:
|
|
233
|
+
"""
|
|
234
|
+
Map SLEIGH register offset to ArchInfo register offset based on name.
|
|
235
|
+
|
|
236
|
+
:param varnode: The varnode to translate
|
|
237
|
+
:return: The register file offset
|
|
238
|
+
"""
|
|
239
|
+
# FIXME: Will need performance optimization
|
|
240
|
+
# FIXME: Should not get trans object this way. Moreover, should have a
|
|
241
|
+
# faster mapping method than going through trans
|
|
242
|
+
reg_name = varnode.getRegisterName()
|
|
243
|
+
try:
|
|
244
|
+
reg_offset = self._manager.arch.get_register_offset(reg_name.lower())
|
|
245
|
+
log.debug("Mapped register '%s' to offset %x", reg_name, reg_offset)
|
|
246
|
+
except ValueError:
|
|
247
|
+
reg_offset = varnode.offset + 0x100000
|
|
248
|
+
log.warning("Could not map register '%s' from archinfo. Mapping to %x", reg_name, reg_offset)
|
|
249
|
+
return reg_offset
|
|
250
|
+
|
|
251
|
+
def _remap_temp(self, offset: int, size: int, is_write: bool) -> int | None:
|
|
252
|
+
"""
|
|
253
|
+
Remap any unique space addresses such that they are written only once
|
|
254
|
+
|
|
255
|
+
:param offset: The unique space address
|
|
256
|
+
:param is_write: Whether the access is a write or a read
|
|
257
|
+
:return: The remapped temporary register index
|
|
258
|
+
"""
|
|
259
|
+
if is_write:
|
|
260
|
+
self._unique_tracker[offset] = self._unique_counter, size
|
|
261
|
+
self._unique_counter += 1
|
|
262
|
+
return self._unique_tracker[offset][0]
|
|
263
|
+
if offset in self._unique_tracker:
|
|
264
|
+
return self._unique_tracker[offset][0]
|
|
265
|
+
# this might be a partial access of an existing temporary variable. return None for now
|
|
266
|
+
return None
|
|
267
|
+
|
|
268
|
+
def _convert_varnode(self, varnode: Varnode, is_write: bool) -> Expression:
|
|
269
|
+
"""
|
|
270
|
+
Convert a varnode to a corresponding AIL expression
|
|
271
|
+
|
|
272
|
+
:param varnode: The varnode to remap
|
|
273
|
+
:param is_write: Whether the varnode is being read or written to
|
|
274
|
+
:return: The corresponding AIL expression
|
|
275
|
+
"""
|
|
276
|
+
space_name = varnode.space.name
|
|
277
|
+
size = varnode.size * 8
|
|
278
|
+
|
|
279
|
+
if space_name == "const":
|
|
280
|
+
return Const(self._manager.next_atom(), None, varnode.offset, size)
|
|
281
|
+
if space_name == "register":
|
|
282
|
+
offset = self._map_register_name(varnode)
|
|
283
|
+
return Register(self._manager.next_atom(), None, offset, size, reg_name=varnode.getRegisterName())
|
|
284
|
+
if space_name == "unique":
|
|
285
|
+
offset = self._remap_temp(varnode.offset, varnode.size, is_write)
|
|
286
|
+
if offset is None:
|
|
287
|
+
# this might be a partial access of an existing temporary variable
|
|
288
|
+
unique_offset = None
|
|
289
|
+
for delta in range(-1, -8, -1):
|
|
290
|
+
if varnode.offset + delta in self._unique_tracker:
|
|
291
|
+
unique_offset = varnode.offset + delta
|
|
292
|
+
break
|
|
293
|
+
assert unique_offset is not None, "Cannot find the source unique variable"
|
|
294
|
+
# TODO: Check size
|
|
295
|
+
_, ori_tmp_size = self._unique_tracker[unique_offset]
|
|
296
|
+
t = Tmp(self._manager.next_atom(), None, unique_offset, ori_tmp_size * 8)
|
|
297
|
+
# FIXME: Asserting BE
|
|
298
|
+
right_shift_amount = varnode.offset + varnode.size - (unique_offset + ori_tmp_size)
|
|
299
|
+
if right_shift_amount != 0:
|
|
300
|
+
t = BinaryOp(
|
|
301
|
+
self._manager.next_atom(),
|
|
302
|
+
"Shr",
|
|
303
|
+
[t, Const(self._manager.next_atom(), None, right_shift_amount * 8, 8)],
|
|
304
|
+
False,
|
|
305
|
+
ins_addr=self._manager.ins_addr,
|
|
306
|
+
)
|
|
307
|
+
return Convert(self._manager.next_atom(), t.bits, size, False, t, ins_addr=self._manager.ins_addr)
|
|
308
|
+
|
|
309
|
+
return Tmp(self._manager.next_atom(), None, offset, size)
|
|
310
|
+
if space_name in ["ram", "mem"]:
|
|
311
|
+
assert not is_write
|
|
312
|
+
addr = Const(self._manager.next_atom(), None, varnode.offset, self._manager.arch.bits)
|
|
313
|
+
# Note: Load takes bytes, not bits, for size
|
|
314
|
+
return Load(
|
|
315
|
+
self._manager.next_atom(),
|
|
316
|
+
addr,
|
|
317
|
+
varnode.size,
|
|
318
|
+
self._manager.arch.memory_endness,
|
|
319
|
+
ins_addr=self._manager.ins_addr,
|
|
320
|
+
)
|
|
321
|
+
raise NotImplementedError
|
|
322
|
+
|
|
323
|
+
def _set_value(self, varnode: Varnode, value: Expression) -> Statement:
|
|
324
|
+
"""
|
|
325
|
+
Create the appropriate assignment statement to store to a varnode
|
|
326
|
+
|
|
327
|
+
This method stores to the appropriate register, or unique space,
|
|
328
|
+
depending on the space indicated by the varnode.
|
|
329
|
+
|
|
330
|
+
:param varnode: Varnode to store into
|
|
331
|
+
:param value: Value to store
|
|
332
|
+
:return: Corresponding AIL statement
|
|
333
|
+
"""
|
|
334
|
+
space_name = varnode.space.name
|
|
335
|
+
|
|
336
|
+
if space_name in ["register", "unique"]:
|
|
337
|
+
return Assignment(
|
|
338
|
+
self._statement_idx, self._convert_varnode(varnode, True), value, ins_addr=self._manager.ins_addr
|
|
339
|
+
)
|
|
340
|
+
if space_name in ["ram", "mem"]:
|
|
341
|
+
addr = Const(self._manager.next_atom(), None, varnode.offset, self._manager.arch.bits)
|
|
342
|
+
return Store(
|
|
343
|
+
self._statement_idx,
|
|
344
|
+
addr,
|
|
345
|
+
value,
|
|
346
|
+
varnode.size,
|
|
347
|
+
self._manager.arch.memory_endness,
|
|
348
|
+
ins_addr=self._manager.ins_addr,
|
|
349
|
+
)
|
|
350
|
+
raise NotImplementedError
|
|
351
|
+
|
|
352
|
+
def _get_value(self, varnode: Varnode) -> Expression:
|
|
353
|
+
"""
|
|
354
|
+
Create the appropriate expression to load from a varnode
|
|
355
|
+
|
|
356
|
+
This method loads from the appropriate const, register, unique, or RAM
|
|
357
|
+
space, depending on the space indicated by the varnode.
|
|
358
|
+
|
|
359
|
+
:param varnode: Varnode to load from.
|
|
360
|
+
:return: Value loaded
|
|
361
|
+
"""
|
|
362
|
+
return self._convert_varnode(varnode, False)
|
|
363
|
+
|
|
364
|
+
def _convert_copy(self) -> None:
|
|
365
|
+
"""
|
|
366
|
+
Convert copy operation
|
|
367
|
+
"""
|
|
368
|
+
out = self._current_op.output
|
|
369
|
+
inp = self._get_value(self._current_op.inputs[0])
|
|
370
|
+
stmt = self._set_value(out, inp)
|
|
371
|
+
self._statements.append(stmt)
|
|
372
|
+
|
|
373
|
+
def _convert_zext(self) -> None:
|
|
374
|
+
"""
|
|
375
|
+
Convert zext operation
|
|
376
|
+
"""
|
|
377
|
+
out = self._current_op.output
|
|
378
|
+
inp = Convert(
|
|
379
|
+
self._manager.next_atom(),
|
|
380
|
+
self._current_op.inputs[0].size * 8,
|
|
381
|
+
out.size * 8,
|
|
382
|
+
False,
|
|
383
|
+
self._get_value(self._current_op.inputs[0]),
|
|
384
|
+
)
|
|
385
|
+
stmt = self._set_value(out, inp)
|
|
386
|
+
self._statements.append(stmt)
|
|
387
|
+
|
|
388
|
+
def _convert_sext(self) -> None:
|
|
389
|
+
"""
|
|
390
|
+
Convert the signed extension operation
|
|
391
|
+
"""
|
|
392
|
+
out = self._current_op.output
|
|
393
|
+
inp = Convert(
|
|
394
|
+
self._manager.next_atom(),
|
|
395
|
+
self._current_op.inputs[0].size * 8,
|
|
396
|
+
out.size * 8,
|
|
397
|
+
False,
|
|
398
|
+
self._get_value(self._current_op.inputs[0]),
|
|
399
|
+
)
|
|
400
|
+
stmt = self._set_value(out, inp)
|
|
401
|
+
self._statements.append(stmt)
|
|
402
|
+
|
|
403
|
+
def _convert_negate(self) -> None:
|
|
404
|
+
"""
|
|
405
|
+
Convert bool negate operation
|
|
406
|
+
"""
|
|
407
|
+
out = self._current_op.output
|
|
408
|
+
inp = self._get_value(self._current_op.inputs[0])
|
|
409
|
+
|
|
410
|
+
cval = Const(self._manager.next_atom(), None, 0, self._current_op.inputs[0].size * 8)
|
|
411
|
+
|
|
412
|
+
expr = BinaryOp(self._manager.next_atom(), "CmpEQ", [inp, cval], signed=False, ins_addr=self._manager.ins_addr)
|
|
413
|
+
|
|
414
|
+
stmt = self._set_value(out, expr)
|
|
415
|
+
self._statements.append(stmt)
|
|
416
|
+
|
|
417
|
+
def _convert_load(self) -> None:
|
|
418
|
+
"""
|
|
419
|
+
Convert a p-code load operation
|
|
420
|
+
"""
|
|
421
|
+
spc = self._current_op.inputs[0].getSpaceFromConst()
|
|
422
|
+
out = self._current_op.output
|
|
423
|
+
spc_name = spc.name.lower()
|
|
424
|
+
assert spc_name in {"ram", "mem", "register"}
|
|
425
|
+
if spc_name == "register":
|
|
426
|
+
# load from register
|
|
427
|
+
res = self._get_value(self._current_op.inputs[1])
|
|
428
|
+
stmt = self._set_value(out, res)
|
|
429
|
+
else:
|
|
430
|
+
# load from memory
|
|
431
|
+
off = self._get_value(self._current_op.inputs[1])
|
|
432
|
+
res = Load(
|
|
433
|
+
self._manager.next_atom(),
|
|
434
|
+
off,
|
|
435
|
+
self._current_op.output.size,
|
|
436
|
+
self._manager.arch.memory_endness,
|
|
437
|
+
ins_addr=self._manager.ins_addr,
|
|
438
|
+
)
|
|
439
|
+
stmt = self._set_value(out, res)
|
|
440
|
+
self._statements.append(stmt)
|
|
441
|
+
|
|
442
|
+
def _convert_store(self) -> None:
|
|
443
|
+
"""
|
|
444
|
+
Convert a p-code store operation
|
|
445
|
+
"""
|
|
446
|
+
spc = self._current_op.inputs[0].getSpaceFromConst()
|
|
447
|
+
spc_name = spc.name.lower()
|
|
448
|
+
assert spc_name in {"ram", "mem", "register"}
|
|
449
|
+
if spc_name == "register":
|
|
450
|
+
# store to register
|
|
451
|
+
out = self._current_op.inputs[2]
|
|
452
|
+
res = self._get_value(self._current_op.inputs[1])
|
|
453
|
+
stmt = self._set_value(out, res)
|
|
454
|
+
else:
|
|
455
|
+
# store to memory
|
|
456
|
+
off = self._get_value(self._current_op.inputs[1])
|
|
457
|
+
data = self._get_value(self._current_op.inputs[2])
|
|
458
|
+
log.debug("Storing %s at offset %s", data, off)
|
|
459
|
+
# self.state.memory.store(off, data, endness=self.project.arch.memory_endness)
|
|
460
|
+
stmt = Store(
|
|
461
|
+
self._statement_idx,
|
|
462
|
+
off,
|
|
463
|
+
data,
|
|
464
|
+
self._current_op.inputs[2].size,
|
|
465
|
+
self._manager.arch.memory_endness,
|
|
466
|
+
ins_addr=self._manager.ins_addr,
|
|
467
|
+
)
|
|
468
|
+
self._statements.append(stmt)
|
|
469
|
+
|
|
470
|
+
def _convert_branch(self) -> None:
|
|
471
|
+
"""
|
|
472
|
+
Convert a p-code branch operation
|
|
473
|
+
"""
|
|
474
|
+
if self._current_op.inputs[0].space == "const":
|
|
475
|
+
raise NotImplementedError("p-code relative branch not supported yet")
|
|
476
|
+
dest_addr = self._current_op.inputs[0].offset
|
|
477
|
+
|
|
478
|
+
# special handling: if the previous statement is a ConditionalJump with a None destination address, then we
|
|
479
|
+
# back-patch the previous statement
|
|
480
|
+
dest = Const(self._manager.next_atom(), None, dest_addr, self._manager.arch.bits)
|
|
481
|
+
if self._statements:
|
|
482
|
+
last_stmt = self._statements[-1]
|
|
483
|
+
if isinstance(last_stmt, ConditionalJump) and last_stmt.false_target is None:
|
|
484
|
+
last_stmt.false_target = dest
|
|
485
|
+
return
|
|
486
|
+
|
|
487
|
+
stmt = Jump(self._statement_idx, dest, ins_addr=self._manager.ins_addr)
|
|
488
|
+
self._statements.append(stmt)
|
|
489
|
+
|
|
490
|
+
def _convert_cbranch(self) -> None:
|
|
491
|
+
"""
|
|
492
|
+
Convert a p-code conditional branch operation
|
|
493
|
+
"""
|
|
494
|
+
if self._current_op.inputs[0].space == "const":
|
|
495
|
+
raise NotImplementedError("p-code relative branch not supported yet")
|
|
496
|
+
dest_addr = self._current_op.inputs[0].offset
|
|
497
|
+
cond = self._get_value(self._current_op.inputs[1])
|
|
498
|
+
cval = Const(self._manager.next_atom(), None, 0, cond.bits)
|
|
499
|
+
condition = BinaryOp(self._manager.next_atom(), "CmpNE", [cond, cval], signed=False)
|
|
500
|
+
dest = Const(self._manager.next_atom(), None, dest_addr, self._manager.arch.bits)
|
|
501
|
+
if self._irsb._ops[-1] is self._current_op:
|
|
502
|
+
# if the cbranch op is the last op, then we need to generate a fallthru target
|
|
503
|
+
fallthru = Const(
|
|
504
|
+
self._manager.next_atom(),
|
|
505
|
+
None,
|
|
506
|
+
self._next_ins_addr,
|
|
507
|
+
self._manager.arch.bits,
|
|
508
|
+
)
|
|
509
|
+
else:
|
|
510
|
+
# there will be a Jump statement that follows the cbranch
|
|
511
|
+
fallthru = None
|
|
512
|
+
stmt = ConditionalJump(self._statement_idx, condition, dest, fallthru, ins_addr=self._manager.ins_addr)
|
|
513
|
+
self._statements.append(stmt)
|
|
514
|
+
|
|
515
|
+
def _convert_ret(self) -> None:
|
|
516
|
+
"""
|
|
517
|
+
Convert a p-code return operation
|
|
518
|
+
"""
|
|
519
|
+
Const(self._manager.next_atom(), None, self._irsb.next, self._manager.arch.bits)
|
|
520
|
+
stmt = Return(
|
|
521
|
+
self._statement_idx,
|
|
522
|
+
[],
|
|
523
|
+
ins_addr=self._manager.ins_addr,
|
|
524
|
+
vex_block_addr=self._manager.block_addr,
|
|
525
|
+
vex_stmt_idx=DEFAULT_STATEMENT,
|
|
526
|
+
)
|
|
527
|
+
self._statements.append(stmt)
|
|
528
|
+
|
|
529
|
+
def _convert_branchind(self) -> None:
|
|
530
|
+
"""
|
|
531
|
+
Convert a p-code indirect branch operation
|
|
532
|
+
"""
|
|
533
|
+
dest = self._get_value(self._current_op.inputs[0])
|
|
534
|
+
stmt = Jump(self._statement_idx, dest, ins_addr=self._manager.ins_addr)
|
|
535
|
+
self._statements.append(stmt)
|
|
536
|
+
|
|
537
|
+
def _convert_call(self) -> None:
|
|
538
|
+
"""
|
|
539
|
+
Convert a p-code call operation
|
|
540
|
+
"""
|
|
541
|
+
ret_reg_offset = self._manager.arch.ret_offset
|
|
542
|
+
ret_expr = (
|
|
543
|
+
None if ret_reg_offset is None else Register(None, None, ret_reg_offset, self._manager.arch.bits)
|
|
544
|
+
) # ???
|
|
545
|
+
dest = Const(self._manager.next_atom(), None, self._irsb.next, self._manager.arch.bits)
|
|
546
|
+
stmt = Call(
|
|
547
|
+
self._manager.next_atom(),
|
|
548
|
+
dest,
|
|
549
|
+
ret_expr=ret_expr,
|
|
550
|
+
ins_addr=self._manager.ins_addr,
|
|
551
|
+
vex_block_addr=self._manager.block_addr,
|
|
552
|
+
vex_stmt_idx=DEFAULT_STATEMENT,
|
|
553
|
+
)
|
|
554
|
+
self._statements.append(stmt)
|
|
555
|
+
|
|
556
|
+
def _convert_callind(self) -> None:
|
|
557
|
+
"""
|
|
558
|
+
Convert a p-code indirect call operation
|
|
559
|
+
"""
|
|
560
|
+
ret_reg_offset = self._manager.arch.ret_offset
|
|
561
|
+
ret_expr = Register(None, None, ret_reg_offset, self._manager.arch.bits) # ???
|
|
562
|
+
dest = self._get_value(self._current_op.inputs[0])
|
|
563
|
+
stmt = Call(
|
|
564
|
+
self._manager.next_atom(),
|
|
565
|
+
dest,
|
|
566
|
+
ret_expr=ret_expr,
|
|
567
|
+
ins_addr=self._manager.ins_addr,
|
|
568
|
+
vex_block_addr=self._manager.block_addr,
|
|
569
|
+
vex_stmt_idx=DEFAULT_STATEMENT,
|
|
570
|
+
)
|
|
571
|
+
self._statements.append(stmt)
|
|
572
|
+
|
|
573
|
+
def _convert_int2float(self) -> None:
|
|
574
|
+
"""
|
|
575
|
+
Convert INT2FLOAT operation.
|
|
576
|
+
"""
|
|
577
|
+
out = self._current_op.output
|
|
578
|
+
inp = Convert(
|
|
579
|
+
self._manager.next_atom(),
|
|
580
|
+
self._current_op.inputs[0].size * 8,
|
|
581
|
+
out.size * 8,
|
|
582
|
+
True,
|
|
583
|
+
self._get_value(self._current_op.inputs[0]),
|
|
584
|
+
from_type=Convert.TYPE_INT,
|
|
585
|
+
to_type=Convert.TYPE_FP,
|
|
586
|
+
)
|
|
587
|
+
stmt = self._set_value(out, inp)
|
|
588
|
+
self._statements.append(stmt)
|
|
589
|
+
|
|
590
|
+
def _convert_float2float(self) -> None:
|
|
591
|
+
"""
|
|
592
|
+
Convert FLOAT2FLOAT operation.
|
|
593
|
+
"""
|
|
594
|
+
out = self._current_op.output
|
|
595
|
+
inp = Convert(
|
|
596
|
+
self._manager.next_atom(),
|
|
597
|
+
self._current_op.inputs[0].size * 8,
|
|
598
|
+
out.size * 8,
|
|
599
|
+
True,
|
|
600
|
+
self._get_value(self._current_op.inputs[0]),
|
|
601
|
+
from_type=Convert.TYPE_FP,
|
|
602
|
+
to_type=Convert.TYPE_FP,
|
|
603
|
+
)
|
|
604
|
+
stmt = self._set_value(out, inp)
|
|
605
|
+
self._statements.append(stmt)
|
|
606
|
+
|
|
607
|
+
def _convert_callother(self) -> None:
|
|
608
|
+
raise NotImplementedError("CALLOTHER emulation not currently supported")
|
|
609
|
+
|
|
610
|
+
def _convert_multiequal(self) -> None:
|
|
611
|
+
raise NotImplementedError("MULTIEQUAL appearing in unheritaged code?")
|
|
612
|
+
|
|
613
|
+
def _convert_indirect(self) -> None:
|
|
614
|
+
raise NotImplementedError("INDIRECT appearing in unheritaged code?")
|
|
615
|
+
|
|
616
|
+
def _convert_segment_op(self) -> None:
|
|
617
|
+
raise NotImplementedError("SEGMENTOP emulation not currently supported")
|
|
618
|
+
|
|
619
|
+
def _convert_cpool_ref(self) -> None:
|
|
620
|
+
raise NotImplementedError("Cannot currently emulate cpool operator")
|
|
621
|
+
|
|
622
|
+
def _convert_new(self) -> None:
|
|
623
|
+
raise NotImplementedError("Cannot currently emulate new operator")
|