[FT32] Implement pointer to address conversion method.
FT32 is a Harvard architecture with two address spaces -- RAM and flash. The patch properly implements the pointer to address conversion method. There are some other small fixes to handle address spaces. gdb/ * ft32-tdep.c (ft32_register_type): Return gdbarch_tdep (gdbarch)->pc_type instead of builtin_func_ptr. (ft32_pointer_to_address): New function. (ft32_address_class_type_flags): New function. (ft32_address_class_type_flags_to_name): New function. (ft32_address_class_name_to_type_flags): New function. (ft32_gdbarch_init): Set tdep->pc_type. Call set_gdbarch_pointer_to_address, set_gdbarch_address_class_type_flags set_gdbarch_address_class_name_to_type_flags, and set_gdbarch_address_class_type_flags_to_name. * ft32-tdep.h (struct gdbarch_tdep) <pc_type>: New field.
This commit is contained in:
parent
3074964fcf
commit
623fb77545
|
@ -1,3 +1,18 @@
|
||||||
|
2015-09-23 James Bowman <james.bowman@ftdichip.com>
|
||||||
|
|
||||||
|
* ft32-tdep.c (ft32_register_type): Return gdbarch_tdep (gdbarch)->pc_type
|
||||||
|
instead of builtin_func_ptr.
|
||||||
|
(ft32_pointer_to_address): New function.
|
||||||
|
(ft32_address_class_type_flags): New function.
|
||||||
|
(ft32_address_class_type_flags_to_name): New function.
|
||||||
|
(ft32_address_class_name_to_type_flags): New function.
|
||||||
|
(ft32_gdbarch_init): Set tdep->pc_type. Call
|
||||||
|
set_gdbarch_pointer_to_address,
|
||||||
|
set_gdbarch_address_class_type_flags
|
||||||
|
set_gdbarch_address_class_name_to_type_flags,
|
||||||
|
and set_gdbarch_address_class_type_flags_to_name.
|
||||||
|
* ft32-tdep.h (struct gdbarch_tdep) <pc_type>: New field.
|
||||||
|
|
||||||
2015-09-23 Pierre-Marie de Rodat <derodat@adacore.com>
|
2015-09-23 Pierre-Marie de Rodat <derodat@adacore.com>
|
||||||
|
|
||||||
* ada-lang.c (ada_evaluate_subexp) <OP_FUNCALL>: When the input
|
* ada-lang.c (ada_evaluate_subexp) <OP_FUNCALL>: When the input
|
||||||
|
|
|
@ -117,7 +117,7 @@ static struct type *
|
||||||
ft32_register_type (struct gdbarch *gdbarch, int reg_nr)
|
ft32_register_type (struct gdbarch *gdbarch, int reg_nr)
|
||||||
{
|
{
|
||||||
if (reg_nr == FT32_PC_REGNUM)
|
if (reg_nr == FT32_PC_REGNUM)
|
||||||
return builtin_type (gdbarch)->builtin_func_ptr;
|
return gdbarch_tdep (gdbarch)->pc_type;
|
||||||
else if (reg_nr == FT32_SP_REGNUM || reg_nr == FT32_FP_REGNUM)
|
else if (reg_nr == FT32_SP_REGNUM || reg_nr == FT32_FP_REGNUM)
|
||||||
return builtin_type (gdbarch)->builtin_data_ptr;
|
return builtin_type (gdbarch)->builtin_data_ptr;
|
||||||
else
|
else
|
||||||
|
@ -270,6 +270,73 @@ ft32_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
|
||||||
return pc;
|
return pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Implementation of `pointer_to_address' gdbarch method.
|
||||||
|
|
||||||
|
On FT32 address space zero is RAM, address space 1 is flash.
|
||||||
|
RAM appears at address RAM_BIAS, flash at address 0. */
|
||||||
|
|
||||||
|
static CORE_ADDR
|
||||||
|
ft32_pointer_to_address (struct gdbarch *gdbarch,
|
||||||
|
struct type *type, const gdb_byte *buf)
|
||||||
|
{
|
||||||
|
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||||||
|
CORE_ADDR addr
|
||||||
|
= extract_unsigned_integer (buf, TYPE_LENGTH (type), byte_order);
|
||||||
|
|
||||||
|
if (TYPE_ADDRESS_CLASS_1 (type))
|
||||||
|
return addr;
|
||||||
|
else
|
||||||
|
return addr | RAM_BIAS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implementation of `address_class_type_flags' gdbarch method.
|
||||||
|
|
||||||
|
This method maps DW_AT_address_class attributes to a
|
||||||
|
type_instance_flag_value. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
ft32_address_class_type_flags (int byte_size, int dwarf2_addr_class)
|
||||||
|
{
|
||||||
|
/* The value 1 of the DW_AT_address_class attribute corresponds to the
|
||||||
|
__flash__ qualifier, meaning pointer to data in FT32 program memory.
|
||||||
|
*/
|
||||||
|
if (dwarf2_addr_class == 1)
|
||||||
|
return TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implementation of `address_class_type_flags_to_name' gdbarch method.
|
||||||
|
|
||||||
|
Convert a type_instance_flag_value to an address space qualifier. */
|
||||||
|
|
||||||
|
static const char*
|
||||||
|
ft32_address_class_type_flags_to_name (struct gdbarch *gdbarch, int type_flags)
|
||||||
|
{
|
||||||
|
if (type_flags & TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1)
|
||||||
|
return "flash";
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implementation of `address_class_name_to_type_flags' gdbarch method.
|
||||||
|
|
||||||
|
Convert an address space qualifier to a type_instance_flag_value. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
ft32_address_class_name_to_type_flags (struct gdbarch *gdbarch,
|
||||||
|
const char* name,
|
||||||
|
int *type_flags_ptr)
|
||||||
|
{
|
||||||
|
if (strcmp (name, "flash") == 0)
|
||||||
|
{
|
||||||
|
*type_flags_ptr = TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Implement the "read_pc" gdbarch method. */
|
/* Implement the "read_pc" gdbarch method. */
|
||||||
|
|
||||||
static CORE_ADDR
|
static CORE_ADDR
|
||||||
|
@ -488,6 +555,8 @@ ft32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||||
{
|
{
|
||||||
struct gdbarch *gdbarch;
|
struct gdbarch *gdbarch;
|
||||||
struct gdbarch_tdep *tdep;
|
struct gdbarch_tdep *tdep;
|
||||||
|
struct type *void_type;
|
||||||
|
struct type *func_void_type;
|
||||||
|
|
||||||
/* If there is already a candidate, use it. */
|
/* If there is already a candidate, use it. */
|
||||||
arches = gdbarch_list_lookup_by_info (arches, &info);
|
arches = gdbarch_list_lookup_by_info (arches, &info);
|
||||||
|
@ -498,6 +567,15 @@ ft32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||||
tdep = XNEW (struct gdbarch_tdep);
|
tdep = XNEW (struct gdbarch_tdep);
|
||||||
gdbarch = gdbarch_alloc (&info, tdep);
|
gdbarch = gdbarch_alloc (&info, tdep);
|
||||||
|
|
||||||
|
/* Create a type for PC. We can't use builtin types here, as they may not
|
||||||
|
be defined. */
|
||||||
|
void_type = arch_type (gdbarch, TYPE_CODE_VOID, 1, "void");
|
||||||
|
func_void_type = make_function_type (void_type, NULL);
|
||||||
|
tdep->pc_type = arch_type (gdbarch, TYPE_CODE_PTR, 4, NULL);
|
||||||
|
TYPE_TARGET_TYPE (tdep->pc_type) = func_void_type;
|
||||||
|
TYPE_UNSIGNED (tdep->pc_type) = 1;
|
||||||
|
TYPE_INSTANCE_FLAGS (tdep->pc_type) |= TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1;
|
||||||
|
|
||||||
set_gdbarch_read_pc (gdbarch, ft32_read_pc);
|
set_gdbarch_read_pc (gdbarch, ft32_read_pc);
|
||||||
set_gdbarch_write_pc (gdbarch, ft32_write_pc);
|
set_gdbarch_write_pc (gdbarch, ft32_write_pc);
|
||||||
set_gdbarch_unwind_sp (gdbarch, ft32_unwind_sp);
|
set_gdbarch_unwind_sp (gdbarch, ft32_unwind_sp);
|
||||||
|
@ -510,6 +588,8 @@ ft32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||||
|
|
||||||
set_gdbarch_return_value (gdbarch, ft32_return_value);
|
set_gdbarch_return_value (gdbarch, ft32_return_value);
|
||||||
|
|
||||||
|
set_gdbarch_pointer_to_address (gdbarch, ft32_pointer_to_address);
|
||||||
|
|
||||||
set_gdbarch_skip_prologue (gdbarch, ft32_skip_prologue);
|
set_gdbarch_skip_prologue (gdbarch, ft32_skip_prologue);
|
||||||
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
|
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
|
||||||
set_gdbarch_breakpoint_from_pc (gdbarch, ft32_breakpoint_from_pc);
|
set_gdbarch_breakpoint_from_pc (gdbarch, ft32_breakpoint_from_pc);
|
||||||
|
@ -535,6 +615,12 @@ ft32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||||
/* Support simple overlay manager. */
|
/* Support simple overlay manager. */
|
||||||
set_gdbarch_overlay_update (gdbarch, simple_overlay_update);
|
set_gdbarch_overlay_update (gdbarch, simple_overlay_update);
|
||||||
|
|
||||||
|
set_gdbarch_address_class_type_flags (gdbarch, ft32_address_class_type_flags);
|
||||||
|
set_gdbarch_address_class_name_to_type_flags
|
||||||
|
(gdbarch, ft32_address_class_name_to_type_flags);
|
||||||
|
set_gdbarch_address_class_type_flags_to_name
|
||||||
|
(gdbarch, ft32_address_class_type_flags_to_name);
|
||||||
|
|
||||||
return gdbarch;
|
return gdbarch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,8 @@
|
||||||
|
|
||||||
struct gdbarch_tdep
|
struct gdbarch_tdep
|
||||||
{
|
{
|
||||||
/* gdbarch target dependent data here. Currently unused for FT32. */
|
/* Type for a pointer to a function. Used for the type of PC. */
|
||||||
|
struct type *pc_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FT32_TDEP_H */
|
#endif /* FT32_TDEP_H */
|
||||||
|
|
Loading…
Reference in New Issue