From dfd639e4e7377ce63d4e7296c0c139b7bf37167e Mon Sep 17 00:00:00 2001
From: Torsten Polle <Torsten.Polle@gmx.de>
Date: Sat, 18 Mar 2017 07:32:39 +0100
Subject: [PATCH] libdw: prepend current directory in read_srclines

read_srclines retrieves sometimes only relative paths for a source
file. The file entry in the line number program header refers to an
entry in the field "include_directories" that is a relative path. We
prepend the current directory of the compilation to make this an
absolute path.

Signed-off-by: Torsten Polle <Torsten.Polle@gmx.de>
---
 libdw/dwarf_getsrclines.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c
index d02c38d..83a511e 100644
--- a/libdw/dwarf_getsrclines.c
+++ b/libdw/dwarf_getsrclines.c
@@ -369,11 +369,28 @@ read_srclines (Dwarf *dbg,
 	new_file->info.name = fname;
       else
 	{
-	  new_file->info.name = libdw_alloc (dbg, char, 1,
-					     dirarray[diridx].len + 1
-					     + fnamelen + 1);
+	  size_t len = dirarray[diridx].len + 1 + fnamelen + 1;
+	  if (dirarray[diridx].dir != NULL
+	      && *dirarray[diridx].dir != '/'
+	      && dirarray[0].dir != NULL)
+	    {
+	      /* If the directory is a relative path, we need to make
+		 room for the compile directory. */
+	      len += dirarray[0].len + 1;
+	    }
+	  new_file->info.name = libdw_alloc (dbg, char, 1, len);
 	  char *cp = new_file->info.name;
 
+	  if (dirarray[diridx].dir != NULL
+	      && *dirarray[diridx].dir != '/'
+	      && dirarray[0].dir != NULL)
+	    {
+	      /* If the directory is a relative path, we prepend the
+		 compile directory. */
+	      cp = stpcpy (cp, dirarray[0].dir);
+	      *cp++ = '/';
+	    }
+
 	  if (dirarray[diridx].dir != NULL)
 	    {
 	      /* This value could be NULL in case the DW_AT_comp_dir
@@ -384,8 +401,7 @@ read_srclines (Dwarf *dbg,
 	    }
 	  *cp++ = '/';
 	  strcpy (cp, fname);
-	  assert (strlen (new_file->info.name)
-		  < dirarray[diridx].len + 1 + fnamelen + 1);
+	  assert (strlen (new_file->info.name) < len);
 	}
 
       /* Next comes the modification time.  */
-- 
2.7.4

