From 57c22c6ce1e294fcec9653c0cf2c37eb77225fe6 Mon Sep 17 00:00:00 2001 From: Bob Rossi Date: Thu, 10 Jun 2004 20:05:45 +0000 Subject: [PATCH] Add the -file-list-exec-source-files command to MI. --- gdb/ChangeLog | 22 +++++ gdb/dbxread.c | 12 ++- gdb/defs.h | 2 - gdb/doc/gdb.texinfo | 14 +++- gdb/dwarf2read.c | 8 ++ gdb/mi/mi-cmd-file.c | 65 +++++++++++++-- gdb/mi/mi-cmds.c | 2 +- gdb/mi/mi-cmds.h | 1 + gdb/source.c | 128 ++++++++++++++++++++++-------- gdb/source.h | 3 + gdb/symtab.c | 4 +- gdb/symtab.h | 4 + gdb/testsuite/gdb.mi/mi2-file.exp | 14 +++- 13 files changed, 229 insertions(+), 50 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5144d2041fc..59e4343ae5a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,25 @@ +2004-06-03 Bob Rossi + + * dbxread.c (read_dbx_symtab): Set pst->dirname when known. + * dwarf2read.c (partial_die_info) : Add dirname field. + (dwarf2_build_psymtabs_hard) : Set pst->dirname when known. + (read_partial_die) : Save away DW_AT_comp_dir. + * defs.h (symtab_to_filename) : Removed. + * source.c (find_and_open_source) : Added. + (open_source_file): Just calls find_and_open_source. + (symtab_to_filename) : Removed. + (symtab_to_fullname, psymtab_to_fullname ) : Added. + * source.h (psymtab_to_fullname,symtab_to_fullname): Added. + * symtab.c (lookup_symtab): Call symtab_to_fullname instead of + symtab_to_filename. + * symtab.h (partial_symtab): Add dirname field. + * mi/mi-cmd-file.c (FILENAME,FULLNAME): Added. + (mi_cmd_file_list_exec_source_file): Call new function symtab_to_fullname + to find fullname. + (mi_cmd_file_list_exec_source_files): Added. + * mi/mi-cmds.c (mi_cmd_mi_cmds) : Add -file-list-exec-source-files. + * mi/mi-cmds.h (mi_cmd_file_list_exec_source_files): Added. + 2004-06-10 Andrew Cagney * avr-tdep.c (avr_gdbarch_init): Do not set use_struct_convention diff --git a/gdb/dbxread.c b/gdb/dbxread.c index c71b0c8fd5e..a505c7774bc 100644 --- a/gdb/dbxread.c +++ b/gdb/dbxread.c @@ -1457,6 +1457,7 @@ read_dbx_symtab (struct objfile *objfile) static int prev_so_symnum = -10; static int first_so_symnum; char *p; + static char *dirname_nso; int prev_textlow_not_set; valu = nlist.n_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); @@ -1514,18 +1515,27 @@ read_dbx_symtab (struct objfile *objfile) p = strrchr (namestring, '/'); if (p && *(p + 1) == '\000') - continue; /* Simply ignore directory name SOs */ + { + /* Save the directory name SOs locally, then save it into + the psymtab when it's created below. */ + dirname_nso = namestring; + continue; + } /* Some other compilers (C++ ones in particular) emit useless SOs for non-existant .c files. We ignore all subsequent SOs that immediately follow the first. */ if (!pst) + { pst = start_psymtab (objfile, namestring, valu, first_so_symnum * symbol_size, objfile->global_psymbols.next, objfile->static_psymbols.next); + pst->dirname = dirname_nso; + dirname_nso = NULL; + } continue; } diff --git a/gdb/defs.h b/gdb/defs.h index 97714285224..c6e3ec36caf 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -626,8 +626,6 @@ extern void init_source_path (void); extern void init_last_source_visited (void); -extern char *symtab_to_filename (struct symtab *); - /* From exec.c */ extern void exec_set_section_offsets (bfd_signed_vma text_off, diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 25a96894716..f78b3d41535 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -16848,14 +16848,24 @@ There's no @value{GDBN} command which directly corresponds to this one. List the source files for the current executable. +It will always output the filename, but only when GDB can find the absolute +file name of a source file, will it output the fullname. + @subsubheading @value{GDBN} Command There's no @value{GDBN} command which directly corresponds to this one. @code{gdbtk} has an analogous command @samp{gdb_listfiles}. @subsubheading Example -N.A. - +@smallexample +(@value{GDBP}) +-file-list-exec-source-files +^done,files=[ +@{file=foo.c,fullname=/home/foo.c@}, +@{file=/home/bar.c,fullname=/home/bar.c@}, +@{file=gdb_could_not_find_fullpath.c@}] +(@value{GDBP}) +@end smallexample @subheading The @code{-file-list-shared-libraries} Command @findex -file-list-shared-libraries diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index a83a69ccc23..b2efc178baf 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -380,6 +380,7 @@ struct partial_die_info sometimes DW_TAG_MIPS_linkage_name or a string computed in some other fashion. */ char *name; + char *dirname; /* The scope to prepend to our children. This is generally allocated on the comp_unit_obstack, so will disappear @@ -1349,6 +1350,9 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) objfile->global_psymbols.next, objfile->static_psymbols.next); + if (comp_unit_die.dirname) + pst->dirname = xstrdup (comp_unit_die.dirname); + pst->read_symtab_private = (char *) obstack_alloc (&objfile->objfile_obstack, sizeof (struct dwarf2_pinfo)); DWARF_INFO_OFFSET (pst) = beg_of_comp_unit - dwarf2_per_objfile->info_buffer; @@ -4875,6 +4879,10 @@ read_partial_die (struct partial_die_info *part_die, if (part_die->name == NULL) part_die->name = DW_STRING (&attr); break; + case DW_AT_comp_dir: + if (part_die->dirname == NULL) + part_die->dirname = DW_STRING (&attr); + break; case DW_AT_MIPS_linkage_name: part_die->name = DW_STRING (&attr); break; diff --git a/gdb/mi/mi-cmd-file.c b/gdb/mi/mi-cmd-file.c index eb1d67a6a8d..aa20a793f3a 100644 --- a/gdb/mi/mi-cmd-file.c +++ b/gdb/mi/mi-cmd-file.c @@ -25,6 +25,7 @@ #include "ui-out.h" #include "symtab.h" #include "source.h" +#include "objfiles.h" /* Return to the client the absolute path and line number of the current file being executed. */ @@ -39,7 +40,6 @@ mi_cmd_file_list_exec_source_file(char *command, char **argv, int argc) if ( !mi_valid_noargs("mi_cmd_file_list_exec_source_file", argc, argv) ) error ("mi_cmd_file_list_exec_source_file: Usage: No args"); - /* Set the default file and line, also get them */ set_default_source_symtab_and_line(); st = get_current_source_symtab_and_line(); @@ -51,17 +51,68 @@ mi_cmd_file_list_exec_source_file(char *command, char **argv, int argc) error ("mi_cmd_file_list_exec_source_file: No symtab"); /* Extract the fullname if it is not known yet */ - if (st.symtab->fullname == NULL) - symtab_to_filename (st.symtab); - - /* We may not be able to open the file (not available). */ - if (st.symtab->fullname == NULL) - error ("mi_cmd_file_list_exec_source_file: File not found"); + symtab_to_fullname (st.symtab); /* Print to the user the line, filename and fullname */ ui_out_field_int (uiout, "line", st.line); ui_out_field_string (uiout, "file", st.symtab->filename); + + /* We may not be able to open the file (not available). */ + if (st.symtab->fullname) ui_out_field_string (uiout, "fullname", st.symtab->fullname); return MI_CMD_DONE; } + +enum mi_cmd_result +mi_cmd_file_list_exec_source_files (char *command, char **argv, int argc) +{ + struct symtab *s; + struct partial_symtab *ps; + struct objfile *objfile; + + if (!mi_valid_noargs ("mi_cmd_file_list_exec_source_files", argc, argv)) + error ("mi_cmd_file_list_exec_source_files: Usage: No args"); + + /* Print the table header */ + ui_out_begin (uiout, ui_out_type_list, "files"); + + /* Look at all of the symtabs */ + ALL_SYMTABS (objfile, s) + { + ui_out_begin (uiout, ui_out_type_tuple, NULL); + + ui_out_field_string (uiout, "file", s->filename); + + /* Extract the fullname if it is not known yet */ + symtab_to_fullname (s); + + if (s->fullname) + ui_out_field_string (uiout, "fullname", s->fullname); + + ui_out_end (uiout, ui_out_type_tuple); + } + + /* Look at all of the psymtabs */ + ALL_PSYMTABS (objfile, ps) + { + if (!ps->readin) + { + ui_out_begin (uiout, ui_out_type_tuple, NULL); + + ui_out_field_string (uiout, "file", ps->filename); + + /* Extract the fullname if it is not known yet */ + psymtab_to_fullname (ps); + + if (ps->fullname) + ui_out_field_string (uiout, "fullname", ps->fullname); + + ui_out_end (uiout, ui_out_type_tuple); + } + } + + ui_out_end (uiout, ui_out_type_list); + + return MI_CMD_DONE; +} diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c index 0dfc2170ec9..918676df26d 100644 --- a/gdb/mi/mi-cmds.c +++ b/gdb/mi/mi-cmds.c @@ -81,7 +81,7 @@ struct mi_cmd mi_cmds[] = { "file-exec-file", { "exec-file", 1 }, NULL, NULL }, { "file-list-exec-sections", { NULL, 0 }, NULL, NULL }, { "file-list-exec-source-file", { NULL, 0 }, 0, mi_cmd_file_list_exec_source_file}, - { "file-list-exec-source-files", { NULL, 0 }, NULL, NULL }, + { "file-list-exec-source-files", { NULL, 0 }, NULL, mi_cmd_file_list_exec_source_files }, { "file-list-shared-libraries", { NULL, 0 }, NULL, NULL }, { "file-list-symbol-files", { NULL, 0 }, NULL, NULL }, { "file-symbol-file", { "symbol-file", 1 }, NULL, NULL }, diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h index 095f31679f3..f9a08d9d30d 100644 --- a/gdb/mi/mi-cmds.h +++ b/gdb/mi/mi-cmds.h @@ -87,6 +87,7 @@ extern mi_cmd_args_ftype mi_cmd_exec_step_instruction; extern mi_cmd_args_ftype mi_cmd_exec_until; extern mi_cmd_args_ftype mi_cmd_exec_interrupt; extern mi_cmd_argv_ftype mi_cmd_file_list_exec_source_file; +extern mi_cmd_argv_ftype mi_cmd_file_list_exec_source_files; extern mi_cmd_argv_ftype mi_cmd_gdb_exit; extern mi_cmd_argv_ftype mi_cmd_interpreter_exec; extern mi_cmd_argv_ftype mi_cmd_stack_info_depth; diff --git a/gdb/source.c b/gdb/source.c index 92cdce426e6..802df92c913 100644 --- a/gdb/source.c +++ b/gdb/source.c @@ -805,30 +805,46 @@ source_full_path_of (char *filename, char **full_pathname) return 1; } - -/* Open a source file given a symtab S. Returns a file descriptor or - negative number for error. */ - +/* This function is capable of finding the absolute path to a + source file, and opening it, provided you give it an + OBJFILE and FILENAME. Both the DIRNAME and FULLNAME are only + added suggestions on where to find the file. + + OBJFILE should be the objfile associated with a psymtab or symtab. + FILENAME should be the filename to open. + DIRNAME is the compilation directory of a particular source file. + Only some debug formats provide this info. + FULLNAME can be the last known absolute path to the file in question. + + On Success + A valid file descriptor is returned. ( the return value is positive ) + FULLNAME is set to the absolute path to the file just opened. + + On Failure + A non valid file descriptor is returned. ( the return value is negitive ) + FULLNAME is set to NULL. */ int -open_source_file (struct symtab *s) +find_and_open_source (struct objfile *objfile, + const char *filename, + const char *dirname, + char **fullname) { char *path = source_path; const char *p; int result; - char *fullname; /* Quick way out if we already know its full name */ - if (s->fullname) + if (*fullname) { - result = open (s->fullname, OPEN_MODE); + result = open (*fullname, OPEN_MODE); if (result >= 0) return result; /* Didn't work -- free old one, try again. */ - xmfree (s->objfile->md, s->fullname); - s->fullname = NULL; + xmfree (objfile->md, *fullname); + *fullname = NULL; } - if (s->dirname != NULL) + if (dirname != NULL) { /* Replace a path entry of $cdir with the compilation directory name */ #define cdir_len 5 @@ -841,60 +857,106 @@ open_source_file (struct symtab *s) int len; path = (char *) - alloca (strlen (source_path) + 1 + strlen (s->dirname) + 1); + alloca (strlen (source_path) + 1 + strlen (dirname) + 1); len = p - source_path; strncpy (path, source_path, len); /* Before $cdir */ - strcpy (path + len, s->dirname); /* new stuff */ + strcpy (path + len, dirname); /* new stuff */ strcat (path + len, source_path + len + cdir_len); /* After $cdir */ } } - result = openp (path, 0, s->filename, OPEN_MODE, 0, &s->fullname); + result = openp (path, 0, filename, OPEN_MODE, 0, fullname); if (result < 0) { /* Didn't work. Try using just the basename. */ - p = lbasename (s->filename); - if (p != s->filename) - result = openp (path, 0, p, OPEN_MODE, 0, &s->fullname); + p = lbasename (filename); + if (p != filename) + result = openp (path, 0, p, OPEN_MODE, 0, fullname); } if (result >= 0) { - fullname = s->fullname; - s->fullname = mstrsave (s->objfile->md, s->fullname); - xfree (fullname); + char *tmp_fullname; + tmp_fullname = *fullname; + *fullname = mstrsave (objfile->md, *fullname); + xfree (tmp_fullname); } return result; } -/* Return the path to the source file associated with symtab. Returns NULL - if no symtab. */ +/* Open a source file given a symtab S. Returns a file descriptor or + negative number for error. + + This function is a convience function to find_and_open_source. */ + +int +open_source_file (struct symtab *s) +{ + if (!s) + return -1; + + return find_and_open_source (s->objfile, s->filename, s->dirname, + &s->fullname); +} + +/* Finds the fullname that a symtab represents. + + If this functions finds the fullname, it will save it in ps->fullname + and it will also return the value. + If this function fails to find the file that this symtab represents, + NULL will be returned and ps->fullname will be set to NULL. */ char * -symtab_to_filename (struct symtab *s) +symtab_to_fullname (struct symtab *s) { - int fd; + int r; if (!s) return NULL; - /* If we've seen the file before, just return fullname. */ + /* Don't check s->fullname here, the file could have been + deleted/moved/..., look for it again */ + r = + find_and_open_source (s->objfile, s->filename, s->dirname, &s->fullname); - if (s->fullname) + if (r) + { + close (r); return s->fullname; + } - /* Try opening the file to setup fullname */ + return NULL; +} - fd = open_source_file (s); - if (fd < 0) - return s->filename; /* File not found. Just use short name */ +/* Finds the fullname that a partial_symtab represents. - /* Found the file. Cleanup and return the full name */ + If this functions finds the fullname, it will save it in ps->fullname + and it will also return the value. - close (fd); - return s->fullname; + If this function fails to find the file that this partial_symtab represents, + NULL will be returned and ps->fullname will be set to NULL. */ +char * +psymtab_to_fullname (struct partial_symtab *ps) +{ + int r; + + if (!ps) + return NULL; + + /* Don't check ps->fullname here, the file could have been + deleted/moved/..., look for it again */ + r = + find_and_open_source (ps->objfile, ps->filename, ps->dirname, + &ps->fullname); + + if (r) + { + close (r); + return ps->fullname; } + return NULL; +} /* Create and initialize the table S->line_charpos that records the positions of the lines in the source file, which is assumed diff --git a/gdb/source.h b/gdb/source.h index 7cfed1ae0e8..ecfe1f0f696 100644 --- a/gdb/source.h +++ b/gdb/source.h @@ -27,6 +27,9 @@ struct symtab; negative number for error. */ extern int open_source_file (struct symtab *s); +extern char* psymtab_to_fullname (struct partial_symtab *ps); +extern char* symtab_to_fullname (struct symtab *s); + /* Create and initialize the table S->line_charpos that records the positions of the lines in the source file, which is assumed to be open on descriptor DESC. All set S->nlines to the number of such diff --git a/gdb/symtab.c b/gdb/symtab.c index d9d94a0c825..bbcad17e3e3 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -181,7 +181,7 @@ got_symtab: if (full_path != NULL) { - const char *fp = symtab_to_filename (s); + const char *fp = symtab_to_fullname (s); if (FILENAME_CMP (full_path, fp) == 0) { return s; @@ -190,7 +190,7 @@ got_symtab: if (real_path != NULL) { - char *rp = gdb_realpath (symtab_to_filename (s)); + char *rp = gdb_realpath (symtab_to_fullname (s)); make_cleanup (xfree, rp); if (FILENAME_CMP (real_path, rp) == 0) { diff --git a/gdb/symtab.h b/gdb/symtab.h index 65395241313..dfde99788e2 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -891,6 +891,10 @@ struct partial_symtab char *fullname; + /* Directory in which it was compiled, or NULL if we don't know. */ + + char *dirname; + /* Information about the object file from which symbols should be read. */ struct objfile *objfile; diff --git a/gdb/testsuite/gdb.mi/mi2-file.exp b/gdb/testsuite/gdb.mi/mi2-file.exp index fe75a934197..9742e2c8a40 100644 --- a/gdb/testsuite/gdb.mi/mi2-file.exp +++ b/gdb/testsuite/gdb.mi/mi2-file.exp @@ -47,7 +47,7 @@ mi_delete_breakpoints mi_gdb_reinitialize_dir $srcdir/$subdir mi_gdb_load ${binfile} -proc test_tbreak_creation_and_listing {} { +proc test_file_list_exec_source_file {} { global srcfile global srcdir global subdir @@ -59,7 +59,17 @@ proc test_tbreak_creation_and_listing {} { "request path info of current source file (${srcfile})" } -test_tbreak_creation_and_listing +proc test_file_list_exec_source_files {} { + global srcfile + + # get the path and absolute path to the current executable + mi_gdb_test "222-file-list-exec-source-files" \ + "222\\\^done,files=\\\[\{file=\".*/${srcfile}\",fullname=\"/.*/${srcfile}\"\},\{file=\".*\"\},\{file=\".*\"\},\{file=\".*\"\},\{file=\".*\"\}\\\]" \ + "Getting a list of source files." +} + +test_file_list_exec_source_file +test_file_list_exec_source_files mi_gdb_exit return 0 -- 2.30.2