2006-06-09 Nathan Sidwell * configure.tgt (gdb_osabi): uclinux is like linux. * m68k-tdep.c (m68k_svr4_extract_return_value): Use tdep->ptr_value_regnum for pointer returns. (m68k_svr4_store_return_value): Likewise. (m68k_svr4_init_abi, m68k_aout_init_abi): Set ptr_value_regnum. (m68k_gdbarch_init): Likewise. * m68k-tdep.h (struct gdbarch_tdep): Add ptr_value_regnum field. * m68kbsd-tdep.c (m68kbsd_aout_init_abi): Use m68k_aout_init_abi. (m68kbsd_elf_init_abi): Add comment. * m68klinux-tdep.c (m68k_linux_init_abi): Just set the struct pointer register here. Index: configure.tgt =================================================================== RCS file: /cvs/src/src/gdb/configure.tgt,v retrieving revision 1.172 diff -c -3 -p -r1.172 configure.tgt *** configure.tgt 20 Apr 2006 23:18:48 -0000 1.172 --- configure.tgt 9 Jun 2006 12:45:08 -0000 *************** esac *** 223,228 **** --- 223,229 ---- case "${target}" in *-*-freebsd*) gdb_osabi=GDB_OSABI_FREEBSD_ELF ;; *-*-linux*) gdb_osabi=GDB_OSABI_LINUX ;; + *-*-uclinux*) gdb_osabi=GDB_OSABI_LINUX ;; *-*-nto*) gdb_osabi=GDB_OSABI_QNXNTO ;; m68*-*-openbsd* | m88*-*-openbsd* | vax-*-openbsd*) ;; *-*-openbsd*) gdb_osabi=GDB_OSABI_OPENBSD_ELF ;; Index: m68k-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/m68k-tdep.c,v retrieving revision 1.106 diff -c -3 -p -r1.106 m68k-tdep.c *** m68k-tdep.c 8 Jun 2006 19:11:45 -0000 1.106 --- m68k-tdep.c 9 Jun 2006 12:45:09 -0000 *************** m68k_svr4_extract_return_value (struct t *** 253,259 **** convert_typed_floating (buf, builtin_type_m68881_ext, valbuf, type); } else if (TYPE_CODE (type) == TYPE_CODE_PTR && len == 4) ! regcache_raw_read (regcache, M68K_A0_REGNUM, valbuf); else m68k_extract_return_value (type, regcache, valbuf); } --- 253,261 ---- convert_typed_floating (buf, builtin_type_m68881_ext, valbuf, type); } else if (TYPE_CODE (type) == TYPE_CODE_PTR && len == 4) ! regcache_raw_read (regcache, ! gdbarch_tdep (current_gdbarch)->ptr_value_regnum, ! valbuf); else m68k_extract_return_value (type, regcache, valbuf); } *************** m68k_svr4_store_return_value (struct typ *** 292,301 **** regcache_raw_write (regcache, M68K_FP0_REGNUM, buf); } else if (TYPE_CODE (type) == TYPE_CODE_PTR && len == 4) ! { ! regcache_raw_write (regcache, M68K_A0_REGNUM, valbuf); ! regcache_raw_write (regcache, M68K_D0_REGNUM, valbuf); ! } else m68k_store_return_value (type, regcache, valbuf); } --- 294,302 ---- regcache_raw_write (regcache, M68K_FP0_REGNUM, buf); } else if (TYPE_CODE (type) == TYPE_CODE_PTR && len == 4) ! regcache_raw_write (regcache, ! gdbarch_tdep (current_gdbarch)->ptr_value_regnum, ! valbuf); else m68k_store_return_value (type, regcache, valbuf); } *************** m68k_svr4_return_value (struct gdbarch * *** 370,394 **** if ((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION) && !m68k_reg_struct_return_p (gdbarch, type)) { ! /* The System V ABI says that: ! ! "A function returning a structure or union also sets %a0 to ! the value it finds in %a0. Thus when the caller receives ! control again, the address of the returned object resides in ! register %a0." ! ! So the ABI guarantees that we can always find the return ! value just after the function has returned. */ ! ! if (readbuf) ! { ! ULONGEST addr; ! ! regcache_raw_read_unsigned (regcache, M68K_A0_REGNUM, &addr); ! read_memory (addr, readbuf, TYPE_LENGTH (type)); ! } ! ! return RETURN_VALUE_ABI_RETURNS_ADDRESS; } /* This special case is for structures consisting of a single --- 371,381 ---- if ((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION) && !m68k_reg_struct_return_p (gdbarch, type)) { ! /* Although they SYSV ABI specifies that a function returning a ! structure this way should preserve %a0, GCC doesn't do that. ! Furthermore there's no point changeing GCC to make it do it, ! as that would just be bloat. */ ! return RETURN_VALUE_STRUCT_CONVENTION; } /* This special case is for structures consisting of a single *************** m68k_svr4_init_abi (struct gdbarch_info *** 1124,1131 **** /* SVR4 uses a different calling convention. */ set_gdbarch_return_value (gdbarch, m68k_svr4_return_value); ! /* SVR4 uses %a0 instead of %a1. */ tdep->struct_value_regnum = M68K_A0_REGNUM; } --- 1111,1137 ---- /* SVR4 uses a different calling convention. */ set_gdbarch_return_value (gdbarch, m68k_svr4_return_value); ! /* SVR4 uses %a0. */ tdep->struct_value_regnum = M68K_A0_REGNUM; + tdep->struct_return = reg_struct_return; + /* Pointers are returned in %a0 */ + tdep->ptr_value_regnum = M68K_A0_REGNUM; + } + + /* a.out */ + + void + m68k_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) + { + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + set_gdbarch_return_value (gdbarch, m68k_return_value); + + /* aout uses %a1 */ + tdep->struct_value_regnum = M68K_A1_REGNUM; + tdep->struct_return = reg_struct_return; + /* Pointers are returned in %a0 */ + tdep->ptr_value_regnum = M68K_A0_REGNUM; } *************** m68k_gdbarch_init (struct gdbarch_info i *** 1175,1182 **** set_gdbarch_register_to_value (gdbarch, m68k_register_to_value); set_gdbarch_value_to_register (gdbarch, m68k_value_to_register); set_gdbarch_push_dummy_call (gdbarch, m68k_push_dummy_call); ! set_gdbarch_return_value (gdbarch, m68k_return_value); /* Disassembler. */ set_gdbarch_print_insn (gdbarch, print_insn_m68k); --- 1181,1194 ---- set_gdbarch_register_to_value (gdbarch, m68k_register_to_value); set_gdbarch_value_to_register (gdbarch, m68k_value_to_register); + /* Function call & return */ set_gdbarch_push_dummy_call (gdbarch, m68k_push_dummy_call); ! /* These values are for bare metal -- os specific ABIs can override ! them */ ! set_gdbarch_return_value (gdbarch, m68k_svr4_return_value); ! tdep->struct_value_regnum = M68K_A0_REGNUM; ! tdep->struct_return = reg_struct_return; ! tdep->ptr_value_regnum = M68K_D0_REGNUM; /* Disassembler. */ set_gdbarch_print_insn (gdbarch, print_insn_m68k); *************** m68k_gdbarch_init (struct gdbarch_info i *** 1187,1194 **** #else tdep->jb_pc = -1; #endif - tdep->struct_value_regnum = M68K_A1_REGNUM; - tdep->struct_return = reg_struct_return; /* Frame unwinder. */ set_gdbarch_unwind_dummy_id (gdbarch, m68k_unwind_dummy_id); --- 1199,1204 ---- Index: m68k-tdep.h =================================================================== RCS file: /cvs/src/src/gdb/m68k-tdep.h,v retrieving revision 1.10 diff -c -3 -p -r1.10 m68k-tdep.h *** m68k-tdep.h 17 Dec 2005 22:34:01 -0000 1.10 --- m68k-tdep.h 9 Jun 2006 12:45:09 -0000 *************** struct gdbarch_tdep *** 76,85 **** --- 76,90 ---- /* Convention for returning structures. */ enum struct_return struct_return; + + /* Register in which pointers are returned. */ + int ptr_value_regnum; }; /* Initialize a SVR4 architecture variant. */ extern void m68k_svr4_init_abi (struct gdbarch_info, struct gdbarch *); + /* Initialize a aout architecture variant. */ + extern void m68k_aout_init_abi (struct gdbarch_info, struct gdbarch *); /* Functions exported from m68kbsd-tdep.c. */ Index: m68kbsd-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/m68kbsd-tdep.c,v retrieving revision 1.7 diff -c -3 -p -r1.7 m68kbsd-tdep.c *** m68kbsd-tdep.c 17 Dec 2005 22:34:01 -0000 1.7 --- m68kbsd-tdep.c 9 Jun 2006 12:45:09 -0000 *************** m68kbsd_aout_init_abi (struct gdbarch_in *** 206,212 **** m68kbsd_init_abi (info, gdbarch); ! tdep->struct_return = reg_struct_return; tramp_frame_prepend_unwinder (gdbarch, &m68kobsd_sigtramp); } --- 206,212 ---- m68kbsd_init_abi (info, gdbarch); ! m68k_aout_init_abi (info, gdbarch); tramp_frame_prepend_unwinder (gdbarch, &m68kobsd_sigtramp); } *************** m68kbsd_elf_init_abi (struct gdbarch_inf *** 222,227 **** --- 222,228 ---- /* NetBSD ELF uses the SVR4 ABI. */ m68k_svr4_init_abi (info, gdbarch); + /* But with pcc structure return */ tdep->struct_return = pcc_struct_return; /* NetBSD ELF uses SVR4-style shared libraries. */ Index: m68klinux-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/m68klinux-tdep.c,v retrieving revision 1.18 diff -c -3 -p -r1.18 m68klinux-tdep.c *** m68klinux-tdep.c 20 Apr 2006 17:29:47 -0000 1.18 --- m68klinux-tdep.c 9 Jun 2006 12:45:09 -0000 *************** m68k_linux_init_abi (struct gdbarch_info *** 291,298 **** address to store a structure value. It also returns small structures in registers instead of memory. */ m68k_svr4_init_abi (info, gdbarch); tdep->struct_value_regnum = M68K_A1_REGNUM; - tdep->struct_return = reg_struct_return; frame_unwind_append_sniffer (gdbarch, m68k_linux_sigtramp_frame_sniffer); --- 291,298 ---- address to store a structure value. It also returns small structures in registers instead of memory. */ m68k_svr4_init_abi (info, gdbarch); + /* But the struct pointer is in %a1 */ tdep->struct_value_regnum = M68K_A1_REGNUM; frame_unwind_append_sniffer (gdbarch, m68k_linux_sigtramp_frame_sniffer);