diff --git a/decompiler/backend/cexpressiongenerator.py b/decompiler/backend/cexpressiongenerator.py index 09bcfac65..6ff59150a 100644 --- a/decompiler/backend/cexpressiongenerator.py +++ b/decompiler/backend/cexpressiongenerator.py @@ -1,5 +1,4 @@ import logging -from ctypes import c_byte, c_int, c_long, c_short, c_ubyte, c_uint, c_ulong, c_ushort from itertools import chain, repeat from decompiler.structures import pseudo as expressions @@ -8,6 +7,7 @@ from decompiler.structures.pseudo import operations as operations from decompiler.structures.pseudo.operations import MemberAccess from decompiler.structures.visitors.interfaces import DataflowObjectVisitorInterface +from decompiler.util.integer_util import normalize_int class CExpressionGenerator(DataflowObjectVisitorInterface): @@ -80,20 +80,6 @@ class CExpressionGenerator(DataflowObjectVisitorInterface): # OperationType.adc: "adc", } - SIGNED_FORMATS = { - 8: lambda x: c_byte(x).value, - 16: lambda x: c_short(x).value, - 32: lambda x: c_int(x).value, - 64: lambda x: c_long(x).value, - } - - UNSIGNED_FORMATS = { - 8: lambda x: c_ubyte(x).value, - 16: lambda x: c_ushort(x).value, - 32: lambda x: c_uint(x).value, - 64: lambda x: c_ulong(x).value, - } - """ Precedence used for correctly generating brackets. Higher precedence is more tightly binding. @@ -298,13 +284,7 @@ def _get_integer_literal_value(self, literal: expressions.Constant) -> int: Return the right integer value for the given type, assuming that the re-compilation host has the same sizes as the decompilation host. """ - if literal.type.is_signed: - if handler := self.SIGNED_FORMATS.get(literal.type.size, None): - return handler(literal.value) - elif literal.value < 0: - if handler := self.UNSIGNED_FORMATS.get(literal.type.size, None): - return handler(literal.value) - return literal.value + return normalize_int(literal.value, literal.type.size, literal.type.is_signed) @staticmethod def _interpret_integer_literal_type(value: int) -> Integer: diff --git a/decompiler/pipeline/controlflowanalysis/expression_simplification/constant_folding.py b/decompiler/pipeline/controlflowanalysis/expression_simplification/constant_folding.py index 81c87498c..f770ff6b1 100644 --- a/decompiler/pipeline/controlflowanalysis/expression_simplification/constant_folding.py +++ b/decompiler/pipeline/controlflowanalysis/expression_simplification/constant_folding.py @@ -3,6 +3,7 @@ from typing import Callable, Optional from decompiler.structures.pseudo import Constant, Integer, OperationType +from decompiler.util.integer_util import normalize_int def constant_fold(operation: OperationType, constants: list[Constant]) -> Constant: @@ -103,27 +104,6 @@ def _constant_fold_shift(constants: list[Constant], fun: Callable[[int, int], in ) -def normalize_int(v: int, size: int, signed: bool) -> int: - """ - Normalizes an integer value to a specific size and signedness. - - This function takes an integer value 'v' and normalizes it to fit within - the specified 'size' in bits by discarding overflowing bits. If 'signed' is - true, the value is treated as a signed integer, i.e. interpreted as a two's complement. - Therefore the return value will be negative iff 'signed' is true and the most-significant bit is set. - - :param v: The value to be normalized. - :param size: The desired bit size for the normalized integer. - :param signed: True if the integer should be treated as signed. - :return: The normalized integer value. - """ - value = v & ((1 << size) - 1) - if signed and value & (1 << (size - 1)): - return value - (1 << size) - else: - return value - - _OPERATION_TO_FOLD_FUNCTION: dict[OperationType, Callable[[list[Constant]], Constant]] = { OperationType.minus: partial(_constant_fold_arithmetic_binary, fun=operator.sub), OperationType.plus: partial(_constant_fold_arithmetic_binary, fun=operator.add), diff --git a/decompiler/pipeline/controlflowanalysis/expression_simplification/rules/positive_constants.py b/decompiler/pipeline/controlflowanalysis/expression_simplification/rules/positive_constants.py index 6b358dd81..42da06986 100644 --- a/decompiler/pipeline/controlflowanalysis/expression_simplification/rules/positive_constants.py +++ b/decompiler/pipeline/controlflowanalysis/expression_simplification/rules/positive_constants.py @@ -1,6 +1,6 @@ -from decompiler.pipeline.controlflowanalysis.expression_simplification.constant_folding import normalize_int from decompiler.pipeline.controlflowanalysis.expression_simplification.rules.rule import SimplificationRule from decompiler.structures.pseudo import BinaryOperation, Constant, Expression, Integer, Operation, OperationType +from decompiler.util.integer_util import normalize_int class PositiveConstants(SimplificationRule): diff --git a/decompiler/util/integer_util.py b/decompiler/util/integer_util.py new file mode 100644 index 000000000..1e96f62bf --- /dev/null +++ b/decompiler/util/integer_util.py @@ -0,0 +1,19 @@ +def normalize_int(v: int, size: int, signed: bool) -> int: + """ + Normalizes an integer value to a specific size and signedness. + + This function takes an integer value 'v' and normalizes it to fit within + the specified 'size' in bits by discarding overflowing bits. If 'signed' is + true, the value is treated as a signed integer, i.e. interpreted as a two's complement. + Therefore the return value will be negative iff 'signed' is true and the most-significant bit is set. + + :param v: The value to be normalized. + :param size: The desired bit size for the normalized integer. + :param signed: True if the integer should be treated as signed. + :return: The normalized integer value. + """ + value = v & ((1 << size) - 1) + if signed and value & (1 << (size - 1)): + return value - (1 << size) + else: + return value \ No newline at end of file