Skip to content

Conversation

@LukeSerne
Copy link
Contributor

Closes #7283

These two commits improve the support of in-place operations by

  1. Adding support for float addition, subtraction, multiplication and division to also be shown using in-place operations
  2. Adding support for operations on values in memory that are first LOADed, then modified using an in-place operation, and finally STOREd to the same location.

Especially the second commit is quite hacky, since STORE operations were never meant to be passed to PrintC::emitInplaceOp, and adding support for it adds some extra complexity. The ugliest hack is caused by the LOAD in the sequence however, since that LOAD needs to not be emitted when the loaded value was only used for the in-place operation. This basically requires detecting the same pattern twice - once from the STORE perspective, and once from the LOAD perspective. Also signalling that nothing has been emitted to the other parts of the C-genereration code is done in a very hacky way by abusing the pending_brace print modifier and then checking for that modifier in several places.

I'm afraid especially the second commit disqualifies this PR from ever being merged, but since it seems to work decently well, I hope it'll be useful to some people running their own builds of Ghidra.

This commit is based off of an initial patch made by @RootCubed here:
NationalSecurityAgency#5601 (comment)
This commit adds support for in-place operations on values in memory
using a LOAD/OP/STORE sequence.
The implementation is quite hacky, for two main reasons:
1. CPUI_STORE was never meant as going through PrintC::emitInplaceOp, so
   it takes a bit of a weird path through the function, which makes the
   function quite unreadable.
2. If the CPUI_STORE is emitted as an in-place op, there might still be
   a spurious CPUI_LOAD left, which has already been emitted. If the
   loaded value is not used elsewhere, the load is now useless. To avoid
   emitting this load, we need to also detect the structure when the
   load instruction goes through PrintC::emitInplaceOp. And if we detect
   the structure, we need to not emit anything. Also avoiding the semi-
   colon and newline being printed requires abusing the print modifiers
   by repurposing the 'pending_brace' modifier to also indicate that the
   previous expression did not emit anything.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature: Decompiler Status: Triage Information is being gathered

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inplace assignment doesn't work in this specific case

3 participants