Skip to content

Commit 843ff33

Browse files
committed
ASTI: add support for stack arguments
1 parent 987d651 commit 843ff33

File tree

5 files changed

+65
-8
lines changed

5 files changed

+65
-8
lines changed

chb/api/AppFunctionSignature.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# ------------------------------------------------------------------------------
55
# The MIT License (MIT)
66
#
7-
# Copyright (c) 2023 Aarno Labs LLC
7+
# Copyright (c) 2023-2024 Aarno Labs LLC
88
#
99
# Permission is hereby granted, free of charge, to any person obtaining a copy
1010
# of this software and associated documentation files (the "Software"), to deal
@@ -54,7 +54,9 @@ class AppFunctionSignature(InterfaceDictionaryRecord):
5454
args[6..]: indices of registers preserved (not normally preserved)
5555
"""
5656

57-
def __init__(self, ixd: "InterfaceDictionary", ixval: IndexedTableValue) -> None:
57+
def __init__(
58+
self, ixd: "InterfaceDictionary", ixval: IndexedTableValue
59+
) -> None:
5860
InterfaceDictionaryRecord.__init__(self, ixd, ixval)
5961

6062
@property
@@ -69,16 +71,22 @@ def parameter_list(self) -> List["FtsParameter"]:
6971
def returntype(self) -> "BCTyp":
7072
return self.bcd.typ(self.args[3])
7173

72-
def index_of_register_parameter_location(self, r: "Register") -> Optional[int]:
74+
def index_of_register_parameter_location(
75+
self, r: "Register") -> Optional[int]:
7376
for p in self.parameter_list:
7477
if p.is_register_parameter_location(r):
7578
return p.argindex
7679
return None
7780

81+
def index_of_stack_parameter_location(self, offset: int) -> Optional[int]:
82+
for p in self.parameter_list:
83+
if p.is_stack_parameter_location(offset):
84+
return p.argindex
85+
return None
86+
7887
def __str__(self) -> str:
7988
return (
8089
str(self.returntype)
8190
+ " ("
8291
+ ", ".join(str(p) for p in self.parameter_list)
8392
+ ")")
84-

chb/api/FtsParameter.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# ------------------------------------------------------------------------------
55
# The MIT License (MIT)
66
#
7-
# Copyright (c) 2023 Aarno Labs LLC
7+
# Copyright (c) 2023-2024 Aarno Labs LLC
88
#
99
# Permission is hereby granted, free of charge, to any person obtaining a copy
1010
# of this software and associated documentation files (the "Software"), to deal
@@ -80,5 +80,10 @@ def is_register_parameter_location(self, r: "Register") -> bool:
8080
return self.parameter_location_list[0].is_register_parameter_location_of(r)
8181
return False
8282

83+
def is_stack_parameter_location(self, offset: int) -> bool:
84+
if len(self.parameter_location_list) == 1:
85+
return self.parameter_location_list[0].is_stack_parameter_location_of(offset)
86+
return False
87+
8388
def __str__(self) -> str:
8489
return str(self.typ) + " " + str(self.name)

chb/api/FtsParameterLocation.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# ------------------------------------------------------------------------------
55
# The MIT License (MIT)
66
#
7-
# Copyright (c) 2023 Aarno Labs LLC
7+
# Copyright (c) 2023-2024 Aarno Labs LLC
88
#
99
# Permission is hereby granted, free of charge, to any person obtaining a copy
1010
# of this software and associated documentation files (the "Software"), to deal
@@ -81,6 +81,9 @@ def is_unknown_location(self) -> bool:
8181
def is_register_parameter_location_of(self, r: "Register") -> bool:
8282
return False
8383

84+
def is_stack_parameter_location_of(self, offset: int) -> bool:
85+
return False
86+
8487

8588
@apiregistry.register_tag("s", FtsParameterLocation)
8689
class FtsStackParameter(FtsParameterLocation):
@@ -98,9 +101,12 @@ def is_stack_parameter(self) -> bool:
98101
return True
99102

100103
@property
101-
def index(self) -> int:
104+
def offset(self) -> int:
102105
return self.args[0]
103106

107+
def is_stack_parameter_location_of(self, offset: int) -> bool:
108+
return offset == self.offset
109+
104110
def __str__(self) -> str:
105111
return "stack-parameter " + str(self.index)
106112

chb/invariants/VAssemblyVariable.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ def is_stack_argument(self) -> bool:
250250
return (
251251
self.base.is_local_stack_frame
252252
and self.offset.is_constant_value_offset
253-
and self.offset.offsetvalue() > 0)
253+
and self.offset.offsetvalue() >= 0)
254254

255255
@property
256256
def is_local_stack_variable(self) -> bool:

chb/invariants/XXprUtil.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,40 @@ def vargument_deref_value_to_ast_lval_expression(
601601
return astree.mk_temp_lval_expression()
602602

603603

604+
def stack_argument_to_ast_lval_expression(
605+
offset: int,
606+
xdata: "InstrXData",
607+
iaddr: str,
608+
astree: ASTInterface,
609+
anonymous: bool = False) -> AST.ASTExpr:
610+
611+
fsig = astree.appsignature
612+
if fsig is None:
613+
chklogger.logger.error(
614+
"Unable to judge stack argument with offset %d without app "
615+
+ "at address %s",
616+
offset, iaddr)
617+
return astree.mk_temp_lval_expression()
618+
619+
optindex = fsig.index_of_stack_parameter_location(offset)
620+
if optindex is not None:
621+
arglvals = astree.function_argument(optindex - 1)
622+
if len(arglvals) != 1:
623+
chklogger.logger.error(
624+
"Encountered multiple arg values for initial stack argument "
625+
+ "%s at address %s",
626+
str(offset), iaddr)
627+
return astree.mk_temp_lval_expression()
628+
else:
629+
return astree.mk_lval_expression(arglvals[0], anonymous=anonymous)
630+
else:
631+
chklogger.logger.error(
632+
"Cannot determine argument index for initial stack argument %s "
633+
+ "at address %s",
634+
str(offset), iaddr)
635+
return astree.mk_temp_lval_expression()
636+
637+
604638
def vinitmemory_value_to_ast_lval_expression(
605639
vconstvar: "VInitialMemoryValue",
606640
xdata: "InstrXData",
@@ -678,6 +712,10 @@ def vinitmemory_value_to_ast_lval_expression(
678712
iaddr)
679713
return astree.mk_temp_lval_expression()
680714

715+
if avar.is_memory_variable and avar.is_stack_argument:
716+
return stack_argument_to_ast_lval_expression(
717+
avar.offset.offsetvalue(), xdata, iaddr, astree, anonymous=anonymous)
718+
681719
chklogger.logger.error(
682720
"AST conversion of vinitmemory value %s of %s not yet supported at "
683721
+ "address %s",

0 commit comments

Comments
 (0)