Skip to content

Commit

Permalink
Don't propagate over relations
Browse files Browse the repository at this point in the history
  • Loading branch information
NeoQuix committed Apr 24, 2024
1 parent 9ecdb8f commit ac51b13
Showing 1 changed file with 25 additions and 4 deletions.
29 changes: 25 additions & 4 deletions decompiler/pipeline/commons/expressionpropagationcommons.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
Operation,
OperationType,
Phi,
Relation,
Return,
UnaryOperation,
UnknownExpression,
Expand Down Expand Up @@ -265,15 +266,17 @@ def _definition_value_could_be_modified_via_memory_access_between_definition_and
) -> bool:
"""
Tests for definition containing aliased if a modification of the aliased value is possible, i.e.
via its pointer (ptr = &aliased) or via use of its reference (aka address) in function calls.
via its pointer (ptr = &aliased) or via use of its reference (aka address) in function calls
or if a relation is in between.
:return: true if a modification of the aliased value is possible (hence, the propagation should be avoided) false otherwise
"""
for aliased_variable in set(self._iter_aliased_variables(definition)):
dangerous_address_uses = self._get_dangerous_uses_of_variable_address(aliased_variable)
dangerous_pointer_uses = self._get_dangerous_uses_of_pointer_to_variable(aliased_variable)
if dangerous_address_uses or dangerous_pointer_uses:
dangerous_uses = dangerous_pointer_uses.union(dangerous_address_uses)
dangerous_alias_uses = self._get_dangerous_relations(aliased_variable)
dangerous_uses = dangerous_pointer_uses | dangerous_address_uses | dangerous_alias_uses
if dangerous_uses:
if self._has_any_of_dangerous_uses_between_definition_and_target(definition, target, dangerous_uses):
return True
return False
Expand Down Expand Up @@ -353,6 +356,24 @@ def _get_dangerous_uses_of_pointer_to_variable(self, var: Variable) -> Set[Instr
dangerous_uses.update(self._get_dangerous_uses_of_pointer(pointer))
return dangerous_uses

def _get_dangerous_relations(self, alias_variable: Variable) -> Set[Instruction]:
"""Return all relations of the alias variable."""
relations = set()
todo = self._use_map.get(alias_variable)
done = set()

while todo:
instr = todo.pop()
if instr in done:
continue
if isinstance(instr, Assignment):
todo |= self._use_map.get(instr.destination)
if isinstance(instr, Relation):
relations |= {instr}
done |= {instr}

return relations

def _get_dangerous_uses_of_pointer(self, pointer: Variable) -> Set[Instruction]:
"""
:param pointer to a variable
Expand Down Expand Up @@ -438,7 +459,7 @@ def _is_aliased_variable(expression: Expression) -> bool:
def _contains_writeable_global_variable(expression: Assignment) -> bool:
"""
:param expression: Assignment expression to be tested
:return: true if any requirement of expression is a GlobalVariable
:return: true if any requirement of expression is a writeable GlobalVariable
"""
for expr in expression.destination.requirements:
if isinstance(expr, GlobalVariable) and not expr.is_constant:
Expand Down

0 comments on commit ac51b13

Please sign in to comment.