projects
/
deliverable
/
binutils-gdb.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
* section.c (_bfd_std_section): Rename from std_section.
[deliverable/binutils-gdb.git]
/
gdb
/
rs6000-tdep.c
diff --git
a/gdb/rs6000-tdep.c
b/gdb/rs6000-tdep.c
index 6ac3e8dc9f38d23434f09d882d2531021ab4989d..a15f757072d18883ca6263b6dedab436272a6956 100644
(file)
--- a/
gdb/rs6000-tdep.c
+++ b/
gdb/rs6000-tdep.c
@@
-1,8
+1,6
@@
/* Target-dependent code for GDB, the GNU debugger.
/* Target-dependent code for GDB, the GNU debugger.
- Copyright (C) 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
- 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1986-2013 Free Software Foundation, Inc.
This file is part of GDB.
This file is part of GDB.
@@
-53,6
+51,7
@@
#include "solib-svr4.h"
#include "ppc-tdep.h"
#include "solib-svr4.h"
#include "ppc-tdep.h"
+#include "ppc-ravenscar-thread.h"
#include "gdb_assert.h"
#include "dis-asm.h"
#include "gdb_assert.h"
#include "dis-asm.h"
@@
-109,7
+108,7
@@
static struct cmd_list_element *showpowerpccmdlist = NULL;
static enum auto_boolean powerpc_soft_float_global = AUTO_BOOLEAN_AUTO;
/* The vector ABI to use. Keep this in sync with powerpc_vector_abi. */
static enum auto_boolean powerpc_soft_float_global = AUTO_BOOLEAN_AUTO;
/* The vector ABI to use. Keep this in sync with powerpc_vector_abi. */
-static const char *powerpc_vector_strings[] =
+static const char *
const
powerpc_vector_strings[] =
{
"auto",
"generic",
{
"auto",
"generic",
@@
-1116,8
+1115,8
@@
ppc_deal_with_atomic_sequence (struct frame_info *frame)
its destination address. */
if ((insn & BRANCH_MASK) == BC_INSN)
{
its destination address. */
if ((insn & BRANCH_MASK) == BC_INSN)
{
- int immediate = ((insn &
~3) << 16) >> 16
;
- int absolute =
((insn >> 1) & 1)
;
+ int immediate = ((insn &
0xfffc) ^ 0x8000) - 0x8000
;
+ int absolute =
insn & 2
;
if (bc_insn_count >= 1)
return 0; /* More than one conditional branch found, fallback
if (bc_insn_count >= 1)
return 0; /* More than one conditional branch found, fallback
@@
-1126,7
+1125,7
@@
ppc_deal_with_atomic_sequence (struct frame_info *frame)
if (absolute)
breaks[1] = immediate;
else
if (absolute)
breaks[1] = immediate;
else
- breaks[1] =
p
c + immediate;
+ breaks[1] =
lo
c + immediate;
bc_insn_count++;
last_breakpoint++;
bc_insn_count++;
last_breakpoint++;
@@
-1150,11
+1149,10
@@
ppc_deal_with_atomic_sequence (struct frame_info *frame)
breaks[0] = loc;
/* Check for duplicated breakpoints. Check also for a breakpoint
breaks[0] = loc;
/* Check for duplicated breakpoints. Check also for a breakpoint
- placed (branch instruction's destination) at the stwcx/stdcx
- instruction, this resets the reservation and take us back to the
- lwarx/ldarx instruction at the beginning of the atomic sequence. */
- if (last_breakpoint && ((breaks[1] == breaks[0])
- || (breaks[1] == closing_insn)))
+ placed (branch instruction's destination) anywhere in sequence. */
+ if (last_breakpoint
+ && (breaks[1] == breaks[0]
+ || (breaks[1] >= pc && breaks[1] <= closing_insn)))
last_breakpoint = 0;
/* Effectively inserts the breakpoints. */
last_breakpoint = 0;
/* Effectively inserts the breakpoints. */
@@
-1824,6
+1822,15
@@
skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
/* Set up frame pointer */
}
/* Set up frame pointer */
}
+ else if (op == 0x603d0000) /* oril r29, r1, 0x0 */
+ {
+ fdata->frameless = 0;
+ framep = 1;
+ fdata->alloca_reg = (tdep->ppc_gp0_regnum + 29);
+ continue;
+
+ /* Another way to set up the frame pointer. */
+ }
else if (op == 0x603f0000 /* oril r31, r1, 0x0 */
|| op == 0x7c3f0b78)
{ /* mr r31, r1 */
else if (op == 0x603f0000 /* oril r31, r1, 0x0 */
|| op == 0x7c3f0b78)
{ /* mr r31, r1 */
@@
-2191,7
+2198,7
@@
rs6000_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
static int
rs6000_in_solib_return_trampoline (struct gdbarch *gdbarch,
static int
rs6000_in_solib_return_trampoline (struct gdbarch *gdbarch,
- CORE_ADDR pc, char *name)
+ CORE_ADDR pc, c
onst c
har *name)
{
return name && !strncmp (name, "@FIX", 4);
}
{
return name && !strncmp (name, "@FIX", 4);
}
@@
-2504,20
+2511,27
@@
rs6000_convert_register_p (struct gdbarch *gdbarch, int regnum,
!= TYPE_LENGTH (builtin_type (gdbarch)->builtin_double));
}
!= TYPE_LENGTH (builtin_type (gdbarch)->builtin_double));
}
-static
void
+static
int
rs6000_register_to_value (struct frame_info *frame,
int regnum,
struct type *type,
rs6000_register_to_value (struct frame_info *frame,
int regnum,
struct type *type,
- gdb_byte *to)
+ gdb_byte *to,
+ int *optimizedp, int *unavailablep)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
gdb_byte from[MAX_REGISTER_SIZE];
gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
{
struct gdbarch *gdbarch = get_frame_arch (frame);
gdb_byte from[MAX_REGISTER_SIZE];
gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
- get_frame_register (frame, regnum, from);
+ if (!get_frame_register_bytes (frame, regnum, 0,
+ register_size (gdbarch, regnum),
+ from, optimizedp, unavailablep))
+ return 0;
+
convert_typed_floating (from, builtin_type (gdbarch)->builtin_double,
to, type);
convert_typed_floating (from, builtin_type (gdbarch)->builtin_double,
to, type);
+ *optimizedp = *unavailablep = 0;
+ return 1;
}
static void
}
static void
@@
-2536,6
+2550,11
@@
rs6000_value_to_register (struct frame_info *frame,
put_frame_register (frame, regnum, to);
}
put_frame_register (frame, regnum, to);
}
+ /* The type of a function that moves the value of REG between CACHE
+ or BUF --- in either direction. */
+typedef enum register_status (*move_ev_register_func) (struct regcache *,
+ int, void *);
+
/* Move SPE vector register values between a 64-bit buffer and the two
32-bit raw register halves in a regcache. This function handles
both splitting a 64-bit value into two 32-bit halves, and joining
/* Move SPE vector register values between a 64-bit buffer and the two
32-bit raw register halves in a regcache. This function handles
both splitting a 64-bit value into two 32-bit halves, and joining
@@
-2559,16
+2578,16
@@
rs6000_value_to_register (struct frame_info *frame,
MOVE, since this function can't tell at compile-time which of
REGCACHE or BUFFER is acting as the source of the data. If C had
co-variant type qualifiers, ... */
MOVE, since this function can't tell at compile-time which of
REGCACHE or BUFFER is acting as the source of the data. If C had
co-variant type qualifiers, ... */
-static void
-e500_move_ev_register (void (*move) (struct regcache *regcache,
- int regnum, gdb_byte *buf),
- struct regcache *regcache, int ev_reg,
- gdb_byte *buffer)
+
+static enum register_status
+e500_move_ev_register (move_ev_register_func move,
+ struct regcache *regcache, int ev_reg, void *buffer)
{
struct gdbarch *arch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
int reg_index;
gdb_byte *byte_buffer = buffer;
{
struct gdbarch *arch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
int reg_index;
gdb_byte *byte_buffer = buffer;
+ enum register_status status;
gdb_assert (IS_SPE_PSEUDOREG (tdep, ev_reg));
gdb_assert (IS_SPE_PSEUDOREG (tdep, ev_reg));
@@
-2576,55
+2595,80
@@
e500_move_ev_register (void (*move) (struct regcache *regcache,
if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG)
{
if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG)
{
- move (regcache, tdep->ppc_ev0_upper_regnum + reg_index, byte_buffer);
- move (regcache, tdep->ppc_gp0_regnum + reg_index, byte_buffer + 4);
+ status = move (regcache, tdep->ppc_ev0_upper_regnum + reg_index,
+ byte_buffer);
+ if (status == REG_VALID)
+ status = move (regcache, tdep->ppc_gp0_regnum + reg_index,
+ byte_buffer + 4);
}
else
{
}
else
{
- move (regcache, tdep->ppc_gp0_regnum + reg_index, byte_buffer);
- move (regcache, tdep->ppc_ev0_upper_regnum + reg_index, byte_buffer + 4);
+ status = move (regcache, tdep->ppc_gp0_regnum + reg_index, byte_buffer);
+ if (status == REG_VALID)
+ status = move (regcache, tdep->ppc_ev0_upper_regnum + reg_index,
+ byte_buffer + 4);
}
}
+
+ return status;
}
}
-static void
+static enum register_status
+do_regcache_raw_read (struct regcache *regcache, int regnum, void *buffer)
+{
+ return regcache_raw_read (regcache, regnum, buffer);
+}
+
+static enum register_status
+do_regcache_raw_write (struct regcache *regcache, int regnum, void *buffer)
+{
+ regcache_raw_write (regcache, regnum, buffer);
+
+ return REG_VALID;
+}
+
+static enum register_status
e500_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, gdb_byte *buffer)
{
e500_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, gdb_byte *buffer)
{
-
e500_move_ev_register (
regcache_raw_read, regcache, reg_nr, buffer);
+
return e500_move_ev_register (do_
regcache_raw_read, regcache, reg_nr, buffer);
}
static void
e500_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, const gdb_byte *buffer)
{
}
static void
e500_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, const gdb_byte *buffer)
{
- e500_move_ev_register ((void (*) (struct regcache *, int, gdb_byte *))
- regcache_raw_write,
- regcache, reg_nr, (gdb_byte *) buffer);
+ e500_move_ev_register (do_regcache_raw_write, regcache,
+ reg_nr, (void *) buffer);
}
/* Read method for DFP pseudo-registers. */
}
/* Read method for DFP pseudo-registers. */
-static
void
+static
enum register_status
dfp_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, gdb_byte *buffer)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int reg_index = reg_nr - tdep->ppc_dl0_regnum;
dfp_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, gdb_byte *buffer)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int reg_index = reg_nr - tdep->ppc_dl0_regnum;
+ enum register_status status;
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
/* Read two FP registers to form a whole dl register. */
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
/* Read two FP registers to form a whole dl register. */
- regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
- 2 * reg_index, buffer);
- regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
- 2 * reg_index + 1, buffer + 8);
+ status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+ 2 * reg_index, buffer);
+ if (status == REG_VALID)
+ status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+ 2 * reg_index + 1, buffer + 8);
}
else
{
}
else
{
- regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
- 2 * reg_index + 1, buffer + 8);
- regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
- 2 * reg_index, buffer);
+ status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+ 2 * reg_index + 1, buffer + 8);
+ if (status == REG_VALID)
+ status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+ 2 * reg_index, buffer);
}
}
+
+ return status;
}
/* Write method for DFP pseudo-registers. */
}
/* Write method for DFP pseudo-registers. */
@@
-2654,33
+2698,38
@@
dfp_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
}
/* Read method for POWER7 VSX pseudo-registers. */
}
/* Read method for POWER7 VSX pseudo-registers. */
-static
void
+static
enum register_status
vsx_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, gdb_byte *buffer)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int reg_index = reg_nr - tdep->ppc_vsr0_regnum;
vsx_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, gdb_byte *buffer)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int reg_index = reg_nr - tdep->ppc_vsr0_regnum;
+ enum register_status status;
/* Read the portion that overlaps the VMX registers. */
if (reg_index > 31)
/* Read the portion that overlaps the VMX registers. */
if (reg_index > 31)
- regcache_raw_read (regcache, tdep->ppc_vr0_regnum +
- reg_index - 32, buffer);
+
status =
regcache_raw_read (regcache, tdep->ppc_vr0_regnum +
+
reg_index - 32, buffer);
else
/* Read the portion that overlaps the FPR registers. */
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
else
/* Read the portion that overlaps the FPR registers. */
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
- regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
- reg_index, buffer);
- regcache_raw_read (regcache, tdep->ppc_vsr0_upper_regnum +
- reg_index, buffer + 8);
+ status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+ reg_index, buffer);
+ if (status == REG_VALID)
+ status = regcache_raw_read (regcache, tdep->ppc_vsr0_upper_regnum +
+ reg_index, buffer + 8);
}
else
{
}
else
{
- regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
- reg_index, buffer + 8);
- regcache_raw_read (regcache, tdep->ppc_vsr0_upper_regnum +
- reg_index, buffer);
+ status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+ reg_index, buffer + 8);
+ if (status == REG_VALID)
+ status = regcache_raw_read (regcache, tdep->ppc_vsr0_upper_regnum +
+ reg_index, buffer);
}
}
+
+ return status;
}
/* Write method for POWER7 VSX pseudo-registers. */
}
/* Write method for POWER7 VSX pseudo-registers. */
@@
-2714,7
+2763,7
@@
vsx_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
}
/* Read method for POWER7 Extended FP pseudo-registers. */
}
/* Read method for POWER7 Extended FP pseudo-registers. */
-static
void
+static
enum register_status
efpr_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, gdb_byte *buffer)
{
efpr_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, gdb_byte *buffer)
{
@@
-2722,8
+2771,8
@@
efpr_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_index = reg_nr - tdep->ppc_efpr0_regnum;
/* Read the portion that overlaps the VMX register. */
int reg_index = reg_nr - tdep->ppc_efpr0_regnum;
/* Read the portion that overlaps the VMX register. */
- regcache_raw_read_part (regcache, tdep->ppc_vr0_regnum + reg_index, 0,
- register_size (gdbarch, reg_nr), buffer);
+ re
turn re
gcache_raw_read_part (regcache, tdep->ppc_vr0_regnum + reg_index, 0,
+
register_size (gdbarch, reg_nr), buffer);
}
/* Write method for POWER7 Extended FP pseudo-registers. */
}
/* Write method for POWER7 Extended FP pseudo-registers. */
@@
-2739,7
+2788,7
@@
efpr_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
register_size (gdbarch, reg_nr), buffer);
}
register_size (gdbarch, reg_nr), buffer);
}
-static
void
+static
enum register_status
rs6000_pseudo_register_read (struct gdbarch *gdbarch,
struct regcache *regcache,
int reg_nr, gdb_byte *buffer)
rs6000_pseudo_register_read (struct gdbarch *gdbarch,
struct regcache *regcache,
int reg_nr, gdb_byte *buffer)
@@
-2750,13
+2799,13
@@
rs6000_pseudo_register_read (struct gdbarch *gdbarch,
gdb_assert (regcache_arch == gdbarch);
if (IS_SPE_PSEUDOREG (tdep, reg_nr))
gdb_assert (regcache_arch == gdbarch);
if (IS_SPE_PSEUDOREG (tdep, reg_nr))
- e500_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+
return
e500_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
else if (IS_DFP_PSEUDOREG (tdep, reg_nr))
else if (IS_DFP_PSEUDOREG (tdep, reg_nr))
- dfp_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+
return
dfp_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
else if (IS_VSX_PSEUDOREG (tdep, reg_nr))
else if (IS_VSX_PSEUDOREG (tdep, reg_nr))
- vsx_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+
return
vsx_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
else if (IS_EFP_PSEUDOREG (tdep, reg_nr))
else if (IS_EFP_PSEUDOREG (tdep, reg_nr))
- efpr_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+
return
efpr_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
else
internal_error (__FILE__, __LINE__,
_("rs6000_pseudo_register_read: "
else
internal_error (__FILE__, __LINE__,
_("rs6000_pseudo_register_read: "
@@
-3035,21
+3084,6
@@
find_variant_by_arch (enum bfd_architecture arch, unsigned long mach)
static int
gdb_print_insn_powerpc (bfd_vma memaddr, disassemble_info *info)
{
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
if (info->endian == BFD_ENDIAN_BIG)
return print_insn_big_powerpc (memaddr, info);
else
@@
-3277,6
+3311,7
@@
rs6000_frame_prev_register (struct frame_info *this_frame,
static const struct frame_unwind rs6000_frame_unwind =
{
NORMAL_FRAME,
static const struct frame_unwind rs6000_frame_unwind =
{
NORMAL_FRAME,
+ default_frame_unwind_stop_reason,
rs6000_frame_this_id,
rs6000_frame_prev_register,
NULL,
rs6000_frame_this_id,
rs6000_frame_prev_register,
NULL,
@@
-3502,7
+3537,6
@@
rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
enum bfd_architecture arch;
unsigned long mach;
bfd abfd;
enum bfd_architecture arch;
unsigned long mach;
bfd abfd;
- asection *sect;
enum auto_boolean soft_float_flag = powerpc_soft_float_global;
int soft_float;
enum powerpc_vector_abi vector_abi = powerpc_vector_abi_global;
enum auto_boolean soft_float_flag = powerpc_soft_float_global;
int soft_float;
enum powerpc_vector_abi vector_abi = powerpc_vector_abi_global;
@@
-4119,6
+4153,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);
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;
}
return gdbarch;
}
This page took
0.02933 seconds
and
4
git commands to generate.