/* Partial symbol tables.
- Copyright (C) 2009-2015 Free Software Foundation, Inc.
+ Copyright (C) 2009-2017 Free Software Foundation, Inc.
This file is part of GDB.
#include "cp-support.h"
#include "gdbcmd.h"
-#ifndef DEV_TTY
-#define DEV_TTY "/dev/tty"
-#endif
-
struct psymbol_bcache
{
struct bcache *bcache;
if (objfile->psymtabs_addrmap != NULL)
{
- pst = addrmap_find (objfile->psymtabs_addrmap, pc);
+ pst = ((struct partial_symtab *)
+ addrmap_find (objfile->psymtabs_addrmap, pc));
if (pst != NULL)
{
/* FIXME: addrmaps currently do not handle overlayed sections,
{
center = bottom + (top - bottom) / 2;
gdb_assert (center < top);
- if (!do_linear_search
- && (SYMBOL_LANGUAGE (*center) == language_java))
- do_linear_search = 1;
if (ordered_compare (SYMBOL_SEARCH_NAME (*center), name) >= 0)
top = center;
else
switch (current_language->la_language)
{
case language_cplus:
- case language_java:
{
if (strchr (name, '('))
{
if (!(center < top))
internal_error (__FILE__, __LINE__,
_("failed internal consistency check"));
- if (!do_linear_search
- && SYMBOL_LANGUAGE (*center) == language_java)
- {
- do_linear_search = 1;
- }
if (strcmp_iw_ordered (SYMBOL_SEARCH_NAME (*center),
search_name) >= 0)
{
if (ps->dirname == NULL || IS_ABSOLUTE_PATH (ps->filename))
fullname = xstrdup (ps->filename);
else
- fullname = concat (ps->dirname, SLASH_STRING, ps->filename, NULL);
+ fullname = concat (ps->dirname, SLASH_STRING,
+ ps->filename, (char *) NULL);
back_to = make_cleanup (xfree, fullname);
ps->fullname = rewrite_source_path (fullname);
static int
compare_psymbols (const void *s1p, const void *s2p)
{
- struct partial_symbol *const *s1 = s1p;
- struct partial_symbol *const *s2 = s2p;
+ struct partial_symbol *const *s1 = (struct partial_symbol * const*) s1p;
+ struct partial_symbol *const *s2 = (struct partial_symbol * const*) s2p;
return strcmp_iw_ordered (SYMBOL_SEARCH_NAME (*s1),
SYMBOL_SEARCH_NAME (*s2));
struct partial_symbol *sym1 = (struct partial_symbol *) addr1;
struct partial_symbol *sym2 = (struct partial_symbol *) addr2;
- return (memcmp (&sym1->ginfo.value, &sym1->ginfo.value,
+ return (memcmp (&sym1->ginfo.value, &sym2->ginfo.value,
sizeof (sym1->ginfo.value)) == 0
&& sym1->ginfo.language == sym2->ginfo.language
&& PSYMBOL_DOMAIN (sym1) == PSYMBOL_DOMAIN (sym2)
struct psymbol_bcache *bcache,
int *added)
{
- return bcache_full (sym,
- sizeof (struct partial_symbol),
- bcache->bcache,
- added);
+ return ((const struct partial_symbol *)
+ bcache_full (sym, sizeof (struct partial_symbol), bcache->bcache,
+ added));
}
/* Helper function, initialises partial symbol structure and stashes
sizeof (struct partial_symtab));
memset (psymtab, 0, sizeof (struct partial_symtab));
- psymtab->filename = bcache (filename, strlen (filename) + 1,
- objfile->per_bfd->filename_cache);
+ psymtab->filename
+ = (const char *) bcache (filename, strlen (filename) + 1,
+ objfile->per_bfd->filename_cache);
psymtab->compunit_symtab = NULL;
/* Prepend it to the psymtab list for the objfile it belongs to.
objfile->free_psymtabs = pst;
}
-/* An object of this type is passed to discard_psymtabs_upto. */
+\f
-struct psymtab_state
-{
- /* The objfile where psymtabs are discarded. */
+/* We need to pass a couple of items to the addrmap_foreach function,
+ so use a struct. */
+struct dump_psymtab_addrmap_data
+{
struct objfile *objfile;
+ struct partial_symtab *psymtab;
+ struct ui_file *outfile;
- /* The first psymtab to save. */
-
- struct partial_symtab *save;
+ /* Non-zero if the previously printed addrmap entry was for PSYMTAB.
+ If so, we want to print the next one as well (since the next addrmap
+ entry defines the end of the range). */
+ int previous_matched;
};
-/* A cleanup function used by make_cleanup_discard_psymtabs. */
+/* Helper function for dump_psymtab_addrmap to print an addrmap entry. */
-static void
-discard_psymtabs_upto (void *arg)
+static int
+dump_psymtab_addrmap_1 (void *datap, CORE_ADDR start_addr, void *obj)
{
- struct psymtab_state *state = arg;
+ struct dump_psymtab_addrmap_data *data
+ = (struct dump_psymtab_addrmap_data *) datap;
+ struct gdbarch *gdbarch = get_objfile_arch (data->objfile);
+ struct partial_symtab *addrmap_psymtab = (struct partial_symtab *) obj;
+ const char *psymtab_address_or_end = NULL;
+
+ QUIT;
+
+ if (data->psymtab == NULL
+ || data->psymtab == addrmap_psymtab)
+ psymtab_address_or_end = host_address_to_string (addrmap_psymtab);
+ else if (data->previous_matched)
+ psymtab_address_or_end = "<ends here>";
+
+ if (data->psymtab == NULL
+ || data->psymtab == addrmap_psymtab
+ || data->previous_matched)
+ {
+ fprintf_filtered (data->outfile, " %s%s %s\n",
+ data->psymtab != NULL ? " " : "",
+ paddress (gdbarch, start_addr),
+ psymtab_address_or_end);
+ }
+
+ data->previous_matched = (data->psymtab == NULL
+ || data->psymtab == addrmap_psymtab);
- while (state->objfile->psymtabs != state->save)
- discard_psymtab (state->objfile, state->objfile->psymtabs);
+ return 0;
}
-/* Return a new cleanup that discards all psymtabs created in OBJFILE
- after this function is called. */
+/* Helper function for maintenance_print_psymbols to print the addrmap
+ of PSYMTAB. If PSYMTAB is NULL print the entire addrmap. */
-struct cleanup *
-make_cleanup_discard_psymtabs (struct objfile *objfile)
+static void
+dump_psymtab_addrmap (struct objfile *objfile, struct partial_symtab *psymtab,
+ struct ui_file *outfile)
{
- struct psymtab_state *state = XNEW (struct psymtab_state);
+ struct dump_psymtab_addrmap_data addrmap_dump_data;
- state->objfile = objfile;
- state->save = objfile->psymtabs;
-
- return make_cleanup_dtor (discard_psymtabs_upto, state, xfree);
+ if ((psymtab == NULL
+ || psymtab->psymtabs_addrmap_supported)
+ && objfile->psymtabs_addrmap != NULL)
+ {
+ addrmap_dump_data.objfile = objfile;
+ addrmap_dump_data.psymtab = psymtab;
+ addrmap_dump_data.outfile = outfile;
+ addrmap_dump_data.previous_matched = 0;
+ fprintf_filtered (outfile, "%sddress map:\n",
+ psymtab == NULL ? "Entire a" : " A");
+ addrmap_foreach (objfile->psymtabs_addrmap, dump_psymtab_addrmap_1,
+ &addrmap_dump_data);
+ }
}
-\f
-
static void
maintenance_print_psymbols (char *args, int from_tty)
{
char **argv;
- struct ui_file *outfile;
+ struct ui_file *outfile = gdb_stdout;
struct cleanup *cleanups;
- char *symname = NULL;
- char *filename = DEV_TTY;
+ char *address_arg = NULL, *source_arg = NULL, *objfile_arg = NULL;
struct objfile *objfile;
struct partial_symtab *ps;
+ int i, outfile_idx, found;
+ CORE_ADDR pc = 0;
+ struct obj_section *section = NULL;
dont_repeat ();
- if (args == NULL)
- {
- error (_("\
-print-psymbols takes an output file name and optional symbol file name"));
- }
argv = gdb_buildargv (args);
cleanups = make_cleanup_freeargv (argv);
- if (argv[0] != NULL)
+ for (i = 0; argv != NULL && argv[i] != NULL; ++i)
{
- filename = argv[0];
- /* If a second arg is supplied, it is a source file name to match on. */
- if (argv[1] != NULL)
+ if (strcmp (argv[i], "-pc") == 0)
+ {
+ if (argv[i + 1] == NULL)
+ error (_("Missing pc value"));
+ address_arg = argv[++i];
+ }
+ else if (strcmp (argv[i], "-source") == 0)
+ {
+ if (argv[i + 1] == NULL)
+ error (_("Missing source file"));
+ source_arg = argv[++i];
+ }
+ else if (strcmp (argv[i], "-objfile") == 0)
{
- symname = argv[1];
+ if (argv[i + 1] == NULL)
+ error (_("Missing objfile name"));
+ objfile_arg = argv[++i];
}
+ else if (strcmp (argv[i], "--") == 0)
+ {
+ /* End of options. */
+ ++i;
+ break;
+ }
+ else if (argv[i][0] == '-')
+ {
+ /* Future proofing: Don't allow OUTFILE to begin with "-". */
+ error (_("Unknown option: %s"), argv[i]);
+ }
+ else
+ break;
}
+ outfile_idx = i;
- filename = tilde_expand (filename);
- make_cleanup (xfree, filename);
+ if (address_arg != NULL && source_arg != NULL)
+ error (_("Must specify at most one of -pc and -source"));
- outfile = gdb_fopen (filename, FOPEN_WT);
- if (outfile == NULL)
- perror_with_name (filename);
- make_cleanup_ui_file_delete (outfile);
+ stdio_file arg_outfile;
- ALL_PSYMTABS (objfile, ps)
+ if (argv != NULL && argv[outfile_idx] != NULL)
{
+ char *outfile_name;
+
+ if (argv[outfile_idx + 1] != NULL)
+ error (_("Junk at end of command"));
+ outfile_name = tilde_expand (argv[outfile_idx]);
+ make_cleanup (xfree, outfile_name);
+ if (!arg_outfile.open (outfile_name, FOPEN_WT))
+ perror_with_name (outfile_name);
+ outfile = &arg_outfile;
+ }
+
+ if (address_arg != NULL)
+ {
+ pc = parse_and_eval_address (address_arg);
+ /* If we fail to find a section, that's ok, try the lookup anyway. */
+ section = find_pc_section (pc);
+ }
+
+ found = 0;
+ ALL_OBJFILES (objfile)
+ {
+ int printed_objfile_header = 0;
+ int print_for_objfile = 1;
+
QUIT;
- if (symname == NULL || filename_cmp (symname, ps->filename) == 0)
- dump_psymtab (objfile, ps, outfile);
+ if (objfile_arg != NULL)
+ print_for_objfile
+ = compare_filenames_for_search (objfile_name (objfile),
+ objfile_arg);
+ if (!print_for_objfile)
+ continue;
+
+ if (address_arg != NULL)
+ {
+ struct bound_minimal_symbol msymbol = { NULL, NULL };
+
+ /* We don't assume each pc has a unique objfile (this is for
+ debugging). */
+ ps = find_pc_sect_psymtab (objfile, pc, section, msymbol);
+ if (ps != NULL)
+ {
+ if (!printed_objfile_header)
+ {
+ outfile->printf ("\nPartial symtabs for objfile %s\n",
+ objfile_name (objfile));
+ printed_objfile_header = 1;
+ }
+ dump_psymtab (objfile, ps, outfile);
+ dump_psymtab_addrmap (objfile, ps, outfile);
+ found = 1;
+ }
+ }
+ else
+ {
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
+ {
+ int print_for_source = 0;
+
+ QUIT;
+ if (source_arg != NULL)
+ {
+ print_for_source
+ = compare_filenames_for_search (ps->filename, source_arg);
+ found = 1;
+ }
+ if (source_arg == NULL
+ || print_for_source)
+ {
+ if (!printed_objfile_header)
+ {
+ outfile->printf ("\nPartial symtabs for objfile %s\n",
+ objfile_name (objfile));
+ printed_objfile_header = 1;
+ }
+ dump_psymtab (objfile, ps, outfile);
+ dump_psymtab_addrmap (objfile, ps, outfile);
+ }
+ }
+ }
+
+ /* If we're printing all the objfile's symbols dump the full addrmap. */
+
+ if (address_arg == NULL
+ && source_arg == NULL
+ && objfile->psymtabs_addrmap != NULL)
+ {
+ outfile->puts ("\n");
+ dump_psymtab_addrmap (objfile, NULL, outfile);
+ }
}
+
+ if (!found)
+ {
+ if (address_arg != NULL)
+ error (_("No partial symtab for address: %s"), address_arg);
+ if (source_arg != NULL)
+ error (_("No partial symtab for source file: %s"), source_arg);
+ }
+
do_cleanups (cleanups);
}
{
add_cmd ("psymbols", class_maintenance, maintenance_print_psymbols, _("\
Print dump of current partial symbol definitions.\n\
-Entries in the partial symbol table are dumped to file OUTFILE.\n\
-If a SOURCE file is specified, dump only that file's partial symbols."),
+Usage: mt print psymbols [-objfile objfile] [-pc address] [--] [outfile]\n\
+ mt print psymbols [-objfile objfile] [-source source] [--] [outfile]\n\
+Entries in the partial symbol table are dumped to file OUTFILE,\n\
+or the terminal if OUTFILE is unspecified.\n\
+If ADDRESS is provided, dump only the file for that address.\n\
+If SOURCE is provided, dump only that file's symbols.\n\
+If OBJFILE is provided, dump only that file's minimal symbols."),
&maintenanceprintlist);
add_cmd ("psymtabs", class_maintenance, maintenance_info_psymtabs, _("\