* emultempl/mmixelf.em: Remove incorrect '#line' directive.
[deliverable/binutils-gdb.git] / gdb / rs6000-tdep.c
index 21ada4e389dcc98b3b7faf3227507f263074e981..25fa5508f6438a3c052f90cd1f32c51625e0d1a2 100644 (file)
@@ -1,7 +1,7 @@
 /* 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
+   Copyright (C) 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -115,11 +115,6 @@ struct reg
 
 CORE_ADDR (*rs6000_find_toc_address_hook) (CORE_ADDR) = NULL;
 
-/* Hook to set the current architecture when starting a child process. 
-   rs6000-nat.c sets this. */
-
-void (*rs6000_set_host_arch_hook) (int) = NULL;
-
 /* Static function prototypes */
 
 static CORE_ADDR branch_dest (int opcode, int instr, CORE_ADDR pc,
@@ -655,7 +650,7 @@ branch_dest (int opcode, int instr, CORE_ADDR pc, CORE_ADDR safety)
             something like 0x3c90.  The current frame is a signal handler
             caller frame, upon completion of the sigreturn system call
             execution will return to the saved PC in the frame.  */
-         if (dest < TEXT_SEGMENT_BASE)
+         if (dest < gdbarch_tdep (current_gdbarch)->text_segment_base)
            {
              struct frame_info *fi;
 
@@ -673,7 +668,7 @@ branch_dest (int opcode, int instr, CORE_ADDR pc, CORE_ADDR safety)
          /* 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 < TEXT_SEGMENT_BASE)
+         if (dest < gdbarch_tdep (current_gdbarch)->text_segment_base)
             dest = read_register (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum) & ~3;
        }
       else
@@ -683,7 +678,7 @@ branch_dest (int opcode, int instr, CORE_ADDR pc, CORE_ADDR safety)
     default:
       return -1;
     }
-  return (dest < TEXT_SEGMENT_BASE) ? safety : dest;
+  return (dest < gdbarch_tdep (current_gdbarch)->text_segment_base) ? safety : dest;
 }
 
 
@@ -902,6 +897,30 @@ store_param_on_stack_p (unsigned long op, int framep, int *r0_contains_arg)
   return 0;
 }
 
+/* Assuming that INSN is a "bl" instruction located at PC, return
+   nonzero if the destination of the branch is a "blrl" instruction.
+   
+   This sequence is sometimes found in certain function prologues.
+   It allows the function to load the LR register with a value that
+   they can use to access PIC data using PC-relative offsets.  */
+
+static int
+bl_to_blrl_insn_p (CORE_ADDR pc, int insn)
+{
+  const int opcode = 18;
+  const CORE_ADDR dest = branch_dest (opcode, insn, pc, -1);
+  int dest_insn;
+
+  if (dest == -1)
+    return 0;  /* Should never happen, but just return zero to be safe.  */
+  
+  dest_insn = read_memory_integer (dest, 4);
+  if ((dest_insn & 0xfc00ffff) == 0x4c000021) /* blrl */
+    return 1;
+
+  return 0;
+}
+
 static CORE_ADDR
 skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
 {
@@ -1133,6 +1152,12 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
                                   to save fprs??? */
 
          fdata->frameless = 0;
+
+         /* 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))
+           continue;
+
          /* Don't skip over the subroutine call if it is not within
             the first three instructions of the prologue and either
             we have no line table information or the line info tells
@@ -1189,6 +1214,13 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
          offset = fdata->offset;
          continue;
        }
+      else if ((op & 0xffff0000) == 0x38210000)
+       {                       /* addi r1,r1,SIMM */
+         fdata->frameless = 0;
+         fdata->offset += SIGNED_SHORT (op);
+         offset = fdata->offset;
+         continue;
+       }
       /* Load up minimal toc pointer */
       else if (((op >> 22) == 0x20f    ||      /* l r31,... or l r30,... */
               (op >> 22) == 0x3af)             /* ld r31,... or ld r30,... */
@@ -2305,14 +2337,6 @@ rs6000_dwarf2_reg_to_regnum (int num)
       }
 }
 
-/* Hook called when a new child process is started.  */
-
-void
-rs6000_create_inferior (int pid)
-{
-  if (rs6000_set_host_arch_hook)
-    rs6000_set_host_arch_hook (pid);
-}
 \f
 /* Support for CONVERT_FROM_FUNC_PTR_ADDR (ARCH, ADDR, TARG).
 
@@ -2894,6 +2918,9 @@ find_variant_by_arch (enum bfd_architecture arch, unsigned long mach)
 static int
 gdb_print_insn_powerpc (bfd_vma memaddr, disassemble_info *info)
 {
+  if (!info->disassembler_options)
+    info->disassembler_options = "any";
+
   if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
     return print_insn_big_powerpc (memaddr, info);
   else
@@ -2937,7 +2964,7 @@ rs6000_frame_cache (struct frame_info *next_frame, void **this_cache)
   (*this_cache) = cache;
   cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
 
-  func = frame_func_unwind (next_frame);
+  func = frame_func_unwind (next_frame, NORMAL_FRAME);
   pc = frame_pc_unwind (next_frame);
   skip_prologue (func, pc, &fdata);
 
@@ -3089,7 +3116,8 @@ rs6000_frame_this_id (struct frame_info *next_frame, void **this_cache,
 {
   struct rs6000_frame_cache *info = rs6000_frame_cache (next_frame,
                                                        this_cache);
-  (*this_id) = frame_id_build (info->base, frame_func_unwind (next_frame));
+  (*this_id) = frame_id_build (info->base,
+                              frame_func_unwind (next_frame, NORMAL_FRAME));
 }
 
 static void
@@ -3291,6 +3319,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_pc_regnum (gdbarch, 64);
   set_gdbarch_sp_regnum (gdbarch, 1);
   set_gdbarch_deprecated_fp_regnum (gdbarch, 1);
+  set_gdbarch_fp0_regnum (gdbarch, 32);
   set_gdbarch_register_sim_regno (gdbarch, rs6000_register_sim_regno);
   if (sysv_abi && wordsize == 8)
     set_gdbarch_return_value (gdbarch, ppc64_sysv_abi_return_value);
@@ -3437,6 +3466,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Helpers for function argument information.  */
   set_gdbarch_fetch_pointer_argument (gdbarch, rs6000_fetch_pointer_argument);
 
+  /* Trampoline.  */
+  set_gdbarch_in_solib_return_trampoline
+    (gdbarch, rs6000_in_solib_return_trampoline);
+  set_gdbarch_skip_trampoline_code (gdbarch, rs6000_skip_trampoline_code);
+
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
 
This page took 0.026205 seconds and 4 git commands to generate.