#include "cp-support.h"
#include "language.h"
#include "cli/cli-utils.h"
-#include "common/symbol.h"
+#include "gdbsupport/symbol.h"
#include <algorithm>
#include "safe-ctype.h"
}
/* Accumulate the minimal symbols for each objfile in bunches of BUNCH_SIZE.
- At the end, copy them all into one newly allocated location on an objfile's
- per-BFD storage obstack. */
+ At the end, copy them all into one newly allocated array. */
#define BUNCH_SIZE 127
lookup_minimal_symbol (const char *name, const char *sfile,
struct objfile *objf)
{
- struct objfile *objfile;
found_minimal_symbols found;
unsigned int mangled_hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
- for (objfile = object_files;
- objfile != NULL && found.external_symbol.minsym == NULL;
- objfile = objfile->next)
+ for (objfile *objfile : current_program_space->objfiles ())
{
+ if (found.external_symbol.minsym != NULL)
+ break;
+
if (objf == NULL || objf == objfile
|| objf == objfile->separate_debug_objfile_backlink)
{
return lookup_minimal_symbol (name, NULL, NULL);
}
-/* See common/symbol.h. */
+/* See gdbsupport/symbol.h. */
int
find_minimal_symbol_address (const char *name, CORE_ADDR *addr,
/* See minsyms.h. */
+bound_minimal_symbol
+lookup_minimal_symbol_linkage (const char *name, struct objfile *objf)
+{
+ unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
+
+ for (objfile *objfile : objf->separate_debug_objfiles ())
+ {
+ for (minimal_symbol *msymbol = objfile->per_bfd->msymbol_hash[hash];
+ msymbol != NULL;
+ msymbol = msymbol->hash_next)
+ {
+ if (strcmp (MSYMBOL_LINKAGE_NAME (msymbol), name) == 0
+ && (MSYMBOL_TYPE (msymbol) == mst_data
+ || MSYMBOL_TYPE (msymbol) == mst_bss))
+ return {msymbol, objfile};
+ }
+ }
+
+ return {};
+}
+
+/* See minsyms.h. */
+
struct bound_minimal_symbol
lookup_minimal_symbol_text (const char *name, struct objfile *objf)
{
- struct objfile *objfile;
struct minimal_symbol *msymbol;
struct bound_minimal_symbol found_symbol = { NULL, NULL };
struct bound_minimal_symbol found_file_symbol = { NULL, NULL };
unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
- for (objfile = object_files;
- objfile != NULL && found_symbol.minsym == NULL;
- objfile = objfile->next)
+ for (objfile *objfile : current_program_space->objfiles ())
{
+ if (found_symbol.minsym != NULL)
+ break;
+
if (objf == NULL || objf == objfile
|| objf == objfile->separate_debug_objfile_backlink)
{
lookup_minimal_symbol_by_pc_name (CORE_ADDR pc, const char *name,
struct objfile *objf)
{
- struct objfile *objfile;
struct minimal_symbol *msymbol;
unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
- for (objfile = object_files;
- objfile != NULL;
- objfile = objfile->next)
+ for (objfile *objfile : current_program_space->objfiles ())
{
if (objf == NULL || objf == objfile
|| objf == objfile->separate_debug_objfile_backlink)
return NULL;
}
-/* See minsyms.h. */
-
-struct bound_minimal_symbol
-lookup_minimal_symbol_solib_trampoline (const char *name,
- struct objfile *objf)
-{
- struct objfile *objfile;
- struct minimal_symbol *msymbol;
- struct bound_minimal_symbol found_symbol = { NULL, NULL };
-
- unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
-
- for (objfile = object_files;
- objfile != NULL;
- objfile = objfile->next)
- {
- if (objf == NULL || objf == objfile
- || objf == objfile->separate_debug_objfile_backlink)
- {
- for (msymbol = objfile->per_bfd->msymbol_hash[hash];
- msymbol != NULL;
- msymbol = msymbol->hash_next)
- {
- if (strcmp (MSYMBOL_LINKAGE_NAME (msymbol), name) == 0 &&
- MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
- {
- found_symbol.objfile = objfile;
- found_symbol.minsym = msymbol;
- return found_symbol;
- }
- }
- }
- }
-
- return found_symbol;
-}
-
/* A helper function that makes *PC section-relative. This searches
the sections of OBJFILE and if *PC is in a section, it subtracts
the section offset and returns true. Otherwise it returns
int lo;
int hi;
int newobj;
- struct objfile *objfile;
struct minimal_symbol *msymbol;
struct minimal_symbol *best_symbol = NULL;
struct objfile *best_objfile = NULL;
gdb_assert (section != NULL);
- for (objfile = section->objfile;
- objfile != NULL;
- objfile = objfile_separate_debug_iterate (section->objfile, objfile))
+ for (objfile *objfile : section->objfile->separate_debug_objfiles ())
{
CORE_ADDR pc = pc_in;
{
int best_zero_sized = -1;
- msymbol = objfile->per_bfd->msymbols;
+ msymbol = objfile->per_bfd->msymbols.get ();
lo = 0;
hi = objfile->per_bfd->minimal_symbol_count - 1;
/* Return non-zero iff PC is in an STT_GNU_IFUNC function resolver. */
-int
+bool
in_gnu_ifunc_stub (CORE_ADDR pc)
{
bound_minimal_symbol msymbol
/* See elf_gnu_ifunc_resolve_name for its real implementation. */
-static int
+static bool
stub_gnu_ifunc_resolve_name (const char *function_name,
CORE_ADDR *function_address_p)
{
/* Discard the currently collected minimal symbols, if any. If we wish
to save them for later use, we must have already copied them somewhere
- else before calling this function.
-
- FIXME: We could allocate the minimal symbol bunches on their own
- obstack and then simply blow the obstack away when we are done with
- it. Is it worth the extra trouble though? */
+ else before calling this function. */
minimal_symbol_reader::~minimal_symbol_reader ()
{
m_msym_bunch = newobj;
}
msymbol = &m_msym_bunch->contents[m_msym_bunch_index];
- MSYMBOL_SET_LANGUAGE (msymbol, language_auto,
- &m_objfile->per_bfd->storage_obstack);
- MSYMBOL_SET_NAMES (msymbol, name, name_len, copy_name, m_objfile);
+ symbol_set_language (msymbol, language_auto,
+ &m_objfile->per_bfd->storage_obstack);
+ symbol_set_names (msymbol, name, name_len, copy_name, m_objfile->per_bfd);
SET_MSYMBOL_VALUE_ADDRESS (msymbol, address);
MSYMBOL_SECTION (msymbol) = section;
return msymbol;
}
-/* Compare two minimal symbols by address and return a signed result based
- on unsigned comparisons, so that we sort into unsigned numeric order.
+/* Compare two minimal symbols by address and return true if FN1's address
+ is less than FN2's, so that we sort into unsigned numeric order.
Within groups with the same address, sort by name. */
-static int
-compare_minimal_symbols (const void *fn1p, const void *fn2p)
+static inline bool
+minimal_symbol_is_less_than (const minimal_symbol &fn1,
+ const minimal_symbol &fn2)
{
- const struct minimal_symbol *fn1;
- const struct minimal_symbol *fn2;
-
- fn1 = (const struct minimal_symbol *) fn1p;
- fn2 = (const struct minimal_symbol *) fn2p;
-
- if (MSYMBOL_VALUE_RAW_ADDRESS (fn1) < MSYMBOL_VALUE_RAW_ADDRESS (fn2))
+ if (MSYMBOL_VALUE_RAW_ADDRESS (&fn1) < MSYMBOL_VALUE_RAW_ADDRESS (&fn2))
{
- return (-1); /* addr 1 is less than addr 2. */
+ return true; /* addr 1 is less than addr 2. */
}
- else if (MSYMBOL_VALUE_RAW_ADDRESS (fn1) > MSYMBOL_VALUE_RAW_ADDRESS (fn2))
+ else if (MSYMBOL_VALUE_RAW_ADDRESS (&fn1) > MSYMBOL_VALUE_RAW_ADDRESS (&fn2))
{
- return (1); /* addr 1 is greater than addr 2. */
+ return false; /* addr 1 is greater than addr 2. */
}
else
/* addrs are equal: sort by name */
{
- const char *name1 = MSYMBOL_LINKAGE_NAME (fn1);
- const char *name2 = MSYMBOL_LINKAGE_NAME (fn2);
+ const char *name1 = MSYMBOL_LINKAGE_NAME (&fn1);
+ const char *name2 = MSYMBOL_LINKAGE_NAME (&fn2);
if (name1 && name2) /* both have names */
- return strcmp (name1, name2);
+ return strcmp (name1, name2) < 0;
else if (name2)
- return 1; /* fn1 has no name, so it is "less". */
+ return true; /* fn1 has no name, so it is "less". */
else if (name1) /* fn2 has no name, so it is "less". */
- return -1;
+ return false;
else
- return (0); /* Neither has a name, so they're equal. */
+ return false; /* Neither has a name, so they're equal. */
}
}
to linearly scan the table, which is done in a number of places. So we
just do one linear scan here and toss out the duplicates.
- Note that we are not concerned here about recovering the space that
- is potentially freed up, because the strings themselves are allocated
- on the storage_obstack, and will get automatically freed when the symbol
- table is freed. The caller can free up the unused minimal symbols at
- the end of the compacted region if their allocation strategy allows it.
-
- Also note we only go up to the next to last entry within the loop
- and then copy the last entry explicitly after the loop terminates.
-
Since the different sources of information for each symbol may
have different levels of "completeness", we may have duplicates
that have one entry with type "mst_unknown" and the other with a
/* Now, (re)insert the actual entries. */
for ((i = objfile->per_bfd->minimal_symbol_count,
- msym = objfile->per_bfd->msymbols);
+ msym = objfile->per_bfd->msymbols.get ());
i > 0;
i--, msym++)
{
minimal symbol table. In most cases there is no minimal symbol table yet
for this objfile, and the existing bunches are used to create one. Once
in a while (for shared libraries for example), we add symbols (e.g. common
- symbols) to an existing objfile.
-
- Because of the way minimal symbols are collected, we generally have no way
- of knowing what source language applies to any particular minimal symbol.
- Specifically, we have no way of knowing if the minimal symbol comes from a
- C++ compilation unit or not. So for the sake of supporting cached
- demangled C++ names, we have no choice but to try and demangle each new one
- that comes in. If the demangling succeeds, then we assume it is a C++
- symbol and set the symbol's language and demangled name fields
- appropriately. Note that in order to avoid unnecessary demanglings, and
- allocating obstack space that subsequently can't be freed for the demangled
- names, we mark all newly added symbols with language_auto. After
- compaction of the minimal symbols, we go back and scan the entire minimal
- symbol table looking for these new symbols. For each new symbol we attempt
- to demangle it, and if successful, record it as a language_cplus symbol
- and cache the demangled form on the symbol obstack. Symbols which don't
- demangle are marked as language_unknown symbols, which inhibits future
- attempts to demangle them if we later add more minimal symbols. */
+ symbols) to an existing objfile. */
void
minimal_symbol_reader::install ()
{
- int bindex;
int mcount;
struct msym_bunch *bunch;
struct minimal_symbol *msymbols;
m_msym_count, objfile_name (m_objfile));
}
- /* Allocate enough space in the obstack, into which we will gather the
- bunches of new and existing minimal symbols, sort them, and then
- compact out the duplicate entries. Once we have a final table,
- we will give back the excess space. */
+ /* Allocate enough space, into which we will gather the bunches
+ of new and existing minimal symbols, sort them, and then
+ compact out the duplicate entries. Once we have a final
+ table, we will give back the excess space. */
alloc_count = m_msym_count + m_objfile->per_bfd->minimal_symbol_count;
- obstack_blank (&m_objfile->per_bfd->storage_obstack,
- alloc_count * sizeof (struct minimal_symbol));
- msymbols = (struct minimal_symbol *)
- obstack_base (&m_objfile->per_bfd->storage_obstack);
+ gdb::unique_xmalloc_ptr<minimal_symbol>
+ msym_holder (XNEWVEC (minimal_symbol, alloc_count));
+ msymbols = msym_holder.get ();
/* Copy in the existing minimal symbols, if there are any. */
if (m_objfile->per_bfd->minimal_symbol_count)
- memcpy ((char *) msymbols, (char *) m_objfile->per_bfd->msymbols,
- m_objfile->per_bfd->minimal_symbol_count * sizeof (struct minimal_symbol));
+ memcpy (msymbols, m_objfile->per_bfd->msymbols.get (),
+ m_objfile->per_bfd->minimal_symbol_count
+ * sizeof (struct minimal_symbol));
/* Walk through the list of minimal symbol bunches, adding each symbol
to the new contiguous array of symbols. Note that we start with the
for (bunch = m_msym_bunch; bunch != NULL; bunch = bunch->next)
{
- for (bindex = 0; bindex < m_msym_bunch_index; bindex++, mcount++)
- msymbols[mcount] = bunch->contents[bindex];
+ memcpy (&msymbols[mcount], &bunch->contents[0],
+ m_msym_bunch_index * sizeof (struct minimal_symbol));
+ mcount += m_msym_bunch_index;
m_msym_bunch_index = BUNCH_SIZE;
}
/* Sort the minimal symbols by address. */
- qsort (msymbols, mcount, sizeof (struct minimal_symbol),
- compare_minimal_symbols);
+ std::sort (msymbols, msymbols + mcount, minimal_symbol_is_less_than);
/* Compact out any duplicates, and free up whatever space we are
no longer using. */
mcount = compact_minimal_symbols (msymbols, mcount, m_objfile);
-
- ssize_t shrink_bytes
- = (mcount + 1 - alloc_count) * sizeof (struct minimal_symbol);
- obstack_blank_fast (&m_objfile->per_bfd->storage_obstack, shrink_bytes);
- msymbols = (struct minimal_symbol *)
- obstack_finish (&m_objfile->per_bfd->storage_obstack);
+ msym_holder.reset (XRESIZEVEC (struct minimal_symbol,
+ msym_holder.release (),
+ mcount));
/* Attach the minimal symbol table to the specified objfile.
The strings themselves are also located in the storage_obstack
of this objfile. */
m_objfile->per_bfd->minimal_symbol_count = mcount;
- m_objfile->per_bfd->msymbols = msymbols;
+ m_objfile->per_bfd->msymbols = std::move (msym_holder);
- /* Now build the hash tables; we can't do this incrementally
- at an earlier point since we weren't finished with the obstack
- yet. (And if the msymbol obstack gets moved, all the internal
- pointers to other msymbols need to be adjusted.) */
build_minimal_symbol_hash_tables (m_objfile);
}
}
CORE_ADDR
minimal_symbol_upper_bound (struct bound_minimal_symbol minsym)
{
- int i;
short section;
struct obj_section *obj_section;
CORE_ADDR result;
- struct minimal_symbol *msymbol;
+ struct minimal_symbol *iter, *msymbol;
gdb_assert (minsym.minsym != NULL);
other sections, to find the next symbol in this section with a
different address. */
+ struct minimal_symbol *past_the_end
+ = (minsym.objfile->per_bfd->msymbols.get ()
+ + minsym.objfile->per_bfd->minimal_symbol_count);
msymbol = minsym.minsym;
section = MSYMBOL_SECTION (msymbol);
- for (i = 1; MSYMBOL_LINKAGE_NAME (msymbol + i) != NULL; i++)
+ for (iter = msymbol + 1; iter != past_the_end; ++iter)
{
- if ((MSYMBOL_VALUE_RAW_ADDRESS (msymbol + i)
+ if ((MSYMBOL_VALUE_RAW_ADDRESS (iter)
!= MSYMBOL_VALUE_RAW_ADDRESS (msymbol))
- && MSYMBOL_SECTION (msymbol + i) == section)
+ && MSYMBOL_SECTION (iter) == section)
break;
}
obj_section = MSYMBOL_OBJ_SECTION (minsym.objfile, minsym.minsym);
- if (MSYMBOL_LINKAGE_NAME (msymbol + i) != NULL
- && (MSYMBOL_VALUE_ADDRESS (minsym.objfile, msymbol + i)
+ if (iter != past_the_end
+ && (MSYMBOL_VALUE_ADDRESS (minsym.objfile, iter)
< obj_section_endaddr (obj_section)))
- result = MSYMBOL_VALUE_ADDRESS (minsym.objfile, msymbol + i);
+ result = MSYMBOL_VALUE_ADDRESS (minsym.objfile, iter);
else
/* We got the start address from the last msymbol in the objfile.
So the end address is the end of the section. */