* coff-h8300.c (h8300_reloc16_extra_cases): Make name a const
[deliverable/binutils-gdb.git] / gdb / hppa-tdep.c
index e8f01ef08a1345a13df0638de1570fea97b06ce2..efc8081cf0a2e33a45535b705ebfaaca479976d0 100644 (file)
@@ -1,5 +1,5 @@
 /* Target-dependent code for the HP PA architecture, for GDB.
-   Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995
+   Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
    Free Software Foundation, Inc.
 
    Contributed by the Center for Software Science at the
@@ -19,7 +19,7 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
 #include "frame.h"
@@ -73,8 +73,7 @@ static int pc_in_interrupt_handler PARAMS ((CORE_ADDR));
 
 static int pc_in_linker_stub PARAMS ((CORE_ADDR));
 
-static int compare_unwind_entries PARAMS ((const struct unwind_table_entry *,
-                                          const struct unwind_table_entry *));
+static int compare_unwind_entries PARAMS ((const void *, const void *));
 
 static void read_unwind_info PARAMS ((struct objfile *));
 
@@ -284,10 +283,13 @@ extract_17 (word)
    larger than the first, and zero if they are equal.  */
 
 static int
-compare_unwind_entries (a, b)
-     const struct unwind_table_entry *a;
-     const struct unwind_table_entry *b;
+compare_unwind_entries (arg1, arg2)
+     const void *arg1;
+     const void *arg2;
 {
+  const struct unwind_table_entry *a = arg1;
+  const struct unwind_table_entry *b = arg2;
+
   if (a->region_start > b->region_start)
     return 1;
   else if (a->region_start < b->region_start)
@@ -487,7 +489,7 @@ read_unwind_info (objfile)
    contains a sorted list of struct unwind_table_entry.  Since we do a binary
    search of the unwind tables, we depend upon them to be sorted.  */
 
-static struct unwind_table_entry *
+struct unwind_table_entry *
 find_unwind_entry(pc)
      CORE_ADDR pc;
 {
@@ -863,9 +865,13 @@ restart:
     }
 
   /* If PC is inside a linker stub, then dig out the address the stub
-     will return to.  */
+     will return to. 
+
+     Don't do this for long branch stubs.  Why?  For some unknown reason
+     _start is marked as a long branch stub in hpux10.  */
   u = find_unwind_entry (pc);
-  if (u && u->stub_type != 0)
+  if (u && u->stub_type != 0
+      && u->stub_type != LONG_BRANCH)
     {
       unsigned int insn;
 
@@ -1072,8 +1078,11 @@ frame_chain (frame)
 
          /* Abominable hack.  */
          if (current_target.to_has_execution == 0
-             && saved_regs.regs[FLAGS_REGNUM]
-             && (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], 4) & 0x2))
+             && ((saved_regs.regs[FLAGS_REGNUM]
+                  && (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], 4)
+                      & 0x2))
+                 || (saved_regs.regs[FLAGS_REGNUM] == 0
+                     && read_register (FLAGS_REGNUM) & 0x2)))
            {
              u = find_unwind_entry (FRAME_SAVED_PC (frame));
              if (!u)
@@ -1087,6 +1096,29 @@ frame_chain (frame)
     }
   else
     {
+      struct frame_saved_regs saved_regs;
+
+      /* Get the innermost frame.  */
+      tmp_frame = frame;
+      while (tmp_frame->next != NULL)
+       tmp_frame = tmp_frame->next;
+
+      get_frame_saved_regs (tmp_frame, &saved_regs);
+      /* Abominable hack.  See above.  */
+      if (current_target.to_has_execution == 0
+         && ((saved_regs.regs[FLAGS_REGNUM]
+              && (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], 4)
+                  & 0x2))
+             || (saved_regs.regs[FLAGS_REGNUM] == 0
+                 && read_register (FLAGS_REGNUM)  & 0x2)))
+       {
+         u = find_unwind_entry (FRAME_SAVED_PC (frame));
+         if (!u)
+           return read_memory_integer (saved_regs.regs[FP_REGNUM], 4);
+          else
+           return frame_base - (u->Total_frame_size << 3);
+       }
+       
       /* The value in %r3 was never saved into the stack (thus %r3 still
         holds the value of the previous frame pointer).  */
       return read_register (FP_REGNUM);
@@ -1128,6 +1160,14 @@ frame_chain_valid (chain, thisframe)
       && SYMBOL_VALUE_ADDRESS (msym_us) == SYMBOL_VALUE_ADDRESS (msym_start))
     return 0;
 
+  /* Grrrr.  Some new idiot decided that they don't want _start for the
+     PRO configurations; $START$ calls main directly....  Deal with it.  */
+  msym_start = lookup_minimal_symbol ("$START$", NULL, NULL);
+  if (msym_us
+      && msym_start
+      && SYMBOL_VALUE_ADDRESS (msym_us) == SYMBOL_VALUE_ADDRESS (msym_start))
+    return 0;
+
   next = get_next_frame (thisframe);
   if (next)
     next_u = find_unwind_entry (next->pc);
@@ -1341,6 +1381,7 @@ hppa_pop_frame ()
       old_chain = make_cleanup (delete_breakpoint, breakpoint);
 
       /* Start up the inferior.  */
+      clear_proceed_status ();
       proceed_to_finish = 1;
       proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
 
@@ -1691,27 +1732,28 @@ target_write_pc (v, pid)
    alignment required by their fields. */
 
 static int
-hppa_alignof (arg)
-     struct type *arg;
+hppa_alignof (type)
+     struct type *type;
 {
   int max_align, align, i;
-  switch (TYPE_CODE (arg))
+  CHECK_TYPEDEF (type);
+  switch (TYPE_CODE (type))
     {
     case TYPE_CODE_PTR:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
-      return TYPE_LENGTH (arg);
+      return TYPE_LENGTH (type);
     case TYPE_CODE_ARRAY:
-      return hppa_alignof (TYPE_FIELD_TYPE (arg, 0));
+      return hppa_alignof (TYPE_FIELD_TYPE (type, 0));
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
       max_align = 2;
-      for (i = 0; i < TYPE_NFIELDS (arg); i++)
+      for (i = 0; i < TYPE_NFIELDS (type); i++)
        {
          /* Bit fields have no real alignment. */
-         if (!TYPE_FIELD_BITPOS (arg, i))
+         if (!TYPE_FIELD_BITPOS (type, i))
            {
-             align = hppa_alignof (TYPE_FIELD_TYPE (arg, i));
+             align = hppa_alignof (TYPE_FIELD_TYPE (type, i));
              max_align = max (max_align, align);
            }
        }
@@ -2276,10 +2318,15 @@ skip_prologue (pc)
      CORE_ADDR pc;
 {
   char buf[4];
+  CORE_ADDR orig_pc = pc;
   unsigned long inst, stack_remaining, save_gr, save_fr, save_rp, save_sp;
-  unsigned long args_stored, status, i;
+  unsigned long args_stored, status, i, restart_gr, restart_fr;
   struct unwind_table_entry *u;
 
+  restart_gr = 0;
+  restart_fr = 0;
+
+restart:
   u = find_unwind_entry (pc);
   if (!u)
     return pc;
@@ -2298,7 +2345,7 @@ skip_prologue (pc)
   /* An indication that args may be stored into the stack.  Unfortunately
      the HPUX compilers tend to set this in cases where no args were
      stored too!.  */
-  args_stored = u->Args_stored;
+  args_stored = 1;
 
   /* Turn the Entry_GR field into a bitmask.  */
   save_gr = 0;
@@ -2310,11 +2357,13 @@ skip_prologue (pc)
 
       save_gr |= (1 << i);
     }
+  save_gr &= ~restart_gr;
 
   /* Turn the Entry_FR field into a bitmask too.  */
   save_fr = 0;
   for (i = 12; i < u->Entry_FR + 12; i++)
     save_fr |= (1 << i);
+  save_fr &= ~restart_fr;
 
   /* Loop until we find everything of interest or hit a branch.
 
@@ -2464,6 +2513,22 @@ skip_prologue (pc)
       pc += 4;
     }
 
+  /* We've got a tenative location for the end of the prologue.  However
+     because of limitations in the unwind descriptor mechanism we may
+     have went too far into user code looking for the save of a register
+     that does not exist.  So, if there registers we expected to be saved
+     but never were, mask them out and restart.
+
+     This should only happen in optimized code, and should be very rare.  */
+  if (save_gr || save_fr
+      && ! (restart_fr || restart_gr))
+    {
+      pc = orig_pc;
+      restart_gr = save_gr;
+      restart_fr = save_fr;
+      goto restart;
+    }
+
   return pc;
 }
 
This page took 0.026221 seconds and 4 git commands to generate.