From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8002 invoked by alias); 15 Feb 2013 19:58:28 -0000 Received: (qmail 7993 invoked by uid 22791); 15 Feb 2013 19:58:27 -0000 X-SWARE-Spam-Status: No, hits=-6.2 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_SPAMHAUS_DROP,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,RP_MATCHES_RCVD,SPF_HELO_PASS,TW_BJ X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 15 Feb 2013 19:58:10 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r1FJw84S007063 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 15 Feb 2013 14:58:08 -0500 Received: from host2.jankratochvil.net (ovpn-116-18.ams2.redhat.com [10.36.116.18]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r1FJw2vq005450 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Fri, 15 Feb 2013 14:58:04 -0500 Date: Fri, 15 Feb 2013 19:58:00 -0000 From: Jan Kratochvil To: gdb-patches Cc: Tom Tromey , Eli Zaretskii , Doug Evans Subject: [patch FYI not for commit] Attempt to properly relativize executable's filenames Message-ID: <20130215195801.GA18966@host2.jankratochvil.net> References: <20130129221118.GB27463@host2.jankratochvil.net> <20130130074859.GB15998@host2.jankratochvil.net> <831ud2ioax.fsf@gnu.org> <20130202180658.GA16269@host2.jankratochvil.net> <20130205182245.GA19307@host2.jankratochvil.net> <87k3qlxwf0.fsf@fleche.redhat.com> <20130207202908.GA30050@host2.jankratochvil.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20130207202908.GA30050@host2.jankratochvil.net> User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2013-02/txt/msg00412.txt.bz2 On Thu, 07 Feb 2013 21:29:08 +0100, Jan Kratochvil wrote: > When thinking about it I believe one wants absolute source names even for any > application which uses >= 2 different DW_AT_comp_dir's. I tried that but - it does not work. Applications contain sources from source filenames outside of their build directory. And it is not clear which such sources are and which are not parts of the application itself. With -lmcheck on Fedora one gets /builddir/build/BUILD/glibc-2.15-a316c1f/malloc/mcheck-init.c from /usr/lib64/libmcheck.a as an example. Then there are included-symtabs from /usr/include/filenames.h; OTOH one has also included-symtabs from the application itself. So currently I give up on some autodetection of proper base directory for inferior executable. Developers of large applications just should do: echo >>~/.gdbinit set filename-display absolute Regards, Jan diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index d26e7c8..e86dd33 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -3762,6 +3762,29 @@ dw2_has_symbols (struct objfile *objfile) return 1; } +static char * +dw2_find_common_dir (struct objfile *objfile) +{ + int i; + char *common_dir = NULL; + + dw2_setup (objfile); + for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i) + { + struct dwarf2_per_cu_data *per_cu = dw2_get_primary_cu (i); + struct quick_file_names *file_data = dw2_get_file_names (objfile, per_cu); + int j; + + for (j = 0; j < file_data->num_file_names; ++j) + { + const char *this_file_name = file_data->file_names[j]; + + reduce_common_dir (&common_dir, this_file_name); + } + } + return common_dir; +} + const struct quick_symbol_functions dwarf2_gdb_index_functions = { dw2_has_symbols, @@ -3779,7 +3802,8 @@ const struct quick_symbol_functions dwarf2_gdb_index_functions = dw2_map_matching_symbols, dw2_expand_symtabs_matching, dw2_find_pc_sect_symtab, - dw2_map_symbol_filenames + dw2_map_symbol_filenames, + dw2_find_common_dir }; /* Initialize for reading DWARF for this objfile. Return 0 if this diff --git a/gdb/objfiles.c b/gdb/objfiles.c index 8c17c14..47a38fc 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -637,6 +637,8 @@ free_objfile (struct objfile *objfile) if (objfile->demangled_names_hash) htab_delete (objfile->demangled_names_hash); obstack_free (&objfile->objfile_obstack, 0); + xfree (objfile->common_dir_raw); + xfree (objfile->common_dir); /* Rebuild section map next time we need it. */ get_objfile_pspace_data (objfile->pspace)->objfiles_changed_p = 1; diff --git a/gdb/objfiles.h b/gdb/objfiles.h index 6d29084..1df8cc4 100644 --- a/gdb/objfiles.h +++ b/gdb/objfiles.h @@ -387,6 +387,8 @@ struct objfile table, so we have to keep them here to relocate them properly. */ struct symbol *template_symbols; + + char *common_dir_raw, *common_dir; }; /* Defines for the objfile flag word. */ diff --git a/gdb/psymtab.c b/gdb/psymtab.c index 2965e9f..8e6f19f 100644 --- a/gdb/psymtab.c +++ b/gdb/psymtab.c @@ -1411,6 +1411,28 @@ objfile_has_psyms (struct objfile *objfile) return objfile->psymtabs != NULL; } +static char * +find_common_dir (struct objfile *objfile) +{ + struct partial_symtab *ps; + char *common_dir = NULL; + + ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps) + { + if (ps->dirname == NULL || IS_ABSOLUTE_PATH (ps->filename)) + reduce_common_dir (&common_dir, ps->filename); + else + { + char *raw_fullname; + + raw_fullname = concat (ps->dirname, SLASH_STRING, ps->filename, NULL); + reduce_common_dir (&common_dir, raw_fullname); + xfree (raw_fullname); + } + } + return common_dir; +} + const struct quick_symbol_functions psym_functions = { objfile_has_psyms, @@ -1428,7 +1450,8 @@ const struct quick_symbol_functions psym_functions = map_matching_symbols_psymtab, expand_symtabs_matching_via_partial, find_pc_sect_symtab_from_partial, - map_symbol_filenames_psymtab + map_symbol_filenames_psymtab, + find_common_dir }; diff --git a/gdb/source.c b/gdb/source.c index f5949e6..6012fd6 100644 --- a/gdb/source.c +++ b/gdb/source.c @@ -113,15 +113,17 @@ show_lines_to_list (struct ui_file *file, int from_tty, static const char filename_display_basename[] = "basename"; static const char filename_display_relative[] = "relative"; static const char filename_display_absolute[] = "absolute"; +static const char filename_display_common[] = "common"; static const char *const filename_display_kind_names[] = { filename_display_basename, filename_display_relative, filename_display_absolute, + filename_display_common, NULL }; -static const char *filename_display_string = filename_display_relative; +static const char *filename_display_string = filename_display_common; static void show_filename_display_string (struct ui_file *file, int from_tty, @@ -1133,6 +1135,24 @@ symtab_to_fullname (struct symtab *s) return s->fullname; } +void +reduce_common_dir (char **common_dir_ptr, const char *filename) +{ + char *common_dir = *common_dir_ptr; + int i; + + if (common_dir == NULL) + { + *common_dir_ptr = ldirname (filename); + return; + } + + for (i = 0; common_dir[i] != 0 && common_dir[i] == filename[i]; i++); + while (i > 0 && !IS_DIR_SEPARATOR (filename[i])) + i--; + common_dir[i] = 0; +} + /* See commentary in source.h. */ const char * @@ -1144,6 +1164,49 @@ symtab_to_filename_for_display (struct symtab *symtab) return symtab_to_fullname (symtab); else if (filename_display_string == filename_display_relative) return symtab->filename; + else if (filename_display_string == filename_display_common) + { + struct objfile *objfile = symtab->objfile; + char *fullname_raw, *dirname_raw; + const char *fullname; + size_t common_dir_raw_len, common_dir_len; + + if (objfile->common_dir_raw == NULL && objfile->sf != NULL) + { + objfile->common_dir_raw = objfile->sf->qf->find_common_dir (objfile); + gdb_assert (objfile->common_dir == NULL); + if (objfile->common_dir_raw == NULL) + objfile->common_dir_raw = xstrdup (""); + if (*objfile->common_dir_raw == 0) + objfile->common_dir = xstrdup (""); + else + objfile->common_dir = gdb_realpath (objfile->common_dir_raw); + } + + if (objfile->common_dir_raw == NULL || *objfile->common_dir_raw == 0) + return symtab_to_fullname (symtab); + + if (IS_ABSOLUTE_PATH (symtab->filename)) + fullname_raw = xstrdup (symtab->filename); + else + fullname_raw = concat (symtab->dirname, SLASH_STRING, symtab->filename, + NULL); + + common_dir_raw_len = strlen (objfile->common_dir_raw); + gdb_assert (strncmp (objfile->common_dir_raw, fullname_raw, + common_dir_raw_len) == 0); + gdb_assert (IS_DIR_SEPARATOR (fullname_raw[common_dir_raw_len])); + + /* File system may have changed in the meantime so gdb_assert would not + be appropriate here. */ + common_dir_len = strlen (objfile->common_dir); + fullname = symtab_to_fullname (symtab); + if (strncmp (objfile->common_dir, fullname, common_dir_len) != 0 + || !IS_DIR_SEPARATOR (fullname[common_dir_len])) + return fullname; + + return &fullname[common_dir_len + 1]; + } else internal_error (__FILE__, __LINE__, _("invalid filename_display_string")); } diff --git a/gdb/source.h b/gdb/source.h index 33cad09..e70ab26 100644 --- a/gdb/source.h +++ b/gdb/source.h @@ -52,6 +52,8 @@ extern char *rewrite_source_path (const char *path); extern const char *symtab_to_fullname (struct symtab *s); +extern void reduce_common_dir (char **common_dir_ptr, const char *filename); + /* Returns filename without the compile directory part, basename or absolute filename. It depends on 'set filename-display' value. */ extern const char *symtab_to_filename_for_display (struct symtab *symtab); diff --git a/gdb/symfile.h b/gdb/symfile.h index 6d6b4b8..b7696ba 100644 --- a/gdb/symfile.h +++ b/gdb/symfile.h @@ -296,6 +296,8 @@ struct quick_symbol_functions void (*map_symbol_filenames) (struct objfile *objfile, symbol_filename_ftype *fun, void *data, int need_fullname); + + char *(*find_common_dir) (struct objfile *objfile); }; /* Structure of functions used for probe support. If one of these functions