• Bug#576242: gdb: Please support Renesas SH(sh4) (2/2)

    From John Paul Adrian Glaubitz@21:1/5 to All on Tue Feb 7 22:00:03 2017
    [continued from previous message]

    #include "arch-utils.h"
    #include "floatformat.h"
    #include "regcache.h"
    +#include "regset.h"
    #include "doublest.h"
    #include "osabi.h"
    #include "reggroups.h"
    @@ -67,23 +71,6 @@ static const char *const sh_cc_enum[] =

    static const char *sh_active_calling_convention = sh_cc_gcc;

    -#define SH_NUM_REGS 67
    -
    -struct sh_frame_cache
    -{
    - /* Base address. */
    - CORE_ADDR base;
    - LONGEST sp_offset;
    - CORE_ADDR pc;
    -
    - /* Flag showing that a frame has been created in the prologue code. */
    - int uses_fp;
    -
    - /* Saved registers. */
    - CORE_ADDR saved_regs[SH_NUM_REGS];
    - CORE_ADDR saved_sp;
    -};
    -
    static int
    sh_is_renesas_calling_convention (struct type *func_type)
    {
    @@ -1043,7 +1030,7 @@ sh_treat_as_flt_p (struct type *type)
    return 0;
    /* Otherwise if the type of that member is float, the whole type is
    treated as float. */
    - if (TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_FLT)
    + if (TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type, 0))) == TYPE_CODE_FLT)
    return 1;
    /* Otherwise it's not treated as float. */
    return 0;
    @@ -1093,7 +1080,7 @@ sh_push_dummy_call_fpu (struct gdbarch *
    in four registers available. Loop thru args from first to last. */
    for (argnum = 0; argnum < nargs; argnum++)
    {
    - type = value_type (args[argnum]);
    + type = check_typedef (value_type (args[argnum]));
    len = TYPE_LENGTH (type);
    val = sh_justify_value_in_reg (gdbarch, args[argnum], len);

    @@ -1819,7 +1806,7 @@ sh_dwarf2_frame_init_reg (struct gdbarch
    reg->how = DWARF2_FRAME_REG_UNDEFINED;
    }

    -static struct sh_frame_cache *
    +struct sh_frame_cache *
    sh_alloc_frame_cache (void)
    {
    struct sh_frame_cache *cache;
    @@ -1846,7 +1833,7 @@ sh_alloc_frame_cache (void)
    return cache;
    }

    -static struct sh_frame_cache *
    +struct sh_frame_cache *
    sh_frame_cache (struct frame_info *this_frame, void **this_cache)
    {
    struct gdbarch *gdbarch = get_frame_arch (this_frame);
    @@ -1913,9 +1900,9 @@ sh_frame_cache (struct frame_info *this_
    return cache;
    }

    -static struct value *
    -sh_frame_prev_register (struct frame_info *this_frame,
    - void **this_cache, int regnum)
    +struct value *
    +sh_frame_prev_register (struct frame_info *this_frame, void **this_cache,
    + int regnum)
    {
    struct gdbarch *gdbarch = get_frame_arch (this_frame);
    struct sh_frame_cache *cache = sh_frame_cache (this_frame, this_cache);
    @@ -1929,7 +1916,7 @@ sh_frame_prev_register (struct frame_inf
    the current frame. Frob regnum so that we pull the value from
    the correct place. */
    if (regnum == gdbarch_pc_regnum (gdbarch))
    - regnum = PR_REGNUM;
    + regnum = PR_REGNUM; /* XXX: really? */

    if (regnum < SH_NUM_REGS && cache->saved_regs[regnum] != -1)
    return frame_unwind_got_memory (this_frame, regnum,
    @@ -2238,8 +2225,8 @@ sh_return_in_first_hidden_param_p (struc
    static struct gdbarch *
    sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
    {
    - struct gdbarch *gdbarch;
    struct gdbarch_tdep *tdep;
    + struct gdbarch *gdbarch;

    /* SH5 is handled entirely in sh64-tdep.c. */
    if (info.bfd_arch_info->mach == bfd_mach_sh5)
    @@ -2255,6 +2242,18 @@ sh_gdbarch_init (struct gdbarch_info inf
    tdep = XCNEW (struct gdbarch_tdep);
    gdbarch = gdbarch_alloc (&info, tdep);

    + /* General-purpose registers. */
    + tdep->gregset = NULL;
    + tdep->gregset_reg_offset = NULL;
    + tdep->gregset_num_regs = 23;
    + tdep->sizeof_gregset = 0;
    +
    + /* Floating-point registers. */
    + tdep->fpregset = NULL;
    + tdep->sizeof_fpregset = 34*4;
    +
    + tdep->jb_pc_offset = -1;
    +
    set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
    set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
    set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
    @@ -2405,10 +2404,11 @@ sh_gdbarch_init (struct gdbarch_info inf
    break;
    }

    + dwarf2_append_unwinders (gdbarch);
    +
    /* Hook in ABI-specific overrides, if they have been registered. */
    gdbarch_init_osabi (info, gdbarch);

    - dwarf2_append_unwinders (gdbarch);
    frame_unwind_append_unwinder (gdbarch, &sh_stub_unwind);
    frame_unwind_append_unwinder (gdbarch, &sh_frame_unwind);

    --- gdb-7.12.orig/gdb/sh-tdep.h
    +++ gdb-7.12/gdb/sh-tdep.h
    @@ -21,6 +21,12 @@

    /* Contributed by Steve Chamberlain sac@cygnus.com. */

    +struct frame_info;
    +struct gdbarch;
    +struct reggroup;
    +struct regset;
    +struct regcache;
    +
    /* Registers for all SH variants. Used also by sh3-rom.c. */
    enum
    {
    @@ -29,6 +35,7 @@ enum
    ARG0_REGNUM = 4,
    ARGLAST_REGNUM = 7,
    FP_REGNUM = 14,
    + SP_REGNUM = 15,
    PC_REGNUM = 16,
    PR_REGNUM = 17,
    GBR_REGNUM = 18,
    @@ -82,6 +89,25 @@ enum
    FV_LAST_REGNUM = 79
    };

    +#define SH_NUM_REGS 67
    +
    +struct sh_frame_cache
    +{
    + /* Base address. */
    + CORE_ADDR base;
    + LONGEST sp_offset;
    + CORE_ADDR pc;
    +
    + /* Flag showing that a frame has been created in the prologue code. */
    + int uses_fp;
    +
    + /* Saved registers. */
    + CORE_ADDR saved_regs[SH_NUM_REGS];
    + CORE_ADDR saved_sp;
    +};
    +
    +extern struct sh_frame_cache *sh_frame_cache (struct frame_info *next_frame, void **this_cache);
    +
    /* This structure de