Index: gdb/rs6000-tdep.c |
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c |
index 1797cc524b5debf751c5c4137e6de925e5757501..477e29e8f3bb089e894996601b0ceec2cb834660 100644 |
--- a/gdb/rs6000-tdep.c |
+++ b/gdb/rs6000-tdep.c |
@@ -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-2013 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 |
@@ -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 */ |