[PATCH] libdwelf: New DWARF ELF Low-level Functions. Add dwelf_elf_gnu_debuglink.

Mark Wielaard mjw at redhat.com
Fri Apr 11 22:30:32 UTC 2014


Here is a first stab at the libdewlf.h infrastructure.
It adds one function dwelf_elf_gnu_debuglink to libdw.so with a simple
testcase. Hopefully it shows how to add new functions and test cases for
libdwelf.

I actually added one extra sanity check to the existing code, to make
sure the section data was actually big enough and the file name was zero
terminated.

I didn't add mudflap support. The mudflap support seems to
have been broken since at least early 2012 when the new color code was
added. And apparently nobody noticed. mudflap has been removed in GCC 4.9.
We already have valgrind support that is ran during make distcheck before
each release. And we should probably add support for the new GCC asan
checker. I intend to remove the mudflap support from the code base before
the next elfutils release.

Patch below and on the mjw/dwelf branch. Comments welcome.

Cheers,

Mark

<- snip ->

New public header elfutils/libdwelf.h for low-level DWARF/ELF helper
functions.  The new function dwelf_elf_gnu_debuglink returns the name and
crc as found in the .gnu_debuglink section of an ELF file.

Signed-off-by: Mark Wielaard <mjw at redhat.com>
---
 ChangeLog                          |    6 ++
 Makefile.am                        |    4 +-
 NEWS                               |    3 +
 configure.ac                       |    3 +
 libdw/ChangeLog                    |    4 ++
 libdw/Makefile.am                  |    5 ++-
 libdw/libdw.map                    |    5 ++
 libdwelf/Makefile.am               |   53 +++++++++++++++++++
 libdwelf/dwelf_elf_gnu_debuglink.c |   99 ++++++++++++++++++++++++++++++++++++
 libdwelf/libdwelf.h                |   54 +++++++++++++++++++
 libdwelf/libdwelfP.h               |   40 ++++++++++++++
 libdwfl/ChangeLog                  |    7 +++
 libdwfl/Makefile.am                |    2 +-
 libdwfl/dwfl_module_getdwarf.c     |   64 +----------------------
 libdwfl/libdwflP.h                 |    1 +
 src/ChangeLog                      |    4 ++
 src/Makefile.am                    |    4 +-
 tests/ChangeLog                    |    9 +++
 tests/Makefile.am                  |    6 ++-
 tests/debuglink.c                  |   64 +++++++++++++++++++++++
 tests/run-debuglink.sh             |   29 +++++++++++
 21 files changed, 397 insertions(+), 69 deletions(-)
 create mode 100644 libdwelf/Makefile.am
 create mode 100644 libdwelf/dwelf_elf_gnu_debuglink.c
 create mode 100644 libdwelf/libdwelf.h
 create mode 100644 libdwelf/libdwelfP.h
 create mode 100644 tests/debuglink.c
 create mode 100755 tests/run-debuglink.sh

diff --git a/ChangeLog b/ChangeLog
index a2436ce..9d385d3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2014-04-11  Mark Wielaard  <mjw at redhat.com>
+
+	* Makefile.am (SUBDIRS): Add libdwelf.
+	* configure.ac (AC_CONFIG_FILES): Add libdwelf/Makefile.
+	* NEWS: Add note about libdwelf.
+
 2014-01-21  Mark Wielaard  <mjw at redhat.com>
 
 	* NEWS (Version 0.159): Add stack -i.
diff --git a/Makefile.am b/Makefile.am
index 7db05f8..aa554e6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -23,8 +23,8 @@ ACLOCAL_AMFLAGS = -I m4
 pkginclude_HEADERS = version.h
 
 # Add doc back when we have some real content.
-SUBDIRS = config m4 lib libelf libebl libdwfl libdw libcpu libasm backends \
-	  src po tests
+SUBDIRS = config m4 lib libelf libebl libdwelf libdwfl libdw libcpu libasm \
+	  backends src po tests
 
 EXTRA_DIST = elfutils.spec GPG-KEY NOTES CONTRIBUTING \
 	     COPYING COPYING-GPLV2 COPYING-LGPLV3
diff --git a/NEWS b/NEWS
index b774ec4..78c42bd 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,9 @@ Version 0.159
 stack: New option -d, --debugname to lookup DWARF debuginfo name for frame.
        New option -i, --inlines to show inlined frames using DWARF debuginfo.
 
+libdwelf: New libdwelf.h header for libdw.so DWARF ELF Low-level Functions.
+          New function dwelf_elf_gnu_debuglink.
+
 Version 0.158
 
 libdwfl: dwfl_core_file_report has new parameter executable.
diff --git a/configure.ac b/configure.ac
index 7bfa1da..3e3bef4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -257,6 +257,9 @@ AC_CONFIG_FILES([libelf/Makefile])
 dnl Higher-level ELF support library.
 AC_CONFIG_FILES([libebl/Makefile])
 
+dnl DWARF-ELF Lower-level Functions support library.
+AC_CONFIG_FILES([libdwelf/Makefile])
+
 dnl DWARF library.
 AC_CONFIG_FILES([libdw/Makefile])
 
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index e8f0eb8..dab3db1 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,7 @@
+2014-04-11  Mark Wielaard  <mjw at redhat.com>
+
+	* libdw.map (ELFUTILS_0.159): New. Add dwelf_elf_gnu_debuglink.
+
 2014-04-09  Mark Wielaard  <mjw at redhat.com>
 
 	* dwarf_begin_elf.c (check_section): Check for unsigned overflow
diff --git a/libdw/Makefile.am b/libdw/Makefile.am
index cd9e314..f8d8e0d 100644
--- a/libdw/Makefile.am
+++ b/libdw/Makefile.am
@@ -102,7 +102,7 @@ libdw_pic_a_SOURCES =
 am_libdw_pic_a_OBJECTS = $(libdw_a_SOURCES:.c=.os)
 
 libdw_so_SOURCES =
-libdw.so: $(srcdir)/libdw.map libdw_pic.a \
+libdw.so: $(srcdir)/libdw.map libdw_pic.a ../libdwelf/libdwelf_pic.a \
 	  ../libdwfl/libdwfl_pic.a ../libebl/libebl.a \
 	  ../libelf/libelf.so
 # The rpath is necessary for libebl because its $ORIGIN use will
@@ -131,6 +131,9 @@ endif
 libdwfl_objects = $(shell $(AR) t ../libdwfl/libdwfl.a)
 libdw_a_LIBADD = $(addprefix ../libdwfl/,$(libdwfl_objects))
 
+libdwelf_objects = $(shell $(AR) t ../libdwelf/libdwelf.a)
+libdw_a_LIBADD += $(addprefix ../libdwelf/,$(libdwelf_objects))
+
 noinst_HEADERS = libdwP.h memory-access.h dwarf_abbrev_hash.h \
 		 dwarf_sig8_hash.h cfi.h encoded-value.h
 
diff --git a/libdw/libdw.map b/libdw/libdw.map
index d0e4731..b26c760 100644
--- a/libdw/libdw.map
+++ b/libdw/libdw.map
@@ -292,3 +292,8 @@ ELFUTILS_0.158 {
     dwfl_core_file_attach;
     dwfl_linux_proc_attach;
 } ELFUTILS_0.157;
+
+ELFUTILS_0.159 {
+  global:
+    dwelf_elf_gnu_debuglink;
+} ELFUTILS_0.157;
diff --git a/libdwelf/Makefile.am b/libdwelf/Makefile.am
new file mode 100644
index 0000000..0f684d4
--- /dev/null
+++ b/libdwelf/Makefile.am
@@ -0,0 +1,53 @@
+## Makefile.am for libdwelf library subdirectory in elfutils.
+##
+## Process this file with automake to create Makefile.in
+##
+## Copyright (C) 2014 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/>.
+##
+include $(top_srcdir)/config/eu.am
+AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libdw
+VERSION = 1
+
+noinst_LIBRARIES = libdwelf.a libdwelf_pic.a
+
+pkginclude_HEADERS = libdwelf.h
+noinst_HEADERS = libdwelfP.h
+
+libdwelf_a_SOURCES = dwelf_elf_gnu_debuglink.c
+
+libdwelf = $(libdw)
+
+libdw = ../libdw/libdw.so
+libelf = ../libelf/libelf.so
+libebl = ../libebl/libebl.a
+libeu = ../lib/libeu.a
+
+libdwelf_pic_a_SOURCES =
+am_libdwelf_pic_a_OBJECTS = $(libdwelf_a_SOURCES:.c=.os)
+
+CLEANFILES += $(am_libdwelf_pic_a_OBJECTS)
diff --git a/libdwelf/dwelf_elf_gnu_debuglink.c b/libdwelf/dwelf_elf_gnu_debuglink.c
new file mode 100644
index 0000000..7b5fc93
--- /dev/null
+++ b/libdwelf/dwelf_elf_gnu_debuglink.c
@@ -0,0 +1,99 @@
+/* Returns the file name and crc stored in the .gnu_debuglink if found.
+   Copyright (C) 2014 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 "libdwelfP.h"
+
+const char *
+dwelf_elf_gnu_debuglink (Elf *elf, GElf_Word *crc)
+{
+  size_t shstrndx;
+  if (elf_getshdrstrndx (elf, &shstrndx) < 0)
+    return NULL;
+
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr == NULL)
+        return NULL;
+
+      const char *name = elf_strptr (elf, shstrndx, shdr->sh_name);
+      if (name == NULL)
+        return NULL;
+
+      if (!strcmp (name, ".gnu_debuglink"))
+        break;
+    }
+
+  if (scn == NULL)
+    return NULL;
+
+  /* Found the .gnu_debuglink section.  Extract its contents.  */
+  Elf_Data *rawdata = elf_rawdata (scn, NULL);
+  if (rawdata == NULL)
+    return NULL;
+
+  /* The CRC comes after the zero-terminated file name,
+     (aligned up to 4 bytes) at the end of the section data.  */
+  if (rawdata->d_size <= sizeof *crc
+      || memchr (rawdata->d_buf, '\0', rawdata->d_size - sizeof *crc) == NULL)
+    return NULL;
+
+  Elf_Data crcdata =
+    {
+      .d_type = ELF_T_WORD,
+      .d_buf = crc,
+      .d_size = sizeof *crc,
+      .d_version = EV_CURRENT,
+    };
+  Elf_Data conv =
+    {
+      .d_type = ELF_T_WORD,
+      .d_buf = rawdata->d_buf + rawdata->d_size - sizeof *crc,
+      .d_size = sizeof *crc,
+      .d_version = EV_CURRENT,
+    };
+
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (ehdr == NULL)
+    return NULL;
+
+  Elf_Data *d = gelf_xlatetom (elf, &crcdata, &conv, ehdr->e_ident[EI_DATA]);
+  if (d == NULL)
+    return NULL;
+  assert (d == &crcdata);
+
+  return rawdata->d_buf;
+}
+INTDEF(dwelf_elf_gnu_debuglink)
diff --git a/libdwelf/libdwelf.h b/libdwelf/libdwelf.h
new file mode 100644
index 0000000..5d636d1
--- /dev/null
+++ b/libdwelf/libdwelf.h
@@ -0,0 +1,54 @@
+/* Interfaces for libdwelf. DWARF ELF Low-level Functions.
+   Copyright (C) 2014 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/>.  */
+
+#ifndef _LIBDWELF_H
+#define _LIBDWELF_H	1
+
+#include "libdw.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* DWARF ELF Low-level Functions (dwelf).
+   Functions starting with dwelf_elf will take a (libelf) Elf object as
+   first argument and might set elf_errno on error.  Functions starting
+   with dwelf_dwarf will take a (libdw) Dwarf object as first argument
+   and might set dwarf_errno on error.  */
+
+/* Returns the name and the CRC32 of the separate debug file from the
+   .gnu_debuglink section if found in the ELF.  Return NULL if the ELF
+   file didn't have a .gnu_debuglink section, had malformed data in the
+   section or some other error occured.  */
+extern const char *dwelf_elf_gnu_debuglink (Elf *elf, GElf_Word *crc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* libdwelf.h */
diff --git a/libdwelf/libdwelfP.h b/libdwelf/libdwelfP.h
new file mode 100644
index 0000000..bdadc8b
--- /dev/null
+++ b/libdwelf/libdwelfP.h
@@ -0,0 +1,40 @@
+/* Internal definitions for libdwelf. DWARF ELF Low-level Functions.
+   Copyright (C) 2014 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/>.  */
+
+#ifndef _LIBDWELFP_H
+#define _LIBDWELFP_H	1
+
+#include <libdwelf.h>
+#include "../libdw/libdwP.h"	/* We need its INTDECLs.  */
+#include <assert.h>
+#include <string.h>
+
+/* Avoid PLT entries.  */
+INTDECL (dwelf_elf_gnu_debuglink)
+
+#endif	/* libdwelfP.h */
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index b6a9161..63bb0ab 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,10 @@
+2014-04-11  Mark Wielaard  <mjw at redhat.com>
+
+	* Makefile.am (AM_CPPFLAGS): Add libdwelf.
+	* libdwflP.h: Include libdwelfP.h.
+	* dwfl_module_getdwarf.c (find_debuglink): Moved to libdwelf.
+	(find_debuginfo): Use dwelf_elf_gnu_debuglink.
+
 2014-03-03  Mark Wielaard  <mjw at redhat.com>
 
 	* elf-from-memory.c (elf_from_remote_memory): Keep track of
diff --git a/libdwfl/Makefile.am b/libdwfl/Makefile.am
index ce590da..335000a 100644
--- a/libdwfl/Makefile.am
+++ b/libdwfl/Makefile.am
@@ -31,7 +31,7 @@
 ##
 include $(top_srcdir)/config/eu.am
 AM_CPPFLAGS += -I$(srcdir) -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
-	   -I$(srcdir)/../libdw
+	   -I$(srcdir)/../libdw -I$(srcdir)/../libdwelf
 VERSION = 1
 
 noinst_LIBRARIES = libdwfl.a
diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c
index f8de80b..f8a7816 100644
--- a/libdwfl/dwfl_module_getdwarf.c
+++ b/libdwfl/dwfl_module_getdwarf.c
@@ -222,66 +222,6 @@ __libdwfl_getelf (Dwfl_Module *mod)
   mod->main_bias = mod->e_type == ET_REL ? 0 : mod->low_addr - mod->main.vaddr;
 }
 
-/* Search an ELF file for a ".gnu_debuglink" section.  */
-static const char *
-find_debuglink (Elf *elf, GElf_Word *crc)
-{
-  size_t shstrndx;
-  if (elf_getshdrstrndx (elf, &shstrndx) < 0)
-    return NULL;
-
-  Elf_Scn *scn = NULL;
-  while ((scn = elf_nextscn (elf, scn)) != NULL)
-    {
-      GElf_Shdr shdr_mem;
-      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
-      if (shdr == NULL)
-	return NULL;
-
-      const char *name = elf_strptr (elf, shstrndx, shdr->sh_name);
-      if (name == NULL)
-	return NULL;
-
-      if (!strcmp (name, ".gnu_debuglink"))
-	break;
-    }
-
-  if (scn == NULL)
-    return NULL;
-
-  /* Found the .gnu_debuglink section.  Extract its contents.  */
-  Elf_Data *rawdata = elf_rawdata (scn, NULL);
-  if (rawdata == NULL)
-    return NULL;
-
-  Elf_Data crcdata =
-    {
-      .d_type = ELF_T_WORD,
-      .d_buf = crc,
-      .d_size = sizeof *crc,
-      .d_version = EV_CURRENT,
-    };
-  Elf_Data conv =
-    {
-      .d_type = ELF_T_WORD,
-      .d_buf = rawdata->d_buf + rawdata->d_size - sizeof *crc,
-      .d_size = sizeof *crc,
-      .d_version = EV_CURRENT,
-    };
-
-  GElf_Ehdr ehdr_mem;
-  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
-  if (ehdr == NULL)
-    return NULL;
-
-  Elf_Data *d = gelf_xlatetom (elf, &crcdata, &conv, ehdr->e_ident[EI_DATA]);
-  if (d == NULL)
-    return NULL;
-  assert (d == &crcdata);
-
-  return rawdata->d_buf;
-}
-
 /* If the main file might have been prelinked, then we need to
    discover the correct synchronization address between the main and
    debug files.  Because of prelink's section juggling, we cannot rely
@@ -544,7 +484,9 @@ find_debuginfo (Dwfl_Module *mod)
     return DWFL_E_NOERROR;
 
   GElf_Word debuglink_crc = 0;
-  const char *debuglink_file = find_debuglink (mod->main.elf, &debuglink_crc);
+  const char *debuglink_file;
+  debuglink_file = INTUSE(dwelf_elf_gnu_debuglink) (mod->main.elf,
+						    &debuglink_crc);
 
   mod->debug.fd = (*mod->dwfl->callbacks->find_debuginfo) (MODCB_ARGS (mod),
 							   mod->main.name,
diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h
index 3a28ac7..e4ab60e 100644
--- a/libdwfl/libdwflP.h
+++ b/libdwfl/libdwflP.h
@@ -42,6 +42,7 @@
 #include <string.h>
 
 #include "../libdw/libdwP.h"	/* We need its INTDECLs.  */
+#include "../libdwelf/libdwelfP.h"
 
 typedef struct Dwfl_Process Dwfl_Process;
 
diff --git a/src/ChangeLog b/src/ChangeLog
index c166267..c4c2ea6 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+2014-04-11  Mark Wielaard  <mjw at redhat.com>
+
+	* Makefile.am (AM_CPPFLAGS): Add -I libdwelf.
+
 2014-03-05  Mark Wielaard  <mjw at redhat.com>
 
 	* readelf.c (attr_callback): Print DW_FORM_sdata values as signed
diff --git a/src/Makefile.am b/src/Makefile.am
index e371160..956cfee 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -20,8 +20,8 @@ include $(top_srcdir)/config/eu.am
 DEFS += $(YYDEBUG) -DDEBUGPRED=@DEBUGPRED@ \
 	-DSRCDIR=\"$(shell cd $(srcdir);pwd)\" -DOBJDIR=\"$(shell pwd)\"
 AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
-	    -I$(srcdir)/../libdw -I$(srcdir)/../libdwfl \
-	    -I$(srcdir)/../libasm
+	    -I$(srcdir)/../libdw -I$(srcdir)/../libdwelf \
+	    -I$(srcdir)/../libdwfl -I$(srcdir)/../libasm
 
 AM_LDFLAGS = -Wl,-rpath-link,../libelf:../libdw
 
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 9b0e7ac..d8e5c38 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,12 @@
+2014-04-11  Mark Wielaard  <mjw at redhat.com>
+
+	* Makefile.am (AM_CPPFLAGS): Add -I libdwelf.
+	(check_PROGRAMS): Add debuglink.
+	(TESTS): Add run-debuglink.sh
+	(debuglink_LDADD): New.
+	* debuglink.c: New file.
+	* run-debuglink.sh: Likewise.
+
 2014-03-11  Josh Stone  <jistone at redhat.com>
 
 	* testfilebaxmin.bz2: New testfile.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 5e64095..c9851c3 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -27,7 +27,7 @@ AM_LDFLAGS =
 
 if !STANDALONE
 AM_CPPFLAGS += -I$(top_srcdir)/libasm -I$(top_srcdir)/libdw \
-	    -I$(top_srcdir)/libdwfl \
+	    -I$(top_srcdir)/libdwfl -I$(top_srcdir)/libdwelf \
 	    -I$(top_srcdir)/libebl -I$(top_srcdir)/libelf \
 	    -I$(top_srcdir)/lib -I..
 AM_LDFLAGS += -Wl,-rpath-link,../libasm:../libdw:../libelf
@@ -53,7 +53,7 @@ check_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \
 		  alldts md5-sha1-test typeiter typeiter2 low_high_pc \
 		  test-elf_cntl_gelf_getshdr dwflsyms dwfllines \
 		  dwfl-report-elf-align varlocs backtrace backtrace-child \
-		  backtrace-data backtrace-dwarf
+		  backtrace-data backtrace-dwarf debuglink
 asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \
 	    asm-tst6 asm-tst7 asm-tst8 asm-tst9
 
@@ -90,6 +90,7 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \
 	run-readelf-macro.sh run-readelf-loc.sh \
 	run-readelf-aranges.sh run-readelf-line.sh \
 	run-native-test.sh run-bug1-test.sh \
+	run-debuglink.sh \
 	dwfl-bug-addr-overflow run-addrname-test.sh \
 	dwfl-bug-fd-leak dwfl-bug-report \
 	run-dwfl-bug-offline-rel.sh run-dwfl-addr-sect.sh \
@@ -402,6 +403,7 @@ backtrace_child_biarch_SOURCES = backtrace-child.c
 backtrace_data_LDADD = $(libdw) $(libelf) $(libmudflap)
 backtrace_dwarf_CFLAGS = -Wno-unused-parameter
 backtrace_dwarf_LDADD = $(libdw) $(libelf) $(libmudflap)
+debuglink_LDADD = $(libdw) $(libelf)
 
 if GCOV
 check: check-am coverage
diff --git a/tests/debuglink.c b/tests/debuglink.c
new file mode 100644
index 0000000..935d102
--- /dev/null
+++ b/tests/debuglink.c
@@ -0,0 +1,64 @@
+/* Test program for dwelf_elf_gnu_debuglink, print name and crc.
+   Copyright (C) 2014 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 the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   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 a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <inttypes.h>
+#include <errno.h>
+#include ELFUTILS_HEADER(dwelf)
+#include <stdio.h>
+#include <error.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+int
+main (int argc, char *argv[])
+{
+  if (argc < 2)
+    error (EXIT_FAILURE, 0, "No input file given");
+
+  elf_version (EV_CURRENT);
+
+  for (int i = 1; i < argc; i++)
+    {
+      const char *file = argv[i];
+      int fd = open (file, O_RDONLY);
+      if (fd < 0)
+	error (EXIT_FAILURE, errno, "couldn't open file '%s'", file);
+
+      Elf *elf = elf_begin (fd, ELF_C_READ, NULL);
+      if (elf == NULL)
+	error (EXIT_FAILURE, 0, "elf_begin failed for '%s': %s",
+	       file, elf_errmsg (-1));
+
+      GElf_Word crc;
+      const char *debug = dwelf_elf_gnu_debuglink (elf, &crc);
+      if (debug == NULL)
+	printf ("%s: <no gnu_debuglink file>\n", file);
+      else
+	printf ("%s: %s, crc: %" PRIx32 "\n", file, debug, crc);
+
+      elf_end (elf);
+      close (fd);
+    }
+
+  return 0;
+}
diff --git a/tests/run-debuglink.sh b/tests/run-debuglink.sh
new file mode 100755
index 0000000..42a816c
--- /dev/null
+++ b/tests/run-debuglink.sh
@@ -0,0 +1,29 @@
+#! /bin/sh
+# Copyright (C) 2014 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 the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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 a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Just some random testfiles, two with, one without .gnu_debuglink
+testfiles testfile36 testfile52-32.so testfile42
+
+testrun_compare  ${abs_builddir}/debuglink testfile36 testfile52-32.so testfile42 <<\EOF
+testfile36: testfile36.debug, crc: 8c5c20a3
+testfile52-32.so: testfile52-32.so.debug, crc: b835a71d
+testfile42: <no gnu_debuglink file>
+EOF
+
+exit 0
-- 
1.7.1



More information about the elfutils-devel mailing list