Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Jan Kratochvil <jan.kratochvil@redhat.com>
To: gdb-patches <gdb-patches@sourceware.org>
Cc: Tom Tromey <tromey@redhat.com>, Eli Zaretskii <eliz@gnu.org>,
	       Doug Evans <dje@google.com>
Subject: [patch FYI not for commit] Attempt to properly relativize executable's filenames
Date: Fri, 15 Feb 2013 19:58:00 -0000	[thread overview]
Message-ID: <20130215195801.GA18966@host2.jankratochvil.net> (raw)
In-Reply-To: <20130207202908.GA30050@host2.jankratochvil.net>

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
 };
 
 \f
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


      reply	other threads:[~2013-02-15 19:58 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-29 22:11 [patchv2 13/11] Make relative-with-system-absolute the default Jan Kratochvil
2013-01-30  7:49 ` [patchv3 " Jan Kratochvil
2013-01-30 17:17   ` Eli Zaretskii
2013-02-02 18:07     ` Jan Kratochvil
2013-02-02 18:27       ` Eli Zaretskii
2013-02-05 17:35       ` Doug Evans
2013-02-05 18:23         ` Jan Kratochvil
2013-02-06 16:02           ` Tom Tromey
2013-02-07 20:25             ` Doug Evans
2013-02-07 20:29               ` Jan Kratochvil
2013-02-15 19:58                 ` Jan Kratochvil [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130215195801.GA18966@host2.jankratochvil.net \
    --to=jan.kratochvil@redhat.com \
    --cc=dje@google.com \
    --cc=eliz@gnu.org \
    --cc=gdb-patches@sourceware.org \
    --cc=tromey@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox