diff options
author | Tom Tromey <tromey@redhat.com> | 2012-07-25 15:47:09 +0000 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2012-07-25 15:47:09 +0000 |
commit | d6b289409bc58646f2a8ca2744e78fbee349497e (patch) | |
tree | 9fea6effd38c9f6841cda97886d26fc29eea82dc /gdb/gdb_bfd.c | |
parent | 6e73ba20e607a06a7cf275e648cd35d011c1f6bd (diff) | |
download | gdb-d6b289409bc58646f2a8ca2744e78fbee349497e.zip gdb-d6b289409bc58646f2a8ca2744e78fbee349497e.tar.gz gdb-d6b289409bc58646f2a8ca2744e78fbee349497e.tar.bz2 |
* NEWS: Mention maint info bfds.
* gdb_bfd.c (all_bfds): New global.
(gdb_bfd_ref, gdb_bfd_unref): Update all_bfds.
(print_one_bfd, maintenance_info_bfds, _initialize_gdb_bfd):
New functions.
gdb/doc
* gdb.texinfo (Maintenance Commands): Document maint info bfds.
Diffstat (limited to 'gdb/gdb_bfd.c')
-rw-r--r-- | gdb/gdb_bfd.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c index 1e6af49..40e1c4d 100644 --- a/gdb/gdb_bfd.c +++ b/gdb/gdb_bfd.c @@ -22,6 +22,8 @@ #include "gdb_bfd.h" #include "gdb_assert.h" #include "gdb_string.h" +#include "ui-out.h" +#include "gdbcmd.h" #include "hashtab.h" #ifdef HAVE_ZLIB_H #include <zlib.h> @@ -48,6 +50,13 @@ struct gdb_bfd_section_data void *map_addr; }; +/* A hash table holding every BFD that gdb knows about. This is not + to be confused with 'gdb_bfd_cache', which is used for sharing + BFDs; in contrast, this hash is used just to implement + "maint info bfd". */ + +static htab_t all_bfds; + /* See gdb_bfd.h. */ void @@ -224,6 +233,7 @@ void gdb_bfd_ref (struct bfd *abfd) { struct gdb_bfd_data *gdata; + void **slot; if (abfd == NULL) return; @@ -240,6 +250,11 @@ gdb_bfd_ref (struct bfd *abfd) gdata->refc = 1; gdata->mtime = bfd_get_mtime (abfd); bfd_usrdata (abfd) = gdata; + + /* This is the first we've seen it, so add it to the hash table. */ + slot = htab_find_slot (all_bfds, abfd, INSERT); + gdb_assert (slot && !*slot); + *slot = abfd; } /* See gdb_bfd.h. */ @@ -249,6 +264,7 @@ gdb_bfd_unref (struct bfd *abfd) { struct gdb_bfd_data *gdata; struct gdb_bfd_cache_search search; + void **slot; if (abfd == NULL) return; @@ -277,6 +293,8 @@ gdb_bfd_unref (struct bfd *abfd) bfd_usrdata (abfd) = NULL; /* Paranoia. */ + htab_remove_elt (all_bfds, abfd); + gdb_bfd_close_or_warn (abfd); } @@ -595,3 +613,58 @@ gdb_bfd_fdopenr (const char *filename, const char *target, int fd) return result; } + + + +/* A callback for htab_traverse that prints a single BFD. */ + +static int +print_one_bfd (void **slot, void *data) +{ + bfd *abfd = *slot; + struct gdb_bfd_data *gdata = bfd_usrdata (abfd); + struct ui_out *uiout = data; + struct cleanup *inner; + + inner = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); + ui_out_field_int (uiout, "refcount", gdata->refc); + ui_out_field_string (uiout, "addr", host_address_to_string (abfd)); + ui_out_field_string (uiout, "filename", bfd_get_filename (abfd)); + ui_out_text (uiout, "\n"); + do_cleanups (inner); + + return 1; +} + +/* Implement the 'maint info bfd' command. */ + +static void +maintenance_info_bfds (char *arg, int from_tty) +{ + struct cleanup *cleanup; + struct ui_out *uiout = current_uiout; + + cleanup = make_cleanup_ui_out_table_begin_end (uiout, 3, -1, "bfds"); + ui_out_table_header (uiout, 10, ui_left, "refcount", "Refcount"); + ui_out_table_header (uiout, 18, ui_left, "addr", "Address"); + ui_out_table_header (uiout, 40, ui_left, "filename", "Filename"); + + ui_out_table_body (uiout); + htab_traverse (all_bfds, print_one_bfd, uiout); + + do_cleanups (cleanup); +} + +/* -Wmissing-prototypes */ +extern initialize_file_ftype _initialize_gdb_bfd; + +void +_initialize_gdb_bfd (void) +{ + all_bfds = htab_create_alloc (10, htab_hash_pointer, htab_eq_pointer, + NULL, xcalloc, xfree); + + add_cmd ("bfds", class_maintenance, maintenance_info_bfds, _("\ +List the BFDs that are currently open."), + &maintenanceinfolist); +} |