This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] Always return the full path of filenames in bfd
- From: Anton Blanchard <anton at samba dot org>
- To: binutils at sourceware dot org
- Date: Sat, 16 Sep 2006 18:59:10 +1000
- Subject: [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);