Add "volatile" keyword to "struct gdb_exception" declaration
[deliverable/binutils-gdb.git] / gdb / rs6000-tdep.c
index 1797cc524b5debf751c5c4137e6de925e5757501..d7416e5a2dcaecb6f0f4cc761ecd53820301c624 100644 (file)
@@ -1,7 +1,6 @@
 /* Target-dependent code for GDB, the GNU debugger.
 
-   Copyright (C) 1986-1987, 1989, 1991-2012 Free Software Foundation,
-   Inc.
+   Copyright (C) 1986-2014 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -52,6 +51,7 @@
 
 #include "solib-svr4.h"
 #include "ppc-tdep.h"
+#include "ppc-ravenscar-thread.h"
 
 #include "gdb_assert.h"
 #include "dis-asm.h"
@@ -943,7 +943,7 @@ rs6000_fetch_pointer_argument (struct frame_info *frame, int argi,
 
 /* Sequence of bytes for breakpoint instruction.  */
 
-const static unsigned char *
+static const unsigned char *
 rs6000_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
                           int *bp_size)
 {
@@ -1616,7 +1616,19 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
          continue;
 
        }
-      else if ((op & 0xffff0000) == 0x60000000)
+      else if ((op & 0xffff0000) == 0x3c4c0000
+              || (op & 0xffff0000) == 0x3c400000
+              || (op & 0xffff0000) == 0x38420000)
+       {
+         /* .  0:      addis 2,12,.TOC.-0b@ha
+            .          addi 2,2,.TOC.-0b@l
+            or
+            .          lis 2,.TOC.@ha
+            .          addi 2,2,.TOC.@l
+            used by ELFv2 global entry points to set up r2.  */
+         continue;
+       }
+      else if (op == 0x60000000)
         {
          /* nop */
          /* Allow nops in the prologue, but do not consider them to
@@ -1627,8 +1639,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
 
        }
       else if ((op & 0xffff0000) == 0x3c000000)
-       {                       /* addis 0,0,NUM, used
-                                  for >= 32k frames */
+       {                       /* addis 0,0,NUM, used for >= 32k frames */
          fdata->offset = (op & 0x0000ffff) << 16;
          fdata->frameless = 0;
           r0_contains_arg = 0;
@@ -1636,8 +1647,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
 
        }
       else if ((op & 0xffff0000) == 0x60000000)
-       {                       /* ori 0,0,NUM, 2nd ha
-                                  lf of >= 32k frames */
+       {                       /* ori 0,0,NUM, 2nd half of >= 32k frames */
          fdata->offset |= (op & 0x0000ffff);
          fdata->frameless = 0;
           r0_contains_arg = 0;
@@ -2152,15 +2162,15 @@ rs6000_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
     {
       CORE_ADDR displ = op & BL_DISPLACEMENT_MASK;
       CORE_ADDR call_dest = pc + 4 + displ;
-      struct minimal_symbol *s = lookup_minimal_symbol_by_pc (call_dest);
+      struct bound_minimal_symbol s = lookup_minimal_symbol_by_pc (call_dest);
 
       /* We check for ___eabi (three leading underscores) in addition
          to __eabi in case the GCC option "-fleading-underscore" was
         used to compile the program.  */
-      if (s != NULL
-          && SYMBOL_LINKAGE_NAME (s) != NULL
-         && (strcmp (SYMBOL_LINKAGE_NAME (s), "__eabi") == 0
-             || strcmp (SYMBOL_LINKAGE_NAME (s), "___eabi") == 0))
+      if (s.minsym != NULL
+          && SYMBOL_LINKAGE_NAME (s.minsym) != NULL
+         && (strcmp (SYMBOL_LINKAGE_NAME (s.minsym), "__eabi") == 0
+             || strcmp (SYMBOL_LINKAGE_NAME (s.minsym), "___eabi") == 0))
        pc += 4;
     }
   return pc;
@@ -2226,7 +2236,7 @@ rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
   unsigned int ii, op;
   int rel;
   CORE_ADDR solib_target_pc;
-  struct minimal_symbol *msymbol;
+  struct bound_minimal_symbol msymbol;
 
   static unsigned trampoline_code[] =
   {
@@ -2242,9 +2252,9 @@ rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
 
   /* Check for bigtoc fixup code.  */
   msymbol = lookup_minimal_symbol_by_pc (pc);
-  if (msymbol 
+  if (msymbol.minsym
       && rs6000_in_solib_return_trampoline (gdbarch, pc,
-                                           SYMBOL_LINKAGE_NAME (msymbol)))
+                                           SYMBOL_LINKAGE_NAME (msymbol.minsym)))
     {
       /* Double-check that the third instruction from PC is relative "b".  */
       op = read_memory_integer (pc + 8, 4, byte_order);
@@ -2854,7 +2864,7 @@ rs6000_stab_reg_to_regnum (struct gdbarch *gdbarch, int num)
   else if (77 <= num && num <= 108)
     return tdep->ppc_vr0_regnum + (num - 77);
   else if (1200 <= num && num < 1200 + 32)
-    return tdep->ppc_ev0_regnum + (num - 1200);
+    return tdep->ppc_ev0_upper_regnum + (num - 1200);
   else
     switch (num)
       {
@@ -2896,7 +2906,7 @@ rs6000_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int num)
   else if (1124 <= num && num < 1124 + 32)
     return tdep->ppc_vr0_regnum + (num - 1124);
   else if (1200 <= num && num < 1200 + 32)
-    return tdep->ppc_ev0_regnum + (num - 1200);
+    return tdep->ppc_ev0_upper_regnum + (num - 1200);
   else
     switch (num)
       {
@@ -3084,21 +3094,6 @@ find_variant_by_arch (enum bfd_architecture arch, unsigned long mach)
 static int
 gdb_print_insn_powerpc (bfd_vma memaddr, disassemble_info *info)
 {
-  if (!info->disassembler_options)
-    {
-      /* When debugging E500 binaries and disassembling code containing
-        E500-specific (SPE) instructions, one sometimes sees AltiVec
-        instructions instead.  The opcode spaces for SPE instructions
-        and AltiVec instructions overlap, and specifiying the "any" cpu
-        looks for AltiVec instructions first.  If we know we're
-        debugging an E500 binary, however, we can specify the "e500x2"
-        cpu and get much more sane disassembly output.  */
-      if (info->mach == bfd_mach_ppc_e500)
-       info->disassembler_options = "e500x2";
-      else
-       info->disassembler_options = "any";
-    }
-
   if (info->endian == BFD_ENDIAN_BIG)
     return print_insn_big_powerpc (memaddr, info);
   else
@@ -3959,7 +3954,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        - "set arch"            trust blindly
        - GDB startup           useless but harmless */
 
-  tdep = XCALLOC (1, struct gdbarch_tdep);
+  tdep = XCNEW (struct gdbarch_tdep);
   tdep->wordsize = wordsize;
   tdep->soft_float = soft_float;
   tdep->vector_abi = vector_abi;
@@ -4168,6 +4163,12 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   gdb_assert (gdbarch_num_regs (gdbarch)
              + gdbarch_num_pseudo_regs (gdbarch) == cur_reg);
 
+  /* Register the ravenscar_arch_ops.  */
+  if (mach == bfd_mach_ppc_e500)
+    register_e500_ravenscar_ops (gdbarch);
+  else
+    register_ppc_ravenscar_ops (gdbarch);
+
   return gdbarch;
 }
 
@@ -4247,6 +4248,75 @@ show_powerpc_exact_watchpoints (struct ui_file *file, int from_tty,
   fprintf_filtered (file, _("Use of exact watchpoints is %s.\n"), value);
 }
 
+/* Read a PPC instruction from memory.  */
+
+static unsigned int
+read_insn (struct frame_info *frame, CORE_ADDR pc)
+{
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
+  return read_memory_unsigned_integer (pc, 4, byte_order);
+}
+
+/* Return non-zero if the instructions at PC match the series
+   described in PATTERN, or zero otherwise.  PATTERN is an array of
+   'struct ppc_insn_pattern' objects, terminated by an entry whose
+   mask is zero.
+
+   When the match is successful, fill INSN[i] with what PATTERN[i]
+   matched.  If PATTERN[i] is optional, and the instruction wasn't
+   present, set INSN[i] to 0 (which is not a valid PPC instruction).
+   INSN should have as many elements as PATTERN.  Note that, if
+   PATTERN contains optional instructions which aren't present in
+   memory, then INSN will have holes, so INSN[i] isn't necessarily the
+   i'th instruction in memory.  */
+
+int
+ppc_insns_match_pattern (struct frame_info *frame, CORE_ADDR pc,
+                        struct ppc_insn_pattern *pattern,
+                        unsigned int *insns)
+{
+  int i;
+  unsigned int insn;
+
+  for (i = 0, insn = 0; pattern[i].mask; i++)
+    {
+      if (insn == 0)
+       insn = read_insn (frame, pc);
+      insns[i] = 0;
+      if ((insn & pattern[i].mask) == pattern[i].data)
+       {
+         insns[i] = insn;
+         pc += 4;
+         insn = 0;
+       }
+      else if (!pattern[i].optional)
+       return 0;
+    }
+
+  return 1;
+}
+
+/* Return the 'd' field of the d-form instruction INSN, properly
+   sign-extended.  */
+
+CORE_ADDR
+ppc_insn_d_field (unsigned int insn)
+{
+  return ((((CORE_ADDR) insn & 0xffff) ^ 0x8000) - 0x8000);
+}
+
+/* Return the 'ds' field of the ds-form instruction INSN, with the two
+   zero bits concatenated at the right, and properly
+   sign-extended.  */
+
+CORE_ADDR
+ppc_insn_ds_field (unsigned int insn)
+{
+  return ((((CORE_ADDR) insn & 0xfffc) ^ 0x8000) - 0x8000);
+}
+
 /* Initialization code.  */
 
 /* -Wmissing-prototypes */
This page took 0.026533 seconds and 4 git commands to generate.