gdb/
[deliverable/binutils-gdb.git] / gdb / rs6000-aix-tdep.c
index 6edea05666bac5c958818e61243dd29fc8d0fd16..3ce3e377775696254cee281f683c2fcbc21ec630 100644 (file)
@@ -1,6 +1,7 @@
 /* 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, 2010, 2011
+   Free Software Foundation, Inc.
 
    Free Software Foundation, Inc.
 
 #include "breakpoint.h"
 #include "rs6000-tdep.h"
 #include "ppc-tdep.h"
+#include "exceptions.h"
 
 /* Hook for determining the TOC address when calling functions in the
-   inferior under AIX. The initialization code in rs6000-nat.c sets
+   inferior under AIX.  The initialization code in rs6000-nat.c sets
    this hook to point to find_toc_address.  */
 
 CORE_ADDR (*rs6000_find_toc_address_hook) (CORE_ADDR) = NULL;
 
 /* If the kernel has to deliver a signal, it pushes a sigcontext
    structure on the stack and then calls the signal handler, passing
-   the address of the sigcontext in an argument register. Usually
+   the address of the sigcontext in an argument register.  Usually
    the signal handler doesn't save this register, so we have to
    access the sigcontext structure via an offset from the signal handler
    frame.
@@ -120,7 +122,7 @@ rs6000_aix_supply_regset (const struct regset *regset,
 }
 
 /* Collect register REGNUM in the general-purpose register set
-   REGSET. from register cache REGCACHE into the buffer specified by
+   REGSET, from register cache REGCACHE into the buffer specified by
    GREGS and LEN.  If REGNUM is -1, do this for all registers in
    REGSET.  */
 
@@ -171,10 +173,10 @@ rs6000_aix_regset_from_core_section (struct gdbarch *gdbarch,
 }
 
 
-/* Pass the arguments in either registers, or in the stack. In RS/6000,
+/* Pass the arguments in either registers, or in the stack.  In RS/6000,
    the first eight words of the argument list (that might be less than
    eight parameters if some parameters occupy more than one word) are
-   passed in r3..r10 registers.  float and double parameters are
+   passed in r3..r10 registers.  Float and double parameters are
    passed in fpr's, in addition to that.  Rest of the parameters if any
    are passed in user stack.  There might be cases in which half of the
    parameter is copied into registers, the other half is pushed into
@@ -194,6 +196,7 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                        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 */
@@ -228,8 +231,7 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       ii++;
     }
 
-/* 
-   effectively indirect call... gcc does...
+/* effectively indirect call... gcc does...
 
    return_val example( float, int);
 
@@ -242,10 +244,9 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
    offset of stack on overflow different 
    both: 
    return in r3 or f0.  If no float, must study how gcc emulates floats;
-   pay attention to arg promotion.  
+   pay attention to arg promotion.
    User may have to cast\args to handle promotion correctly 
-   since gdb won't know if prototype supplied or not.
- */
+   since gdb won't know if prototype supplied or not.  */
 
   for (argno = 0, argbytes = 0; argno < nargs && ii < 8; ++ii)
     {
@@ -259,7 +260,7 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
        {
 
          /* Floating point arguments are passed in fpr's, as well as gpr's.
-            There are 13 fpr's reserved for passing parameters. At this point
+            There are 13 fpr's reserved for passing parameters.  At this point
             there is no way we would run out of them.  */
 
          gdb_assert (len <= 8);
@@ -348,7 +349,7 @@ ran_out_of_registers_for_arguments:
       sp -= space;
 
       /* This is another instance we need to be concerned about
-         securing our stack space. If we write anything underneath %sp
+         securing our stack space.  If we write anything underneath %sp
          (r1), we might conflict with the kernel who thinks he is free
          to use this area.  So, update %sp first before doing anything
          else.  */
@@ -404,7 +405,7 @@ ran_out_of_registers_for_arguments:
   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
@@ -429,6 +430,7 @@ rs6000_return_value (struct gdbarch *gdbarch, struct type *func_type,
                     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
@@ -452,7 +454,7 @@ rs6000_return_value (struct gdbarch *gdbarch, struct type *func_type,
   /* If the called subprogram returns an aggregate, there exists an
      implicit first argument, whose value is the address of a caller-
      allocated buffer into which the callee is assumed to store its
-     return value. All explicit parameters are appropriately
+     return value.  All explicit parameters are appropriately
      relabeled.  */
   if (TYPE_CODE (valtype) == TYPE_CODE_STRUCT
       || TYPE_CODE (valtype) == TYPE_CODE_UNION
@@ -500,7 +502,8 @@ rs6000_return_value (struct gdbarch *gdbarch, struct type *func_type,
          /* For reading we don't have to worry about sign extension.  */
          regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum + 3,
                                         &regval);
-         store_unsigned_integer (readbuf, TYPE_LENGTH (valtype), regval);
+         store_unsigned_integer (readbuf, TYPE_LENGTH (valtype), byte_order,
+                                 regval);
        }
       if (writebuf)
        {
@@ -546,8 +549,8 @@ rs6000_return_value (struct gdbarch *gdbarch, struct type *func_type,
 /* Support for CONVERT_FROM_FUNC_PTR_ADDR (ARCH, ADDR, TARG).
 
    Usually a function pointer's representation is simply the address
-   of the function. On the RS/6000 however, a function pointer is
-   represented by a pointer to an OPD entry. This OPD entry contains
+   of the function.  On the RS/6000 however, a function pointer is
+   represented by a pointer to an OPD entry.  This OPD entry contains
    three words, the first word is the address of the function, the
    second word is the TOC pointer (r2), and the third word is the
    static chain value.  Throughout GDB it is currently assumed that a
@@ -567,6 +570,8 @@ rs6000_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
                                   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);
@@ -577,9 +582,22 @@ rs6000_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
      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, gdbarch_tdep (gdbarch)->wordsize);
-      struct obj_section *pc_section = find_pc_section (pc);
+      CORE_ADDR pc = 0;
+      struct obj_section *pc_section;
+      struct gdb_exception e;
+
+      TRY_CATCH (e, RETURN_MASK_ERROR)
+        {
+          pc = read_memory_unsigned_integer (addr, tdep->wordsize, byte_order);
+        }
+      if (e.reason < 0)
+        {
+          /* An error occured during reading.  Probably a memory error
+             due to the section not being loaded yet.  This address
+             cannot be a function descriptor.  */
+          return addr;
+        }
+      pc_section = find_pc_section (pc);
 
       if (pc_section && (pc_section->the_bfd_section->flags & SEC_CODE))
         return pc;
@@ -595,7 +613,9 @@ static CORE_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;
@@ -635,18 +655,20 @@ branch_dest (struct frame_info *frame, int opcode, int instr,
          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 */
        {
-          dest = get_frame_register_unsigned (frame, tdep->ppc_ctr_regnum) & ~3;
+          dest = get_frame_register_unsigned (frame,
+                                             tdep->ppc_ctr_regnum) & ~3;
 
          /* If we are about to execute a system call, dest is something
             like 0x22fc or 0x3b00.  Upon completion the system call
             will return to the address in the link register.  */
          if (dest < AIX_TEXT_SEGMENT_BASE)
-            dest = get_frame_register_unsigned (frame, tdep->ppc_lr_regnum) & ~3;
+            dest = get_frame_register_unsigned (frame,
+                                               tdep->ppc_lr_regnum) & ~3;
        }
       else
        return -1;
@@ -663,6 +685,9 @@ branch_dest (struct frame_info *frame, int opcode, int instr,
 static int
 rs6000_software_single_step (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);
   int ii, insn;
   CORE_ADDR loc;
   CORE_ADDR breaks[2];
@@ -670,7 +695,7 @@ rs6000_software_single_step (struct frame_info *frame)
 
   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;
@@ -679,19 +704,19 @@ rs6000_software_single_step (struct frame_info *frame)
   opcode = insn >> 26;
   breaks[1] = branch_dest (frame, opcode, insn, loc, breaks[0]);
 
-  /* Don't put two breakpoints on the same address. */
+  /* Don't put two breakpoints on the same address.  */
   if (breaks[1] == breaks[0])
     breaks[1] = -1;
 
   for (ii = 0; ii < 2; ++ii)
     {
-      /* ignore invalid breakpoint. */
+      /* ignore invalid breakpoint.  */
       if (breaks[ii] == -1)
        continue;
-      insert_single_step_breakpoint (breaks[ii]);
+      insert_single_step_breakpoint (gdbarch, aspace, breaks[ii]);
     }
 
-  errno = 0;                   /* FIXME, don't ignore errors! */
+  errno = 0;                   /* FIXME, don't ignore errors!  */
   /* What errors?  {read,write}_memory call error().  */
   return 1;
 }
@@ -714,6 +739,13 @@ rs6000_aix_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
   /* 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);
@@ -742,6 +774,9 @@ rs6000_aix_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
     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)
 {
This page took 0.034041 seconds and 4 git commands to generate.