gdb/testsuite: Add compiler options parameter to function_range helper
[deliverable/binutils-gdb.git] / gdb / buildsym.c
index 24d1e0f806b412ff487c09aae0eb41e4f365e18d..46c5bb1477b6e7a952d09b4cd611868b31a69652 100644 (file)
@@ -1,5 +1,5 @@
 /* Support routines for building symbol tables in GDB's internal format.
-   Copyright (C) 1986-2019 Free Software Foundation, Inc.
+   Copyright (C) 1986-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -120,7 +120,7 @@ buildsym_compunit::get_macro_table ()
 {
   if (m_pending_macros == nullptr)
     m_pending_macros = new_macro_table (&m_objfile->per_bfd->storage_obstack,
-                                       &m_objfile->per_bfd->macro_cache,
+                                       &m_objfile->per_bfd->string_cache,
                                        m_compunit_symtab);
   return m_pending_macros;
 }
@@ -135,7 +135,7 @@ add_symbol_to_list (struct symbol *symbol, struct pending **listhead)
   struct pending *link;
 
   /* If this is an alias for another symbol, don't add it.  */
-  if (symbol->name && symbol->name[0] == '#')
+  if (symbol->linkage_name () && symbol->linkage_name ()[0] == '#')
     return;
 
   /* We keep PENDINGSIZE symbols in each link of the list.  If we
@@ -164,7 +164,7 @@ find_symbol_in_list (struct pending *list, char *name, int length)
     {
       for (j = list->nsyms; --j >= 0;)
        {
-         pp = SYMBOL_LINKAGE_NAME (list->symbol[j]);
+         pp = list->symbol[j]->linkage_name ();
          if (*pp == *name && strncmp (pp, name, length) == 0
              && pp[length] == '\0')
            {
@@ -319,7 +319,7 @@ buildsym_compunit::finish_block_internal
        {
          complaint (_("block end address less than block "
                       "start address in %s (patched it)"),
-                    SYMBOL_PRINT_NAME (symbol));
+                    symbol->print_name ());
        }
       else
        {
@@ -356,7 +356,7 @@ buildsym_compunit::finish_block_internal
              if (symbol)
                {
                  complaint (_("inner block not inside outer block in %s"),
-                            SYMBOL_PRINT_NAME (symbol));
+                            symbol->print_name ());
                }
              else
                {
@@ -666,16 +666,10 @@ buildsym_compunit::pop_subfile ()
 
 void
 buildsym_compunit::record_line (struct subfile *subfile, int line,
-                               CORE_ADDR pc)
+                               CORE_ADDR pc, bool is_stmt)
 {
   struct linetable_entry *e;
 
-  /* Ignore the dummy line number in libg.o */
-  if (line == 0xffff)
-    {
-      return;
-    }
-
   /* Make sure line vector exists and is big enough.  */
   if (!subfile->line_vector)
     {
@@ -687,7 +681,21 @@ buildsym_compunit::record_line (struct subfile *subfile, int line,
       m_have_line_numbers = true;
     }
 
-  if (subfile->line_vector->nitems + 1 >= subfile->line_vector_length)
+  if (subfile->line_vector->nitems > 0)
+    {
+      /* If we have a duplicate for the previous entry then ignore the new
+        entry, except, if the new entry is setting the is_stmt flag, then
+        ensure the previous entry respects the new setting.  */
+      e = subfile->line_vector->item + subfile->line_vector->nitems - 1;
+      if (e->line == line && e->pc == pc)
+       {
+         if (is_stmt && !e->is_stmt)
+           e->is_stmt = 1;
+         return;
+       }
+    }
+
+  if (subfile->line_vector->nitems >= subfile->line_vector_length)
     {
       subfile->line_vector_length *= 2;
       subfile->line_vector = (struct linetable *)
@@ -697,51 +705,37 @@ buildsym_compunit::record_line (struct subfile *subfile, int line,
                      * sizeof (struct linetable_entry))));
     }
 
-  /* Normally, we treat lines as unsorted.  But the end of sequence
-     marker is special.  We sort line markers at the same PC by line
-     number, so end of sequence markers (which have line == 0) appear
-     first.  This is right if the marker ends the previous function,
-     and there is no padding before the next function.  But it is
-     wrong if the previous line was empty and we are now marking a
-     switch to a different subfile.  We must leave the end of sequence
-     marker at the end of this group of lines, not sort the empty line
-     to after the marker.  The easiest way to accomplish this is to
-     delete any empty lines from our table, if they are followed by
-     end of sequence markers.  All we lose is the ability to set
-     breakpoints at some lines which contain no instructions
-     anyway.  */
+  /* The end of sequence marker is special.  We need to reset the
+     is_stmt flag on previous lines at the same PC, otherwise these
+     lines may cause problems since they might be at the same address
+     as the following function.  For instance suppose a function calls
+     abort there is no reason to emit a ret after that point (no joke).
+     So the label may be at the same address where the following
+     function begins.  A similar problem appears if a label is at the
+     same address where an inline function ends we cannot reliably tell
+     if this is considered part of the inline function or the calling
+     program or even the next inline function, so stack traces may
+     give surprising results.  Expect gdb.cp/step-and-next-inline.exp
+     to fail if these lines are not modified here.  */
   if (line == 0 && subfile->line_vector->nitems > 0)
     {
-      e = subfile->line_vector->item + subfile->line_vector->nitems - 1;
-      while (subfile->line_vector->nitems > 0 && e->pc == pc)
+      e = subfile->line_vector->item + subfile->line_vector->nitems;
+      do
        {
          e--;
-         subfile->line_vector->nitems--;
+         if (e->pc != pc || e->line == 0)
+           break;
+         e->is_stmt = 0;
        }
+      while (e > subfile->line_vector->item);
     }
 
   e = subfile->line_vector->item + subfile->line_vector->nitems++;
   e->line = line;
+  e->is_stmt = is_stmt ? 1 : 0;
   e->pc = pc;
 }
 
-/* Needed in order to sort line tables from IBM xcoff files.  Sigh!  */
-
-static bool
-lte_is_less_than (const linetable_entry &ln1, const linetable_entry &ln2)
-{
-  /* Note: this code does not assume that CORE_ADDRs can fit in ints.
-     Please keep it that way.  */
-  if (ln1.pc < ln2.pc)
-    return true;
-
-  if (ln1.pc > ln2.pc)
-    return false;
-
-  /* If pc equal, sort by line.  I'm not sure whether this is optimum
-     behavior (see comment at struct linetable in symtab.h).  */
-  return ln1.line < ln2.line;
-}
 \f
 /* Subroutine of end_symtab to simplify it.  Look for a subfile that
    matches the main source file's basename.  If there is only one, and
@@ -959,14 +953,23 @@ buildsym_compunit::end_symtab_with_blockvector (struct block *static_block,
          linetablesize = sizeof (struct linetable) +
            subfile->line_vector->nitems * sizeof (struct linetable_entry);
 
-         /* Like the pending blocks, the line table may be
-            scrambled in reordered executables.  Sort it if
-            OBJF_REORDERED is true.  */
+         const auto lte_is_less_than
+           = [] (const linetable_entry &ln1,
+                 const linetable_entry &ln2) -> bool
+             {
+               return (ln1.pc < ln2.pc);
+             };
+
+         /* Like the pending blocks, the line table may be scrambled in
+            reordered executables.  Sort it if OBJF_REORDERED is true.  It
+            is important to preserve the order of lines at the same
+            address, as this maintains the inline function caller/callee
+            relationships, this is why std::stable_sort is used.  */
          if (m_objfile->flags & OBJF_REORDERED)
-           std::sort (subfile->line_vector->item,
-                      subfile->line_vector->item
-                        + subfile->line_vector->nitems,
-                      lte_is_less_than);
+           std::stable_sort (subfile->line_vector->item,
+                             subfile->line_vector->item
+                             + subfile->line_vector->nitems,
+                             lte_is_less_than);
        }
 
       /* Allocate a symbol table if necessary.  */
This page took 0.027945 seconds and 4 git commands to generate.