+2014-04-11 Mark Wielaard <mjw@redhat.com>
+
+ * Makefile.am (SUBDIRS): Add libdwelf.
+ * configure.ac (AC_CONFIG_FILES): Add libdwelf/Makefile.
+ * NEWS: Add note about libdwelf.
+
2014-04-13 Mark Wielaard <mjw@redhat.com>
* configure.ac: Remove mudflap enable arg and MUDFLAP conditional.
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
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.
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])
+2014-04-11 Mark Wielaard <mjw@redhat.com>
+
+ * libdw.map (ELFUTILS_0.159): New. Add dwelf_elf_gnu_debuglink.
+ * Makefile.am (libdw.so): Depend on libdwelf_pic.a.
+ (libdwelf_objects): New variable.
+ (libdw_a_LIBADD): Add libdwelf objects.
+
2014-04-22 Mark Wielaard <mjw@redhat.com>
* memory-access.h (get_sleb128_step): Remove undefined behavior
am_libdw_pic_a_OBJECTS = $(libdw_a_SOURCES:.c=.os)
libdw_so_SOURCES =
-libdw.so$(EXEEXT): $(srcdir)/libdw.map libdw_pic.a \
+libdw.so$(EXEEXT): $(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
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
dwfl_core_file_attach;
dwfl_linux_proc_attach;
} ELFUTILS_0.157;
+
+ELFUTILS_0.159 {
+ global:
+ dwelf_elf_gnu_debuglink;
+} ELFUTILS_0.158;
--- /dev/null
+2014-04-11 Mark Wielaard <mjw@redhat.com>
+
+ * Makefile.am: New file.
+ * libdwelf.h: Likewise.
+ * libdwelfP.h: Likewise.
+ * dwelf_elf_gnu_debuglink.c: Likewise.
--- /dev/null
+## 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)
--- /dev/null
+/* 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)
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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 */
+2014-04-11 Mark Wielaard <mjw@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-04-22 Mark Wielaard <mjw@redhat.com>
* frame_unwind.c (__libdwfl_frame_reg_get): Use uint64_t when
##
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
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
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,
#include <string.h>
#include "../libdw/libdwP.h" /* We need its INTDECLs. */
+#include "../libdwelf/libdwelfP.h"
typedef struct Dwfl_Process Dwfl_Process;
+2014-04-11 Mark Wielaard <mjw@redhat.com>
+
+ * Makefile.am (AM_CPPFLAGS): Add -I libdwelf.
+
2014-04-22 Mark Wielaard <mjw@redhat.com>
* readelf.c (handle_core_item): Make sure variable length array
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
+2014-04-11 Mark Wielaard <mjw@redhat.com>
+
+ * Makefile.am (AM_CPPFLAGS): Add -I libdwelf.
+ (check_PROGRAMS): Add debuglink.
+ (TESTS): Add run-debuglink.sh
+ (EXTRA_DIST): Likewise.
+ (debuglink_LDADD): New.
+ * debuglink.c: New file.
+ * run-debuglink.sh: Likewise.
+
2014-03-23 Mark Wielaard <mjw@redhat.com>
* run-nm-self.sh: Use test = not == for string comparisons.
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
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
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 \
run-readelf-test1.sh run-readelf-test2.sh run-readelf-test3.sh \
run-readelf-test4.sh run-readelf-twofiles.sh \
run-bug1-test.sh testfile28.bz2 testfile28.rdwr.bz2 \
+ run-debuglink.sh \
testfile29.bz2 testfile29.rdwr.bz2 \
testfile30.bz2 testfile31.bz2 testfile32.bz2 testfile33.bz2 \
testfile34.bz2 testfile35.bz2 testfile35.debug.bz2 \
backtrace_data_LDADD = $(libdw) $(libelf)
backtrace_dwarf_CFLAGS = -Wno-unused-parameter
backtrace_dwarf_LDADD = $(libdw) $(libelf)
+debuglink_LDADD = $(libdw) $(libelf)
if GCOV
check: check-am coverage
--- /dev/null
+/* 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;
+}
--- /dev/null
+#! /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