doc/ChangeLog:

--------------

	* gdb.texinfo (Set SH Calling convention): New @item.
	(Show SH Calling convention): Ditto.

ChangeLog:
----------

	* NEWS: Add information on calling convention and new SH CLI options.

	* sh-tdep.c (sh_cc_gcc): New static string.
	(sh_cc_renesas): Ditto.
	(sh_cc_enum): New static string array.
	(sh_active_calling_convention): New static string pointer denoting
	active user chosen ABI.
	(sh_is_renesas_calling_convention): New function to return function
	specific ABI, or user choice if necessary.
	(sh_use_struct_convention): Rename first argument and turn around its
	meaning.  Check for renesas ABI and return accordingly.
	(sh_use_struct_convention_nofpu): New function.
	(sh_next_flt_argreg): Get function type as third parameter.  Check
	for renesas ABI and choose floating registers accordingly.
	(sh_push_dummy_call_fpu): Check for ABI and choose argument slot and
	struct return slot accordingly.
	(sh_push_dummy_call_nofpu): Ditto.
	(sh_return_value_nofpu): Call sh_use_struct_convention_nofpu from here.
	Evaluate ABI and give to sh_use_struct_convention_nofpu.
	(sh_return_value_fpu):  Evaluate ABI and give to
	sh_use_struct_convention.
	(show_sh_command): New function.
	(set_sh_command): Ditto.
	(_initialize_sh_tdep): Initialize `set/show sh calling-convention
	CLI command.

	* gdbarch.sh (return_value): Add func_type argument.
	* gdbarch.c: Regenerate.
	* gdbarch.h: Ditto.
	* eval.c (evaluate_subexp_standard): Rename local variable value_type to
	val_type so as not to collide with value_type function.  Call
	using_struct_return with additional function type argument.
	* infcall.c (call_function_by_hand): Call using_struct_return and
	gdbarch_return_value with additional function type argument.
	* infcmd.c (print_return_value): Take addition func_type argument.
	Call gdbarch_return_value with additional function type argument.
	(finish_command_continuation): Call print_return_value with additional
	function type argument.
	(finish_command): Ditto.
	* sparc-tdep.c (sparc32_push_dummy_code): Call using_struct_return with
	additional function type argument.
	* stack.c (return_command): Call using_struct_return and
	gdbarch_return_value with additional function type argument.
	* value.c (using_struct_return): Take additional function type argument.
	* value.h (using_struct_return): Accommodate declaration.
	* alpha-tdep.c (alpha_return_value): Add func_type argument.
	* amd64-tdep.c (amd64_return_value): Ditto.
	* arm-tdep.c (arm_return_value): Ditto.
	* avr-tdep.c (avr_return_value): Ditto.
	* cris-tdep.c (cris_return_value): Ditto.
	* frv-tdep.c (frv_return_value): Ditto.
	* h8300-tdep.c (h8300_return_value): Ditto.
	(h8300h_return_value): Ditto.
	* hppa-tdep.c (hppa32_return_value): Ditto.
	(hppa64_return_value): Ditto.
	* i386-tdep.c (i386_return_value): Ditto.
	* ia64-tdep.c (ia64_return_value): Ditto.
	* iq2000-tdep.c (iq2000_return_value): Ditto.
	* m32c-tdep.c (m32c_return_value): Ditto.
	* m32r-tdep.c (m32r_return_value): Ditto.
	* m68hc11-tdep.c (m68hc11_return_value): Ditto.
	* m68k-tdep.c (m68k_return_value): Ditto.
	(m68k_svr4_return_value): Ditto.
	* m88k-tdep.c  (m88k_return_value): Ditto.
	* mep-tdep.c (mep_return_value): Ditto.
	* mips-tdep.c (mips_eabi_return_value): Ditto.
	(mips_n32n64_return_value): Ditto.
	(mips_o32_return_value): Ditto.
	(mips_o64_return_value): Ditto.
	* mn10300-tdep.c (mn10300_return_value): Ditto.
	* mt-tdep.c (mt_return_value): Ditto.
	* ppc-linux-tdep.c (ppc_linux_return_value): Ditto.
	* ppc-sysv-tdep.c (ppc_sysv_abi_return_value): Ditto.
	(ppc_sysv_abi_broken_return_value): Ditto.
	(ppc64_sysv_abi_return_value): Ditto.
	* ppc-tdep.h (ppc_sysv_abi_return_value): Ditto.
	(ppc_sysv_abi_broken_return_value): Ditto.
	(ppc64_sysv_abi_return_value): Ditto.
	* ppcnbsd-tdep.c (ppcnbsd_return_value): Ditto.
	* rs6000-tdep.c (rs6000_return_value): Ditto.
	* s390-tdep.c (s390_return_value): Ditto.
	* score-tdep.c (score_return_value): Ditto.
	* sh-tdep.c (sh_return_value_nofpu): Ditto.
	(sh_return_value_fpu): Ditto.
	* sh64-tdep.c (sh64_return_value): Ditto.
	* sparc-tdep.c (sparc32_return_value): Ditto.
	* sparc64-tdep.c (sparc64_return_value): Ditto.
	* spu-tdep.c (spu_return_value): Ditto.
	* v850-tdep.c (v850_return_value): Ditto.
	* vax-tdep.c (vax_return_value): Ditto.
	* xstormy16-tdep.c (xstormy16_return_value): Ditto.
	* xtensa-tdep.c (xtensa_return_value): Ditto.

	* gdbtypes.h (struct type): Add calling_convention member.
	* dwarf2read.c (read_subroutine_type): Add calling convention read
	from DW_AT_calling_convention attribute to function type.
This commit is contained in:
Corinna Vinschen
2008-04-22 11:03:42 +00:00
parent 9eec4d1e39
commit c055b1010f
51 changed files with 441 additions and 156 deletions

View File

@@ -51,9 +51,24 @@
/* sh flags */
#include "elf/sh.h"
#include "elf/dwarf2.h"
/* registers numbers shared with the simulator */
#include "gdb/sim-sh.h"
/* List of "set sh ..." and "show sh ..." commands. */
static struct cmd_list_element *setshcmdlist = NULL;
static struct cmd_list_element *showshcmdlist = NULL;
static const char sh_cc_gcc[] = "gcc";
static const char sh_cc_renesas[] = "renesas";
static const char *sh_cc_enum[] = {
sh_cc_gcc,
sh_cc_renesas,
NULL
};
static const char *sh_active_calling_convention = sh_cc_gcc;
static void (*sh_show_regs) (struct frame_info *);
#define SH_NUM_REGS 67
@@ -73,6 +88,14 @@ struct sh_frame_cache
CORE_ADDR saved_sp;
};
static int
sh_is_renesas_calling_convention (struct type *func_type)
{
return ((func_type
&& TYPE_CALLING_CONVENTION (func_type) == DW_CC_GNU_renesas_sh)
|| sh_active_calling_convention == sh_cc_renesas);
}
static const char *
sh_sh_register_name (struct gdbarch *gdbarch, int reg_nr)
{
@@ -783,11 +806,16 @@ sh_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
*/
static int
sh_use_struct_convention (int gcc_p, struct type *type)
sh_use_struct_convention (int renesas_abi, struct type *type)
{
int len = TYPE_LENGTH (type);
int nelem = TYPE_NFIELDS (type);
/* The Renesas ABI returns aggregate types always on stack. */
if (renesas_abi && (TYPE_CODE (type) == TYPE_CODE_STRUCT
|| TYPE_CODE (type) == TYPE_CODE_UNION))
return 1;
/* Non-power of 2 length types and types bigger than 8 bytes (which don't
fit in two registers anyway) use struct convention. */
if (len != 1 && len != 2 && len != 4 && len != 8)
@@ -813,6 +841,15 @@ sh_use_struct_convention (int gcc_p, struct type *type)
return 1;
}
static int
sh_use_struct_convention_nofpu (int renesas_abi, struct type *type)
{
/* The Renesas ABI returns long longs/doubles etc. always on stack. */
if (renesas_abi && TYPE_NFIELDS (type) == 0 && TYPE_LENGTH (type) >= 8)
return 1;
return sh_use_struct_convention (renesas_abi, type);
}
static CORE_ADDR
sh_frame_align (struct gdbarch *ignore, CORE_ADDR sp)
{
@@ -924,7 +961,7 @@ sh_init_flt_argreg (void)
29) the parity of the register number is preserved, which is important
for the double register passing test (see the "argreg & 1" test below). */
static int
sh_next_flt_argreg (struct gdbarch *gdbarch, int len)
sh_next_flt_argreg (struct gdbarch *gdbarch, int len, struct type *func_type)
{
int argreg;
@@ -943,7 +980,10 @@ sh_next_flt_argreg (struct gdbarch *gdbarch, int len)
/* Doubles are always starting in a even register number. */
if (argreg & 1)
{
flt_argreg_array[argreg] = 1;
/* In gcc ABI, the skipped register is lost for further argument
passing now. Not so in Renesas ABI. */
if (!sh_is_renesas_calling_convention (func_type))
flt_argreg_array[argreg] = 1;
++argreg;
@@ -954,7 +994,8 @@ sh_next_flt_argreg (struct gdbarch *gdbarch, int len)
/* Also mark the next register as used. */
flt_argreg_array[argreg + 1] = 1;
}
else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE
&& !sh_is_renesas_calling_convention (func_type))
{
/* In little endian, gcc passes floats like this: f5, f4, f7, f6, ... */
if (!flt_argreg_array[argreg + 1])
@@ -1026,20 +1067,25 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
int argreg = ARG0_REGNUM;
int flt_argreg = 0;
int argnum;
struct type *func_type = value_type (function);
struct type *type;
CORE_ADDR regval;
char *val;
int len, reg_size = 0;
int pass_on_stack = 0;
int treat_as_flt;
int last_reg_arg = INT_MAX;
/* The Renesas ABI expects all varargs arguments, plus the last
non-vararg argument to be on the stack, no matter how many
registers have been used so far. */
if (sh_is_renesas_calling_convention (func_type)
&& (TYPE_FLAGS (func_type) & TYPE_FLAG_VARARGS))
last_reg_arg = TYPE_NFIELDS (func_type) - 2;
/* first force sp to a 4-byte alignment */
sp = sh_frame_align (gdbarch, sp);
if (struct_return)
regcache_cooked_write_unsigned (regcache,
STRUCT_RETURN_REGNUM, struct_addr);
/* make room on stack for args */
sp -= sh_stack_allocsize (nargs, args);
@@ -1062,7 +1108,14 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
/* Find out the next register to use for a floating point value. */
treat_as_flt = sh_treat_as_flt_p (type);
if (treat_as_flt)
flt_argreg = sh_next_flt_argreg (gdbarch, len);
flt_argreg = sh_next_flt_argreg (gdbarch, len, func_type);
/* In Renesas ABI, long longs and aggregate types are always passed
on stack. */
else if (sh_is_renesas_calling_convention (func_type)
&& ((TYPE_CODE (type) == TYPE_CODE_INT && len == 8)
|| TYPE_CODE (type) == TYPE_CODE_STRUCT
|| TYPE_CODE (type) == TYPE_CODE_UNION))
pass_on_stack = 1;
/* In contrast to non-FPU CPUs, arguments are never split between
registers and stack. If an argument doesn't fit in the remaining
registers it's always pushed entirely on the stack. */
@@ -1073,7 +1126,8 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
{
if ((treat_as_flt && flt_argreg > FLOAT_ARGLAST_REGNUM)
|| (!treat_as_flt && (argreg > ARGLAST_REGNUM
|| pass_on_stack)))
|| pass_on_stack))
|| argnum > last_reg_arg)
{
/* The data goes entirely on the stack, 4-byte aligned. */
reg_size = (len + 3) & ~3;
@@ -1116,6 +1170,19 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
}
}
if (struct_return)
{
if (sh_is_renesas_calling_convention (func_type))
/* If the function uses the Renesas ABI, subtract another 4 bytes from
the stack and store the struct return address there. */
write_memory_unsigned_integer (sp -= 4, 4, struct_addr);
else
/* Using the gcc ABI, the "struct return pointer" pseudo-argument has
its own dedicated register. */
regcache_cooked_write_unsigned (regcache,
STRUCT_RETURN_REGNUM, struct_addr);
}
/* Store return address. */
regcache_cooked_write_unsigned (regcache, PR_REGNUM, bp_addr);
@@ -1138,18 +1205,24 @@ sh_push_dummy_call_nofpu (struct gdbarch *gdbarch,
int stack_offset = 0;
int argreg = ARG0_REGNUM;
int argnum;
struct type *func_type = value_type (function);
struct type *type;
CORE_ADDR regval;
char *val;
int len, reg_size;
int len, reg_size = 0;
int pass_on_stack = 0;
int last_reg_arg = INT_MAX;
/* The Renesas ABI expects all varargs arguments, plus the last
non-vararg argument to be on the stack, no matter how many
registers have been used so far. */
if (sh_is_renesas_calling_convention (func_type)
&& (TYPE_FLAGS (func_type) & TYPE_FLAG_VARARGS))
last_reg_arg = TYPE_NFIELDS (func_type) - 2;
/* first force sp to a 4-byte alignment */
sp = sh_frame_align (gdbarch, sp);
if (struct_return)
regcache_cooked_write_unsigned (regcache,
STRUCT_RETURN_REGNUM, struct_addr);
/* make room on stack for args */
sp -= sh_stack_allocsize (nargs, args);
@@ -1162,9 +1235,21 @@ sh_push_dummy_call_nofpu (struct gdbarch *gdbarch,
len = TYPE_LENGTH (type);
val = sh_justify_value_in_reg (gdbarch, args[argnum], len);
/* Some decisions have to be made how various types are handled.
This also differs in different ABIs. */
pass_on_stack = 0;
/* Renesas ABI pushes doubles and long longs entirely on stack.
Same goes for aggregate types. */
if (sh_is_renesas_calling_convention (func_type)
&& ((TYPE_CODE (type) == TYPE_CODE_INT && len >= 8)
|| (TYPE_CODE (type) == TYPE_CODE_FLT && len >= 8)
|| TYPE_CODE (type) == TYPE_CODE_STRUCT
|| TYPE_CODE (type) == TYPE_CODE_UNION))
pass_on_stack = 1;
while (len > 0)
{
if (argreg > ARGLAST_REGNUM)
if (argreg > ARGLAST_REGNUM || pass_on_stack
|| argnum > last_reg_arg)
{
/* The remainder of the data goes entirely on the stack,
4-byte aligned. */
@@ -1187,6 +1272,19 @@ sh_push_dummy_call_nofpu (struct gdbarch *gdbarch,
}
}
if (struct_return)
{
if (sh_is_renesas_calling_convention (func_type))
/* If the function uses the Renesas ABI, subtract another 4 bytes from
the stack and store the struct return address there. */
write_memory_unsigned_integer (sp -= 4, 4, struct_addr);
else
/* Using the gcc ABI, the "struct return pointer" pseudo-argument has
its own dedicated register. */
regcache_cooked_write_unsigned (regcache,
STRUCT_RETURN_REGNUM, struct_addr);
}
/* Store return address. */
regcache_cooked_write_unsigned (regcache, PR_REGNUM, bp_addr);
@@ -1292,11 +1390,12 @@ sh_store_return_value_fpu (struct type *type, struct regcache *regcache,
}
static enum return_value_convention
sh_return_value_nofpu (struct gdbarch *gdbarch, struct type *type,
struct regcache *regcache,
sh_return_value_nofpu (struct gdbarch *gdbarch, struct type *func_type,
struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf)
{
if (sh_use_struct_convention (0, type))
if (sh_use_struct_convention_nofpu (
sh_is_renesas_calling_convention (func_type), type))
return RETURN_VALUE_STRUCT_CONVENTION;
if (writebuf)
sh_store_return_value_nofpu (type, regcache, writebuf);
@@ -1306,11 +1405,12 @@ sh_return_value_nofpu (struct gdbarch *gdbarch, struct type *type,
}
static enum return_value_convention
sh_return_value_fpu (struct gdbarch *gdbarch, struct type *type,
struct regcache *regcache,
sh_return_value_fpu (struct gdbarch *gdbarch, struct type *func_type,
struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf)
{
if (sh_use_struct_convention (0, type))
if (sh_use_struct_convention (
sh_is_renesas_calling_convention (func_type), type))
return RETURN_VALUE_STRUCT_CONVENTION;
if (writebuf)
sh_store_return_value_fpu (type, regcache, writebuf);
@@ -2879,6 +2979,20 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
return gdbarch;
}
static void
show_sh_command (char *args, int from_tty)
{
help_list (showshcmdlist, "show sh ", all_commands, gdb_stdout);
}
static void
set_sh_command (char *args, int from_tty)
{
printf_unfiltered
("\"set sh\" must be followed by an appropriate subcommand.\n");
help_list (setshcmdlist, "set sh ", all_commands, gdb_stdout);
}
extern initialize_file_ftype _initialize_sh_tdep; /* -Wmissing-prototypes */
void
@@ -2889,4 +3003,20 @@ _initialize_sh_tdep (void)
gdbarch_register (bfd_arch_sh, sh_gdbarch_init, NULL);
add_com ("regs", class_vars, sh_show_regs_command, _("Print all registers"));
add_prefix_cmd ("sh", no_class, set_sh_command, "SH specific commands.",
&setshcmdlist, "set sh ", 0, &setlist);
add_prefix_cmd ("sh", no_class, show_sh_command, "SH specific commands.",
&showshcmdlist, "show sh ", 0, &showlist);
add_setshow_enum_cmd ("calling-convention", class_vars, sh_cc_enum,
&sh_active_calling_convention,
_("Set calling convention used when calling target "
"functions from GDB."),
_("Show calling convention used when calling target "
"functions from GDB."),
_("gcc - Use GCC calling convention (default).\n"
"renesas - Enforce Renesas calling convention."),
NULL, NULL,
&setshcmdlist, &showshcmdlist);
}