(_bfd_link_section_stabs): Do not skip N_EXCL stabs.
[deliverable/binutils-gdb.git] / gdb / mips-tdep.c
index fb80964e6ed81d75c9bcd41c6c63451f3201b68c..95a0063611a8ca84cc8590e506bff89872ebed05 100644 (file)
@@ -54,6 +54,8 @@
 #include "frame-base.h"
 #include "trad-frame.h"
 
+static const struct objfile_data *mips_pdr_data;
+
 static void set_reg_offset (CORE_ADDR *saved_regs, int regnum, CORE_ADDR off);
 static struct type *mips_register_type (struct gdbarch *gdbarch, int regnum);
 
@@ -2298,7 +2300,7 @@ non_heuristic_proc_desc (CORE_ADDR pc, CORE_ADDR *addrptr)
   sec = find_pc_section (pc);
   if (sec != NULL)
     {
-      priv = (struct mips_objfile_private *) sec->objfile->obj_private;
+      priv = (struct mips_objfile_private *) objfile_data (sec->objfile, mips_pdr_data);
 
       /* Search the ".pdr" section generated by GAS.  This includes most of
          the information normally found in ECOFF PDRs.  */
@@ -2316,7 +2318,7 @@ non_heuristic_proc_desc (CORE_ADDR pc, CORE_ADDR *addrptr)
          priv = obstack_alloc (&sec->objfile->objfile_obstack,
                                sizeof (struct mips_objfile_private));
          priv->size = 0;
-         sec->objfile->obj_private = priv;
+         set_objfile_data (sec->objfile, mips_pdr_data, priv);
        }
       else if (priv == NULL)
        {
@@ -2344,7 +2346,7 @@ non_heuristic_proc_desc (CORE_ADDR pc, CORE_ADDR *addrptr)
          else
            priv->size = 0;
 
-         sec->objfile->obj_private = priv;
+         set_objfile_data (sec->objfile, mips_pdr_data, priv);
        }
       the_bfd = NULL;
 
@@ -2352,38 +2354,70 @@ non_heuristic_proc_desc (CORE_ADDR pc, CORE_ADDR *addrptr)
        {
          int low, mid, high;
          char *ptr;
+         CORE_ADDR pdr_pc;
 
          low = 0;
          high = priv->size / 32;
 
+         /* We've found a .pdr section describing this objfile.  We want to
+            find the entry which describes this code address.  The .pdr
+            information is not very descriptive; we have only a function
+            start address.  We have to look for the closest entry, because
+            the local symbol at the beginning of this function may have
+            been stripped - so if we ask the symbol table for the start
+            address we may get a preceding global function.  */
+
+         /* First, find the last .pdr entry starting at or before PC.  */
          do
            {
-             CORE_ADDR pdr_pc;
-
              mid = (low + high) / 2;
 
              ptr = priv->contents + mid * 32;
              pdr_pc = bfd_get_signed_32 (sec->objfile->obfd, ptr);
              pdr_pc += ANOFFSET (sec->objfile->section_offsets,
                                  SECT_OFF_TEXT (sec->objfile));
-             if (pdr_pc == startaddr)
-               break;
-             if (pdr_pc > startaddr)
+
+             if (pdr_pc > pc)
                high = mid;
              else
                low = mid + 1;
            }
          while (low != high);
 
-         if (low != high)
+         /* Both low and high point one past the PDR of interest.  If
+            both are zero, that means this PC is before any region
+            covered by a PDR, i.e. pdr_pc for the first PDR entry is
+            greater than PC.  */
+         if (low > 0)
+           {
+             ptr = priv->contents + (low - 1) * 32;
+             pdr_pc = bfd_get_signed_32 (sec->objfile->obfd, ptr);
+             pdr_pc += ANOFFSET (sec->objfile->section_offsets,
+                                 SECT_OFF_TEXT (sec->objfile));
+           }
+
+         /* We don't have a range, so we have no way to know for sure
+            whether we're in the correct PDR or a PDR for a preceding
+            function and the current function was a stripped local
+            symbol.  But if the PDR's PC is at least as great as the
+            best guess from the symbol table, assume that it does cover
+            the right area; if a .pdr section is present at all then
+            nearly every function will have an entry.  The biggest exception
+            will be the dynamic linker stubs; conveniently these are
+            placed before .text instead of after.  */
+
+         if (pc >= pdr_pc && pdr_pc >= startaddr)
            {
              struct symbol *sym = find_pc_function (pc);
 
+             if (addrptr)
+               *addrptr = pdr_pc;
+
              /* Fill in what we need of the proc_desc.  */
              proc_desc = (mips_extra_func_info_t)
                obstack_alloc (&sec->objfile->objfile_obstack,
                               sizeof (struct mips_extra_func_info));
-             PROC_LOW_ADDR (proc_desc) = startaddr;
+             PROC_LOW_ADDR (proc_desc) = pdr_pc;
 
              /* Only used for dummy frames.  */
              PROC_HIGH_ADDR (proc_desc) = 0;
@@ -4564,62 +4598,6 @@ mips_step_skips_delay (CORE_ADDR pc)
                     extract_unsigned_integer (buf, MIPS_INSTLEN));
 }
 
-
-/* Given PC at the function's start address, attempt to find the
-   prologue end using SAL information.  Return zero if the skip fails.
-
-   A non-optimized prologue traditionally has one SAL for the function
-   and a second for the function body.  A single line function has
-   them both pointing at the same line.
-
-   An optimized prologue is similar but the prologue may contain
-   instructions (SALs) from the instruction body.  Need to skip those
-   while not getting into the function body.
-
-   The functions end point and an increasing SAL line are used as
-   indicators of the prologue's endpoint.
-
-   This code is based on the function refine_prologue_limit (versions
-   found in both ia64 and ppc).  */
-
-static CORE_ADDR
-skip_prologue_using_sal (CORE_ADDR func_addr)
-{
-  struct symtab_and_line prologue_sal;
-  CORE_ADDR start_pc;
-  CORE_ADDR end_pc;
-
-  /* Get an initial range for the function.  */
-  find_pc_partial_function (func_addr, NULL, &start_pc, &end_pc);
-  start_pc += FUNCTION_START_OFFSET;
-
-  prologue_sal = find_pc_line (start_pc, 0);
-  if (prologue_sal.line != 0)
-    {
-      while (prologue_sal.end < end_pc)
-       {
-         struct symtab_and_line sal;
-
-         sal = find_pc_line (prologue_sal.end, 0);
-         if (sal.line == 0)
-           break;
-         /* Assume that a consecutive SAL for the same (or larger)
-            line mark the prologue -> body transition.  */
-         if (sal.line >= prologue_sal.line)
-           break;
-         /* The case in which compiler's optimizer/scheduler has
-            moved instructions into the prologue.  We look ahead in
-            the function looking for address ranges whose
-            corresponding line number is less the first one that we
-            found for the function.  This is more conservative then
-            refine_prologue_limit which scans a large number of SALs
-            looking for any in the prologue */
-         prologue_sal = sal;
-       }
-    }
-  return prologue_sal.end;
-}
-
 /* Skip the PC past function prologue instructions (32-bit version).
    This is a helper function for mips_skip_prologue.  */
 
@@ -5765,9 +5743,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Unwind the frame.  */
   set_gdbarch_unwind_pc (gdbarch, mips_unwind_pc);
-  frame_unwind_append_sniffer (gdbarch, mips_mdebug_frame_sniffer);
   set_gdbarch_unwind_dummy_id (gdbarch, mips_unwind_dummy_id);
-  frame_base_append_sniffer (gdbarch, mips_mdebug_frame_base_sniffer);
 
   /* Map debug register numbers onto internal register numbers.  */
   set_gdbarch_stab_reg_to_regnum (gdbarch, mips_stab_reg_to_regnum);
@@ -5803,7 +5779,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_register_type (gdbarch, mips_register_type);
 
   set_gdbarch_print_registers_info (gdbarch, mips_print_registers_info);
-  set_gdbarch_pc_in_sigtramp (gdbarch, mips_pc_in_sigtramp);
+  set_gdbarch_deprecated_pc_in_sigtramp (gdbarch, mips_pc_in_sigtramp);
 
   set_gdbarch_print_insn (gdbarch, gdb_print_insn_mips);
 
@@ -5832,6 +5808,10 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Hook in OS ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
 
+  /* Unwind the frame.  */
+  frame_unwind_append_sniffer (gdbarch, mips_mdebug_frame_sniffer);
+  frame_base_append_sniffer (gdbarch, mips_mdebug_frame_base_sniffer);
+
   return gdbarch;
 }
 
@@ -6126,6 +6106,8 @@ _initialize_mips_tdep (void)
 
   gdbarch_register (bfd_arch_mips, mips_gdbarch_init, mips_dump_tdep);
 
+  mips_pdr_data = register_objfile_data ();
+
   /* Add root prefix command for all "set mips"/"show mips" commands */
   add_prefix_cmd ("mips", no_class, set_mips_command,
                  "Various MIPS specific commands.",
This page took 0.025666 seconds and 4 git commands to generate.