summaryrefslogtreecommitdiff
path: root/gnu/egcs/gcc
diff options
context:
space:
mode:
authorHiroaki Etoh <etoh@cvs.openbsd.org>2003-07-29 00:51:19 +0000
committerHiroaki Etoh <etoh@cvs.openbsd.org>2003-07-29 00:51:19 +0000
commitcc98494444f98a29b142a4fc05855a11b8549352 (patch)
tree5cbe1fc4e88239a1c0c772b70c581832ddc28da7 /gnu/egcs/gcc
parent01d8ba637a9516a05afe40eae428a163ff7e0d24 (diff)
change_arg_use_in_operand: convert "set () (incoming_args)" to "set () (plus (vfp const))". The incoming_args alone is derived from the address operation of the 1st function argument. This fixes to protect the 1st function argument from buffer overflow.
ok pvalcehv@
Diffstat (limited to 'gnu/egcs/gcc')
-rw-r--r--gnu/egcs/gcc/protector.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/gnu/egcs/gcc/protector.c b/gnu/egcs/gcc/protector.c
index e8bf3f97aa5..14fa5ad2dfd 100644
--- a/gnu/egcs/gcc/protector.c
+++ b/gnu/egcs/gcc/protector.c
@@ -1559,6 +1559,29 @@ change_arg_use_in_operand (x, orig, new, size)
}
break;
+ case SET:
+ /* Handle special case of "set (REG or MEM) (incoming_args)".
+ It means that the the address of the 1st argument is stored. */
+ if (GET_CODE (orig) == MEM
+ && XEXP (x, 1) == virtual_incoming_args_rtx)
+ {
+ offset = 0;
+
+ /* the operand related to the sweep variable */
+ if (AUTO_OFFSET(XEXP (orig, 0)) <= offset &&
+ offset < AUTO_OFFSET(XEXP (orig, 0)) + size) {
+
+ offset = AUTO_OFFSET(XEXP (new, 0))
+ + (offset - AUTO_OFFSET(XEXP (orig, 0)));
+
+ XEXP (x, 1) = plus_constant (virtual_stack_vars_rtx, offset);
+ XEXP (x, 1)->used = 1;
+
+ return;
+ }
+ }
+ break;
+
case CALL_PLACEHOLDER:
change_arg_use_of_insns (XEXP (x, 0), orig, new, size);
change_arg_use_of_insns (XEXP (x, 1), orig, new, size);