From 233d95b548ec948c4a6d01cd05c307385dd615fb Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Sun, 3 Feb 2013 16:25:56 +0000 Subject: [PATCH] gdb/ * dwarf2read.c (file_file_name): New function with code from file_full_name. (file_full_name): Move most of the code to file_file_name. (macro_start_file): Rename variable full_name to file_name and use file_file_name for it. Add comp_dir parameter to new_macro_table. * macrocmd.c (show_pp_source_pos): New variable fullname. Replace any macro_source_file->filename access by macro_source_fullname call. * macroscope.c (_initialize_macroscope): Update the new_macro_table caller. * macrotab.c (struct macro_table): New field comp_dir. (macro_include): New variables link_fullname and source_fullname. Replace any macro_source_file->filename access by macro_source_fullname call. (macro_lookup_inclusion): Remove the partial filenames checking code. (check_for_redefinition): New variables source_fullname and found_key_fullname. Replace any macro_source_file->filename access by macro_source_fullname call. (macro_undef): New variables source_fullname and key_fullname. Replace any macro_source_file->filename access by macro_source_fullname call. (macro_lookup_definition): New variables retval and source_fullname. Replace any macro_source_file->filename access by macro_source_fullname call. (foreach_macro): New variable key_fullname. Replace any macro_source_file->filename access by macro_source_fullname call. (foreach_macro_in_scope): New variable datum_fullname. Replace any macro_source_file->filename access by macro_source_fullname call. (new_macro_table): Add parameter comp_dir. Initialize T with it. (macro_source_fullname): New function. * macrotab.h (struct macro_source_file): Extent the filename field comment. (new_macro_table): New parameter comp_dir, add a comment for it. (macro_source_fullname): new declaration. gdb/testsuite/ * gdb.linespec/base/one/header.h: New file. * gdb.linespec/base/two/header.h: New file. * gdb.linespec/macro-relative.c: New file. * gdb.linespec/macro-relative.exp: New file. --- gdb/ChangeLog | 35 ++++++++++ gdb/dwarf2read.c | 65 ++++++++++-------- gdb/macrocmd.c | 11 ++- gdb/macroscope.c | 2 +- gdb/macrotab.c | 98 ++++++++++++++++++--------- gdb/macrotab.h | 19 +++++- gdb/testsuite/ChangeLog | 7 ++ gdb/testsuite/gdb.linespec/base/one/header.h | 29 ++++++++ gdb/testsuite/gdb.linespec/base/two/header.h | 29 ++++++++ gdb/testsuite/gdb.linespec/macro-relative.c | 29 ++++++++ gdb/testsuite/gdb.linespec/macro-relative.exp | 47 +++++++++++++ 11 files changed, 302 insertions(+), 69 deletions(-) create mode 100644 gdb/testsuite/gdb.linespec/base/one/header.h create mode 100644 gdb/testsuite/gdb.linespec/base/two/header.h create mode 100644 gdb/testsuite/gdb.linespec/macro-relative.c create mode 100644 gdb/testsuite/gdb.linespec/macro-relative.exp diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 53ee3c4..a7f2e0c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,40 @@ 2013-02-03 Jan Kratochvil + * dwarf2read.c (file_file_name): New function with code from + file_full_name. + (file_full_name): Move most of the code to file_file_name. + (macro_start_file): Rename variable full_name to file_name and use + file_file_name for it. Add comp_dir parameter to new_macro_table. + * macrocmd.c (show_pp_source_pos): New variable fullname. Replace any + macro_source_file->filename access by macro_source_fullname call. + * macroscope.c (_initialize_macroscope): Update the new_macro_table + caller. + * macrotab.c (struct macro_table): New field comp_dir. + (macro_include): New variables link_fullname and source_fullname. + Replace any macro_source_file->filename access by macro_source_fullname + call. + (macro_lookup_inclusion): Remove the partial filenames checking code. + (check_for_redefinition): New variables source_fullname and + found_key_fullname. Replace any macro_source_file->filename access by + macro_source_fullname call. + (macro_undef): New variables source_fullname and key_fullname. Replace + any macro_source_file->filename access by macro_source_fullname call. + (macro_lookup_definition): New variables retval and source_fullname. + Replace any macro_source_file->filename access by macro_source_fullname + call. + (foreach_macro): New variable key_fullname. Replace any + macro_source_file->filename access by macro_source_fullname call. + (foreach_macro_in_scope): New variable datum_fullname. Replace any + macro_source_file->filename access by macro_source_fullname call. + (new_macro_table): Add parameter comp_dir. Initialize T with it. + (macro_source_fullname): New function. + * macrotab.h (struct macro_source_file): Extent the filename field + comment. + (new_macro_table): New parameter comp_dir, add a comment for it. + (macro_source_fullname): new declaration. + +2013-02-03 Jan Kratochvil + * dwarf2read.c (dw2_map_symtabs_matching_filename): Move variable this_real_name to outer block. Use it also for compare_filenames_for_search. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index e017586..d26e7c8 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -18034,12 +18034,12 @@ dwarf_alloc_die (struct dwarf2_cu *cu, int num_attrs) /* Macro support. */ -/* Return the full name of file number I in *LH's file name table. - Use COMP_DIR as the name of the current directory of the - compilation. The result is allocated using xmalloc; the caller is +/* Return file name relative to the compilation directory of file number I in + *LH's file name table. The result is allocated using xmalloc; the caller is responsible for freeing it. */ + static char * -file_full_name (int file, struct line_header *lh, const char *comp_dir) +file_file_name (int file, struct line_header *lh) { /* Is the file number a valid index into the line header's file name table? Remember that file numbers start with one, not zero. */ @@ -18047,27 +18047,10 @@ file_full_name (int file, struct line_header *lh, const char *comp_dir) { struct file_entry *fe = &lh->file_names[file - 1]; - if (IS_ABSOLUTE_PATH (fe->name)) + if (IS_ABSOLUTE_PATH (fe->name) || fe->dir_index == 0) return xstrdup (fe->name); - else - { - const char *dir; - - if (fe->dir_index == 0) - dir = comp_dir; - else - { - dir = lh->include_dirs[fe->dir_index - 1]; - if (!IS_ABSOLUTE_PATH (dir)) - return concat (comp_dir, SLASH_STRING, dir, SLASH_STRING, - fe->name, NULL); - } - - if (dir) - return concat (dir, SLASH_STRING, fe->name, NULL); - else - return xstrdup (fe->name); - } + return concat (lh->include_dirs[fe->dir_index - 1], SLASH_STRING, + fe->name, NULL); } else { @@ -18087,6 +18070,27 @@ file_full_name (int file, struct line_header *lh, const char *comp_dir) } } +/* Return the full name of file number I in *LH's file name table. + Use COMP_DIR as the name of the current directory of the + compilation. The result is allocated using xmalloc; the caller is + responsible for freeing it. */ +static char * +file_full_name (int file, struct line_header *lh, const char *comp_dir) +{ + /* Is the file number a valid index into the line header's file name + table? Remember that file numbers start with one, not zero. */ + if (1 <= file && file <= lh->num_file_names) + { + char *relative = file_file_name (file, lh); + + if (IS_ABSOLUTE_PATH (relative) || comp_dir == NULL) + return relative; + return reconcat (relative, comp_dir, SLASH_STRING, relative, NULL); + } + else + return file_file_name (file, lh); +} + static struct macro_source_file * macro_start_file (int file, int line, @@ -18094,26 +18098,27 @@ macro_start_file (int file, int line, const char *comp_dir, struct line_header *lh, struct objfile *objfile) { - /* The full name of this source file. */ - char *full_name = file_full_name (file, lh, comp_dir); + /* File name relative to the compilation directory of this source file. */ + char *file_name = file_file_name (file, lh); /* We don't create a macro table for this compilation unit at all until we actually get a filename. */ if (! pending_macros) pending_macros = new_macro_table (&objfile->per_bfd->storage_obstack, - objfile->per_bfd->macro_cache); + objfile->per_bfd->macro_cache, + comp_dir); if (! current_file) { /* If we have no current file, then this must be the start_file directive for the compilation unit's main source file. */ - current_file = macro_set_main (pending_macros, full_name); + current_file = macro_set_main (pending_macros, file_name); macro_define_special (pending_macros); } else - current_file = macro_include (current_file, line, full_name); + current_file = macro_include (current_file, line, file_name); - xfree (full_name); + xfree (file_name); return current_file; } diff --git a/gdb/macrocmd.c b/gdb/macrocmd.c index 9e4b083..250a1f0 100644 --- a/gdb/macrocmd.c +++ b/gdb/macrocmd.c @@ -129,13 +129,18 @@ show_pp_source_pos (struct ui_file *stream, struct macro_source_file *file, int line) { - fprintf_filtered (stream, "%s:%d\n", file->filename, line); + char *fullname; + + fullname = macro_source_fullname (file); + fprintf_filtered (stream, "%s:%d\n", fullname, line); + xfree (fullname); while (file->included_by) { - fprintf_filtered (gdb_stdout, " included at %s:%d\n", - file->included_by->filename, + fullname = macro_source_fullname (file->included_by); + fprintf_filtered (gdb_stdout, " included at %s:%d\n", fullname, file->included_at_line); + xfree (fullname); file = file->included_by; } } diff --git a/gdb/macroscope.c b/gdb/macroscope.c index c7a6c35..03f9df4 100644 --- a/gdb/macroscope.c +++ b/gdb/macroscope.c @@ -159,7 +159,7 @@ extern initialize_file_ftype _initialize_macroscope; void _initialize_macroscope (void) { - macro_user_macros = new_macro_table (0, 0); + macro_user_macros = new_macro_table (NULL, NULL, NULL); macro_set_main (macro_user_macros, ""); macro_allow_redefinitions (macro_user_macros); } diff --git a/gdb/macrotab.c b/gdb/macrotab.c index 31ca830..2e5592b 100644 --- a/gdb/macrotab.c +++ b/gdb/macrotab.c @@ -48,6 +48,10 @@ struct macro_table #inclusion tree; everything else is #included from here. */ struct macro_source_file *main_source; + /* Compilation directory for all files of this macro table. It is allocated + on objfile's obstack. */ + const char *comp_dir; + /* True if macros in this table can be redefined without issuing an error. */ int redef_ok; @@ -463,6 +467,8 @@ macro_include (struct macro_source_file *source, the new one? */ if (*link && line == (*link)->included_at_line) { + char *link_fullname, *source_fullname; + /* This means the compiler is emitting bogus debug info. (GCC circa March 2002 did this.) It also means that the splay tree ordering function, macro_tree_compare, will abort, @@ -470,9 +476,14 @@ macro_include (struct macro_source_file *source, should tolerate bad debug info. So: First, squawk. */ + + link_fullname = macro_source_fullname (*link); + source_fullname = macro_source_fullname (source); complaint (&symfile_complaints, _("both `%s' and `%s' allegedly #included at %s:%d"), - included, (*link)->filename, source->filename, line); + included, link_fullname, source_fullname, line); + xfree (source_fullname); + xfree (link_fullname); /* Now, choose a new, unoccupied line number for this #inclusion, after the alleged #inclusion line. */ @@ -504,22 +515,6 @@ macro_lookup_inclusion (struct macro_source_file *source, const char *name) if (filename_cmp (name, source->filename) == 0) return source; - /* The filename in the source structure is probably a full path, but - NAME could be just the final component of the name. */ - { - int name_len = strlen (name); - int src_name_len = strlen (source->filename); - - /* We do mean < here, and not <=; if the lengths are the same, - then the filename_cmp above should have triggered, and we need to - check for a slash here. */ - if (name_len < src_name_len - && IS_DIR_SEPARATOR (source->filename[src_name_len - name_len - 1]) - && filename_cmp (name, - source->filename + src_name_len - name_len) == 0) - return source; - } - /* It's not us. Try all our children, and return the lowest. */ { struct macro_source_file *child; @@ -730,11 +725,17 @@ check_for_redefinition (struct macro_source_file *source, int line, if (! same) { + char *source_fullname, *found_key_fullname; + + source_fullname = macro_source_fullname (source); + found_key_fullname = macro_source_fullname (found_key->start_file); complaint (&symfile_complaints, _("macro `%s' redefined at %s:%d; " "original definition at %s:%d"), - name, source->filename, line, - found_key->start_file->filename, found_key->start_line); + name, source_fullname, line, found_key_fullname, + found_key->start_line); + xfree (found_key_fullname); + xfree (source_fullname); } return found_key; @@ -853,12 +854,17 @@ macro_undef (struct macro_source_file *source, int line, #definition. */ if (key->end_file) { + char *source_fullname, *key_fullname; + + source_fullname = macro_source_fullname (source); + key_fullname = macro_source_fullname (key->end_file); complaint (&symfile_complaints, _("macro '%s' is #undefined twice," " at %s:%d and %s:%d"), - name, - source->filename, line, - key->end_file->filename, key->end_line); + name, source_fullname, line, key_fullname, + key->end_line); + xfree (key_fullname); + xfree (source_fullname); } /* Whether or not we've seen a prior #undefinition, wipe out @@ -918,8 +924,16 @@ macro_lookup_definition (struct macro_source_file *source, splay_tree_node n = find_definition (name, source, line); if (n) - return fixup_definition (source->filename, line, - (struct macro_definition *) n->value); + { + struct macro_definition *retval; + char *source_fullname; + + source_fullname = macro_source_fullname (source); + retval = fixup_definition (source_fullname, line, + (struct macro_definition *) n->value); + xfree (source_fullname); + return retval; + } else return 0; } @@ -962,9 +976,13 @@ foreach_macro (splay_tree_node node, void *arg) { struct macro_for_each_data *datum = (struct macro_for_each_data *) arg; struct macro_key *key = (struct macro_key *) node->key; - struct macro_definition *def - = fixup_definition (key->start_file->filename, key->start_line, - (struct macro_definition *) node->value); + struct macro_definition *def; + char *key_fullname; + + key_fullname = macro_source_fullname (key->start_file); + def = fixup_definition (key_fullname, key->start_line, + (struct macro_definition *) node->value); + xfree (key_fullname); (*datum->fn) (key->name, def, key->start_file, key->start_line, datum->user_data); @@ -990,9 +1008,13 @@ foreach_macro_in_scope (splay_tree_node node, void *info) { struct macro_for_each_data *datum = (struct macro_for_each_data *) info; struct macro_key *key = (struct macro_key *) node->key; - struct macro_definition *def - = fixup_definition (datum->file->filename, datum->line, - (struct macro_definition *) node->value); + struct macro_definition *def; + char *datum_fullname; + + datum_fullname = macro_source_fullname (datum->file); + def = fixup_definition (datum_fullname, datum->line, + (struct macro_definition *) node->value); + xfree (datum_fullname); /* See if this macro is defined before the passed-in line, and extends past that line. */ @@ -1027,8 +1049,8 @@ macro_for_each_in_scope (struct macro_source_file *file, int line, struct macro_table * -new_macro_table (struct obstack *obstack, - struct bcache *b) +new_macro_table (struct obstack *obstack, struct bcache *b, + const char *comp_dir) { struct macro_table *t; @@ -1042,6 +1064,7 @@ new_macro_table (struct obstack *obstack, t->obstack = obstack; t->bcache = b; t->main_source = NULL; + t->comp_dir = comp_dir; t->redef_ok = 0; t->definitions = (splay_tree_new_with_allocator (macro_tree_compare, @@ -1064,3 +1087,14 @@ free_macro_table (struct macro_table *table) /* Free the table of macro definitions. */ splay_tree_delete (table->definitions); } + +/* See macrotab.h for the comment. */ + +char * +macro_source_fullname (struct macro_source_file *file) +{ + if (file->table->comp_dir == NULL || IS_ABSOLUTE_PATH (file->filename)) + return xstrdup (file->filename); + + return concat (file->table->comp_dir, SLASH_STRING, file->filename, NULL); +} diff --git a/gdb/macrotab.h b/gdb/macrotab.h index eeef7ee..075dfd9 100644 --- a/gdb/macrotab.h +++ b/gdb/macrotab.h @@ -125,7 +125,9 @@ struct macro_source_file a part of. */ struct macro_table *table; - /* A source file --- possibly a header file. */ + /* A source file --- possibly a header file. This filename is relative to + the compilation directory (table->comp_dir), it exactly matches the + symtab->filename content. */ const char *filename; /* The location we were #included from, or zero if we are the @@ -152,7 +154,8 @@ struct macro_source_file xmalloc if OBSTACK is zero. Use BCACHE to store all macro names, arguments, definitions, and anything else that might be the same amongst compilation units in an executable file; if BCACHE is zero, - don't cache these things. + don't cache these things. COMP_DIR optionally contains the compilation + directory of all files for this macro table. Note that, if either OBSTACK or BCACHE are non-zero, then removing information from the table may leak memory. Neither obstacks nor @@ -164,7 +167,8 @@ struct macro_source_file the same source location (although 'gcc -DFOO -UFOO -DFOO=2' does do that in GCC 4.1.2.). */ struct macro_table *new_macro_table (struct obstack *obstack, - struct bcache *bcache); + struct bcache *bcache, + const char *comp_dir); /* Free TABLE, and any macro definitions, source file structures, @@ -347,5 +351,14 @@ void macro_for_each_in_scope (struct macro_source_file *file, int line, macro_callback_fn fn, void *user_data); +/* Return FILE->filename with possibly prepended compilation directory name. + This is raw concatenation without the "set substitute-path" and gdb_realpath + applications done by symtab_to_fullname. Returned string must be freed by + xfree. + + THis function ignores the "set filename-display" setting. Its default + setting is "relative" which is backward compatible but the former behavior + of macro filenames printing was "absolute". */ +extern char *macro_source_fullname (struct macro_source_file *file); #endif /* MACROTAB_H */ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index b8011eb..ea61dd8 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,12 @@ 2013-02-03 Jan Kratochvil + * gdb.linespec/base/one/header.h: New file. + * gdb.linespec/base/two/header.h: New file. + * gdb.linespec/macro-relative.c: New file. + * gdb.linespec/macro-relative.exp: New file. + +2013-02-03 Jan Kratochvil + * gdb.base/fullpath-expand-func.c: New file. * gdb.base/fullpath-expand.c: New file. * gdb.base/fullpath-expand.exp: New file. diff --git a/gdb/testsuite/gdb.linespec/base/one/header.h b/gdb/testsuite/gdb.linespec/base/one/header.h new file mode 100644 index 0000000..f437495 --- /dev/null +++ b/gdb/testsuite/gdb.linespec/base/one/header.h @@ -0,0 +1,29 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2013 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#if 1 +# define HEADER 1 +#endif +#if 0 +# undef HEADER +# define HEADER 2 +void header_two_func (void) {} +#endif +#if 1 +/* #include "header.h" does not work, why? */ +# include +#endif diff --git a/gdb/testsuite/gdb.linespec/base/two/header.h b/gdb/testsuite/gdb.linespec/base/two/header.h new file mode 100644 index 0000000..aab791b --- /dev/null +++ b/gdb/testsuite/gdb.linespec/base/two/header.h @@ -0,0 +1,29 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2013 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#if 0 +# define HEADER 1 +#endif +#if 1 +# undef HEADER +# define HEADER 2 +void header_two_func (void) {} +#endif +#if 0 +/* #include "header.h" does not work, why? */ +# include +#endif diff --git a/gdb/testsuite/gdb.linespec/macro-relative.c b/gdb/testsuite/gdb.linespec/macro-relative.c new file mode 100644 index 0000000..7bb40b4 --- /dev/null +++ b/gdb/testsuite/gdb.linespec/macro-relative.c @@ -0,0 +1,29 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2013 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* GCC cannot compile directly a .h file. */ + +/* Use trailing "./header.h" to match the #include line in "one/header.h". */ + +#include "../one/./header.h" + +int +main (void) +{ + header_two_func (); + return 0; +} diff --git a/gdb/testsuite/gdb.linespec/macro-relative.exp b/gdb/testsuite/gdb.linespec/macro-relative.exp new file mode 100644 index 0000000..0a056e3 --- /dev/null +++ b/gdb/testsuite/gdb.linespec/macro-relative.exp @@ -0,0 +1,47 @@ +# Copyright 2013 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +standard_testfile + +set opts {debug additional_flags=-I.} + +get_compiler_info +if [test_compiler_info gcc*] { + lappend opts additional_flags=-g3 +} + +if { [file pathtype $objdir] == "relative" } { + untested "objdir $objdir should be absolute" + return +} +set saved_pwd [pwd] +cd $srcdir/${subdir}/base/two +set err [gdb_compile "../../${srcfile}" "${binfile}" executable $opts] +cd $saved_pwd +if { $err != "" } { + untested "compilation failed" + return -1 +} + +clean_restart ${testfile} + +# Test macros respect DW_AT_comp_dir. + +# "list header_two_func" does not set exactly the one line we want. +if ![runto header_two_func] { + return -1 +} + +gdb_test "info macro HEADER" "\r\n#define HEADER 2" -- 2.7.4