This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils 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]

Re: File index given line (libdw)


On Mon, 2017-07-17 at 17:28 +0000, Sasha Da Rocha Pinheiro wrote:
> I understand your argument. Since I was doing:
>    
>    dwarf_getsrclines(&cuDIE, &lineBuffer, &lineCount)
>    dwarf_getsrcfiles(&cuDIE, &files, &filecount)
> 
> I knew they were related because I used the same DIE. But someone
> trying to use a function which returns only the index could be
> confusing about what Dwarf_Files it came from. 
> 
> But, with
> 
> extern int *
> dwarf_line_files (Dwarf_Line *line, Dwarf_Files **files, size_t *idx);
> 
> they would know what Dwarf_Files the line is related to. For me,
> though, I could pass NULL for files, since I already knew what it is.

I would always double check your assumption that the Dwarf_Files match
with what you expect. And I am still not really convinced storing the
index as a proxy for the actual file name/path associated with a
Dwarf_Line is really a good idea.

But I was working on adding support for DWARF5 .debug_lines and since
files (and directories) can have arbitrary attributes in that version it
makes sense to go from Dwarf_Line to the associated Dwarf_Files/index.
Instead of duplicating the accessor functions (like we now have both
dwarf_filesrc and dwarf_linesrc).

Note that I changed the name to dwarf_line_file. (Dropping the s.)

This does show that we might want to change how we internally store the
Dwarf_Files though. Currently we resolve the whole file path immediately
and don't keep track of the original file name and directory name/path.
You can only get the full file path (through dwarf_filesrc) but not the
associated directory. I am cleaning that up while adding the DWARF5
support. And will add a more generic interface for access file and
directory properties.

Cheers,

Mark
From 84ded5d99cbb20de864ecbca8d0d860510da4234 Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mark@klomp.org>
Date: Fri, 21 Jul 2017 21:23:07 +0200
Subject: [PATCH] libdw: Add dwarf_line_file.

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 libdw/ChangeLog         |  7 +++++++
 libdw/Makefile.am       |  2 +-
 libdw/dwarf_line_file.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++
 libdw/libdw.h           |  5 +++++
 libdw/libdw.map         |  5 +++++
 tests/ChangeLog         |  4 ++++
 tests/get-lines.c       | 23 ++++++++++++++++++++++
 7 files changed, 97 insertions(+), 1 deletion(-)
 create mode 100644 libdw/dwarf_line_file.c

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 1e282e4..5d9091a 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,10 @@
+2017-07-21  Mark Wielaard  <mark@klomp.org>
+
+	* dwarf_line_file.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add dwarf_line_file.c.
+	* libdw.h (dwarf_line_file): New function declaration.
+	* libdw.map (ELFUTILS_0.167): New. Add dwarf_line_file.
+
 2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
 
 	* libdw.h: Remove attribute macro declarations and use
diff --git a/libdw/Makefile.am b/libdw/Makefile.am
index 082d96c..bde8856 100644
--- a/libdw/Makefile.am
+++ b/libdw/Makefile.am
@@ -65,7 +65,7 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \
 		  dwarf_lineendsequence.c dwarf_lineblock.c \
 		  dwarf_lineprologueend.c dwarf_lineepiloguebegin.c \
 		  dwarf_lineisa.c dwarf_linediscriminator.c \
-		  dwarf_lineop_index.c \
+		  dwarf_lineop_index.c dwarf_line_file.c \
 		  dwarf_onesrcline.c dwarf_formblock.c \
 		  dwarf_getsrcfiles.c dwarf_filesrc.c dwarf_getsrcdirs.c \
 		  dwarf_getlocation.c dwarf_getstring.c dwarf_offabbrev.c \
diff --git a/libdw/dwarf_line_file.c b/libdw/dwarf_line_file.c
new file mode 100644
index 0000000..e2df642
--- /dev/null
+++ b/libdw/dwarf_line_file.c
@@ -0,0 +1,52 @@
+/* Find line information for address.
+   Copyright (C) 2017 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_line_file (Dwarf_Line *line, Dwarf_Files **files, size_t *idx)
+{
+  if (line == NULL)
+    return -1;
+
+  if (line->file >= line->files->nfiles)
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return -1;
+    }
+
+  *files = line->files;
+  *idx = line->file;
+
+  return 0;
+}
diff --git a/libdw/libdw.h b/libdw/libdw.h
index 9ae80eb..4903b55 100644
--- a/libdw/libdw.h
+++ b/libdw/libdw.h
@@ -640,6 +640,11 @@ extern const char *dwarf_linesrc (Dwarf_Line *line,
 extern const char *dwarf_filesrc (Dwarf_Files *file, size_t idx,
 				  Dwarf_Word *mtime, Dwarf_Word *length);
 
+/* Return the Dwarf_Files and index associated with the given Dwarf_Line.  */
+extern int dwarf_line_file (Dwarf_Line *line,
+			    Dwarf_Files **files, size_t *idx)
+    __nonnull_attribute__ (2, 3);
+
 /* Return the directory list used in the file information extracted.
    (*RESULT)[0] is the CU's DW_AT_comp_dir value, and may be null.
    (*RESULT)[0..*NDIRS-1] are the compile-time include directory path
diff --git a/libdw/libdw.map b/libdw/libdw.map
index 83cb1d9..44e096a 100644
--- a/libdw/libdw.map
+++ b/libdw/libdw.map
@@ -338,3 +338,8 @@ ELFUTILS_0.167 {
     dwelf_strent_str;
     dwelf_strtab_free;
 } ELFUTILS_0.165;
+
+ELFUTILS_0.170 {
+  global:
+    dwarf_line_file;
+} ELFUTILS_0.167;
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 3dd6f2a..920084f 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,7 @@
+2017-07-21  Mark Wielaard  <mark@klomp.org>
+
+	* get-lines.c (main): Add dwarf_line_file test.
+
 2017-07-14  Mark Wielaard  <mark@klomp.org>
 
 	* run-strip-remove-keep.sh: New test.
diff --git a/tests/get-lines.c b/tests/get-lines.c
index c361a2c..188d016 100644
--- a/tests/get-lines.c
+++ b/tests/get-lines.c
@@ -24,6 +24,7 @@
 #include <libelf.h>
 #include ELFUTILS_HEADER(dw)
 #include <stdio.h>
+#include <string.h>
 #include <unistd.h>
 
 
@@ -100,6 +101,28 @@ main (int argc, char *argv[])
 	      printf ("%" PRIx64 ": %s:%d:", (uint64_t) addr,
 		      file ?: "???", line);
 
+	      /* Getting the file path through the Dwarf_Files should
+		 result in the same path.  */
+	      Dwarf_Files *files;
+	      size_t idx;
+	      if (dwarf_line_file (l, &files, &idx) != 0)
+		{
+		  printf ("%s: cannot get file from line (%zd): %s\n",
+			  argv[cnt], i, dwarf_errmsg (-1));
+		  result = 1;
+		  break;
+		}
+	      const char *path = dwarf_filesrc (files, idx, NULL, NULL);
+	      if ((path == NULL && file != NULL)
+		  || (path != NULL && file == NULL)
+		  || (strcmp (file, path) != 0))
+		{
+		  printf ("%s: line %zd srcline (%s) != file srcline (%s)\n",
+			  argv[cnt], i, file ?: "???", path ?: "???");
+		  result = 1;
+		  break;
+		}
+
 	      int column;
 	      if (dwarf_linecol (l, &column) != 0)
 		column = 0;
-- 
1.8.3.1


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