This is the mail archive of the binutils@sourceware.org mailing list for the binutils 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] Always return the full path of filenames in bfd


Hi,

I noticed oprofile would sometimes fail to find matching source files
for a program. In particular it would fail when a program compiles or
links across directories. eg:

# gcc -g -o foo bar/foo.c

It turns out bfd_find_nearest_line returns a relative path for this
(ie bar/foo.c).

Conversely if you build in the same directory:

# gcc -g -o foo foo.c

bfd_find_nearest_line returns an absolute path (ie /tmp/bar/foo.c).

This seems inconsistent to me and would expect to always get an absolute
filename.

I narrowed the issue down to dwarf2.c:concat_filename() where it only
applies the compile directory to a filename if the filename didnt have a
directory component.

Does the patch below look reasonable?

Anton


2006-09-16  Anton Blanchard  <anton@samba.org>

	* dwarf2.c (concat_filename) Always apply DW_AT_comp_dir if a
	  filename isnt absolute.

Index: bfd/dwarf2.c
===================================================================
RCS file: /cvs/src/src/bfd/dwarf2.c,v
retrieving revision 1.89
diff -u -r1.89 dwarf2.c
--- bfd/dwarf2.c	2 May 2006 10:01:56 -0000	1.89
+++ bfd/dwarf2.c	16 Sep 2006 04:51:51 -0000
@@ -876,22 +876,38 @@
 
   if (! IS_ABSOLUTE_PATH (filename))
     {
-      char *dirname = (table->files[file - 1].dir
-		       ? table->dirs[table->files[file - 1].dir - 1]
-		       : table->comp_dir);
+      char * dirname = table->comp_dir;
+      char * subdirname = NULL;
+      int len;
+      char * name;
+
+      if (table->files[file - 1].dir)
+	subdirname = table->dirs[table->files[file - 1].dir - 1];
 
       /* Not all tools set DW_AT_comp_dir, so dirname may be unknown.
 	 The best we can do is return the filename part.  */
-      if (dirname != NULL)
-	{
-	  unsigned int len = strlen (dirname) + strlen (filename) + 2;
-	  char * name;
+      if (!dirname) {
+	dirname = subdirname;
+	subdirname = NULL;
+      }
 
-	  name = bfd_malloc (len);
-	  if (name)
-	    sprintf (name, "%s/%s", dirname, filename);
-	  return name;
-	}
+      if (!dirname)
+	return strdup (filename);
+
+      len = strlen (dirname) + strlen (filename) + 2;
+
+      if (subdirname) {
+	len += strlen (subdirname) + 1;
+	name = bfd_malloc (len);
+	if (name)
+	  sprintf (name, "%s/%s/%s", dirname, subdirname, filename);
+      } else {
+	name = bfd_malloc (len);
+	if (name)
+	  sprintf (name, "%s/%s", dirname, filename);
+      }
+
+      return name;
     }
 
   return strdup (filename);


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