aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorBob Rossi <bob@brasko.net>2004-06-10 20:05:45 +0000
committerBob Rossi <bob@brasko.net>2004-06-10 20:05:45 +0000
commit57c22c6ce1e294fcec9653c0cf2c37eb77225fe6 (patch)
tree1cf1db59680a0f24ebb22438fa5ef981bf8d8c74 /gdb
parent239ae8c7556347fead17ce5caef2e9a441e89e05 (diff)
downloadgdb-57c22c6ce1e294fcec9653c0cf2c37eb77225fe6.zip
gdb-57c22c6ce1e294fcec9653c0cf2c37eb77225fe6.tar.gz
gdb-57c22c6ce1e294fcec9653c0cf2c37eb77225fe6.tar.bz2
Add the -file-list-exec-source-files command to MI.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog22
-rw-r--r--gdb/dbxread.c12
-rw-r--r--gdb/defs.h2
-rw-r--r--gdb/doc/gdb.texinfo14
-rw-r--r--gdb/dwarf2read.c8
-rw-r--r--gdb/mi/mi-cmd-file.c65
-rw-r--r--gdb/mi/mi-cmds.c2
-rw-r--r--gdb/mi/mi-cmds.h1
-rw-r--r--gdb/source.c128
-rw-r--r--gdb/source.h3
-rw-r--r--gdb/symtab.c4
-rw-r--r--gdb/symtab.h4
-rw-r--r--gdb/testsuite/gdb.mi/mi2-file.exp14
13 files changed, 229 insertions, 50 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 5144d20..59e4343 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,25 @@
+2004-06-03 Bob Rossi <bob@brasko.net>
+
+ * 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 <cagney@gnu.org>
* avr-tdep.c (avr_gdbarch_init): Do not set use_struct_convention
diff --git a/gdb/dbxread.c b/gdb/dbxread.c
index c71b0c8..a505c77 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 9771428..c6e3ec3 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 25a9689..f78b3d4 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 a83a69c..b2efc17 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 eb1d67a..aa20a79 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 0dfc217..918676d 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 095f316..f9a08d9 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 92cdce4..802df92 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 7cfed1a..ecfe1f0 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 d9d94a0..bbcad17 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 6539524..dfde997 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 fe75a93..9742e2c 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