/* Native support code for PPC AIX, for GDB the GNU debugger.
- Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
Free Software Foundation, Inc.
int struct_return, CORE_ADDR struct_addr)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int ii;
int len = 0;
int argno; /* current argument number */
regcache_raw_write_signed (regcache, gdbarch_sp_regnum (gdbarch), sp);
/* Set back chain properly. */
- store_unsigned_integer (tmp_buffer, wordsize, saved_sp);
+ store_unsigned_integer (tmp_buffer, wordsize, byte_order, saved_sp);
write_memory (sp, tmp_buffer, wordsize);
/* Point the inferior function call's return address at the dummy's
gdb_byte *readbuf, const gdb_byte *writebuf)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
gdb_byte buf[8];
/* The calling convention this function implements assumes the
/* For reading we don't have to worry about sign extension. */
regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum + 3,
®val);
- store_unsigned_integer (readbuf, TYPE_LENGTH (valtype), regval);
+ store_unsigned_integer (readbuf, TYPE_LENGTH (valtype), byte_order,
+ regval);
}
if (writebuf)
{
CORE_ADDR addr,
struct target_ops *targ)
{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct obj_section *s;
s = find_pc_section (addr);
- if (s && s->the_bfd_section->flags & SEC_CODE)
- return addr;
- /* ADDR is in the data space, so it's a special function pointer. */
- return read_memory_unsigned_integer (addr, gdbarch_tdep (gdbarch)->wordsize);
+ /* Normally, functions live inside a section that is executable.
+ So, if ADDR points to a non-executable section, then treat it
+ as a function descriptor and return the target address iff
+ the target address itself points to a section that is executable. */
+ if (s && (s->the_bfd_section->flags & SEC_CODE) == 0)
+ {
+ CORE_ADDR pc =
+ read_memory_unsigned_integer (addr, tdep->wordsize, byte_order);
+ struct obj_section *pc_section = find_pc_section (pc);
+
+ if (pc_section && (pc_section->the_bfd_section->flags & SEC_CODE))
+ return pc;
+ }
+
+ return addr;
}
branch_dest (struct frame_info *frame, int opcode, int instr,
CORE_ADDR pc, CORE_ADDR safety)
{
- 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);
CORE_ADDR dest;
int immediate;
int absolute;
if (dest < AIX_TEXT_SEGMENT_BASE)
dest = read_memory_unsigned_integer
(get_frame_base (frame) + SIG_FRAME_PC_OFFSET,
- tdep->wordsize);
+ tdep->wordsize, byte_order);
}
else if (ext_op == 528) /* br cond to count reg */
static int
rs6000_software_single_step (struct frame_info *frame)
{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int ii, insn;
CORE_ADDR loc;
CORE_ADDR breaks[2];
loc = get_frame_pc (frame);
- insn = read_memory_integer (loc, 4);
+ insn = read_memory_integer (loc, 4, byte_order);
if (ppc_deal_with_atomic_sequence (frame))
return 1;
/* ignore invalid breakpoint. */
if (breaks[ii] == -1)
continue;
- insert_single_step_breakpoint (breaks[ii]);
+ insert_single_step_breakpoint (gdbarch, breaks[ii]);
}
errno = 0; /* FIXME, don't ignore errors! */
/* RS6000/AIX does not support PT_STEP. Has to be simulated. */
set_gdbarch_software_single_step (gdbarch, rs6000_software_single_step);
+ /* Displaced stepping is currently not supported in combination with
+ software single-stepping. */
+ set_gdbarch_displaced_step_copy_insn (gdbarch, NULL);
+ set_gdbarch_displaced_step_fixup (gdbarch, NULL);
+ set_gdbarch_displaced_step_free_closure (gdbarch, NULL);
+ set_gdbarch_displaced_step_location (gdbarch, NULL);
+
set_gdbarch_push_dummy_call (gdbarch, rs6000_push_dummy_call);
set_gdbarch_return_value (gdbarch, rs6000_return_value);
set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
set_gdbarch_frame_red_zone_size (gdbarch, 0);
}
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_rs6000_aix_tdep;
+
void
_initialize_rs6000_aix_tdep (void)
{