diff options
Diffstat (limited to 'gdb/symmisc.c')
-rw-r--r-- | gdb/symmisc.c | 219 |
1 files changed, 149 insertions, 70 deletions
diff --git a/gdb/symmisc.c b/gdb/symmisc.c index ba6883d..dd5b13c 100644 --- a/gdb/symmisc.c +++ b/gdb/symmisc.c @@ -40,10 +40,6 @@ #include "psymtab.h" -#ifndef DEV_TTY -#define DEV_TTY "/dev/tty" -#endif - /* Unfortunately for debugging, stderr is usually a macro. This is painful when calling functions that take FILE *'s from the debugger. So we make a variable which has the same value and which is accessible when @@ -412,49 +408,118 @@ static void maintenance_print_symbols (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; - struct objfile *objfile; - struct compunit_symtab *cu; - struct symtab *s; + char *address_arg = NULL, *source_arg = NULL, *objfile_arg = NULL; + int i, outfile_idx; dont_repeat (); - if (args == NULL) - { - error (_("Arguments missing: an output file name " - "and an optional symbol file name")); - } argv = gdb_buildargv (args); cleanups = make_cleanup_freeargv (argv); - if (argv[0] != NULL) + for (i = 0; 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) + { + 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] == '-') { - symname = argv[1]; + /* 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 == 0) - perror_with_name (filename); - make_cleanup_ui_file_delete (outfile); + if (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); + outfile = gdb_fopen (outfile_name, FOPEN_WT); + if (outfile == NULL) + perror_with_name (outfile_name); + make_cleanup_ui_file_delete (outfile); + } - ALL_FILETABS (objfile, cu, s) + if (address_arg != NULL) { - QUIT; - if (symname == NULL - || filename_cmp (symname, symtab_to_filename_for_display (s)) == 0) - dump_symtab (s, outfile); + CORE_ADDR pc = parse_and_eval_address (address_arg); + struct symtab *s = find_pc_line_symtab (pc); + + if (s == NULL) + error (_("No symtab for address: %s"), address_arg); + dump_symtab (s, outfile); } + else + { + struct objfile *objfile; + struct compunit_symtab *cu; + struct symtab *s; + int found = 0; + + ALL_OBJFILES (objfile) + { + int print_for_objfile = 1; + + if (objfile_arg != NULL) + print_for_objfile + = compare_filenames_for_search (objfile_name (objfile), + objfile_arg); + if (!print_for_objfile) + continue; + + ALL_OBJFILE_FILETABS (objfile, cu, s) + { + int print_for_source = 0; + + QUIT; + if (source_arg != NULL) + { + print_for_source + = compare_filenames_for_search + (symtab_to_filename_for_display (s), source_arg); + found = 1; + } + if (source_arg == NULL + || print_for_source) + dump_symtab (s, outfile); + } + } + + if (source_arg != NULL && !found) + error (_("No symtab for source file: %s"), source_arg); + } + do_cleanups (cleanups); } @@ -644,56 +709,63 @@ static void maintenance_print_msymbols (char *args, int from_tty) { char **argv; - struct ui_file *outfile; + struct ui_file *outfile = gdb_stdout; struct cleanup *cleanups; - char *filename = DEV_TTY; - char *symname = NULL; - struct program_space *pspace; + char *objfile_arg = NULL; struct objfile *objfile; - - struct stat sym_st, obj_st; + int i, outfile_idx; dont_repeat (); - if (args == NULL) - { - error (_("print-msymbols 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[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], "-objfile") == 0) { - symname = gdb_realpath (argv[1]); - make_cleanup (xfree, symname); - if (symname && stat (symname, &sym_st)) - perror_with_name (symname); + 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 (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); + outfile = gdb_fopen (outfile_name, FOPEN_WT); + if (outfile == NULL) + perror_with_name (outfile_name); + make_cleanup_ui_file_delete (outfile); + } - outfile = gdb_fopen (filename, FOPEN_WT); - if (outfile == 0) - perror_with_name (filename); - make_cleanup_ui_file_delete (outfile); + ALL_OBJFILES (objfile) + { + QUIT; + if (objfile_arg == NULL + || compare_filenames_for_search (objfile_name (objfile), objfile_arg)) + dump_msymbols (objfile, outfile); + } - ALL_PSPACES (pspace) - ALL_PSPACE_OBJFILES (pspace, objfile) - { - QUIT; - if (symname == NULL || (!stat (objfile_name (objfile), &obj_st) - && sym_st.st_dev == obj_st.st_dev - && sym_st.st_ino == obj_st.st_ino)) - dump_msymbols (objfile, outfile); - } - fprintf_filtered (outfile, "\n\n"); do_cleanups (cleanups); } @@ -1047,14 +1119,21 @@ _initialize_symmisc (void) add_cmd ("symbols", class_maintenance, maintenance_print_symbols, _("\ Print dump of current symbol definitions.\n\ -Entries in the full symbol table are dumped to file OUTFILE.\n\ -If a SOURCE file is specified, dump only that file's symbols."), +Usage: mt print symbols [-pc address] [--] [outfile]\n\ + mt print symbols [-objfile objfile] [-source source] [--] [outfile]\n\ +Entries in the full 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 ("msymbols", class_maintenance, maintenance_print_msymbols, _("\ Print dump of current minimal symbol definitions.\n\ -Entries in the minimal symbol table are dumped to file OUTFILE.\n\ -If a SOURCE file is specified, dump only that file's minimal symbols."), +Usage: mt print msymbols [-objfile objfile] [--] [outfile]\n\ +Entries in the minimal symbol table are dumped to file OUTFILE,\n\ +or the terminal if OUTFILE is unspecified.\n\ +If OBJFILE is provided, dump only that file's minimal symbols."), &maintenanceprintlist); add_cmd ("objfiles", class_maintenance, maintenance_print_objfiles, |