/* 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
- Free Software Foundation, Inc.
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+ 2010 Free Software Foundation, Inc.
This file is part of GDB.
#include "features/rs6000/powerpc-vsx32.c"
#include "features/rs6000/powerpc-403.c"
#include "features/rs6000/powerpc-403gc.c"
+#include "features/rs6000/powerpc-405.c"
#include "features/rs6000/powerpc-505.c"
#include "features/rs6000/powerpc-601.c"
#include "features/rs6000/powerpc-602.c"
rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
bfd_byte insn_buf[PPC_INSN_SIZE];
CORE_ADDR scan_pc, func_start, func_end, epilogue_start, epilogue_end;
unsigned long insn;
{
if (!safe_frame_unwind_memory (curfrm, scan_pc, insn_buf, PPC_INSN_SIZE))
return 0;
- insn = extract_unsigned_integer (insn_buf, PPC_INSN_SIZE);
+ insn = extract_unsigned_integer (insn_buf, PPC_INSN_SIZE, byte_order);
if (insn == 0x4e800020)
break;
/* Assume a bctr is a tail call unless it points strictly within
{
if (!safe_frame_unwind_memory (curfrm, scan_pc, insn_buf, PPC_INSN_SIZE))
return 0;
- insn = extract_unsigned_integer (insn_buf, PPC_INSN_SIZE);
+ insn = extract_unsigned_integer (insn_buf, PPC_INSN_SIZE, byte_order);
if (insn_changes_sp_or_jumps (insn))
return 1;
}
CORE_ADDR from, CORE_ADDR to,
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. */
ULONGEST insn = extract_unsigned_integer ((gdb_byte *) closure,
- PPC_INSN_SIZE);
+ PPC_INSN_SIZE, byte_order);
ULONGEST opcode = 0;
/* Offset for non PC-relative instructions. */
LONGEST offset = PPC_INSN_SIZE;
if (debug_displaced)
fprintf_unfiltered (gdb_stdlog,
- "displaced: (ppc) fixup (0x%s, 0x%s)\n",
- paddr_nz (from), paddr_nz (to));
+ "displaced: (ppc) fixup (%s, %s)\n",
+ paddress (gdbarch, from), paddress (gdbarch, to));
/* Handle PC-relative branch instructions. */
if (debug_displaced)
fprintf_unfiltered
(gdb_stdlog,
- "displaced: (ppc) branch instruction: 0x%s\n"
- "displaced: (ppc) adjusted PC from 0x%s to 0x%s\n",
- paddr_nz (insn), paddr_nz (current_pc),
- paddr_nz (from + offset));
+ "displaced: (ppc) branch instruction: %s\n"
+ "displaced: (ppc) adjusted PC from %s to %s\n",
+ paddress (gdbarch, insn), paddress (gdbarch, current_pc),
+ paddress (gdbarch, from + offset));
regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch),
from + offset);
from + PPC_INSN_SIZE);
if (debug_displaced)
fprintf_unfiltered (gdb_stdlog,
- "displaced: (ppc) adjusted LR to 0x%s\n",
- paddr_nz (from + PPC_INSN_SIZE));
+ "displaced: (ppc) adjusted LR to %s\n",
+ paddress (gdbarch, from + PPC_INSN_SIZE));
}
}
from + offset);
}
+/* Always use hardware single-stepping to execute the
+ displaced instruction. */
+static int
+ppc_displaced_step_hw_singlestep (struct gdbarch *gdbarch,
+ struct displaced_step_closure *closure)
+{
+ return 1;
+}
+
/* Instruction masks used during single-stepping of atomic sequences. */
#define LWARX_MASK 0xfc0007fe
#define LWARX_INSTRUCTION 0x7c000028
int
ppc_deal_with_atomic_sequence (struct frame_info *frame)
{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ struct address_space *aspace = get_frame_address_space (frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR pc = get_frame_pc (frame);
CORE_ADDR breaks[2] = {-1, -1};
CORE_ADDR loc = pc;
CORE_ADDR closing_insn; /* Instruction that closes the atomic sequence. */
- int insn = read_memory_integer (loc, PPC_INSN_SIZE);
+ int insn = read_memory_integer (loc, PPC_INSN_SIZE, byte_order);
int insn_count;
int index;
int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */
for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count)
{
loc += PPC_INSN_SIZE;
- insn = read_memory_integer (loc, PPC_INSN_SIZE);
+ insn = read_memory_integer (loc, PPC_INSN_SIZE, byte_order);
/* Assume that there is at most one conditional branch in the atomic
sequence. If a conditional branch is found, put a breakpoint in
closing_insn = loc;
loc += PPC_INSN_SIZE;
- insn = read_memory_integer (loc, PPC_INSN_SIZE);
+ insn = read_memory_integer (loc, PPC_INSN_SIZE, byte_order);
/* Insert a breakpoint right after the end of the atomic sequence. */
breaks[0] = loc;
/* Effectively inserts the breakpoints. */
for (index = 0; index <= last_breakpoint; index++)
- insert_single_step_breakpoint (breaks[index]);
+ insert_single_step_breakpoint (gdbarch, aspace, breaks[index]);
return 1;
}
they can use to access PIC data using PC-relative offsets. */
static int
-bl_to_blrl_insn_p (CORE_ADDR pc, int insn)
+bl_to_blrl_insn_p (CORE_ADDR pc, int insn, enum bfd_endian byte_order)
{
CORE_ADDR dest;
int immediate;
else
dest = pc + immediate;
- dest_insn = read_memory_integer (dest, 4);
+ dest_insn = read_memory_integer (dest, 4, byte_order);
if ((dest_insn & 0xfc00ffff) == 0x4c000021) /* blrl */
return 1;
#define BL_DISPLACEMENT_MASK 0x03fffffc
static unsigned long
-rs6000_fetch_instruction (const CORE_ADDR pc)
+rs6000_fetch_instruction (struct gdbarch *gdbarch, const CORE_ADDR pc)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
gdb_byte buf[4];
unsigned long op;
/* Fetch the instruction and convert it to an integer. */
if (target_read_memory (pc, buf, 4))
return 0;
- op = extract_unsigned_integer (buf, 4);
+ op = extract_unsigned_integer (buf, 4, byte_order);
return op;
}
instruction immediately past this sequence. Otherwise, return START_PC. */
static CORE_ADDR
-rs6000_skip_stack_check (const CORE_ADDR start_pc)
+rs6000_skip_stack_check (struct gdbarch *gdbarch, const CORE_ADDR start_pc)
{
CORE_ADDR pc = start_pc;
- unsigned long op = rs6000_fetch_instruction (pc);
+ unsigned long op = rs6000_fetch_instruction (gdbarch, pc);
/* First possible sequence: A small number of probes.
stw 0, -<some immediate>(1)
while ((op & 0xffff0000) == 0x90010000)
{
pc = pc + 4;
- op = rs6000_fetch_instruction (pc);
+ op = rs6000_fetch_instruction (gdbarch, pc);
}
return pc;
}
/* lis 0,-<some immediate> */
pc = pc + 4;
- op = rs6000_fetch_instruction (pc);
+ op = rs6000_fetch_instruction (gdbarch, pc);
if ((op & 0xffff0000) != 0x3c000000)
break;
pc = pc + 4;
- op = rs6000_fetch_instruction (pc);
+ op = rs6000_fetch_instruction (gdbarch, pc);
/* [possibly ori 0,0,<some immediate>] */
if ((op & 0xffff0000) == 0x60000000)
{
pc = pc + 4;
- op = rs6000_fetch_instruction (pc);
+ op = rs6000_fetch_instruction (gdbarch, pc);
}
/* add 0,12,0 */
if (op != 0x7c0c0214)
/* cmpw 0,12,0 */
pc = pc + 4;
- op = rs6000_fetch_instruction (pc);
+ op = rs6000_fetch_instruction (gdbarch, pc);
if (op != 0x7c0c0000)
break;
/* beq 0,<disp> */
pc = pc + 4;
- op = rs6000_fetch_instruction (pc);
+ op = rs6000_fetch_instruction (gdbarch, pc);
if ((op & 0xff9f0001) != 0x41820000)
break;
/* addi 12,12,-<some immediate> */
pc = pc + 4;
- op = rs6000_fetch_instruction (pc);
+ op = rs6000_fetch_instruction (gdbarch, pc);
if ((op & 0xffff0000) != 0x398c0000)
break;
/* stw 0,0(12) */
pc = pc + 4;
- op = rs6000_fetch_instruction (pc);
+ op = rs6000_fetch_instruction (gdbarch, pc);
if (op != 0x900c0000)
break;
/* b <disp> */
pc = pc + 4;
- op = rs6000_fetch_instruction (pc);
+ op = rs6000_fetch_instruction (gdbarch, pc);
if ((op & 0xfc000001) != 0x48000000)
break;
/* [possibly one last probe: stw 0,<some immediate>(12)] */
pc = pc + 4;
- op = rs6000_fetch_instruction (pc);
+ op = rs6000_fetch_instruction (gdbarch, pc);
if ((op & 0xffff0000) == 0x900c0000)
{
pc = pc + 4;
- op = rs6000_fetch_instruction (pc);
+ op = rs6000_fetch_instruction (gdbarch, pc);
}
/* We found a valid stack-check sequence, return the new PC. */
/* addic 0,0,-<some immediate> */
pc = pc + 4;
- op = rs6000_fetch_instruction (pc);
+ op = rs6000_fetch_instruction (gdbarch, pc);
if ((op & 0xffff0000) != 0x30000000)
break;
}
/* lis 12,<some immediate> */
pc = pc + 4;
- op = rs6000_fetch_instruction (pc);
+ op = rs6000_fetch_instruction (gdbarch, pc);
if ((op & 0xffff0000) != 0x3d800000)
break;
/* lwz 12,<some immediate>(12) */
pc = pc + 4;
- op = rs6000_fetch_instruction (pc);
+ op = rs6000_fetch_instruction (gdbarch, pc);
if ((op & 0xffff0000) != 0x818c0000)
break;
/* twllt 0,12 */
pc = pc + 4;
- op = rs6000_fetch_instruction (pc);
+ op = rs6000_fetch_instruction (gdbarch, pc);
if ((op & 0xfffffffe) != 0x7c406008)
break;
int r0_contains_arg = 0;
const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
memset (fdata, 0, sizeof (struct rs6000_framedata));
fdata->saved_gpr = -1;
fdata->nosavedpc = 1;
fdata->lr_register = -1;
- pc = rs6000_skip_stack_check (pc);
+ pc = rs6000_skip_stack_check (gdbarch, pc);
if (pc >= lim_pc)
pc = lim_pc;
/* Fetch the instruction and convert it to an integer. */
if (target_read_memory (pc, buf, 4))
break;
- op = extract_unsigned_integer (buf, 4);
+ op = extract_unsigned_integer (buf, 4, byte_order);
if ((op & 0xfc1fffff) == 0x7c0802a6)
{ /* mflr Rx */
/* If the return address has already been saved, we can skip
calls to blrl (for PIC). */
- if (lr_reg != -1 && bl_to_blrl_insn_p (pc, op))
+ if (lr_reg != -1 && bl_to_blrl_insn_p (pc, op, byte_order))
{
fdata->used_bl = 1;
continue;
break;
}
- op = read_memory_integer (pc + 4, 4);
+ op = read_memory_integer (pc + 4, 4, byte_order);
/* At this point, make sure this is not a trampoline
function (a function that simply calls another functions,
if ((op & 0xfc000001) == 0x48000001)
{ /* bl foo, an initializer function? */
- op = read_memory_integer (pc + 4, 4);
+ op = read_memory_integer (pc + 4, 4, byte_order);
if (op == 0x4def7b82)
{ /* cror 0xf, 0xf, 0xf (nop) */
static CORE_ADDR
rs6000_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
gdb_byte buf[4];
unsigned long op;
if (target_read_memory (pc, buf, 4))
return pc;
- op = extract_unsigned_integer (buf, 4);
+ op = extract_unsigned_integer (buf, 4, byte_order);
if ((op & BL_MASK) == BL_INSTRUCTION)
{
@FIX code. */
static int
-rs6000_in_solib_return_trampoline (CORE_ADDR pc, char *name)
+rs6000_in_solib_return_trampoline (struct gdbarch *gdbarch,
+ CORE_ADDR pc, char *name)
{
return name && !strncmp (name, "@FIX", 4);
}
static CORE_ADDR
rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
unsigned int ii, op;
int rel;
CORE_ADDR solib_target_pc;
/* Check for bigtoc fixup code. */
msymbol = lookup_minimal_symbol_by_pc (pc);
if (msymbol
- && rs6000_in_solib_return_trampoline (pc, SYMBOL_LINKAGE_NAME (msymbol)))
+ && rs6000_in_solib_return_trampoline (gdbarch, pc,
+ SYMBOL_LINKAGE_NAME (msymbol)))
{
/* Double-check that the third instruction from PC is relative "b". */
- op = read_memory_integer (pc + 8, 4);
+ op = read_memory_integer (pc + 8, 4, byte_order);
if ((op & 0xfc000003) == 0x48000000)
{
/* Extract bits 6-29 as a signed 24-bit relative word address and
for (ii = 0; trampoline_code[ii]; ++ii)
{
- op = read_memory_integer (pc + (ii * 4), 4);
+ op = read_memory_integer (pc + (ii * 4), 4, byte_order);
if (op != trampoline_code[ii])
return 0;
}
ii = get_frame_register_unsigned (frame, 11); /* r11 holds destination addr */
- pc = read_memory_unsigned_integer (ii, tdep->wordsize); /* (r11) value */
+ pc = read_memory_unsigned_integer (ii, tdep->wordsize, byte_order);
return pc;
}
struct type *t;
- t = init_composite_type ("__ppc_builtin_type_vec64", TYPE_CODE_UNION);
+ t = arch_composite_type (gdbarch,
+ "__ppc_builtin_type_vec64", TYPE_CODE_UNION);
append_composite_type_field (t, "uint64", bt->builtin_int64);
append_composite_type_field (t, "v2_float",
init_vector_type (bt->builtin_float, 2));
type = union __ppc_builtin_type_vec128 {
uint128_t uint128;
+ double v2_double[2];
float v4_float[4];
int32_t v4_int32[4];
int16_t v8_int16[8];
struct type *t;
- t = init_composite_type ("__ppc_builtin_type_vec128", TYPE_CODE_UNION);
+ t = arch_composite_type (gdbarch,
+ "__ppc_builtin_type_vec128", TYPE_CODE_UNION);
append_composite_type_field (t, "uint128", bt->builtin_uint128);
+ append_composite_type_field (t, "v2_double",
+ init_vector_type (bt->builtin_double, 2));
append_composite_type_field (t, "v4_float",
init_vector_type (bt->builtin_float, 4));
append_composite_type_field (t, "v4_int32",
bfd_mach_rs6k, &tdesc_rs6000},
{"403", "IBM PowerPC 403", bfd_arch_powerpc,
bfd_mach_ppc_403, &tdesc_powerpc_403},
+ {"405", "IBM PowerPC 405", bfd_arch_powerpc,
+ bfd_mach_ppc_405, &tdesc_powerpc_405},
{"601", "Motorola PowerPC 601", bfd_arch_powerpc,
bfd_mach_ppc_601, &tdesc_powerpc_601},
{"602", "Motorola PowerPC 602", bfd_arch_powerpc,
struct rs6000_frame_cache *cache;
struct gdbarch *gdbarch = get_frame_arch (this_frame);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct rs6000_framedata fdata;
int wordsize = tdep->wordsize;
CORE_ADDR func, pc;
if (!fdata.frameless)
/* Frameless really means stackless. */
- cache->base = read_memory_unsigned_integer (cache->base, wordsize);
+ cache->base
+ = read_memory_unsigned_integer (cache->base, wordsize, byte_order);
trad_frame_set_value (cache->saved_regs,
gdbarch_sp_regnum (gdbarch), cache->base);
int num_pseudoregs = 0;
int cur_reg;
+ /* INFO may refer to a binary that is not of the PowerPC architecture,
+ e.g. when debugging a stand-alone SPE executable on a Cell/B.E. system.
+ In this case, we must not attempt to infer properties of the (PowerPC
+ side) of the target system from properties of that executable. Trust
+ the target description instead. */
+ if (info.abfd
+ && bfd_get_arch (info.abfd) != bfd_arch_powerpc
+ && bfd_get_arch (info.abfd) != bfd_arch_rs6000)
+ info.abfd = NULL;
+
from_xcoff_exec = info.abfd && info.abfd->format == bfd_object &&
bfd_get_flavour (info.abfd) == bfd_target_xcoff_flavour;
/* Setup displaced stepping. */
set_gdbarch_displaced_step_copy_insn (gdbarch,
simple_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);
set_gdbarch_displaced_step_free_closure (gdbarch,
simple_displaced_step_free_closure);
initialize_tdesc_powerpc_vsx32 ();
initialize_tdesc_powerpc_403 ();
initialize_tdesc_powerpc_403gc ();
+ initialize_tdesc_powerpc_405 ();
initialize_tdesc_powerpc_505 ();
initialize_tdesc_powerpc_601 ();
initialize_tdesc_powerpc_602 ();