X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Frs6000-tdep.c;h=2460eb5b8d8d594e4d33fd98c18d06634c71be8e;hb=a12ac51333cf97f4da0597d049cc694b4535e7dd;hp=baf6b67d0963c3ff2c77d711e4afc8f588eff155;hpb=ede5f15146ae45f4c017f5701629a4fa04ef2beb;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index baf6b67d09..2460eb5b8d 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -1,6 +1,6 @@ /* Target-dependent code for GDB, the GNU debugger. - Copyright (C) 1986-2015 Free Software Foundation, Inc. + Copyright (C) 1986-2016 Free Software Foundation, Inc. This file is part of GDB. @@ -63,6 +63,9 @@ #include "frame-unwind.h" #include "frame-base.h" +#include "ax.h" +#include "ax-gdb.h" + #include "features/rs6000/powerpc-32.c" #include "features/rs6000/powerpc-altivec32.c" #include "features/rs6000/powerpc-vsx32.c" @@ -328,7 +331,7 @@ init_sim_regno_table (struct gdbarch *arch) set_sim_regno (sim_regno, tdep->ppc_acc_regnum, sim_ppc_acc_regnum); /* spefscr is a special-purpose register, so the code below handles it. */ -#ifdef WITH_SIM +#ifdef WITH_PPC_SIM /* Now handle all special-purpose registers. Verify that they haven't mistakenly been assigned numbers by any of the above code. */ @@ -2919,6 +2922,62 @@ rs6000_pseudo_register_write (struct gdbarch *gdbarch, gdbarch_register_name (gdbarch, reg_nr), reg_nr); } +static int +rs6000_ax_pseudo_register_collect (struct gdbarch *gdbarch, + struct agent_expr *ax, int reg_nr) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + if (IS_SPE_PSEUDOREG (tdep, reg_nr)) + { + int reg_index = reg_nr - tdep->ppc_ev0_regnum; + ax_reg_mask (ax, tdep->ppc_gp0_regnum + reg_index); + ax_reg_mask (ax, tdep->ppc_ev0_upper_regnum + reg_index); + } + else if (IS_DFP_PSEUDOREG (tdep, reg_nr)) + { + int reg_index = reg_nr - tdep->ppc_dl0_regnum; + ax_reg_mask (ax, tdep->ppc_fp0_regnum + 2 * reg_index); + ax_reg_mask (ax, tdep->ppc_fp0_regnum + 2 * reg_index + 1); + } + else if (IS_VSX_PSEUDOREG (tdep, reg_nr)) + { + int reg_index = reg_nr - tdep->ppc_vsr0_regnum; + if (reg_index > 31) + { + ax_reg_mask (ax, tdep->ppc_vr0_regnum + reg_index - 32); + } + else + { + ax_reg_mask (ax, tdep->ppc_fp0_regnum + reg_index); + ax_reg_mask (ax, tdep->ppc_vsr0_upper_regnum + reg_index); + } + } + else if (IS_EFP_PSEUDOREG (tdep, reg_nr)) + { + int reg_index = reg_nr - tdep->ppc_efpr0_regnum; + ax_reg_mask (ax, tdep->ppc_vr0_regnum + reg_index); + } + else + internal_error (__FILE__, __LINE__, + _("rs6000_pseudo_register_collect: " + "called on unexpected register '%s' (%d)"), + gdbarch_register_name (gdbarch, reg_nr), reg_nr); + return 0; +} + + +static void +rs6000_gen_return_address (struct gdbarch *gdbarch, + struct agent_expr *ax, struct axs_value *value, + CORE_ADDR scope) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + value->type = register_type (gdbarch, tdep->ppc_lr_regnum); + value->kind = axs_lvalue_register; + value->u.reg = tdep->ppc_lr_regnum; +} + + /* Convert a DBX STABS register number to a GDB register number. */ static int rs6000_stab_reg_to_regnum (struct gdbarch *gdbarch, int num) @@ -3144,7 +3203,7 @@ static struct variant variants[] = {"rs2", "IBM POWER RS2", bfd_arch_rs6000, bfd_mach_rs6k_rs2, &tdesc_rs6000}, - {0, 0, 0, 0, 0} + {0, 0, (enum bfd_architecture) 0, 0, 0} }; /* Return the variant corresponding to architecture ARCH and machine number @@ -3191,6 +3250,13 @@ struct rs6000_frame_cache CORE_ADDR base; CORE_ADDR initial_sp; struct trad_frame_saved_reg *saved_regs; + + /* Set BASE_P to true if this frame cache is properly initialized. + Otherwise set to false because some registers or memory cannot + collected. */ + int base_p; + /* Cache PC for building unavailable frame. */ + CORE_ADDR pc; }; static struct rs6000_frame_cache * @@ -3202,27 +3268,39 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache) enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct rs6000_framedata fdata; int wordsize = tdep->wordsize; - CORE_ADDR func, pc; + CORE_ADDR func = 0, pc = 0; if ((*this_cache) != NULL) return (struct rs6000_frame_cache *) (*this_cache); cache = FRAME_OBSTACK_ZALLOC (struct rs6000_frame_cache); (*this_cache) = cache; + cache->pc = 0; cache->saved_regs = trad_frame_alloc_saved_regs (this_frame); - func = get_frame_func (this_frame); - pc = get_frame_pc (this_frame); - skip_prologue (gdbarch, func, pc, &fdata); - - /* Figure out the parent's stack pointer. */ - - /* NOTE: cagney/2002-04-14: The ->frame points to the inner-most - address of the current frame. Things might be easier if the - ->frame pointed to the outer-most address of the frame. In - the mean time, the address of the prev frame is used as the - base address of this frame. */ - cache->base = get_frame_register_unsigned - (this_frame, gdbarch_sp_regnum (gdbarch)); + TRY + { + func = get_frame_func (this_frame); + cache->pc = func; + pc = get_frame_pc (this_frame); + skip_prologue (gdbarch, func, pc, &fdata); + + /* Figure out the parent's stack pointer. */ + + /* NOTE: cagney/2002-04-14: The ->frame points to the inner-most + address of the current frame. Things might be easier if the + ->frame pointed to the outer-most address of the frame. In + the mean time, the address of the prev frame is used as the + base address of this frame. */ + cache->base = get_frame_register_unsigned + (this_frame, gdbarch_sp_regnum (gdbarch)); + } + CATCH (ex, RETURN_MASK_ERROR) + { + if (ex.error != NOT_AVAILABLE_ERROR) + throw_exception (ex); + return (struct rs6000_frame_cache *) (*this_cache); + } + END_CATCH /* If the function appears to be frameless, check a couple of likely indicators that we have simply failed to find the frame setup. @@ -3258,10 +3336,10 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache) if (!fdata.frameless) { /* Frameless really means stackless. */ - LONGEST backchain; + ULONGEST backchain; - if (safe_read_memory_integer (cache->base, wordsize, - byte_order, &backchain)) + if (safe_read_memory_unsigned_integer (cache->base, wordsize, + byte_order, &backchain)) cache->base = (CORE_ADDR) backchain; } @@ -3371,6 +3449,7 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache) cache->initial_sp = get_frame_register_unsigned (this_frame, fdata.alloca_reg); + cache->base_p = 1; return cache; } @@ -3380,6 +3459,13 @@ rs6000_frame_this_id (struct frame_info *this_frame, void **this_cache, { struct rs6000_frame_cache *info = rs6000_frame_cache (this_frame, this_cache); + + if (!info->base_p) + { + (*this_id) = frame_id_build_unavailable_stack (info->pc); + return; + } + /* This marks the outermost frame. */ if (info->base == 0) return; @@ -5897,8 +5983,12 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_pseudo_register_read (gdbarch, rs6000_pseudo_register_read); set_gdbarch_pseudo_register_write (gdbarch, rs6000_pseudo_register_write); + set_gdbarch_ax_pseudo_register_collect (gdbarch, + rs6000_ax_pseudo_register_collect); } + set_gdbarch_gen_return_address (gdbarch, rs6000_gen_return_address); + set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1); /* Select instruction printer. */