This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]