* Rebuild phi statements instead of mutating them in place
* Update the phis of every dispatcher target
* Return only the variables the outlined region defines
* SimStruct: Remove _arch_memo to fix the cache leak.
* Fix the comment
* Better typing.
* Fix RustSimTypes.
* More fixes.
* Fix caching for anonymous structs.
* SimUnion: Cache alignment.
* Convert returnty to a arch-ed returnty.
* RustSimType: Do not shadow SimType.with_arch.
* Rust: Bind an arch to types before they reach the type solver.
* RustSimType: Make it a subclass of SimType.
* Decompiler: Test common C conditions.
* Improve c-style null compatison implementation
* Make order-sensitive
---------
Co-authored-by: Kevin Phoenix <kevin@kphoenix.us>
- Make SPropagator, SRDA, and BlockSimplifier normal classes instead of Analysis classes.
- Share peephole optimizer instances across BlockSimplifiers.
- BlockSimplifier: Skip unnecessary peephole passes; avoid block-level comparisons for fixpoint determination.
- Add a runtime-only peephole_optimized flag to AIL statements so we skip running peephole optimizations on already optimized statements.
* Typehoon: index subtype constraint components
* Refactor the code to eliminate weird terminology.
* Fix test cases.
---------
Co-authored-by: Fish <fishw@asu.edu>
* Rewrite the amd64 CondO/CondNO ccall family
amd64g_calculate_condition with cond CondO/CondNO had no rewrite arm at
all, so every jo/jno/seto/cmovno site leaked into the decompilation as an
uncompilable _ccall(0|1, cc_op, ...).
Add arms for the cc_op families that define OF:
LOGIC{B,W,L,Q} and/or/xor always clear OF -> constant 0 / 1
ADD{B,W,L,Q} -> __OFADD__(dep_1, dep_2)
SUB{B,W,L,Q} -> __OFSUB__(dep_1, dep_2)
UMUL{B,W,L,Q} -> __OFUMUL__(dep_1, dep_2)
SMUL{B,W,L,Q} -> __OFSMUL__(dep_1, dep_2)
INC{B,W,L,Q} result == signed minimum
DEC{B,W,L,Q} result == signed maximum
COPY test the stored OF bit
The overflow helpers follow the existing __CFADD__ arm: a named usercall
whose operands carry the operation width. CondNO reuses the same helper
and compares it against zero.
Unsigned multiply overflow is defined as "the high half of the full
2N-bit product is nonzero", i.e. the product does not fit in N unsigned
bits. Note this is NOT the threshold used by the x86 rewriter, which
compares the product against 1 << (N - 1) -- that is the signed
threshold, half the correct unsigned one, and it reports overflow for
every product in [2^(N-1), 2^N - 1] even though those fit. At 8 bits it
misclassifies 820 of 65536 operand pairs, all false positives.
pc_actions_UMUL in the VEX ccall helpers is itself wrong here: it
multiplies two N-bit values without widening, so its `>> nbits` is
always zero and its CF/OF do not agree with the hardware. The rewrite
arm follows the hardware and pc_actions_SMUL's (correct) structure
instead; fixing the helper is left alone.
Every arm was checked exhaustively at 8 bits against
pc_calculate_condition, and the ADD/SUB/UMUL/SMUL arms additionally
against real setcc results.
* Drop the synthetic CondO fixture test
The real gzip and file fixtures already cover the CondO arms; a purpose
built binary added nothing that the unit tests do not already check.
* Cover the CondNO overflow path with a real binary
tar's argp helper guards a multiply with 'mul %rbp; jno', exercising the
CondNO side of UMULQ that gzip and file do not reach. Other cc_op
families still leak a ccall in that function, so only the OF conditions
are asserted.
* Cover the CondO overflow arms with three more real binaries
coreutils cat, grep and zlib's minigzip each carry the xalloc /
__builtin_mul_overflow idiom, between them exercising CondO against
ADDQ, SMULQ and UMULQ across three separate projects. Verified symbols
and addresses are cited on each test.
* Correct the tar overflow test to CondO
The jno there is canonicalized into CondO with an inverted branch, so the
ccall reaching the rewriter carries cond 0, not cond 1. The negation seen
in the output is the structurer's, not the condition's.
`(x << N) >> N` was rewritten into a Convert-of-Convert pair whose outer Convert
zero-extended for BOTH logical (Shr) and arithmetic (Sar) right shifts. For Sar
this is unsound: the idiom sign-extends the low (M-N) bits, but the zero-extending
Convert rendered as a bitmask, so e.g. `(int)(x << 20) >> 20` decompiled to
`x & 0xfff` (and the 64-bit twin to `x & 0xffffffffff`), which drops the
sign bit.
* CFGFast: Tolerate a single leading null byte when scanning for strings.
* CFGFast: Scan for mixed pointers in high-based images during complete scanning.
* Tests: Add a regression test for data detection in a PE32 with data tables in .text.
Also,
- Refactored variable_kb into kb.dec_variables.
- Spill decompilation cache into RuntimeDb.
- Save decompilation cache into angrDb. Decompilation results can be preserved across runs.
- No longer check in _pb2.py files; they are generated during build.
* typehoon: type function-scope pointer-to-array locals as element pointers (T*) so they render as pointers, not arrays
c_repr drops the "*" for pointer-to-array, so such locals were declared
as arrays and assignments to them were invalid C. Flatten T (*)[N] to
T * for function-scope variables; globals and plain arrays unchanged.
* tests: accept element-pointer rendering in reverting-switch-lowering test
Locals typed as element pointers render "ptr = p + 1;" instead of
"ptr = &p[1];"; both are equivalent. Accept either form.