This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[rfc] Inferior call return value must never be an lvalue
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: gdb-patches at sourceware dot org
- Date: Fri, 11 Mar 2011 23:50:16 +0100 (CET)
- Subject: [rfc] Inferior call return value must never be an lvalue
Hello,
call_function_by_hand currently creates the function return value as
retval = value_at (values_type, struct_addr);
if the struct_return convention is in use.
This has the unfortunate effect that the value actually is constructed
as lval_memory ... which means that future attempts to take its address
or modify it will succeed. Not only does this violate language rules
(a function return value is not an lvalue), this would also cause
writes to no-longer-valid stack memory.
This turned up when testing a patch to fix the -mabi=no-altivec case
for powerpc64, because in this case vectors are returned by reference.
Tested on powerpc64-linux.
Any comments? I'm planning to commit this in a couple of days ...
Bye,
Ulrich
ChangeLog:
* infcall.c (call_function_by_hand): Function return value is
always a non_lval, even when using struct_return.
Index: gdb/infcall.c
===================================================================
RCS file: /cvs/src/src/gdb/infcall.c,v
retrieving revision 1.140
diff -u -p -r1.140 infcall.c
--- gdb/infcall.c 4 Mar 2011 18:31:22 -0000 1.140
+++ gdb/infcall.c 11 Mar 2011 20:25:03 -0000
@@ -1010,29 +1010,29 @@ When the function is done executing, GDB
restore_infcall_control_state (inf_status);
/* Figure out the value returned by the function. */
+ retval = allocate_value (values_type);
if (lang_struct_return)
- retval = value_at (values_type, struct_addr);
- else if (TYPE_CODE (target_values_type) == TYPE_CODE_VOID)
+ read_value_memory (retval, 0, 1, struct_addr,
+ value_contents_raw (retval),
+ TYPE_LENGTH (values_type));
+ else if (TYPE_CODE (target_values_type) != TYPE_CODE_VOID)
{
/* If the function returns void, don't bother fetching the
return value. */
- retval = allocate_value (values_type);
- }
- else
- {
switch (gdbarch_return_value (gdbarch, value_type (function),
target_values_type, NULL, NULL, NULL))
{
case RETURN_VALUE_REGISTER_CONVENTION:
case RETURN_VALUE_ABI_RETURNS_ADDRESS:
case RETURN_VALUE_ABI_PRESERVES_ADDRESS:
- retval = allocate_value (values_type);
gdbarch_return_value (gdbarch, value_type (function), values_type,
retbuf, value_contents_raw (retval), NULL);
break;
case RETURN_VALUE_STRUCT_CONVENTION:
- retval = value_at (values_type, struct_addr);
+ read_value_memory (retval, 0, 1, struct_addr,
+ value_contents_raw (retval),
+ TYPE_LENGTH (values_type));
break;
}
}
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com