/* Support routines for building symbol tables in GDB's internal format.
- Copyright (C) 1986-2018 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. */
const char *comp_dir_,
enum language language_,
CORE_ADDR last_addr)
- : objfile (objfile_),
+ : m_objfile (objfile_),
m_last_source_file (name == nullptr ? nullptr : xstrdup (name)),
- comp_dir (comp_dir_ == nullptr ? nullptr : xstrdup (comp_dir_)),
- language (language_),
+ m_comp_dir (comp_dir_ == nullptr ? nullptr : xstrdup (comp_dir_)),
+ m_language (language_),
m_last_source_start_addr (last_addr)
{
/* Allocate the compunit symtab now. The caller needs it to allocate
non-primary symtabs. It is also needed by get_macro_table. */
- compunit_symtab = allocate_compunit_symtab (objfile, name);
+ m_compunit_symtab = allocate_compunit_symtab (m_objfile, name);
/* Build the subfile for NAME (the main source file) so that we can record
a pointer to it for later.
start_subfile (name);
/* Save this so that we don't have to go looking for it at the end
of the subfiles list. */
- main_subfile = m_current_subfile;
+ m_main_subfile = m_current_subfile;
}
buildsym_compunit::~buildsym_compunit ()
if (m_pending_macros != nullptr)
free_macro_table (m_pending_macros);
- for (subfile = subfiles;
+ for (subfile = m_subfiles;
subfile != NULL;
subfile = nextsub)
{
buildsym_compunit::get_macro_table ()
{
if (m_pending_macros == nullptr)
- m_pending_macros = new_macro_table (&objfile->per_bfd->storage_obstack,
- objfile->per_bfd->macro_cache,
- compunit_symtab);
+ m_pending_macros = new_macro_table (&m_objfile->per_bfd->storage_obstack,
+ &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')
{
CORE_ADDR start, CORE_ADDR end,
int is_global, int expandable)
{
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = m_objfile->arch ();
struct pending *next, *next1;
struct block *block;
struct pending_block *pblock;
struct pending_block *opblock;
block = (is_global
- ? allocate_global_block (&objfile->objfile_obstack)
- : allocate_block (&objfile->objfile_obstack));
+ ? allocate_global_block (&m_objfile->objfile_obstack)
+ : allocate_block (&m_objfile->objfile_obstack));
if (symbol)
{
- BLOCK_DICT (block)
- = dict_create_linear (&objfile->objfile_obstack,
- language, *listhead);
+ BLOCK_MULTIDICT (block)
+ = mdict_create_linear (&m_objfile->objfile_obstack, *listhead);
}
else
{
if (expandable)
{
- BLOCK_DICT (block) = dict_create_hashed_expandable (language);
- dict_add_pending (BLOCK_DICT (block), *listhead);
+ BLOCK_MULTIDICT (block) = mdict_create_hashed_expandable (m_language);
+ mdict_add_pending (BLOCK_MULTIDICT (block), *listhead);
}
else
{
- BLOCK_DICT (block) =
- dict_create_hashed (&objfile->objfile_obstack,
- language, *listhead);
+ BLOCK_MULTIDICT (block) =
+ mdict_create_hashed (&m_objfile->objfile_obstack, *listhead);
}
}
if (symbol)
{
struct type *ftype = SYMBOL_TYPE (symbol);
- struct dict_iterator iter;
+ struct mdict_iterator miter;
SYMBOL_BLOCK_VALUE (symbol) = block;
BLOCK_FUNCTION (block) = symbol;
- if (TYPE_NFIELDS (ftype) <= 0)
+ if (ftype->num_fields () <= 0)
{
/* No parameter type information is recorded with the
function's type. Set that from the type of the
/* Here we want to directly access the dictionary, because
we haven't fully initialized the block yet. */
- ALL_DICT_SYMBOLS (BLOCK_DICT (block), iter, sym)
+ ALL_DICT_SYMBOLS (BLOCK_MULTIDICT (block), miter, sym)
{
if (SYMBOL_IS_ARGUMENT (sym))
nparams++;
}
if (nparams > 0)
{
- TYPE_NFIELDS (ftype) = nparams;
- TYPE_FIELDS (ftype) = (struct field *)
- TYPE_ALLOC (ftype, nparams * sizeof (struct field));
+ ftype->set_num_fields (nparams);
+ ftype->set_fields
+ ((struct field *)
+ TYPE_ALLOC (ftype, nparams * sizeof (struct field)));
iparams = 0;
/* Here we want to directly access the dictionary, because
we haven't fully initialized the block yet. */
- ALL_DICT_SYMBOLS (BLOCK_DICT (block), iter, sym)
+ ALL_DICT_SYMBOLS (BLOCK_MULTIDICT (block), miter, sym)
{
if (iparams == nparams)
break;
}
if (static_link != NULL)
- objfile_register_static_link (objfile, block, static_link);
+ objfile_register_static_link (m_objfile, block, static_link);
/* Now free the links of the list, and empty the list. */
{
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
{
(is_global
? m_global_using_directives
: m_local_using_directives),
- &objfile->objfile_obstack);
+ &m_objfile->objfile_obstack);
if (is_global)
m_global_using_directives = NULL;
else
}
blockvector = (struct blockvector *)
- obstack_alloc (&objfile->objfile_obstack,
+ obstack_alloc (&m_objfile->objfile_obstack,
(sizeof (struct blockvector)
+ (i - 1) * sizeof (struct block *)));
blockvector. */
if (m_pending_addrmap != nullptr && m_pending_addrmap_interesting)
BLOCKVECTOR_MAP (blockvector)
- = addrmap_create_fixed (m_pending_addrmap, &objfile->objfile_obstack);
+ = addrmap_create_fixed (m_pending_addrmap, &m_objfile->objfile_obstack);
else
BLOCKVECTOR_MAP (blockvector) = 0;
const char *subfile_dirname;
struct subfile *subfile;
- subfile_dirname = comp_dir.get ();
+ subfile_dirname = m_comp_dir.get ();
/* See if this subfile is already registered. */
- for (subfile = subfiles; subfile; subfile = subfile->next)
+ for (subfile = m_subfiles; subfile; subfile = subfile->next)
{
char *subfile_name;
memset (subfile, 0, sizeof (struct subfile));
subfile->buildsym_compunit = this;
- subfile->next = subfiles;
- subfiles = subfile;
+ subfile->next = m_subfiles;
+ m_subfiles = subfile;
m_current_subfile = subfile;
enum language sublang = deduce_language_from_filename (subfile->name);
if (sublang == language_cplus || sublang == language_fortran)
- for (s = subfiles; s != NULL; s = s->next)
+ for (s = m_subfiles; s != NULL; s = s->next)
if (s->language == language_c)
s->language = sublang;
}
const char *name)
{
if (subfile != NULL
- && comp_dir == NULL
+ && m_comp_dir == NULL
&& subfile->name != NULL
&& IS_DIR_SEPARATOR (subfile->name[strlen (subfile->name) - 1]))
{
- comp_dir.reset (subfile->name);
+ m_comp_dir.reset (subfile->name);
subfile->name = xstrdup (name);
set_last_source_file (name);
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 >= subfile->line_vector_length)
{
subfile->line_vector_length *= 2;
subfile->line_vector = (struct linetable *)
end of sequence markers. All we lose is the ability to set
breakpoints at some lines which contain no instructions
anyway. */
- if (line == 0 && subfile->line_vector->nitems > 0)
+ if (line == 0)
{
- e = subfile->line_vector->item + subfile->line_vector->nitems - 1;
- while (subfile->line_vector->nitems > 0 && e->pc == pc)
+ while (subfile->line_vector->nitems > 0)
{
- e--;
+ e = subfile->line_vector->item + subfile->line_vector->nitems - 1;
+ if (e->pc != pc)
+ break;
subfile->line_vector->nitems--;
}
}
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
struct subfile *mainsub, *subfile;
/* Get the main source file. */
- mainsub = main_subfile;
+ mainsub = m_main_subfile;
/* If the main source file doesn't have any line number or symbol
info, look for an alias in another subfile. */
struct subfile *prev_mainsub_alias = NULL;
prevsub = NULL;
- for (subfile = subfiles;
+ for (subfile = m_subfiles;
subfile != NULL;
subfile = subfile->next)
{
mainsub->symtab = mainsub_alias->symtab;
if (prev_mainsub_alias == NULL)
- subfiles = mainsub_alias->next;
+ m_subfiles = mainsub_alias->next;
else
prev_mainsub_alias->next = mainsub_alias->next;
xfree (mainsub_alias->name);
/* Reordered executables may have out of order pending blocks; if
OBJF_REORDERED is true, then sort the pending blocks. */
- if ((objfile->flags & OBJF_REORDERED) && m_pending_blocks)
+ if ((m_objfile->flags & OBJF_REORDERED) && m_pending_blocks)
{
struct pending_block *pb;
are no-ops. FIXME: Is this handled right in case of QUIT? Can
we make this cleaner? */
- cleanup_undefined_stabs_types (objfile);
- finish_global_stabs (objfile);
+ cleanup_undefined_stabs_types (m_objfile);
+ finish_global_stabs (m_objfile);
if (!required
&& m_pending_blocks == NULL
buildsym_compunit::end_symtab_with_blockvector (struct block *static_block,
int section, int expandable)
{
- struct compunit_symtab *cu = compunit_symtab;
- struct symtab *symtab;
+ struct compunit_symtab *cu = m_compunit_symtab;
struct blockvector *blockvector;
struct subfile *subfile;
CORE_ADDR end_addr;
gdb_assert (static_block != NULL);
- gdb_assert (subfiles != NULL);
+ gdb_assert (m_subfiles != NULL);
end_addr = BLOCK_END (static_block);
/* Read the line table if it has to be read separately.
This is only used by xcoffread.c. */
- if (objfile->sf->sym_read_linetable != NULL)
- objfile->sf->sym_read_linetable (objfile);
+ if (m_objfile->sf->sym_read_linetable != NULL)
+ m_objfile->sf->sym_read_linetable (m_objfile);
/* Handle the case where the debug info specifies a different path
for the main source file. It can cause us to lose track of its
/* Now create the symtab objects proper, if not already done,
one for each subfile. */
- for (subfile = subfiles;
+ for (subfile = m_subfiles;
subfile != NULL;
subfile = subfile->next)
{
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. */
- if (objfile->flags & OBJF_REORDERED)
- qsort (subfile->line_vector->item,
- subfile->line_vector->nitems,
- sizeof (struct linetable_entry), compare_line_numbers);
+ 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::stable_sort (subfile->line_vector->item,
+ subfile->line_vector->item
+ + subfile->line_vector->nitems,
+ lte_is_less_than);
}
/* Allocate a symbol table if necessary. */
if (subfile->symtab == NULL)
subfile->symtab = allocate_symtab (cu, subfile->name);
- symtab = subfile->symtab;
+ struct symtab *symtab = subfile->symtab;
/* Fill in its components. */
{
/* Reallocate the line table on the symbol obstack. */
SYMTAB_LINETABLE (symtab) = (struct linetable *)
- obstack_alloc (&objfile->objfile_obstack, linetablesize);
+ obstack_alloc (&m_objfile->objfile_obstack, linetablesize);
memcpy (SYMTAB_LINETABLE (symtab), subfile->line_vector,
linetablesize);
}
{
struct symtab *main_symtab, *prev_symtab;
- main_symtab = main_subfile->symtab;
+ main_symtab = m_main_subfile->symtab;
prev_symtab = NULL;
- ALL_COMPUNIT_FILETABS (cu, symtab)
+ for (symtab *symtab : compunit_filetabs (cu))
{
if (symtab == main_symtab)
{
/* Fill out the compunit symtab. */
- if (comp_dir != NULL)
+ if (m_comp_dir != NULL)
{
/* Reallocate the dirname on the symbol obstack. */
- const char *comp_dir = this->comp_dir.get ();
- COMPUNIT_DIRNAME (cu)
- = (const char *) obstack_copy0 (&objfile->objfile_obstack,
- comp_dir, strlen (comp_dir));
+ const char *comp_dir = m_comp_dir.get ();
+ COMPUNIT_DIRNAME (cu) = obstack_strdup (&m_objfile->objfile_obstack,
+ comp_dir);
}
/* Save the debug format string (if any) in the symtab. */
- COMPUNIT_DEBUGFORMAT (cu) = debugformat;
+ COMPUNIT_DEBUGFORMAT (cu) = m_debugformat;
/* Similarly for the producer. */
- COMPUNIT_PRODUCER (cu) = producer;
+ COMPUNIT_PRODUCER (cu) = m_producer;
COMPUNIT_BLOCKVECTOR (cu) = blockvector;
{
int block_i;
/* The main source file's symtab. */
- symtab = COMPUNIT_FILETABS (cu);
+ struct symtab *symtab = COMPUNIT_FILETABS (cu);
for (block_i = 0; block_i < BLOCKVECTOR_NBLOCKS (blockvector); block_i++)
{
struct block *block = BLOCKVECTOR_BLOCK (blockvector, block_i);
struct symbol *sym;
- struct dict_iterator iter;
+ struct mdict_iterator miter;
/* Inlined functions may have symbols not in the global or
static symbol lists. */
/* Note that we only want to fix up symbols from the local
blocks, not blocks coming from included symtabs. That is why
we use ALL_DICT_SYMBOLS here and not ALL_BLOCK_SYMBOLS. */
- ALL_DICT_SYMBOLS (BLOCK_DICT (block), iter, sym)
+ ALL_DICT_SYMBOLS (BLOCK_MULTIDICT (block), miter, sym)
if (symbol_symtab (sym) == NULL)
symbol_set_symtab (sym, symtab);
}
void
buildsym_compunit::augment_type_symtab ()
{
- struct compunit_symtab *cust = compunit_symtab;
+ struct compunit_symtab *cust = m_compunit_symtab;
const struct blockvector *blockvector = COMPUNIT_BLOCKVECTOR (cust);
if (!m_context_stack.empty ())
to the primary symtab. */
set_missing_symtab (m_file_symbols, cust);
- dict_add_pending (BLOCK_DICT (block), m_file_symbols);
+ mdict_add_pending (BLOCK_MULTIDICT (block), m_file_symbols);
}
if (m_global_symbols != NULL)
to the primary symtab. */
set_missing_symtab (m_global_symbols, cust);
- dict_add_pending (BLOCK_DICT (block),
+ mdict_add_pending (BLOCK_MULTIDICT (block),
m_global_symbols);
}
}