angr 9.2.160__cp310-abi3-manylinux2014_aarch64.whl → 9.2.162__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 +4 -1
- angr/analyses/analysis.py +0 -1
- angr/analyses/cfg/cfg_base.py +5 -1
- angr/analyses/decompiler/ail_simplifier.py +101 -2
- angr/analyses/decompiler/block_simplifier.py +13 -8
- angr/analyses/decompiler/clinic.py +1 -0
- angr/analyses/decompiler/condition_processor.py +24 -0
- angr/analyses/decompiler/counters/call_counter.py +11 -1
- angr/analyses/decompiler/decompiler.py +3 -1
- angr/analyses/decompiler/graph_region.py +11 -2
- angr/analyses/decompiler/optimization_passes/const_prop_reverter.py +1 -1
- angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +1 -0
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +31 -11
- angr/analyses/decompiler/optimization_passes/return_duplicator_low.py +2 -0
- angr/analyses/decompiler/peephole_optimizations/__init__.py +4 -4
- angr/analyses/decompiler/peephole_optimizations/eager_eval.py +53 -0
- angr/analyses/decompiler/peephole_optimizations/modulo_simplifier.py +89 -0
- angr/analyses/decompiler/peephole_optimizations/{const_mull_a_shift.py → optimized_div_simplifier.py} +139 -25
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_bitmasks.py +18 -9
- angr/analyses/decompiler/region_simplifiers/goto.py +3 -3
- angr/analyses/decompiler/region_simplifiers/if_.py +2 -2
- angr/analyses/decompiler/region_simplifiers/loop.py +2 -2
- angr/analyses/decompiler/structured_codegen/c.py +3 -3
- angr/analyses/decompiler/structuring/dream.py +1 -1
- angr/analyses/decompiler/structuring/phoenix.py +138 -99
- angr/analyses/decompiler/structuring/recursive_structurer.py +3 -2
- angr/analyses/decompiler/structuring/sailr.py +51 -43
- angr/analyses/decompiler/structuring/structurer_base.py +2 -3
- angr/analyses/deobfuscator/string_obf_opt_passes.py +1 -1
- angr/analyses/disassembly.py +1 -1
- angr/analyses/reaching_definitions/function_handler.py +1 -0
- angr/analyses/s_propagator.py +2 -2
- angr/analyses/s_reaching_definitions/s_rda_model.py +1 -0
- angr/analyses/s_reaching_definitions/s_reaching_definitions.py +5 -2
- angr/analyses/variable_recovery/engine_base.py +17 -1
- angr/analyses/variable_recovery/variable_recovery_base.py +30 -2
- angr/analyses/variable_recovery/variable_recovery_fast.py +11 -2
- angr/emulator.py +143 -0
- angr/engines/concrete.py +66 -0
- angr/engines/icicle.py +66 -30
- angr/exploration_techniques/driller_core.py +2 -2
- angr/knowledge_plugins/functions/function.py +1 -1
- angr/knowledge_plugins/functions/function_manager.py +1 -2
- angr/project.py +7 -0
- angr/rustylib.abi3.so +0 -0
- angr/sim_type.py +16 -8
- angr/simos/javavm.py +1 -1
- angr/utils/graph.py +48 -13
- angr/utils/library.py +13 -12
- angr/utils/ssa/__init__.py +57 -5
- {angr-9.2.160.dist-info → angr-9.2.162.dist-info}/METADATA +5 -5
- {angr-9.2.160.dist-info → angr-9.2.162.dist-info}/RECORD +56 -54
- angr/analyses/decompiler/peephole_optimizations/a_sub_a_div_const_mul_const.py +0 -57
- {angr-9.2.160.dist-info → angr-9.2.162.dist-info}/WHEEL +0 -0
- {angr-9.2.160.dist-info → angr-9.2.162.dist-info}/entry_points.txt +0 -0
- {angr-9.2.160.dist-info → angr-9.2.162.dist-info}/licenses/LICENSE +0 -0
- {angr-9.2.160.dist-info → angr-9.2.162.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# pylint:disable=too-many-boolean-expressions
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from angr.ailment.expression import BinaryOp, Const, Convert
|
|
4
|
+
|
|
5
|
+
from .base import PeepholeOptimizationExprBase
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ModuloSimplifier(PeepholeOptimizationExprBase):
|
|
9
|
+
"""
|
|
10
|
+
Simplify division and multiplication expressions that can be reduced to a modulo operation.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
__slots__ = ()
|
|
14
|
+
|
|
15
|
+
NAME = "a - (a / N) * N => a % N"
|
|
16
|
+
expr_classes = (BinaryOp,)
|
|
17
|
+
|
|
18
|
+
def optimize( # pylint:disable=unused-argument
|
|
19
|
+
self, expr: BinaryOp, stmt_idx: int | None = None, block=None, **kwargs
|
|
20
|
+
):
|
|
21
|
+
if expr.op == "Sub" and len(expr.operands) == 2:
|
|
22
|
+
sub0, sub1 = expr.operands
|
|
23
|
+
# unpack Conversions
|
|
24
|
+
outer_conv_expr = None
|
|
25
|
+
if (
|
|
26
|
+
isinstance(sub0, Convert)
|
|
27
|
+
and isinstance(sub1, Convert)
|
|
28
|
+
and sub0.to_bits == sub1.to_bits
|
|
29
|
+
and sub0.from_bits == sub1.from_bits
|
|
30
|
+
and sub0.to_bits > sub0.from_bits
|
|
31
|
+
and sub0.is_signed == sub1.is_signed
|
|
32
|
+
):
|
|
33
|
+
# Convert(a) - Convert(a / N * N) ==> Convert(a % N)
|
|
34
|
+
outer_conv_expr = sub0
|
|
35
|
+
sub0 = sub0.operand
|
|
36
|
+
sub1 = sub1.operand
|
|
37
|
+
|
|
38
|
+
if isinstance(sub1, BinaryOp) and sub1.op == "Mul" and isinstance(sub1.operands[1], Const):
|
|
39
|
+
a0, op1 = sub0, sub1
|
|
40
|
+
op1_left = op1.operands[0]
|
|
41
|
+
mul_const = sub1.operands[1]
|
|
42
|
+
|
|
43
|
+
if (
|
|
44
|
+
isinstance(op1_left, Convert)
|
|
45
|
+
and isinstance(a0, Convert)
|
|
46
|
+
and op1_left.to_bits == a0.to_bits
|
|
47
|
+
and op1_left.from_bits == a0.from_bits
|
|
48
|
+
):
|
|
49
|
+
# Convert(a) - (Convert(a / N)) * N ==> Convert(a) % N
|
|
50
|
+
inner_conv_expr = a0
|
|
51
|
+
a0 = a0.operand
|
|
52
|
+
op1_left = op1_left.operand
|
|
53
|
+
else:
|
|
54
|
+
inner_conv_expr = None
|
|
55
|
+
|
|
56
|
+
if isinstance(op1_left, BinaryOp) and op1_left.op == "Div" and isinstance(op1_left.operands[1], Const):
|
|
57
|
+
# a - (a / N) * N ==> a % N
|
|
58
|
+
a1 = op1_left.operands[0]
|
|
59
|
+
div_const = op1_left.operands[1]
|
|
60
|
+
|
|
61
|
+
if a0.likes(a1) and mul_const.value == div_const.value:
|
|
62
|
+
operands = [a0, div_const]
|
|
63
|
+
mod = BinaryOp(expr.idx, "Mod", operands, False, bits=a0.bits, **expr.tags)
|
|
64
|
+
if inner_conv_expr is not None:
|
|
65
|
+
conv_from_bits = inner_conv_expr.from_bits
|
|
66
|
+
conv_to_bits = (
|
|
67
|
+
inner_conv_expr.to_bits if outer_conv_expr is None else outer_conv_expr.to_bits
|
|
68
|
+
)
|
|
69
|
+
conv_signed = inner_conv_expr.is_signed
|
|
70
|
+
conv_expr = inner_conv_expr
|
|
71
|
+
elif outer_conv_expr is not None:
|
|
72
|
+
conv_from_bits = outer_conv_expr.from_bits
|
|
73
|
+
conv_to_bits = outer_conv_expr.to_bits
|
|
74
|
+
conv_signed = outer_conv_expr.is_signed
|
|
75
|
+
conv_expr = outer_conv_expr
|
|
76
|
+
else:
|
|
77
|
+
# no conversion necessary
|
|
78
|
+
return mod
|
|
79
|
+
|
|
80
|
+
return Convert(
|
|
81
|
+
conv_expr.idx,
|
|
82
|
+
conv_from_bits,
|
|
83
|
+
conv_to_bits,
|
|
84
|
+
conv_signed,
|
|
85
|
+
mod,
|
|
86
|
+
**conv_expr.tags,
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
return None
|
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
# pylint:disable=too-many-boolean-expressions
|
|
2
2
|
from __future__ import annotations
|
|
3
|
+
import math
|
|
3
4
|
|
|
4
5
|
from angr.ailment.expression import Convert, BinaryOp, Const, Expression
|
|
5
6
|
|
|
6
7
|
from .base import PeepholeOptimizationExprBase
|
|
7
8
|
|
|
8
9
|
|
|
9
|
-
class
|
|
10
|
+
class OptimizedDivisionSimplifier(PeepholeOptimizationExprBase):
|
|
10
11
|
"""
|
|
11
12
|
Convert expressions with right shifts into expressions with divisions.
|
|
12
13
|
"""
|
|
13
14
|
|
|
14
15
|
__slots__ = ()
|
|
15
16
|
|
|
16
|
-
NAME = "
|
|
17
|
+
NAME = "Simplify optimized division expressions, e.g., (N * a) >> M => a / N1"
|
|
17
18
|
expr_classes = (Convert, BinaryOp)
|
|
18
19
|
|
|
19
|
-
def optimize(
|
|
20
|
+
def optimize( # pylint:disable=unused-argument
|
|
21
|
+
self, expr: Convert | BinaryOp, stmt_idx: int | None = None, block=None, **kwargs
|
|
22
|
+
):
|
|
20
23
|
r = None
|
|
21
24
|
|
|
22
25
|
if isinstance(expr, Convert):
|
|
@@ -37,28 +40,16 @@ class ConstMullAShift(PeepholeOptimizationExprBase):
|
|
|
37
40
|
# try to unify if both operands are wrapped with Convert()
|
|
38
41
|
conv_expr = self._unify_conversion(original_expr)
|
|
39
42
|
expr = original_expr if conv_expr is None else conv_expr.operand
|
|
43
|
+
assert isinstance(expr, BinaryOp)
|
|
40
44
|
|
|
41
45
|
if expr.op == "Shr" and isinstance(expr.operands[1], Const):
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
C = inner.operands[1].value
|
|
50
|
-
X = inner.operands[0]
|
|
51
|
-
else:
|
|
52
|
-
C = X = None
|
|
53
|
-
|
|
54
|
-
if C is not None and X is not None:
|
|
55
|
-
V = expr.operands[1].value
|
|
56
|
-
ndigits = 5 if V == 32 else 6
|
|
57
|
-
divisor = self._check_divisor(pow(2, V), C, ndigits)
|
|
58
|
-
if divisor is not None:
|
|
59
|
-
new_const = Const(None, None, divisor, X.bits)
|
|
60
|
-
r = BinaryOp(inner.idx, "Div", [X, new_const], inner.signed, **inner.tags)
|
|
61
|
-
return self._reconvert(r, conv_expr) if conv_expr is not None else r
|
|
46
|
+
r = self._match_case_b(expr)
|
|
47
|
+
if r is not None:
|
|
48
|
+
return self._reconvert(r, conv_expr) if conv_expr is not None else r
|
|
49
|
+
assert isinstance(expr.operands[1].value, int)
|
|
50
|
+
r = self._match_case_c(expr.operands[0], expr.operands[1].value)
|
|
51
|
+
if r is not None:
|
|
52
|
+
return self._reconvert(r, conv_expr) if conv_expr is not None else r
|
|
62
53
|
|
|
63
54
|
elif expr.op in {"Add", "Sub"}:
|
|
64
55
|
expr0, expr1 = expr.operands
|
|
@@ -119,13 +110,13 @@ class ConstMullAShift(PeepholeOptimizationExprBase):
|
|
|
119
110
|
|
|
120
111
|
return None
|
|
121
112
|
|
|
122
|
-
def _match_case_a(self, expr0: Expression,
|
|
113
|
+
def _match_case_a(self, expr0: Expression, expr1: Convert) -> BinaryOp | None:
|
|
123
114
|
# (
|
|
124
115
|
# (((Conv(32->64, vvar_44{reg 32}) * 0x4325c53f<64>) >>a 0x24<8>) & 0xffffffff<64>) -
|
|
125
116
|
# Conv(32->s64, (vvar_44{reg 32} >>a 0x1f<8>))
|
|
126
117
|
# )
|
|
127
118
|
|
|
128
|
-
expr1_op =
|
|
119
|
+
expr1_op = expr1.operand
|
|
129
120
|
|
|
130
121
|
if (
|
|
131
122
|
isinstance(expr0, BinaryOp)
|
|
@@ -187,6 +178,129 @@ class ConstMullAShift(PeepholeOptimizationExprBase):
|
|
|
187
178
|
|
|
188
179
|
return None
|
|
189
180
|
|
|
181
|
+
@staticmethod
|
|
182
|
+
def _match_case_b(expr: BinaryOp) -> BinaryOp | Convert | None:
|
|
183
|
+
"""
|
|
184
|
+
A more complex (but general) case for unsigned 32-bit division by a constant integer.
|
|
185
|
+
|
|
186
|
+
Ref: https://ridiculousfish.com/blog/posts/labor-of-division-episode-i.html
|
|
187
|
+
|
|
188
|
+
Given n and d, n//d (unsigned) can be rewritten to t >> (p - 1) where
|
|
189
|
+
- p = ceiling(log2(d))
|
|
190
|
+
- m = ceiling((2 ** (32 + p) / d))
|
|
191
|
+
- q = (m * n) >> 32
|
|
192
|
+
- t = q + ((n - q) >> 1)
|
|
193
|
+
|
|
194
|
+
We can match the expression against t >> (p - 1).
|
|
195
|
+
"""
|
|
196
|
+
|
|
197
|
+
# t >> (p - 1)
|
|
198
|
+
if not (isinstance(expr, BinaryOp) and expr.op == "Shr"):
|
|
199
|
+
return None
|
|
200
|
+
if not (isinstance(expr.operands[1], Const) and expr.operands[1].value > 0):
|
|
201
|
+
return None
|
|
202
|
+
p_minus_1 = expr.operands[1].value
|
|
203
|
+
p = p_minus_1 + 1
|
|
204
|
+
t = expr.operands[0]
|
|
205
|
+
|
|
206
|
+
# unmask
|
|
207
|
+
if isinstance(t, BinaryOp) and t.op == "And":
|
|
208
|
+
if isinstance(t.operands[1], Const) and t.operands[1].value == 0xFFFFFFFF:
|
|
209
|
+
t = t.operands[0]
|
|
210
|
+
elif isinstance(t.operands[0], Const) and t.operands[0].value == 0xFFFFFFFF:
|
|
211
|
+
t = t.operands[1]
|
|
212
|
+
else:
|
|
213
|
+
return None
|
|
214
|
+
|
|
215
|
+
# t = q + ((n - q) >> 1)
|
|
216
|
+
if not (isinstance(t, BinaryOp) and t.op == "Add"):
|
|
217
|
+
return None
|
|
218
|
+
|
|
219
|
+
if (
|
|
220
|
+
isinstance(t.operands[0], BinaryOp)
|
|
221
|
+
and t.operands[0].op == "Shr"
|
|
222
|
+
and isinstance(t.operands[0].operands[1], Const)
|
|
223
|
+
and t.operands[0].operands[1].value == 1
|
|
224
|
+
):
|
|
225
|
+
q = t.operands[1]
|
|
226
|
+
n_minus_q = t.operands[0].operands[0]
|
|
227
|
+
elif (
|
|
228
|
+
isinstance(t.operands[1], BinaryOp)
|
|
229
|
+
and t.operands[1].op == "Shr"
|
|
230
|
+
and isinstance(t.operands[1].operands[1], Const)
|
|
231
|
+
and t.operands[1].operands[1].value == 1
|
|
232
|
+
):
|
|
233
|
+
q = t.operands[0]
|
|
234
|
+
n_minus_q = t.operands[1]
|
|
235
|
+
else:
|
|
236
|
+
return None
|
|
237
|
+
if isinstance(q, Convert) and q.from_bits == 64 and q.to_bits == 32:
|
|
238
|
+
q = q.operand
|
|
239
|
+
if isinstance(n_minus_q, Convert) and n_minus_q.from_bits == 64 and n_minus_q.to_bits == 32:
|
|
240
|
+
n_minus_q = n_minus_q.operand
|
|
241
|
+
|
|
242
|
+
# unmask
|
|
243
|
+
if isinstance(n_minus_q, BinaryOp) and n_minus_q.op == "And":
|
|
244
|
+
if isinstance(n_minus_q.operands[1], Const) and n_minus_q.operands[1].value == 0xFFFFFFFF:
|
|
245
|
+
n_minus_q = n_minus_q.operands[0]
|
|
246
|
+
elif isinstance(n_minus_q.operands[0], Const) and n_minus_q.operands[0].value == 0xFFFFFFFF:
|
|
247
|
+
n_minus_q = n_minus_q.operands[1]
|
|
248
|
+
else:
|
|
249
|
+
return None
|
|
250
|
+
|
|
251
|
+
if not (isinstance(n_minus_q, BinaryOp) and n_minus_q.op == "Sub"):
|
|
252
|
+
return None
|
|
253
|
+
if not q.likes(n_minus_q.operands[1]):
|
|
254
|
+
return None
|
|
255
|
+
|
|
256
|
+
# q = (m * n) >> 32
|
|
257
|
+
if not (
|
|
258
|
+
isinstance(q, BinaryOp) and q.op == "Shr" and isinstance(q.operands[1], Const) and q.operands[1].value == 32
|
|
259
|
+
):
|
|
260
|
+
return None
|
|
261
|
+
if not (isinstance(q.operands[0], BinaryOp) and q.operands[0].op in {"Mull", "Mul"}):
|
|
262
|
+
return None
|
|
263
|
+
if isinstance(q.operands[0].operands[1], Const):
|
|
264
|
+
n = q.operands[0].operands[0]
|
|
265
|
+
m = q.operands[0].operands[1].value
|
|
266
|
+
elif isinstance(q.operands[0].operands[0], Const):
|
|
267
|
+
n = q.operands[0].operands[1]
|
|
268
|
+
m = q.operands[0].operands[0].value
|
|
269
|
+
else:
|
|
270
|
+
# this should never happen, because multiplication of two constants are eagerly evaluated
|
|
271
|
+
return None
|
|
272
|
+
|
|
273
|
+
assert isinstance(m, int) and isinstance(p, int)
|
|
274
|
+
divisor = math.ceil((2 ** (32 + p)) / (m + 0x1_0000_0000))
|
|
275
|
+
if divisor == 0:
|
|
276
|
+
return None
|
|
277
|
+
divisor_expr = Const(None, None, divisor, n.bits)
|
|
278
|
+
div = BinaryOp(expr.idx, "Div", [n, divisor_expr], signed=False, **expr.tags)
|
|
279
|
+
if expr.bits != div.bits:
|
|
280
|
+
div = Convert(expr.idx, div.bits, expr.bits, False, div, **expr.tags)
|
|
281
|
+
return div
|
|
282
|
+
|
|
283
|
+
def _match_case_c(self, inner, m: int) -> BinaryOp | None:
|
|
284
|
+
# (N * a) >> M ==> a / N1
|
|
285
|
+
if isinstance(inner, BinaryOp) and inner.op in {"Mull", "Mul"} and not inner.signed:
|
|
286
|
+
if isinstance(inner.operands[0], Const) and not isinstance(inner.operands[1], Const):
|
|
287
|
+
C = inner.operands[0].value
|
|
288
|
+
X = inner.operands[1]
|
|
289
|
+
elif isinstance(inner.operands[1], Const) and not isinstance(inner.operands[0], Const):
|
|
290
|
+
C = inner.operands[1].value
|
|
291
|
+
X = inner.operands[0]
|
|
292
|
+
else:
|
|
293
|
+
C = X = None
|
|
294
|
+
|
|
295
|
+
if C is not None and X is not None:
|
|
296
|
+
V = m
|
|
297
|
+
ndigits = 5 if V == 32 else 6
|
|
298
|
+
divisor = self._check_divisor(pow(2, V), C, ndigits)
|
|
299
|
+
if divisor is not None:
|
|
300
|
+
new_const = Const(None, None, divisor, X.bits)
|
|
301
|
+
return BinaryOp(inner.idx, "Div", [X, new_const], inner.signed, **inner.tags)
|
|
302
|
+
return None
|
|
303
|
+
|
|
190
304
|
@staticmethod
|
|
191
305
|
def _check_divisor(a, b, ndigits=6):
|
|
192
306
|
if b == 0:
|
|
@@ -33,6 +33,7 @@ class RemoveRedundantBitmasks(PeepholeOptimizationExprBase):
|
|
|
33
33
|
def _optimize_BinaryOp(self, expr: BinaryOp):
|
|
34
34
|
# And(expr, full_N_bitmask) ==> expr
|
|
35
35
|
# And(SHR(expr, N), bitmask)) ==> SHR(expr, N)
|
|
36
|
+
# And(Div(Conv(M->N, expr), P), 2 ** M - 1) ==> Div(Conv(M->N, expr), P) where M < N
|
|
36
37
|
# And(Conv(1->N, expr), bitmask) ==> Conv(1->N, expr)
|
|
37
38
|
# And(Conv(1->N, bool_expr), bitmask) ==> Conv(1->N, bool_expr)
|
|
38
39
|
# And(ITE(?, const_expr, const_expr), bitmask) ==> ITE(?, const_expr, const_expr)
|
|
@@ -41,15 +42,23 @@ class RemoveRedundantBitmasks(PeepholeOptimizationExprBase):
|
|
|
41
42
|
if expr.operands[1].value == _MASKS.get(inner_expr.bits, None):
|
|
42
43
|
return inner_expr
|
|
43
44
|
|
|
44
|
-
if isinstance(inner_expr, BinaryOp)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
if isinstance(inner_expr, BinaryOp):
|
|
46
|
+
if inner_expr.op == "Shr":
|
|
47
|
+
mask = expr.operands[1]
|
|
48
|
+
shift_val = inner_expr.operands[1]
|
|
49
|
+
if (
|
|
50
|
+
isinstance(shift_val, Const)
|
|
51
|
+
and shift_val.value in _MASKS
|
|
52
|
+
and mask.value == _MASKS.get(int(64 - shift_val.value), None)
|
|
53
|
+
):
|
|
54
|
+
return inner_expr
|
|
55
|
+
if inner_expr.op == "Div" and isinstance(inner_expr.operands[0], Convert):
|
|
56
|
+
from_bits = inner_expr.operands[0].from_bits
|
|
57
|
+
to_bits = inner_expr.operands[0].to_bits
|
|
58
|
+
if from_bits < to_bits:
|
|
59
|
+
mask = expr.operands[1]
|
|
60
|
+
if mask.value == _MASKS.get(from_bits):
|
|
61
|
+
return inner_expr
|
|
53
62
|
|
|
54
63
|
if isinstance(inner_expr, Convert) and self.is_bool_expr(inner_expr.operand):
|
|
55
64
|
# useless masking
|
|
@@ -58,7 +58,7 @@ class GotoSimplifier(SequenceWalker):
|
|
|
58
58
|
:return:
|
|
59
59
|
"""
|
|
60
60
|
|
|
61
|
-
for n0, n1 in zip(node.nodes, node.nodes[1:]
|
|
61
|
+
for n0, n1 in zip(node.nodes, [*node.nodes[1:], successor]):
|
|
62
62
|
self._handle(n0, successor=n1)
|
|
63
63
|
|
|
64
64
|
def _handle_codenode(self, node, successor=None, **kwargs):
|
|
@@ -109,7 +109,7 @@ class GotoSimplifier(SequenceWalker):
|
|
|
109
109
|
:return:
|
|
110
110
|
"""
|
|
111
111
|
|
|
112
|
-
for n0, n1 in zip(node.nodes, node.nodes[1:]
|
|
112
|
+
for n0, n1 in zip(node.nodes, [*node.nodes[1:], successor]):
|
|
113
113
|
self._handle(n0, successor=n1)
|
|
114
114
|
|
|
115
115
|
def _handle_block(self, block, successor=None, **kwargs): # pylint:disable=no-self-use
|
|
@@ -170,7 +170,7 @@ class GotoSimplifier(SequenceWalker):
|
|
|
170
170
|
dst_target = goto_stmt.true_target
|
|
171
171
|
# false branch of a conditional jump
|
|
172
172
|
else:
|
|
173
|
-
dst_target = goto_stmt.
|
|
173
|
+
dst_target = goto_stmt.false_target
|
|
174
174
|
|
|
175
175
|
src_ins_addr = goto_stmt.ins_addr if "ins_addr" in goto_stmt.tags else block.addr
|
|
176
176
|
goto = Goto(block.addr, dst_target.value, src_idx=block.idx, dst_idx=None, src_ins_addr=src_ins_addr)
|
|
@@ -44,7 +44,7 @@ class IfSimplifier(SequenceWalker):
|
|
|
44
44
|
:return:
|
|
45
45
|
"""
|
|
46
46
|
|
|
47
|
-
for n0, n1 in zip(node.nodes, node.nodes[1:]
|
|
47
|
+
for n0, n1 in zip(node.nodes, [*node.nodes[1:], successor]):
|
|
48
48
|
self._handle(n0, successor=n1)
|
|
49
49
|
|
|
50
50
|
def _handle_codenode(self, node, successor=None, **kwargs):
|
|
@@ -92,7 +92,7 @@ class IfSimplifier(SequenceWalker):
|
|
|
92
92
|
:return:
|
|
93
93
|
"""
|
|
94
94
|
|
|
95
|
-
for n0, n1 in zip(node.nodes, node.nodes[1:]
|
|
95
|
+
for n0, n1 in zip(node.nodes, [*node.nodes[1:], successor]):
|
|
96
96
|
self._handle(n0, successor=n1)
|
|
97
97
|
|
|
98
98
|
def _handle_block(self, block, successor=None, **kwargs): # pylint:disable=no-self-use
|
|
@@ -47,7 +47,7 @@ class LoopSimplifier(SequenceWalker):
|
|
|
47
47
|
)
|
|
48
48
|
|
|
49
49
|
def _handle_sequencenode(self, node, predecessor=None, successor=None, loop=None, loop_successor=None, **kwargs):
|
|
50
|
-
for n0, n1, n2 in zip(node.nodes, node.nodes[1:]
|
|
50
|
+
for n0, n1, n2 in zip(node.nodes, [*node.nodes[1:], successor], [predecessor, *node.nodes[:-1]]):
|
|
51
51
|
self._handle(n0, predecessor=n2, successor=n1, loop=loop, loop_successor=loop_successor)
|
|
52
52
|
|
|
53
53
|
def _handle_codenode(self, node, predecessor=None, successor=None, loop=None, loop_successor=None, **kwargs):
|
|
@@ -126,7 +126,7 @@ class LoopSimplifier(SequenceWalker):
|
|
|
126
126
|
predecessor.statements = predecessor.statements[:-1]
|
|
127
127
|
|
|
128
128
|
def _handle_multinode(self, node, predecessor=None, successor=None, loop=None, loop_successor=None, **kwargs):
|
|
129
|
-
for n0, n1, n2 in zip(node.nodes, node.nodes[1:]
|
|
129
|
+
for n0, n1, n2 in zip(node.nodes, [*node.nodes[1:], successor], [predecessor, *node.nodes[:-1]]):
|
|
130
130
|
self._handle(n0, predecessor=n2, successor=n1, loop=loop, loop_successor=loop_successor)
|
|
131
131
|
|
|
132
132
|
def _handle_block(
|
|
@@ -581,7 +581,7 @@ class CFunction(CConstruct): # pylint:disable=abstract-method
|
|
|
581
581
|
yield " ", None
|
|
582
582
|
# function name
|
|
583
583
|
if self.demangled_name and self.show_demangled_name:
|
|
584
|
-
normalized_name = get_cpp_function_name(self.demangled_name
|
|
584
|
+
normalized_name = get_cpp_function_name(self.demangled_name)
|
|
585
585
|
else:
|
|
586
586
|
normalized_name = self.name
|
|
587
587
|
yield normalized_name, self
|
|
@@ -1357,7 +1357,7 @@ class CFunctionCall(CStatement, CExpression):
|
|
|
1357
1357
|
|
|
1358
1358
|
if self.callee_func is not None:
|
|
1359
1359
|
if self.callee_func.demangled_name and self.show_demangled_name:
|
|
1360
|
-
func_name = get_cpp_function_name(self.callee_func.demangled_name
|
|
1360
|
+
func_name = get_cpp_function_name(self.callee_func.demangled_name)
|
|
1361
1361
|
else:
|
|
1362
1362
|
func_name = self.callee_func.name
|
|
1363
1363
|
if (
|
|
@@ -2240,7 +2240,7 @@ class CConstant(CExpression):
|
|
|
2240
2240
|
yield CConstant.str_to_c_str(v.content.decode("utf-8")), self
|
|
2241
2241
|
return
|
|
2242
2242
|
elif isinstance(v, Function):
|
|
2243
|
-
yield get_cpp_function_name(v.demangled_name
|
|
2243
|
+
yield get_cpp_function_name(v.demangled_name), self
|
|
2244
2244
|
return
|
|
2245
2245
|
elif isinstance(v, str):
|
|
2246
2246
|
yield CConstant.str_to_c_str(v), self
|
|
@@ -466,7 +466,7 @@ class DreamStructurer(StructurerBase):
|
|
|
466
466
|
self._merge_nodes(node_0.node, node_1.node),
|
|
467
467
|
node_0.reaching_condition,
|
|
468
468
|
)
|
|
469
|
-
seq.nodes = seq.nodes[:i]
|
|
469
|
+
seq.nodes = [*seq.nodes[:i], new_node, *seq.nodes[i + 2 :]]
|
|
470
470
|
continue
|
|
471
471
|
i += 1
|
|
472
472
|
|