diff options
author | Mark Kettenis <kettenis@gnu.org> | 2005-08-17 07:44:13 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@gnu.org> | 2005-08-17 07:44:13 +0000 |
commit | 61bf9ae086ed8e0107ab376dd19659e6f1c923a0 (patch) | |
tree | 80d79ecd60d87d30868de9b53a4025a3b2cef5f7 /gdb/ppc-sysv-tdep.c | |
parent | 24dc748d60dcf80ab486ba7b99e97f1180b9158e (diff) | |
download | gdb-61bf9ae086ed8e0107ab376dd19659e6f1c923a0.zip gdb-61bf9ae086ed8e0107ab376dd19659e6f1c923a0.tar.gz gdb-61bf9ae086ed8e0107ab376dd19659e6f1c923a0.tar.bz2 |
* ppc-sysv-tdep.c (do_ppc_sysv_return_value): Fix the code that
deals with the broken GCC convention.
Diffstat (limited to 'gdb/ppc-sysv-tdep.c')
-rw-r--r-- | gdb/ppc-sysv-tdep.c | 61 |
1 files changed, 21 insertions, 40 deletions
diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c index 3824c99..4285077 100644 --- a/gdb/ppc-sysv-tdep.c +++ b/gdb/ppc-sysv-tdep.c @@ -451,52 +451,33 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *type, } if (broken_gcc && TYPE_LENGTH (type) <= 8) { + /* GCC screwed up for structures or unions whose size is less + than or equal to 8 bytes.. Instead of left-aligning, it + right-aligns the data into the buffer formed by r3, r4. */ + gdb_byte regvals[MAX_REGISTER_SIZE * 2]; + int len = TYPE_LENGTH (type); + int offset = (2 * tdep->wordsize - len) % tdep->wordsize; + if (readbuf) { - /* GCC screwed up. The last register isn't "left" aligned. - Need to extract the least significant part of each - register and then store that. */ - /* Transfer any full words. */ - int word = 0; - while (1) - { - ULONGEST reg; - int len = TYPE_LENGTH (type) - word * tdep->wordsize; - if (len <= 0) - break; - if (len > tdep->wordsize) - len = tdep->wordsize; - regcache_cooked_read_unsigned (regcache, - tdep->ppc_gp0_regnum + 3 + word, - ®); - store_unsigned_integer (((bfd_byte *) readbuf - + word * tdep->wordsize), len, reg); - word++; - } + regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, + regvals + 0 * tdep->wordsize); + if (len > tdep->wordsize) + regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 4, + regvals + 1 * tdep->wordsize); + memcpy (readbuf, regvals + offset, len); } if (writebuf) { - /* GCC screwed up. The last register isn't "left" aligned. - Need to extract the least significant part of each - register and then store that. */ - /* Transfer any full words. */ - int word = 0; - while (1) - { - ULONGEST reg; - int len = TYPE_LENGTH (type) - word * tdep->wordsize; - if (len <= 0) - break; - if (len > tdep->wordsize) - len = tdep->wordsize; - reg = extract_unsigned_integer (((const bfd_byte *) writebuf - + word * tdep->wordsize), len); - regcache_cooked_write_unsigned (regcache, - tdep->ppc_gp0_regnum + 3 + word, - reg); - word++; - } + memset (regvals, 0, sizeof regvals); + memcpy (regvals + offset, writebuf, len); + regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3, + regvals + 0 * tdep->wordsize); + if (len > tdep->wordsize) + regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 4, + regvals + 1 * tdep->wordsize); } + return RETURN_VALUE_REGISTER_CONVENTION; } if (TYPE_LENGTH (type) <= 8) |