2001-10-04 Frank Ch. Eigler <fche@redhat.com>
[binutils-gdb.git] / gdb / rs6000-tdep.c
index efdff362ab3122c80fb26ab50054ce09404046e0..82c18c1dac2e9210aba04013c97ce9ce07724731 100644 (file)
@@ -1,5 +1,6 @@
 /* Target-dependent code for GDB, the GNU debugger.
-   Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
+   Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+   1998, 1999, 2000, 2001
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -29,6 +30,8 @@
 #include "symfile.h"
 #include "objfiles.h"
 #include "arch-utils.h"
+#include "regcache.h"
+#include "doublest.h"
 
 #include "bfd/libbfd.h"                /* for bfd_default_set_arch_mach */
 #include "coff/internal.h"     /* for libcoff.h */
@@ -297,7 +300,8 @@ rs6000_breakpoint_from_pc (CORE_ADDR *bp_addr, int *bp_size)
 /* AIX does not support PT_STEP. Simulate it. */
 
 void
-rs6000_software_single_step (unsigned int signal, int insert_breakpoints_p)
+rs6000_software_single_step (enum target_signal signal,
+                            int insert_breakpoints_p)
 {
 #define        INSNLEN(OPCODE)  4
 
@@ -750,7 +754,7 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
             function as well. */
 
          tmp = find_pc_misc_function (pc);
-         if (tmp >= 0 && STREQ (misc_function_vector[tmp].name, "main"))
+         if (tmp >= 0 && STREQ (misc_function_vector[tmp].name, main_name ()))
            return pc + 8;
        }
     }
@@ -842,7 +846,7 @@ rs6000_pop_frame (void)
 
 static void
 rs6000_fix_call_dummy (char *dummyname, CORE_ADDR pc, CORE_ADDR fun,
-                      int nargs, value_ptr *args, struct type *type,
+                      int nargs, struct value **args, struct type *type,
                       int gcc_p)
 {
 #define        TOC_ADDR_OFFSET         20
@@ -875,7 +879,7 @@ rs6000_fix_call_dummy (char *dummyname, CORE_ADDR pc, CORE_ADDR fun,
    starting from r4. */
 
 static CORE_ADDR
-rs6000_push_arguments (int nargs, value_ptr *args, CORE_ADDR sp,
+rs6000_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
                       int struct_return, CORE_ADDR struct_addr)
 {
   int ii;
@@ -886,7 +890,7 @@ rs6000_push_arguments (int nargs, value_ptr *args, CORE_ADDR sp,
   int f_argno = 0;             /* current floating point argno */
   int wordsize = TDEP->wordsize;
 
-  value_ptr arg = 0;
+  struct value *arg = 0;
   struct type *type;
 
   CORE_ADDR saved_sp;
@@ -1005,7 +1009,7 @@ ran_out_of_registers_for_arguments:
 
       for (; jj < nargs; ++jj)
        {
-         value_ptr val = args[jj];
+         struct value *val = args[jj];
          space += ((TYPE_LENGTH (VALUE_TYPE (val))) + 3) & -4;
        }
 
@@ -1129,19 +1133,55 @@ rs6000_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
 
 static CORE_ADDR rs6000_struct_return_address;
 
-/* Indirect function calls use a piece of trampoline code to do context
-   switching, i.e. to set the new TOC table. Skip such code if we are on
-   its first instruction (as when we have single-stepped to here). 
-   Also skip shared library trampoline code (which is different from
+/* Return whether handle_inferior_event() should proceed through code
+   starting at PC in function NAME when stepping.
+
+   The AIX -bbigtoc linker option generates functions @FIX0, @FIX1, etc. to
+   handle memory references that are too distant to fit in instructions
+   generated by the compiler.  For example, if 'foo' in the following
+   instruction:
+
+     lwz r9,foo(r2)
+
+   is greater than 32767, the linker might replace the lwz with a branch to
+   somewhere in @FIX1 that does the load in 2 instructions and then branches
+   back to where execution should continue.
+
+   GDB should silently step over @FIX code, just like AIX dbx does.
+   Unfortunately, the linker uses the "b" instruction for the branches,
+   meaning that the link register doesn't get set.  Therefore, GDB's usual
+   step_over_function() mechanism won't work.
+
+   Instead, use the IN_SOLIB_RETURN_TRAMPOLINE and SKIP_TRAMPOLINE_CODE hooks
+   in handle_inferior_event() to skip past @FIX code.  */
+
+int
+rs6000_in_solib_return_trampoline (CORE_ADDR pc, char *name)
+{
+  return name && !strncmp (name, "@FIX", 4);
+}
+
+/* Skip code that the user doesn't want to see when stepping:
+
+   1. Indirect function calls use a piece of trampoline code to do context
+   switching, i.e. to set the new TOC table.  Skip such code if we are on
+   its first instruction (as when we have single-stepped to here).
+
+   2. Skip shared library trampoline code (which is different from
    indirect function call trampolines).
+
+   3. Skip bigtoc fixup code.
+
    Result is desired PC to step until, or NULL if we are not in
-   trampoline code.  */
+   code that should be skipped.  */
 
 CORE_ADDR
 rs6000_skip_trampoline_code (CORE_ADDR pc)
 {
   register unsigned int ii, op;
+  int rel;
   CORE_ADDR solib_target_pc;
+  struct minimal_symbol *msymbol;
 
   static unsigned trampoline_code[] =
   {
@@ -1155,6 +1195,21 @@ rs6000_skip_trampoline_code (CORE_ADDR pc)
     0
   };
 
+  /* Check for bigtoc fixup code.  */
+  msymbol = lookup_minimal_symbol_by_pc (pc);
+  if (msymbol && rs6000_in_solib_return_trampoline (pc, SYMBOL_NAME (msymbol)))
+    {
+      /* Double-check that the third instruction from PC is relative "b".  */
+      op = read_memory_integer (pc + 8, 4);
+      if ((op & 0xfc000003) == 0x48000000)
+       {
+         /* Extract bits 6-29 as a signed 24-bit relative word address and
+            add it to the containing PC.  */
+         rel = ((int)(op << 6) >> 6);
+         return pc + 8 + rel;
+       }
+    }
+
   /* If pc is in a shared library trampoline, return its target.  */
   solib_target_pc = find_solib_trampoline_target (pc);
   if (solib_target_pc)
@@ -2039,8 +2094,9 @@ process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
              *os_ident_ptr = ELFOSABI_SOLARIS;
              break;
            default :
-             internal_error (
-               "process_note_abi_sections: unknown OS number %d", os_number);
+             internal_error (__FILE__, __LINE__,
+                             "process_note_abi_sections: unknown OS number %d",
+                             os_number);
              break;
            }
        }
@@ -2107,8 +2163,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   osabi = get_elfosabi (info.abfd);
 
-  /* Check word size.  If INFO is from a binary file, infer it from that,
-     else use the previously-inferred size. */
+  /* Check word size.  If INFO is from a binary file, infer it from
+     that, else choose a likely default. */
   if (from_xcoff_exec)
     {
       if (xcoff_data (info.abfd)->xcoff64)
@@ -2125,11 +2181,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     }
   else
     {
-      tdep = TDEP;
-      if (tdep)
-       wordsize = tdep->wordsize;
-      else
-       wordsize = 4;
+      wordsize = 4;
     }
 
   /* Find a candidate among extant architectures. */
@@ -2155,7 +2207,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   if (!from_xcoff_exec)
     {
-      arch = info.bfd_architecture;
+      arch = info.bfd_arch_info->arch;
       mach = info.bfd_arch_info->mach;
     }
   else