mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-17 13:10:12 +08:00
* symfile.c (clear_symtab_users_once, cashier_psymtab,
free_named_symtabs): Move these routines from symmisc.c.
This commit is contained in:
parent
3cc2ca3f5c
commit
9d19971230
186
gdb/symfile.c
186
gdb/symfile.c
@ -47,6 +47,7 @@ extern char *getenv ();
|
||||
/* Functions this file defines */
|
||||
static bfd *symfile_open();
|
||||
static struct sym_fns *symfile_init();
|
||||
static void clear_symtab_users_once();
|
||||
|
||||
/* List of all available sym_fns. */
|
||||
|
||||
@ -93,6 +94,14 @@ struct complaint complaint_root[1] = {
|
||||
{(char *)0, 0, complaint_root},
|
||||
};
|
||||
|
||||
/* Some actual complaints. */
|
||||
|
||||
struct complaint oldsyms_complaint = {
|
||||
"Replacing old symbols for `%s'", 0, 0 };
|
||||
|
||||
struct complaint empty_symtab_complaint = {
|
||||
"Empty symbol table found for `%s'", 0, 0 };
|
||||
|
||||
|
||||
/* In the following sort, we always make sure that
|
||||
register debug symbol declarations always come before regular
|
||||
@ -723,6 +732,183 @@ clear_complaints ()
|
||||
p->counter = 0;
|
||||
}
|
||||
|
||||
/* clear_symtab_users_once:
|
||||
|
||||
This function is run after symbol reading, or from a cleanup.
|
||||
If an old symbol table was obsoleted, the old symbol table
|
||||
has been blown away, but the other GDB data structures that may
|
||||
reference it have not yet been cleared or re-directed. (The old
|
||||
symtab was zapped, and the cleanup queued, in free_named_symtab()
|
||||
below.)
|
||||
|
||||
This function can be queued N times as a cleanup, or called
|
||||
directly; it will do all the work the first time, and then will be a
|
||||
no-op until the next time it is queued. This works by bumping a
|
||||
counter at queueing time. Much later when the cleanup is run, or at
|
||||
the end of symbol processing (in case the cleanup is discarded), if
|
||||
the queued count is greater than the "done-count", we do the work
|
||||
and set the done-count to the queued count. If the queued count is
|
||||
less than or equal to the done-count, we just ignore the call. This
|
||||
is needed because reading a single .o file will often replace many
|
||||
symtabs (one per .h file, for example), and we don't want to reset
|
||||
the breakpoints N times in the user's face.
|
||||
|
||||
The reason we both queue a cleanup, and call it directly after symbol
|
||||
reading, is because the cleanup protects us in case of errors, but is
|
||||
discarded if symbol reading is successful. */
|
||||
|
||||
static int clear_symtab_users_queued;
|
||||
static int clear_symtab_users_done;
|
||||
|
||||
static void
|
||||
clear_symtab_users_once ()
|
||||
{
|
||||
/* Enforce once-per-`do_cleanups'-semantics */
|
||||
if (clear_symtab_users_queued <= clear_symtab_users_done)
|
||||
return;
|
||||
clear_symtab_users_done = clear_symtab_users_queued;
|
||||
|
||||
printf ("Resetting debugger state after updating old symbol tables\n");
|
||||
|
||||
/* Someday, we should do better than this, by only blowing away
|
||||
the things that really need to be blown. */
|
||||
clear_value_history ();
|
||||
clear_displays ();
|
||||
clear_internalvars ();
|
||||
breakpoint_re_set ();
|
||||
set_default_breakpoint (0, 0, 0, 0);
|
||||
current_source_symtab = 0;
|
||||
}
|
||||
|
||||
/* Delete the specified psymtab, and any others that reference it. */
|
||||
|
||||
cashier_psymtab (pst)
|
||||
struct partial_symtab *pst;
|
||||
{
|
||||
struct partial_symtab *ps, *pprev;
|
||||
int i;
|
||||
|
||||
/* Find its previous psymtab in the chain */
|
||||
for (ps = partial_symtab_list; ps; ps = ps->next) {
|
||||
if (ps == pst)
|
||||
break;
|
||||
pprev = ps;
|
||||
}
|
||||
|
||||
if (ps) {
|
||||
/* Unhook it from the chain. */
|
||||
if (ps == partial_symtab_list)
|
||||
partial_symtab_list = ps->next;
|
||||
else
|
||||
pprev->next = ps->next;
|
||||
|
||||
/* FIXME, we can't conveniently deallocate the entries in the
|
||||
partial_symbol lists (global_psymbols/static_psymbols) that
|
||||
this psymtab points to. These just take up space until all
|
||||
the psymtabs are reclaimed. Ditto the dependencies list and
|
||||
filename, which are all in the psymbol_obstack. */
|
||||
|
||||
/* We need to cashier any psymtab that has this one as a dependency... */
|
||||
again:
|
||||
for (ps = partial_symtab_list; ps; ps = ps->next) {
|
||||
for (i = 0; i < ps->number_of_dependencies; i++) {
|
||||
if (ps->dependencies[i] == pst) {
|
||||
cashier_psymtab (ps);
|
||||
goto again; /* Must restart, chain has been munged. */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If a symtab or psymtab for filename NAME is found, free it along
|
||||
with any dependent breakpoints, displays, etc.
|
||||
Used when loading new versions of object modules with the "add-file"
|
||||
command. This is only called on the top-level symtab or psymtab's name;
|
||||
it is not called for subsidiary files such as .h files.
|
||||
|
||||
Return value is 1 if we blew away the environment, 0 if not.
|
||||
|
||||
FIXME. I think this is not the best way to do this. We should
|
||||
work on being gentler to the environment while still cleaning up
|
||||
all stray pointers into the freed symtab. */
|
||||
|
||||
int
|
||||
free_named_symtabs (name)
|
||||
char *name;
|
||||
{
|
||||
register struct symtab *s;
|
||||
register struct symtab *prev;
|
||||
register struct partial_symtab *ps;
|
||||
register struct partial_symtab *pprev;
|
||||
struct blockvector *bv;
|
||||
int blewit = 0;
|
||||
|
||||
/* Look for a psymtab with the specified name. */
|
||||
|
||||
again2:
|
||||
for (ps = partial_symtab_list; ps; ps = ps->next) {
|
||||
if (!strcmp (name, ps->filename)) {
|
||||
cashier_psymtab (ps); /* Blow it away...and its little dog, too. */
|
||||
goto again2; /* Must restart, chain has been munged */
|
||||
}
|
||||
}
|
||||
|
||||
/* Look for a symtab with the specified name. */
|
||||
|
||||
for (s = symtab_list; s; s = s->next)
|
||||
{
|
||||
if (!strcmp (name, s->filename))
|
||||
break;
|
||||
prev = s;
|
||||
}
|
||||
|
||||
if (s)
|
||||
{
|
||||
if (s == symtab_list)
|
||||
symtab_list = s->next;
|
||||
else
|
||||
prev->next = s->next;
|
||||
|
||||
/* For now, queue a delete for all breakpoints, displays, etc., whether
|
||||
or not they depend on the symtab being freed. This should be
|
||||
changed so that only those data structures affected are deleted. */
|
||||
|
||||
/* But don't delete anything if the symtab is empty.
|
||||
This test is necessary due to a bug in "dbxread.c" that
|
||||
causes empty symtabs to be created for N_SO symbols that
|
||||
contain the pathname of the object file. (This problem
|
||||
has been fixed in GDB 3.9x). */
|
||||
|
||||
bv = BLOCKLIST (s);
|
||||
if (BLOCKLIST_NBLOCKS (bv) > 2
|
||||
|| BLOCK_NSYMS (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK))
|
||||
|| BLOCK_NSYMS (BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)))
|
||||
{
|
||||
complain (&oldsyms_complaint, name);
|
||||
|
||||
clear_symtab_users_queued++;
|
||||
make_cleanup (clear_symtab_users_once, 0);
|
||||
blewit = 1;
|
||||
} else {
|
||||
complain (&empty_symtab_complaint, name);
|
||||
}
|
||||
|
||||
free_symtab (s);
|
||||
}
|
||||
else
|
||||
/* It is still possible that some breakpoints will be affected
|
||||
even though no symtab was found, since the file might have
|
||||
been compiled without debugging, and hence not be associated
|
||||
with a symtab. In order to handle this correctly, we would need
|
||||
to keep a list of text address ranges for undebuggable files.
|
||||
For now, we do nothing, since this is a fairly obscure case. */
|
||||
;
|
||||
|
||||
/* FIXME, what about the misc function vector? */
|
||||
return blewit;
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_symfile ()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user