Add basic support for AArch64.
[deliverable/binutils-gdb.git] / gdb / rs6000-aix-tdep.c
index a49bcbb863859a12ae9cc0f4d6d45448c7b1f8f4..0b70ad1670c903c509f80fe0736cadb40999f72b 100644 (file)
@@ -1,6 +1,6 @@
 /* Native support code for PPC AIX, for GDB the GNU debugger.
 
-   Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2006-2013 Free Software Foundation, Inc.
 
    Free Software Foundation, Inc.
 
 #include "breakpoint.h"
 #include "rs6000-tdep.h"
 #include "ppc-tdep.h"
+#include "exceptions.h"
+#include "xcoffread.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
@@ -229,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);
 
@@ -243,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)
     {
@@ -260,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);
@@ -349,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.  */
@@ -425,13 +425,12 @@ ran_out_of_registers_for_arguments:
 }
 
 static enum return_value_convention
-rs6000_return_value (struct gdbarch *gdbarch, struct type *func_type,
+rs6000_return_value (struct gdbarch *gdbarch, struct value *function,
                     struct type *valtype, struct regcache *regcache,
                     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
      processor has floating-point registers.  We shouldn't be using it
@@ -454,7 +453,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
@@ -549,8 +548,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
@@ -582,9 +581,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, tdep->wordsize, byte_order);
-      struct obj_section *pc_section = find_pc_section (pc);
+      CORE_ADDR pc = 0;
+      struct obj_section *pc_section;
+      volatile 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;
@@ -647,13 +659,15 @@ branch_dest (struct frame_info *frame, int opcode, int instr,
 
       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;
@@ -689,31 +703,51 @@ 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 (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;
 }
 
+/* Implement the "auto_wide_charset" gdbarch method for this platform.  */
+
+static const char *
+rs6000_aix_auto_wide_charset (void)
+{
+  return "UTF-16";
+}
+
+/* Implement an osabi sniffer for RS6000/AIX.
+
+   This function assumes that ABFD's flavour is XCOFF.  In other words,
+   it should be registered as a sniffer for bfd_target_xcoff_flavour
+   objfiles only.  A failed assertion will be raised if this condition
+   is not met.  */
+
 static enum gdb_osabi
 rs6000_aix_osabi_sniffer (bfd *abfd)
 {
-  
-  if (bfd_get_flavour (abfd) == bfd_target_xcoff_flavour);
-    return GDB_OSABI_AIX;
+  gdb_assert (bfd_get_flavour (abfd) == bfd_target_xcoff_flavour);
 
-  return GDB_OSABI_UNKNOWN;
+  /* The only noticeable difference between Lynx178 XCOFF files and
+     AIX XCOFF files comes from the fact that there are no shared
+     libraries on Lynx178.  On AIX, we are betting that an executable
+     linked with no shared library will never exist.  */
+  if (xcoff_get_n_import_files (abfd) <= 0)
+    return GDB_OSABI_UNKNOWN;
+
+  return GDB_OSABI_AIX;
 }
 
 static void
@@ -757,6 +791,8 @@ rs6000_aix_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
     set_gdbarch_frame_red_zone_size (gdbarch, 224);
   else
     set_gdbarch_frame_red_zone_size (gdbarch, 0);
+
+  set_gdbarch_auto_wide_charset (gdbarch, rs6000_aix_auto_wide_charset);
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
This page took 0.027841 seconds and 4 git commands to generate.