This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[commit] Fix several PowerPC64 ABI issues
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: gdb-patches at sourceware dot org
- Date: Sat, 3 May 2008 01:25:27 +0200 (CEST)
- Subject: [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