Add end_psymtab_common, have all debug info readers call it.
[deliverable/binutils-gdb.git] / gdb / rs6000-tdep.c
index 6b6fe93f3cf6c2f8d8736202b30d3e252c8b71b4..785f4519a5f7d362b501cb977551c51a5b0f333a 100644 (file)
@@ -934,10 +934,10 @@ rs6000_in_function_epilogue_frame_p (struct frame_info *curfrm,
   return 0;
 }
 
-/* Implementation of gdbarch_in_function_epilogue_p.  */
+/* Implement the stack_frame_destroyed_p gdbarch method.  */
 
 static int
-rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+rs6000_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   return rs6000_in_function_epilogue_frame_p (get_current_frame (),
                                              gdbarch, pc);
@@ -974,6 +974,61 @@ rs6000_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
 #define BXL_INSN 0x4c000000
 #define BP_INSN 0x7C000008
 
+/* Instruction masks used during single-stepping of atomic
+   sequences.  */
+#define LWARX_MASK 0xfc0007fe
+#define LWARX_INSTRUCTION 0x7c000028
+#define LDARX_INSTRUCTION 0x7c0000A8
+#define STWCX_MASK 0xfc0007ff
+#define STWCX_INSTRUCTION 0x7c00012d
+#define STDCX_INSTRUCTION 0x7c0001ad
+
+/* We can't displaced step atomic sequences.  Otherwise this is just
+   like simple_displaced_step_copy_insn.  */
+
+static struct displaced_step_closure *
+ppc_displaced_step_copy_insn (struct gdbarch *gdbarch,
+                             CORE_ADDR from, CORE_ADDR to,
+                             struct regcache *regs)
+{
+  size_t len = gdbarch_max_insn_length (gdbarch);
+  gdb_byte *buf = xmalloc (len);
+  struct cleanup *old_chain = make_cleanup (xfree, buf);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  int insn;
+
+  read_memory (from, buf, len);
+
+  insn = extract_signed_integer (buf, PPC_INSN_SIZE, byte_order);
+
+  /* Assume all atomic sequences start with a lwarx/ldarx instruction.  */
+  if ((insn & LWARX_MASK) == LWARX_INSTRUCTION
+      || (insn & LWARX_MASK) == LDARX_INSTRUCTION)
+    {
+      if (debug_displaced)
+       {
+         fprintf_unfiltered (gdb_stdlog,
+                             "displaced: can't displaced step "
+                             "atomic sequence at %s\n",
+                             paddress (gdbarch, from));
+       }
+      do_cleanups (old_chain);
+      return NULL;
+    }
+
+  write_memory (to, buf, len);
+
+  if (debug_displaced)
+    {
+      fprintf_unfiltered (gdb_stdlog, "displaced: copy %s->%s: ",
+                          paddress (gdbarch, from), paddress (gdbarch, to));
+      displaced_step_dump_bytes (gdb_stdlog, buf, len);
+    }
+
+  discard_cleanups (old_chain);
+  return (struct displaced_step_closure *) buf;
+}
+
 /* Fix up the state of registers and memory after having single-stepped
    a displaced instruction.  */
 static void
@@ -983,8 +1038,7 @@ ppc_displaced_step_fixup (struct gdbarch *gdbarch,
                          struct regcache *regs)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  /* Since we use simple_displaced_step_copy_insn, our closure is a
-     copy of the instruction.  */
+  /* Our closure is a copy of the instruction.  */
   ULONGEST insn  = extract_unsigned_integer ((gdb_byte *) closure,
                                              PPC_INSN_SIZE, byte_order);
   ULONGEST opcode = 0;
@@ -1077,14 +1131,6 @@ ppc_displaced_step_hw_singlestep (struct gdbarch *gdbarch,
   return 1;
 }
 
-/* Instruction masks used during single-stepping of atomic sequences.  */
-#define LWARX_MASK 0xfc0007fe
-#define LWARX_INSTRUCTION 0x7c000028
-#define LDARX_INSTRUCTION 0x7c0000A8
-#define STWCX_MASK 0xfc0007ff
-#define STWCX_INSTRUCTION 0x7c00012d
-#define STDCX_INSTRUCTION 0x7c0001ad
-
 /* Checks for an atomic sequence of instructions beginning with a LWARX/LDARX
    instruction and ending with a STWCX/STDCX instruction.  If such a sequence
    is found, attempt to step through it.  A breakpoint is placed at the end of 
@@ -2220,7 +2266,7 @@ static int
 rs6000_in_solib_return_trampoline (struct gdbarch *gdbarch,
                                   CORE_ADDR pc, const char *name)
 {
-  return name && !strncmp (name, "@FIX", 4);
+  return name && startswith (name, "@FIX");
 }
 
 /* Skip code that the user doesn't want to see when stepping:
@@ -3349,14 +3395,15 @@ static const struct frame_unwind rs6000_frame_unwind =
   default_frame_sniffer
 };
 
+/* Allocate and initialize a frame cache for an epilogue frame.
+   SP is restored and prev-PC is stored in LR.  */
+
 static struct rs6000_frame_cache *
 rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
 {
-  volatile struct gdb_exception ex;
   struct rs6000_frame_cache *cache;
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  CORE_ADDR sp;
 
   if (*this_cache)
     return *this_cache;
@@ -3365,7 +3412,7 @@ rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
   (*this_cache) = cache;
   cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
 
-  TRY_CATCH (ex, RETURN_MASK_ERROR)
+  TRY
     {
       /* At this point the stack looks as if we just entered the
         function, and the return address is stored in LR.  */
@@ -3380,12 +3427,19 @@ rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
       trad_frame_set_value (cache->saved_regs,
                            gdbarch_pc_regnum (gdbarch), lr);
     }
-  if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
-    throw_exception (ex);
+  CATCH (ex, RETURN_MASK_ERROR)
+    {
+      if (ex.error != NOT_AVAILABLE_ERROR)
+       throw_exception (ex);
+    }
+  END_CATCH
 
   return cache;
 }
 
+/* Implementation of frame_unwind.this_id, as defined in frame_unwind.h.
+   Return the frame ID of an epilogue frame.  */
+
 static void
 rs6000_epilogue_frame_this_id (struct frame_info *this_frame,
                               void **this_cache, struct frame_id *this_id)
@@ -3401,6 +3455,9 @@ rs6000_epilogue_frame_this_id (struct frame_info *this_frame,
     (*this_id) = frame_id_build (info->base, pc);
 }
 
+/* Implementation of frame_unwind.prev_register, as defined in frame_unwind.h.
+   Return the register value of REGNUM in previous frame.  */
+
 static struct value *
 rs6000_epilogue_frame_prev_register (struct frame_info *this_frame,
                                     void **this_cache, int regnum)
@@ -3410,6 +3467,9 @@ rs6000_epilogue_frame_prev_register (struct frame_info *this_frame,
   return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
 }
 
+/* Implementation of frame_unwind.sniffer, as defined in frame_unwind.h.
+   Check whether this an epilogue frame.  */
+
 static int
 rs6000_epilogue_frame_sniffer (const struct frame_unwind *self,
                               struct frame_info *this_frame,
@@ -3423,6 +3483,9 @@ rs6000_epilogue_frame_sniffer (const struct frame_unwind *self,
     return 0;
 }
 
+/* Frame unwinder for epilogue frame.  This is required for reverse step-over
+   a function without debug information.  */
+
 static const struct frame_unwind rs6000_epilogue_frame_unwind =
 {
   NORMAL_FRAME,
@@ -3669,7 +3732,9 @@ bfd_uses_spe_extensions (bfd *abfd)
 #define PPC_XT(insn)   ((PPC_TX (insn) << 5) | PPC_T (insn))
 #define PPC_XER_NB(xer)        (xer & 0x7f)
 
-/* Record Vector-Scalar Registers.  */
+/* Record Vector-Scalar Registers.
+   For VSR less than 32, it's represented by an FPR and an VSR-upper register.
+   Otherwise, it's just a VR register.  Record them accordingly.  */
 
 static int
 ppc_record_vsr (struct regcache *regcache, struct gdbarch_tdep *tdep, int vsr)
@@ -3694,11 +3759,12 @@ ppc_record_vsr (struct regcache *regcache, struct gdbarch_tdep *tdep, int vsr)
   return 0;
 }
 
-/* Parse instructions of primary opcode-4.  */
+/* Parse and record instructions primary opcode-4 at ADDR.
+   Return 0 if successful.  */
 
 static int
 ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
-                          CORE_ADDR addr, uint32_t insn)
+                       CORE_ADDR addr, uint32_t insn)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int ext = PPC_FIELD (insn, 21, 11);
@@ -3957,12 +4023,13 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
       return 0;
     }
 
-  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
-                     "%08x at %08lx, 4-%d.\n", insn, addr, ext);
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
+                     "at %s, 4-%d.\n", insn, paddress (gdbarch, addr), ext);
   return -1;
 }
 
-/* Parse instructions of primary opcode-19.  */
+/* Parse and record instructions of primary opcode-19 at ADDR.
+   Return 0 if successful.  */
 
 static int
 ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
@@ -4000,12 +4067,13 @@ ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
       return 0;
     }
 
-  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
-                     "%08x at %08lx, 19-%d.\n", insn, addr, ext);
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
+                     "at %s, 19-%d.\n", insn, paddress (gdbarch, addr), ext);
   return -1;
 }
 
-/* Parse instructions of primary opcode-31.  */
+/* Parse and record instructions of primary opcode-31 at ADDR.
+   Return 0 if successful.  */
 
 static int
 ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
@@ -4458,7 +4526,8 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 878:          /* Transaction Abort Doubleword Conditional Immediate */
     case 910:          /* Transaction Abort */
       fprintf_unfiltered (gdb_stdlog, "Cannot record Transaction instructions. "
-                         "%08x at %08lx, 31-%d.\n", insn, addr, ext);
+                         "%08x at %s, 31-%d.\n",
+                         insn, paddress (gdbarch, addr), ext);
       return -1;
 
     case 1014:         /* Data Cache Block set to Zero */
@@ -4477,12 +4546,13 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     }
 
 UNKNOWN_OP:
-  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
-                     "%08x at %08lx, 31-%d.\n", insn, addr, ext);
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
+                     "at %s, 31-%d.\n", insn, paddress (gdbarch, addr), ext);
   return -1;
 }
 
-/* Parse instructions of primary opcode-59.  */
+/* Parse and record instructions of primary opcode-59 at ADDR.
+   Return 0 if successful.  */
 
 static int
 ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
@@ -4569,12 +4639,13 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
       return 0;
     }
 
-  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
-                     "%08x at %08lx, 59-%d.\n", insn, addr, ext);
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
+                     "at %s, 59-%d.\n", insn, paddress (gdbarch, addr), ext);
   return -1;
 }
 
-/* Parse instructions of primary opcode-60.  */
+/* Parse and record instructions of primary opcode-60 at ADDR.
+   Return 0 if successful.  */
 
 static int
 ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
@@ -4582,7 +4653,6 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int ext = PPC_EXTOP (insn);
-  int tmp;
 
   switch (ext >> 2)
     {
@@ -4852,12 +4922,13 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
       return 0;
     }
 
-  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
-                     "%08x at %08lx, 60-%d.\n", insn, addr, ext);
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
+                     "at %s, 60-%d.\n", insn, paddress (gdbarch, addr), ext);
   return -1;
 }
 
-/* Parse instructions of primary opcode-63.  */
+/* Parse and record instructions of primary opcode-63 at ADDR.
+   Return 0 if successful.  */
 
 static int
 ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
@@ -5018,8 +5089,8 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
 
     }
 
-  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
-                     "%08x at %08lx, 59-%d.\n", insn, addr, ext);
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
+                     "at %s, 59-%d.\n", insn, paddress (gdbarch, addr), ext);
   return -1;
 }
 
@@ -5298,8 +5369,8 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 
     default:
 UNKNOWN_OP:
-      fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
-                         "%08x at %08lx, %d.\n", insn, addr, op6);
+      fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
+                         "at %s, %d.\n", insn, paddress (gdbarch, addr), op6);
       return -1;
     }
 
@@ -5865,7 +5936,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     set_gdbarch_push_dummy_call (gdbarch, ppc64_sysv_abi_push_dummy_call);
 
   set_gdbarch_skip_prologue (gdbarch, rs6000_skip_prologue);
-  set_gdbarch_in_function_epilogue_p (gdbarch, rs6000_in_function_epilogue_p);
+  set_gdbarch_stack_frame_destroyed_p (gdbarch, rs6000_stack_frame_destroyed_p);
   set_gdbarch_skip_main_prologue (gdbarch, rs6000_skip_main_prologue);
 
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
@@ -5898,7 +5969,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Setup displaced stepping.  */
   set_gdbarch_displaced_step_copy_insn (gdbarch,
-                                       simple_displaced_step_copy_insn);
+                                       ppc_displaced_step_copy_insn);
   set_gdbarch_displaced_step_hw_singlestep (gdbarch,
                                            ppc_displaced_step_hw_singlestep);
   set_gdbarch_displaced_step_fixup (gdbarch, ppc_displaced_step_fixup);
@@ -6027,7 +6098,7 @@ powerpc_set_vector_abi (char *args, int from_tty,
                        struct cmd_list_element *c)
 {
   struct gdbarch_info info;
-  enum powerpc_vector_abi vector_abi;
+  int vector_abi;
 
   for (vector_abi = POWERPC_VEC_AUTO;
        vector_abi != POWERPC_VEC_LAST;
@@ -6035,7 +6106,7 @@ powerpc_set_vector_abi (char *args, int from_tty,
     if (strcmp (powerpc_vector_abi_string,
                powerpc_vector_strings[vector_abi]) == 0)
       {
-       powerpc_vector_abi_global = vector_abi;
+       powerpc_vector_abi_global = (enum powerpc_vector_abi) vector_abi;
        break;
       }
 
This page took 0.029564 seconds and 4 git commands to generate.