X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fmicroblaze-tdep.c;h=44bfe7f361e143967cbbf12770c4bed0e079a7ab;hb=036003a671233c43e35b3004f91e4cbd61255cf3;hp=ca592133e7f5c34a73f405053ae5229ce0204419;hpb=22e048c9ddfdfd4e4580998f543f80e70f9770f7;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c index ca592133e7..44bfe7f361 100644 --- a/gdb/microblaze-tdep.c +++ b/gdb/microblaze-tdep.c @@ -1,6 +1,6 @@ /* Target-dependent code for Xilinx MicroBlaze. - Copyright 2009-2012 Free Software Foundation, Inc. + Copyright (C) 2009-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -29,18 +29,18 @@ #include "inferior.h" #include "regcache.h" #include "target.h" -#include "frame.h" #include "frame-base.h" #include "frame-unwind.h" #include "dwarf2-frame.h" #include "osabi.h" - -#include "gdb_assert.h" -#include "gdb_string.h" #include "target-descriptions.h" #include "opcodes/microblaze-opcm.h" #include "opcodes/microblaze-dis.h" #include "microblaze-tdep.h" +#include "remote.h" + +#include "features/microblaze-with-stack-protect.c" +#include "features/microblaze.c" /* Instruction macros used for analyzing the prologue. */ /* This set of instruction macros need to be changed whenever the @@ -74,14 +74,15 @@ static const char *microblaze_register_names[] = "rpc", "rmsr", "rear", "resr", "rfsr", "rbtr", "rpvr0", "rpvr1", "rpvr2", "rpvr3", "rpvr4", "rpvr5", "rpvr6", "rpvr7", "rpvr8", "rpvr9", "rpvr10", "rpvr11", - "redr", "rpid", "rzpr", "rtlbx", "rtlbsx", "rtlblo", "rtlbhi" + "redr", "rpid", "rzpr", "rtlbx", "rtlbsx", "rtlblo", "rtlbhi", + "rslr", "rshr" }; #define MICROBLAZE_NUM_REGS ARRAY_SIZE (microblaze_register_names) -static int microblaze_debug_flag = 0; +static unsigned int microblaze_debug_flag = 0; -static void +static void ATTRIBUTE_PRINTF (1, 2) microblaze_debug (const char *fmt, ...) { if (microblaze_debug_flag) @@ -123,49 +124,20 @@ microblaze_register_type (struct gdbarch *gdbarch, int regnum) static unsigned long microblaze_fetch_instruction (CORE_ADDR pc) { - enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); gdb_byte buf[4]; /* If we can't read the instruction at PC, return zero. */ - if (target_read_memory (pc, buf, sizeof (buf))) + if (target_read_code (pc, buf, sizeof (buf))) return 0; return extract_unsigned_integer (buf, 4, byte_order); } +constexpr gdb_byte microblaze_break_insn[] = MICROBLAZE_BREAKPOINT; -static CORE_ADDR -microblaze_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp, - CORE_ADDR funcaddr, - struct value **args, int nargs, - struct type *value_type, - CORE_ADDR *real_pc, CORE_ADDR *bp_addr, - struct regcache *regcache) -{ - error (_("push_dummy_code not implemented")); - return sp; -} - +typedef BP_MANIPULATION (microblaze_break_insn) microblaze_breakpoint; -static CORE_ADDR -microblaze_push_dummy_call (struct gdbarch *gdbarch, struct value *function, - struct regcache *regcache, CORE_ADDR bp_addr, - int nargs, struct value **args, CORE_ADDR sp, - int struct_return, CORE_ADDR struct_addr) -{ - error (_("store_arguments not implemented")); - return sp; -} - -static const gdb_byte * -microblaze_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, - int *len) -{ - static gdb_byte break_insn[] = MICROBLAZE_BREAKPOINT; - - *len = sizeof (break_insn); - return break_insn; -} /* Allocate and initialize a frame cache. */ @@ -381,12 +353,13 @@ microblaze_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, instruction. */ { - unsigned op = (unsigned)insn >> 26; + unsigned ctrl_op = (unsigned)insn >> 26; /* continue if not control flow (branch, return). */ - if (op != 0x26 && op != 0x27 && op != 0x2d && op != 0x2e && op != 0x2f) + if (ctrl_op != 0x26 && ctrl_op != 0x27 && ctrl_op != 0x2d + && ctrl_op != 0x2e && ctrl_op != 0x2f) continue; - else if (op == 0x2c) + else if (ctrl_op == 0x2c) continue; /* continue if imm. */ } @@ -460,11 +433,10 @@ microblaze_frame_cache (struct frame_info *next_frame, void **this_cache) { struct microblaze_frame_cache *cache; struct gdbarch *gdbarch = get_frame_arch (next_frame); - CORE_ADDR func; int rn; if (*this_cache) - return *this_cache; + return (struct microblaze_frame_cache *) *this_cache; cache = microblaze_alloc_frame_cache (); *this_cache = cache; @@ -474,7 +446,8 @@ microblaze_frame_cache (struct frame_info *next_frame, void **this_cache) for (rn = 0; rn < gdbarch_num_regs (gdbarch); rn++) cache->register_offsets[rn] = -1; - func = get_frame_func (next_frame); + /* Call for side effects. */ + get_frame_func (next_frame); cache->pc = get_frame_address_in_block (next_frame); @@ -557,17 +530,17 @@ microblaze_extract_return_value (struct type *type, struct regcache *regcache, switch (TYPE_LENGTH (type)) { case 1: /* return last byte in the register. */ - regcache_cooked_read (regcache, MICROBLAZE_RETVAL_REGNUM, buf); + regcache->cooked_read (MICROBLAZE_RETVAL_REGNUM, buf); memcpy(valbuf, buf + MICROBLAZE_REGISTER_SIZE - 1, 1); return; case 2: /* return last 2 bytes in register. */ - regcache_cooked_read (regcache, MICROBLAZE_RETVAL_REGNUM, buf); + regcache->cooked_read (MICROBLAZE_RETVAL_REGNUM, buf); memcpy(valbuf, buf + MICROBLAZE_REGISTER_SIZE - 2, 2); return; case 4: /* for sizes 4 or 8, copy the required length. */ case 8: - regcache_cooked_read (regcache, MICROBLAZE_RETVAL_REGNUM, buf); - regcache_cooked_read (regcache, MICROBLAZE_RETVAL_REGNUM+1, buf+4); + regcache->cooked_read (MICROBLAZE_RETVAL_REGNUM, buf); + regcache->cooked_read (MICROBLAZE_RETVAL_REGNUM + 1, buf+4); memcpy (valbuf, buf, TYPE_LENGTH (type)); return; default: @@ -601,13 +574,13 @@ microblaze_store_return_value (struct type *type, struct regcache *regcache, { gdb_assert (len == 8); memcpy (buf, valbuf, 8); - regcache_cooked_write (regcache, MICROBLAZE_RETVAL_REGNUM+1, buf + 4); + regcache->cooked_write (MICROBLAZE_RETVAL_REGNUM+1, buf + 4); } else /* ??? Do we need to do any sign-extension here? */ memcpy (buf + 4 - len, valbuf, len); - regcache_cooked_write (regcache, MICROBLAZE_RETVAL_REGNUM, buf); + regcache->cooked_write (MICROBLAZE_RETVAL_REGNUM, buf); } static enum return_value_convention @@ -629,11 +602,6 @@ microblaze_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type) return (TYPE_LENGTH (type) == 16); } -static void -microblaze_write_pc (struct regcache *regcache, CORE_ADDR pc) -{ - regcache_cooked_write_unsigned (regcache, MICROBLAZE_PC_REGNUM, pc); -} static int dwarf2_to_reg_map[78] = { 0 /* r0 */, 1 /* r1 */, 2 /* r2 */, 3 /* r3 */, /* 0- 3 */ @@ -661,8 +629,21 @@ static int dwarf2_to_reg_map[78] = static int microblaze_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg) { - gdb_assert (reg < sizeof (dwarf2_to_reg_map)); - return dwarf2_to_reg_map[reg]; + if (reg >= 0 && reg < sizeof (dwarf2_to_reg_map)) + return dwarf2_to_reg_map[reg]; + return -1; +} + +static void +microblaze_register_g_packet_guesses (struct gdbarch *gdbarch) +{ + register_remote_g_packet_guess (gdbarch, + 4 * MICROBLAZE_NUM_CORE_REGS, + tdesc_microblaze); + + register_remote_g_packet_guess (gdbarch, + 4 * MICROBLAZE_NUM_REGS, + tdesc_microblaze_with_stack_protect); } static struct gdbarch * @@ -670,14 +651,55 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { struct gdbarch_tdep *tdep; struct gdbarch *gdbarch; + struct tdesc_arch_data *tdesc_data = NULL; + const struct target_desc *tdesc = info.target_desc; /* If there is already a candidate, use it. */ arches = gdbarch_list_lookup_by_info (arches, &info); if (arches != NULL) return arches->gdbarch; + if (tdesc == NULL) + tdesc = tdesc_microblaze; + + /* Check any target description for validity. */ + if (tdesc_has_registers (tdesc)) + { + const struct tdesc_feature *feature; + int valid_p; + int i; + + feature = tdesc_find_feature (tdesc, + "org.gnu.gdb.microblaze.core"); + if (feature == NULL) + return NULL; + tdesc_data = tdesc_data_alloc (); + + valid_p = 1; + for (i = 0; i < MICROBLAZE_NUM_CORE_REGS; i++) + valid_p &= tdesc_numbered_register (feature, tdesc_data, i, + microblaze_register_names[i]); + feature = tdesc_find_feature (tdesc, + "org.gnu.gdb.microblaze.stack-protect"); + if (feature != NULL) + { + valid_p = 1; + valid_p &= tdesc_numbered_register (feature, tdesc_data, + MICROBLAZE_SLR_REGNUM, + "rslr"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + MICROBLAZE_SHR_REGNUM, + "rshr"); + } + + if (!valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + } /* Allocate space for the new architecture. */ - tdep = XMALLOC (struct gdbarch_tdep); + tdep = XCNEW (struct gdbarch_tdep); gdbarch = gdbarch_alloc (&info, tdep); set_gdbarch_long_double_bit (gdbarch, 128); @@ -695,8 +717,6 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Call dummy code. */ set_gdbarch_call_dummy_location (gdbarch, ON_STACK); - set_gdbarch_push_dummy_code (gdbarch, microblaze_push_dummy_code); - set_gdbarch_push_dummy_call (gdbarch, microblaze_push_dummy_call); set_gdbarch_return_value (gdbarch, microblaze_return_value); set_gdbarch_stabs_argument_has_addr @@ -707,16 +727,17 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Stack grows downward. */ set_gdbarch_inner_than (gdbarch, core_addr_lessthan); - set_gdbarch_breakpoint_from_pc (gdbarch, microblaze_breakpoint_from_pc); + set_gdbarch_breakpoint_kind_from_pc (gdbarch, + microblaze_breakpoint::kind_from_pc); + set_gdbarch_sw_breakpoint_from_kind (gdbarch, + microblaze_breakpoint::bp_from_kind); set_gdbarch_frame_args_skip (gdbarch, 8); - set_gdbarch_print_insn (gdbarch, print_insn_microblaze); - - set_gdbarch_write_pc (gdbarch, microblaze_write_pc); - set_gdbarch_unwind_pc (gdbarch, microblaze_unwind_pc); + microblaze_register_g_packet_guesses (gdbarch); + frame_base_set_default (gdbarch, µblaze_frame_base); /* Hook in ABI-specific overrides, if they have been registered. */ @@ -726,26 +747,27 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) dwarf2_append_unwinders (gdbarch); frame_unwind_append_unwinder (gdbarch, µblaze_frame_unwind); frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer); + if (tdesc_data != NULL) + tdesc_use_registers (gdbarch, tdesc, tdesc_data); return gdbarch; } -/* Provide a prototype to silence -Wmissing-prototypes. */ -void _initialize_microblaze_tdep (void); - void _initialize_microblaze_tdep (void) { register_gdbarch_init (bfd_arch_microblaze, microblaze_gdbarch_init); + initialize_tdesc_microblaze_with_stack_protect (); + initialize_tdesc_microblaze (); /* Debug this files internals. */ - add_setshow_zinteger_cmd ("microblaze", class_maintenance, - µblaze_debug_flag, _("\ + add_setshow_zuinteger_cmd ("microblaze", class_maintenance, + µblaze_debug_flag, _("\ Set microblaze debugging."), _("\ Show microblaze debugging."), _("\ When non-zero, microblaze specific debugging is enabled."), - NULL, - NULL, - &setdebuglist, &showdebuglist); + NULL, + NULL, + &setdebuglist, &showdebuglist); }