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]

[commit] Fix several PowerPC64 ABI issues


Hello,

this patch fixes a number of PowerPC64 ABI issues:

- Small structs are supposed to be passed right-aligned, not left-aligned.
  Joseph Myers' patch:
     http://sourceware.org/ml/gdb-patches/2007-10/msg00689.html
  already fixed this for structs passed in registers, but not for those
  passed on the stack.

- ppc64_sysv_abi_push_dummy_call and ppc64_sysv_abi_return_value neglected
  to handle type codes not common in C (TYPE_CODE_BOOL, TYPE_CODE_CHAR,
  TYPE_CODE_REF, TYPE_CODE_METHOD).  These need to be treated the same as
  their C counterparts for ABI purposes.

- When checking for a function pointer argument type (in order to convert
  the function value passed as argument back to a function descriptor),
  the code neglected to allow for a typedef'd function type.

All in all, this fixes the following test case failures:

FAIL: gdb.base/call-ar-st.exp: print print_long_arg_list (pattern 12)
FAIL: gdb.cp/bool.exp: print return_true()
FAIL: gdb.cp/userdef.exp: print *c
FAIL: gdb.gdb/observer.exp: second observer attached; check second observer counter value
FAIL: gdb.gdb/observer.exp: 1st observer added; check first observer counter value
FAIL: gdb.gdb/observer.exp: 2nd observer added; check first observer counter value
FAIL: gdb.gdb/observer.exp: 2nd observer added; check second observer counter value
FAIL: gdb.gdb/observer.exp: 3rd observer added; check first observer counter value
FAIL: gdb.gdb/observer.exp: 3rd observer added; check second observer counter value
FAIL: gdb.gdb/observer.exp: 3rd observer added; check third observer counter value
FAIL: gdb.gdb/observer.exp: 2nd observer removed; check first observer counter value
FAIL: gdb.gdb/observer.exp: 2nd observer removed; check third observer counter value
FAIL: gdb.gdb/observer.exp: 1st observer removed; check third observer counter value
FAIL: gdb.gdb/observer.exp: three observers added; check first observer counter value
FAIL: gdb.gdb/observer.exp: three observers added; check second observer counter value
FAIL: gdb.gdb/observer.exp: three observers added; check third observer counter value
FAIL: gdb.gdb/observer.exp: third observer removed; check first observer counter value
FAIL: gdb.gdb/observer.exp: third observer removed; check second observer counter value
FAIL: gdb.gdb/observer.exp: second observer removed; check first observer counter value

Tested on powerpc64-linux and powerpc-linux.  Committed to mainline.

Bye,
Ulrich


ChangeLog:

	* ppc-sysv-tdep.c (ppc64_sysv_abi_push_dummy_call): Handle
	TYPE_CODE_BOOL and TYPE_CODE_CHAR the same as TYPE_CODE_INT.
	Handle TYPE_CODE_REF the same as TYPE_CODE_PTR.
	Handle TYPE_CODE_METHOD the same as TYPE_CODE_FUNC.
	Allow typedefs when checking for function pointer arguments.
	Right-align small structs passed on the stack.
	(ppc64_sysv_abi_return_value): Handle TYPE_CODE_BOOL and
	TYPE_CODE_CHAR the same as TYPE_CODE_INT.
	Handle TYPE_CODE_REF the same as TYPE_CODE_PTR.


diff -urNp gdb-orig/gdb/ppc-sysv-tdep.c gdb-head/gdb/ppc-sysv-tdep.c
--- gdb-orig/gdb/ppc-sysv-tdep.c	2008-04-22 23:14:47.000000000 +0200
+++ gdb-head/gdb/ppc-sysv-tdep.c	2008-05-02 21:41:08.658654574 +0200
@@ -1149,7 +1149,10 @@ ppc64_sysv_abi_push_dummy_call (struct g
 	    }
 	  else if ((TYPE_CODE (type) == TYPE_CODE_INT
 		    || TYPE_CODE (type) == TYPE_CODE_ENUM
-		    || TYPE_CODE (type) == TYPE_CODE_PTR)
+		    || TYPE_CODE (type) == TYPE_CODE_BOOL
+		    || TYPE_CODE (type) == TYPE_CODE_CHAR
+		    || TYPE_CODE (type) == TYPE_CODE_PTR
+		    || TYPE_CODE (type) == TYPE_CODE_REF)
 		   && TYPE_LENGTH (type) <= 8)
 	    {
 	      /* Scalars and Pointers get sign[un]extended and go in
@@ -1161,11 +1164,18 @@ ppc64_sysv_abi_push_dummy_call (struct g
 		  /* Convert any function code addresses into
 		     descriptors.  */
 		  if (TYPE_CODE (type) == TYPE_CODE_PTR
-		      && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC)
+		      || TYPE_CODE (type) == TYPE_CODE_REF)
 		    {
-		      CORE_ADDR desc = word;
-		      convert_code_addr_to_desc_addr (word, &desc);
-		      word = desc;
+		      struct type *target_type;
+		      target_type = check_typedef (TYPE_TARGET_TYPE (type));
+
+		      if (TYPE_CODE (target_type) == TYPE_CODE_FUNC
+			  || TYPE_CODE (target_type) == TYPE_CODE_METHOD)
+			{
+			  CORE_ADDR desc = word;
+			  convert_code_addr_to_desc_addr (word, &desc);
+			  word = desc;
+			}
 		    }
 		  if (greg <= 10)
 		    regcache_cooked_write_unsigned (regcache,
@@ -1206,14 +1216,20 @@ ppc64_sysv_abi_push_dummy_call (struct g
 		  greg++;
 		}
 	      if (write_pass)
-		/* WARNING: cagney/2003-09-21: Strictly speaking, this
-		   isn't necessary, unfortunately, GCC appears to get
-		   "struct convention" parameter passing wrong putting
-		   odd sized structures in memory instead of in a
-		   register.  Work around this by always writing the
-		   value to memory.  Fortunately, doing this
-		   simplifies the code.  */
-		write_memory (gparam, val, TYPE_LENGTH (type));
+		{
+		  /* WARNING: cagney/2003-09-21: Strictly speaking, this
+		     isn't necessary, unfortunately, GCC appears to get
+		     "struct convention" parameter passing wrong putting
+		     odd sized structures in memory instead of in a
+		     register.  Work around this by always writing the
+		     value to memory.  Fortunately, doing this
+		     simplifies the code.  */
+		  int len = TYPE_LENGTH (type);
+		  if (len < tdep->wordsize)
+		    write_memory (gparam + tdep->wordsize - len, val, len);
+		  else
+		    write_memory (gparam, val, len);
+		}
 	      if (freg <= 13
 		  && TYPE_CODE (type) == TYPE_CODE_STRUCT
 		  && TYPE_NFIELDS (type) == 1
@@ -1356,7 +1372,9 @@ ppc64_sysv_abi_return_value (struct gdba
 					   writebuf);
   /* Integers in r3.  */
   if ((TYPE_CODE (valtype) == TYPE_CODE_INT
-       || TYPE_CODE (valtype) == TYPE_CODE_ENUM)
+       || TYPE_CODE (valtype) == TYPE_CODE_ENUM
+       || TYPE_CODE (valtype) == TYPE_CODE_CHAR
+       || TYPE_CODE (valtype) == TYPE_CODE_BOOL)
       && TYPE_LENGTH (valtype) <= 8)
     {
       if (writebuf != NULL)
@@ -1377,7 +1395,8 @@ ppc64_sysv_abi_return_value (struct gdba
       return RETURN_VALUE_REGISTER_CONVENTION;
     }
   /* All pointers live in r3.  */
-  if (TYPE_CODE (valtype) == TYPE_CODE_PTR)
+  if (TYPE_CODE (valtype) == TYPE_CODE_PTR
+      || TYPE_CODE (valtype) == TYPE_CODE_REF)
     {
       /* All pointers live in r3.  */
       if (writebuf != NULL)
-- 
  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]