/* 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.
struct block *block;
};
-static int compare_line_numbers (const void *ln1p, const void *ln2p);
-
/* Initial sizes of data structures. These are realloc'd larger if
needed, and realloc'd down to the size actually used, when
completed. */
{
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;
}
struct pending *link;
/* If this is an alias for another symbol, don't add it. */
- if (symbol->ginfo.name && symbol->ginfo.name[0] == '#')
+ if (symbol->linkage_name () && symbol->linkage_name ()[0] == '#')
return;
/* We keep PENDINGSIZE symbols in each link of the list. If we
{
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')
{
{
complaint (_("block end address less than block "
"start address in %s (patched it)"),
- SYMBOL_PRINT_NAME (symbol));
+ symbol->print_name ());
}
else
{
if (symbol)
{
complaint (_("inner block not inside outer block in %s"),
- SYMBOL_PRINT_NAME (symbol));
+ symbol->print_name ());
}
else
{
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)
{
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 *)
* 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 int
-compare_line_numbers (const void *ln1p, const void *ln2p)
-{
- struct linetable_entry *ln1 = (struct linetable_entry *) ln1p;
- struct linetable_entry *ln2 = (struct linetable_entry *) ln2p;
-
- /* Note: this code does not assume that CORE_ADDRs can fit in ints.
- Please keep it that way. */
- if (ln1->pc < ln2->pc)
- return -1;
-
- if (ln1->pc > ln2->pc)
- return 1;
-
- /* 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
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)
- qsort (subfile->line_vector->item,
- subfile->line_vector->nitems,
- sizeof (struct linetable_entry), compare_line_numbers);
+ 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. */