From 84ded5d99cbb20de864ecbca8d0d860510da4234 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Fri, 21 Jul 2017 21:23:07 +0200 Subject: [PATCH] libdw: Add dwarf_line_file. Signed-off-by: Mark Wielaard --- 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 + + * 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 * 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 . */ + +#ifdef HAVE_CONFIG_H +# include +#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 + + * get-lines.c (main): Add dwarf_line_file test. + 2017-07-14 Mark Wielaard * 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 #include ELFUTILS_HEADER(dw) #include +#include #include @@ -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