mirror of
https://github.com/isledecomp/isle.git
synced 2026-01-23 16:21:15 +00:00
feat: Support verifying return values larger than 4 bytes
This commit is contained in:
parent
56b8c96d6a
commit
3737b2df8b
@ -17,6 +17,7 @@
|
||||
CppStackSymbol,
|
||||
)
|
||||
from lego_util.ghidra_helper import (
|
||||
add_pointer_type,
|
||||
get_ghidra_namespace,
|
||||
sanitize_name,
|
||||
)
|
||||
@ -82,7 +83,20 @@ def matches_ghidra_function(self, ghidra_function: Function) -> bool:
|
||||
"""Checks whether this function declaration already matches the description in Ghidra"""
|
||||
name_match = self.name == ghidra_function.getName(False)
|
||||
namespace_match = self.namespace == ghidra_function.getParentNamespace()
|
||||
return_type_match = self.return_type == ghidra_function.getReturnType()
|
||||
ghidra_return_type = ghidra_function.getReturnType()
|
||||
return_type_match = self.return_type == ghidra_return_type
|
||||
|
||||
# Handle edge case: Return type X that is larger than the return register.
|
||||
# In that case, the function returns `X*` and has another argument `X* __return_storage_ptr`.
|
||||
if (
|
||||
(not return_type_match)
|
||||
and (self.return_type.getLength() > 4)
|
||||
and (add_pointer_type(self.api, self.return_type) == ghidra_return_type)
|
||||
and any(param for param in ghidra_function.getParameters() if param.getName() == "__return_storage_ptr__")
|
||||
):
|
||||
logger.debug("%s has a return type larger than 4 bytes", self.get_full_name())
|
||||
return_type_match = True
|
||||
|
||||
# match arguments: decide if thiscall or not
|
||||
thiscall_matches = (
|
||||
self.signature.call_type == ghidra_function.getCallingConventionName()
|
||||
@ -128,6 +142,14 @@ def _matches_thiscall_parameters(self, ghidra_function: Function) -> bool:
|
||||
return self._parameter_lists_match(ghidra_params)
|
||||
|
||||
def _parameter_lists_match(self, ghidra_params: "list[Parameter]") -> bool:
|
||||
# Remove return storage pointer from comparison if present.
|
||||
# This is relevant to returning values larger than 4 bytes, and is not mentioned in the PDB
|
||||
ghidra_params = [
|
||||
param
|
||||
for param in ghidra_params
|
||||
if param.getName() != "__return_storage_ptr__"
|
||||
]
|
||||
|
||||
if len(self.arguments) != len(ghidra_params):
|
||||
logger.info("Mismatching argument count")
|
||||
return False
|
||||
|
||||
Loading…
Reference in New Issue
Block a user