aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>1997-08-02 17:14:33 +0000
committerRichard Kenner <kenner@vlsi1.ultra.nyu.edu>1997-08-02 17:14:33 +0000
commit6a0f22270834e90dbfd65592048d6b70b2f4eafb (patch)
tree534f4c15e119aac9bb72f881fa3b543277b985cf
parentb40e6869b3513d5ae151db3e1c7a3c7aa501b58f (diff)
(expand_call): If -fcheck-memory-usage, use pseudo-register, check
indirectly called function is executable, and set rights of memory for aggregate as write only. (store_one_arg): If -fcheck-memory-usage, set rights for pushed stack argument. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@14608 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/calls.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index 35166a5ea64..2ae1b31d2cc 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -594,6 +594,13 @@ expand_call (exp, target, ignore)
register tree p;
register int i, j;
+ /* The value of the function call can be put in a hard register. But
+ if -fcheck-memory-usage, code which invokes functions (and thus
+ damages some hard registers) can be inserted before using the value.
+ So, target is always a pseudo-register in that case. */
+ if (flag_check_memory_usage)
+ target = 0;
+
/* See if we can find a DECL-node for the actual function.
As a result, decide whether this is a call to an integrable function. */
@@ -1595,6 +1602,12 @@ expand_call (exp, target, ignore)
push_temp_slots ();
funexp = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
pop_temp_slots (); /* FUNEXP can't be BLKmode */
+
+ /* Check the function is executable. */
+ if (flag_check_memory_usage)
+ emit_library_call (chkr_check_exec_libfunc, 1,
+ VOIDmode, 1,
+ funexp, ptr_mode);
emit_queue ();
}
@@ -1838,6 +1851,15 @@ expand_call (exp, target, ignore)
force_reg (Pmode,
force_operand (structure_value_addr,
NULL_RTX)));
+
+ /* Mark the memory for the aggregate as write-only. */
+ if (flag_check_memory_usage)
+ emit_library_call (chkr_set_right_libfunc, 1,
+ VOIDmode, 3,
+ structure_value_addr, ptr_mode,
+ GEN_INT (struct_value_size), TYPE_MODE (sizetype),
+ GEN_INT (MEMORY_USE_WO), QImode);
+
if (GET_CODE (struct_value_rtx) == REG)
use_reg (&call_fusage, struct_value_rtx);
}
@@ -3531,8 +3553,20 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size, fndecl,
do_pending_stack_adjust ();
if (arg->value == arg->stack)
- /* If the value is already in the stack slot, we are done. */
- ;
+ {
+ /* If the value is already in the stack slot, we are done. */
+ if (flag_check_memory_usage && GET_CODE (arg->stack) == MEM)
+ {
+ if (arg->mode == BLKmode)
+ abort ();
+
+ emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
+ XEXP (arg->stack, 0), ptr_mode,
+ GEN_INT (GET_MODE_SIZE (arg->mode)),
+ TYPE_MODE (sizetype),
+ GEN_INT (MEMORY_USE_RW), QImode);
+ }
+ }
else if (arg->mode != BLKmode)
{
register int size;