This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch FYI not for commit] Attempt to properly relativize executable's filenames


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]