Snap for 6063671 from 5f92182e496a66149ba09c92fe497135643663f5 to rvc-release

Change-Id: Ia2ecdb79b5912854c9f214a819bfcb5aa40c6067
diff --git a/ChangeLog b/ChangeLog
index 911cf35..0e22962 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2019-11-26  Mark Wielaard  <mark@klomp.org>
+
+	* configure.ac: Set version to 0.178.
+	NEWS: Add 0.178 section.
+
+2019-11-26  Mark Wielaard  <mark@klomp.org>
+
+	* configure.ac: Add CXXFLAGS for gcov.
+
+2019-10-28  Aaron Merey  <amerey@redhat.com>
+
+	* debuginfod/: New directory for debuginfod code.
+	* Makefile.am (SUBDIRS): Recurse there.
+	* configure.ac (--enable-debuginfod): New flag & checks.
+
+2019-08-25  Jonathon Anderson <jma14@rice.edu>
+
+	* configure.ac: Add new --enable-valgrind-annotations
+	* configure.ac: Add new --with-valgrind (headers only)
+
 2019-07-05  Omar Sandoval  <osandov@fb.com>
 
 	* configure.ac: Get rid of --enable-libebl-subdir.
diff --git a/METADATA b/METADATA
index 4cc663f..b6da4fa 100644
--- a/METADATA
+++ b/METADATA
@@ -9,10 +9,10 @@
     type: GIT
     value: "git://sourceware.org/git/elfutils.git"
   }
-  version: "09c9e8091c36eff7f1f4220ac12afe66d0322c59"
+  version: "elfutils-0.178"
   last_upgrade_date {
     year: 2019
-    month: 11
-    day: 6
+    month: 12
+    day: 10
   }
 }
diff --git a/Makefile.am b/Makefile.am
index 52f64fc..bd8926b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -29,6 +29,10 @@
 SUBDIRS = config m4 lib libelf libcpu backends libebl libdwelf libdwfl libdw \
 	  libasm src po doc tests
 
+if DEBUGINFOD
+SUBDIRS += debuginfod
+endif
+
 EXTRA_DIST = elfutils.spec GPG-KEY NOTES CONTRIBUTING \
 	     COPYING COPYING-GPLV2 COPYING-LGPLV3
 
diff --git a/NEWS b/NEWS
index 2bf19d9..c147ad3 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,25 @@
+Version 0.178
+
+debuginfod: New server, client tool and library to index and fetch
+            ELF/DWARF files addressed by build-id through HTTP.
+
+doc: There are now some manual pages for functions and tools.
+
+backends: The libebl libraries are no longer dynamically loaded through
+          dlopen, but are now compiled into libdw.so directly.
+
+readelf: -n, --notes now takes an optional "SECTION" argument.
+         -p and -x now also handle section numbers.
+         New option --dyn-sym to show just the dynamic symbol table.
+
+libcpu: Add RISC-V disassembler.
+
+libdw: Abbrevs and DIEs can now be read concurrently by multiple
+       threads through the same Dwarf handle.
+
+libdwfl: Will try to use debuginfod when installed as fallback to
+         retrieve ELF and DWARF debug data files by build-id.
+
 Version 0.177
 
 elfclassify: New tool to analyze ELF objects.
diff --git a/config/ChangeLog b/config/ChangeLog
index b641d0d..1637920 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,23 @@
+2019-11-26  Mark Wielaard  <mark@klomp.org>
+
+	* elfutils.spec.in: Remove Group tags, remove fedora and rhel
+	specifics, introduce elfutils-libs subpackage, move Requires
+	and BuildRequires around for new subpackage, remove dot at end
+	of Summary tags, add post/postun ldconfig for libs and
+	debuginfod-client, remove default defattr(-,root,root) for file
+	lists, order binaries by name.
+
+2019-11-25  Mark Wielaard  <mark@klomp.org>
+
+	* elfutils.spec.in: Add BuildRequires curl.
+
+2019-10-28  Frank Ch. Eigler  <fche@redhat.com>
+
+	* eu.am (AM_CXXFLAGS): Clone & amend AM_CFLAGS for c++11 code.
+	* debuginfod.service, debuginfod.sysconfig: New files: systemd.
+	* Makefile.am: Install them.
+	* elfutils.spec.in: Add debuginfod and debuginfod-client subrpms.
+
 2019-08-29  Mark Wielaard  <mark@klomp.org>
 
 	* elfutils.spec.in (%description devel): Remove libebl text.
diff --git a/config/Makefile.am b/config/Makefile.am
index 9d292ce..55e895a 100644
--- a/config/Makefile.am
+++ b/config/Makefile.am
@@ -28,11 +28,12 @@
 ## the GNU Lesser General Public License along with this program.  If
 ## not, see <http://www.gnu.org/licenses/>.
 ##
-EXTRA_DIST = elfutils.spec.in known-dwarf.awk 10-default-yama-scope.conf
-	     libelf.pc.in libdw.pc.in
+EXTRA_DIST = elfutils.spec.in known-dwarf.awk 10-default-yama-scope.conf \
+	     libelf.pc.in libdw.pc.in libdebuginfod.pc.in \
+	     debuginfod.service debuginfod.sysconfig
 
 pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = libelf.pc libdw.pc
+pkgconfig_DATA = libelf.pc libdw.pc libdebuginfod.pc
 
 if MAINTAINER_MODE
 $(srcdir)/elfutils.spec.in: $(top_srcdir)/NEWS
diff --git a/config/debuginfod.service b/config/debuginfod.service
new file mode 100644
index 0000000..d8ef072
--- /dev/null
+++ b/config/debuginfod.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=elfutils debuginfo-over-http server
+Documentation=http://elfutils.org/
+After=network.target
+
+[Service]
+EnvironmentFile=/etc/sysconfig/debuginfod
+User=debuginfod
+Group=debuginfod
+#CacheDirectory=debuginfod
+ExecStart=/usr/bin/debuginfod -d /var/cache/debuginfod/debuginfod.sqlite -p $DEBUGINFOD_PORT $DEBUGINFOD_VERBOSE $DEBUGINFOD_PRAGMAS $DEBUGINFOD_PATHS
+TimeoutStopSec=10
+
+[Install]
+WantedBy=multi-user.target
diff --git a/config/debuginfod.sysconfig b/config/debuginfod.sysconfig
new file mode 100644
index 0000000..c56bcf3
--- /dev/null
+++ b/config/debuginfod.sysconfig
@@ -0,0 +1,14 @@
+#
+DEBUGINFOD_PORT="8002"
+#DEBUGINFOD_VERBOSE="-v"
+
+# some common places to find trustworthy ELF/DWARF files and RPMs
+DEBUGINFOD_PATHS="-t43200 -F -R /usr/lib/debug /usr/bin /usr/libexec /usr/sbin /usr/lib /usr/lib64 /var/cache/yum /var/cache/dnf"
+
+# prefer reliability/durability over performance
+#DEBUGINFOD_PRAGMAS="-D 'pragma synchronous=full;'"
+
+# upstream debuginfods
+#DEBUGINFOD_URLS="http://secondhost:8002 http://thirdhost:8002"
+#DEBUGINFOD_TIMEOUT="5"
+#DEBUGINFOD_CACHE_DIR=""
diff --git a/config/elfutils.spec.in b/config/elfutils.spec.in
index 6771d13..4677934 100644
--- a/config/elfutils.spec.in
+++ b/config/elfutils.spec.in
@@ -5,49 +5,74 @@
 Release: 1
 URL: http://elfutils.org/
 License: GPLv3+ and (GPLv2+ or LGPLv3+) and GFDL
-Group: Development/Tools
 Source: ftp://sourceware.org/pub/elfutils/%{version}/elfutils-%{version}.tar.bz2
-Obsoletes: libelf libelf-devel
+
 Requires: elfutils-libelf = %{version}-%{release}
-Requires: glibc >= 2.7
-Requires: libstdc++
-Requires: default-yama-scope
+Requires: elfutils-libs = %{version}-%{release}
+# Can be a Recommends if rpm supports that
+Requires: elfutils-debuginfod-client
 
-# ExcludeArch: xxx
+BuildRequires: gcc
+# For libstdc++ demangle support
+BuildRequires: gcc-c++
 
-BuildRoot: %{_tmppath}/%{name}-root
-BuildRequires: gcc >= 4.1.2-33
-BuildRequires: glibc >= 2.7
-BuildRequires: bison >= 1.875
-BuildRequires: flex >= 2.5.4a
-BuildRequires: bzip2
-BuildRequires: m4
 BuildRequires: gettext
+BuildRequires: bison
+BuildRequires: flex
+
+# Compression support
 BuildRequires: zlib-devel
 BuildRequires: bzip2-devel
 BuildRequires: xz-devel
-BuildRequires: gcc-c++
+
+# For debuginfod
+BuildRequires: pkgconfig(libmicrohttpd) >= 0.9.33
+BuildRequires: pkgconfig(libcurl) >= 7.29.0
+BuildRequires: pkgconfig(sqlite3) >= 3.7.17
+BuildRequires: pkgconfig(libarchive) >= 3.1.2
+
+# For tests need to bunzip2 test files.
+BuildRequires: bzip2
+# For the run-debuginfod-find.sh test case in %check for /usr/sbin/ss
+BuildRequires: iproute
+BuildRequires: curl
 
 %define _gnu %{nil}
 %define _programprefix eu-
 
 %description
-
 Elfutils is a collection of utilities, including stack (to show
 backtraces), nm (for listing symbols from object files), size
 (for listing the section sizes of an object or archive file),
 strip (for discarding symbols), readelf (to see the raw ELF file
 structures), elflint (to check for well-formed ELF files) and
 elfcompress (to compress or decompress ELF sections).
-Also included are helper libraries which implement DWARF, ELF,
-and machine-specific ELF handling and process introspection.
+
+%package libs
+Summary: Libraries to handle compiled objects
+License: GPLv2+ or LGPLv3+
+Requires: elfutils-libelf = %{version}-%{release}
+Requires: default-yama-scope
+# Can be a Recommends if rpm supports that
+Requires: elfutils-debuginfod-client
+
+%description libs
+The elfutils-libs package contains libraries which implement DWARF, ELF,
+and machine-specific ELF handling and process introspection.  These
+libraries are used by the programs in the elfutils package.  The
+elfutils-devel package enables building other programs using these
+libraries.
 
 %package devel
-Summary: Development libraries to handle compiled objects.
-Group: Development/Tools
-License: (GPLv2+ or LGPLv3+) and GFDL
-Requires: elfutils = %{version}-%{release}
+Summary: Development libraries to handle compiled objects
+License: GPLv2+ or LGPLv3+
+Requires: elfutils-libs = %{version}-%{release}
 Requires: elfutils-libelf-devel = %{version}-%{release}
+%if 0%{?rhel} >= 8 || 0%{?fedora} >= 20
+Recommends: elfutils-debuginfod-client-devel
+%else
+Requires: elfutils-debuginfod-client-devel
+%endif
 
 %description devel
 The elfutils-devel package contains the libraries to create
@@ -56,18 +81,17 @@
 assembler interface.
 
 %package devel-static
-Summary: Static archives to handle compiled objects.
-Group: Development/Tools
+Summary: Static archives to handle compiled objects
 License: GPLv2+ or LGPLv3+
 Requires: elfutils-devel = %{version}-%{release}
+Requires: elfutils-libelf-devel-static = %{version}-%{release}
 
 %description devel-static
 The elfutils-devel-static archive contains the static archives
 with the code the handle compiled objects.
 
 %package libelf
-Summary: Library to read and write ELF files.
-Group: Development/Tools
+Summary: Library to read and write ELF files
 License: GPLv2+ or LGPLv3+
 
 %description libelf
@@ -78,7 +102,6 @@
 
 %package libelf-devel
 Summary: Development support for libelf
-Group: Development/Tools
 License: GPLv2+ or LGPLv3+
 Requires: elfutils-libelf = %{version}-%{release}
 Conflicts: libelf-devel
@@ -91,7 +114,6 @@
 
 %package libelf-devel-static
 Summary: Static archive of libelf
-Group: Development/Tools
 License: GPLv2+ or LGPLv3+
 Requires: elfutils-libelf-devel = %{version}-%{release}
 Conflicts: libelf-devel
@@ -102,7 +124,6 @@
 
 %package default-yama-scope
 Summary: Default yama attach scope sysctl setting
-Group: Development/Tools
 License: GPLv2+ or LGPLv3+
 Provides: default-yama-scope
 BuildArch: noarch
@@ -116,18 +137,54 @@
 (like synchronisation, signaling, debugging, tracing and
 profiling) of processes.
 
+%package debuginfod-client
+Summary: Library and command line client for build-id HTTP ELF/DWARF server
+License: GPLv3+ and (GPLv2+ or LGPLv3+)
+
+%package debuginfod-client-devel
+Summary: Libraries and headers to build debuginfod client applications
+License: GPLv2+ or LGPLv3+
+
+%package debuginfod
+Summary: HTTP ELF/DWARF file server addressed by build-id
+License: GPLv3+
+BuildRequires: systemd
+Requires(post):   systemd
+Requires(preun):  systemd
+Requires(postun): systemd
+Requires(pre): shadow-utils
+# For /usr/bin/cpio2rpm
+Requires: rpm
+
+%description debuginfod-client
+The elfutils-debuginfod-client package contains shared libraries
+dynamically loaded from -ldw, which use a debuginfod service
+to look up debuginfo and associated data. Also includes a
+command-line frontend.
+
+%description debuginfod-client-devel
+The elfutils-debuginfod-client-devel package contains the libraries
+to create applications to use the debuginfod service.
+
+%description debuginfod
+The elfutils-debuginfod package contains the debuginfod binary
+and control files for a service that can provide ELF/DWARF
+files to remote clients, based on build-id identification.
+The ELF/DWARF file searching functions in libdwfl can query
+such servers to download those files on demand.
+
 %prep
 %setup -q
 
 %build
-%configure --program-prefix=%{_programprefix}
-make
+%configure --program-prefix=%{_programprefix} --enable-debuginfod
+make -s %{?_smp_mflags}
 
 %install
 rm -rf ${RPM_BUILD_ROOT}
 mkdir -p ${RPM_BUILD_ROOT}%{_prefix}
 
-%makeinstall
+%make_install
 
 chmod +x ${RPM_BUILD_ROOT}%{_prefix}/%{_lib}/lib*.so*
 
@@ -140,52 +197,58 @@
 
 install -Dm0644 config/10-default-yama-scope.conf ${RPM_BUILD_ROOT}%{_sysctldir}/10-default-yama-scope.conf
 
+install -Dm0644 config/debuginfod.service ${RPM_BUILD_ROOT}%{_unitdir}/debuginfod.service
+install -Dm0644 config/debuginfod.sysconfig ${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig/debuginfod
+mkdir -p ${RPM_BUILD_ROOT}%{_localstatedir}/cache/debuginfod
+touch ${RPM_BUILD_ROOT}%{_localstatedir}/cache/debuginfod/debuginfod.sqlite
+
 %check
-make check
+make -s %{?_smp_mflags} check
 
-%clean
-rm -rf ${RPM_BUILD_ROOT}
-
-%post -p /sbin/ldconfig
-
-%postun -p /sbin/ldconfig
-
+%post libs -p /sbin/ldconfig
+%postun libs -p /sbin/ldconfig
 %post libelf -p /sbin/ldconfig
-
 %postun libelf -p /sbin/ldconfig
+%post debuginfod-client -p /sbin/ldconfig
+%postun debuginfod-client -p /sbin/ldconfig
 
 %post default-yama-scope
+# Due to circular dependencies might not be installed yet, so double check.
+# (systemd -> elfutils-libs -> default-yama-scope -> systemd)
+if [ -x /usr/lib/systemd/systemd-sysctl ] ; then
 %sysctl_apply 10-default-yama-scope.conf
+fi
 
 %files
-%defattr(-,root,root)
 %license COPYING COPYING-GPLV2 COPYING-LGPLV3 doc/COPYING-GFDL
 %doc README TODO CONTRIBUTING
+%{_bindir}/eu-addr2line
+%{_bindir}/eu-ar
+%{_bindir}/eu-elfclassify
+%{_bindir}/eu-elfcmp
+%{_bindir}/eu-elfcompress
 %{_bindir}/eu-elflint
+%{_bindir}/eu-findtextrel
+%{_bindir}/eu-make-debug-archive
 %{_bindir}/eu-nm
+%{_bindir}/eu-objdump
+%{_bindir}/eu-ranlib
 %{_bindir}/eu-readelf
 %{_bindir}/eu-size
 %{_bindir}/eu-stack
-%{_bindir}/eu-strip
-%{_bindir}/eu-findtextrel
-%{_bindir}/eu-addr2line
-%{_bindir}/eu-elfclassify
-%{_bindir}/eu-elfcmp
-%{_bindir}/eu-ranlib
 %{_bindir}/eu-strings
-%{_bindir}/eu-objdump
-%{_bindir}/eu-ar
+%{_bindir}/eu-strip
 %{_bindir}/eu-unstrip
-%{_bindir}/eu-make-debug-archive
-%{_bindir}/eu-elfcompress
+%{_mandir}/man1/eu-*.1*
+
+%files libs
+%license COPYING-GPLV2 COPYING-LGPLV3
 %{_libdir}/libasm-%{version}.so
 %{_libdir}/libdw-%{version}.so
 %{_libdir}/libasm.so.*
 %{_libdir}/libdw.so.*
-%{_mandir}/man1/eu-*.1*
 
 %files devel
-%defattr(-,root,root)
 %{_includedir}/dwarf.h
 %dir %{_includedir}/elfutils
 %{_includedir}/elfutils/elf-knowledge.h
@@ -204,17 +267,15 @@
 #%{_libdir}/libasm.a
 
 %files libelf
-%defattr(-,root,root)
+%license COPYING-GPLV2 COPYING-LGPLV3
 %{_libdir}/libelf-%{version}.so
 %{_libdir}/libelf.so.*
 %{_datadir}/locale/*/LC_MESSAGES/elfutils.mo
 
 %files libelf-devel
-%defattr(-,root,root)
 %{_includedir}/libelf.h
 %{_includedir}/gelf.h
 %{_includedir}/nlist.h
-%{_includedir}/elfutils/version.h
 %{_libdir}/libelf.so
 %{_libdir}/pkgconfig/libelf.pc
 %{_mandir}/man3/elf_*.3*
@@ -225,7 +286,59 @@
 %files default-yama-scope
 %{_sysctldir}/10-default-yama-scope.conf
 
+%files debuginfod-client
+%defattr(-,root,root)
+%{_libdir}/libdebuginfod-%{version}.so
+%{_bindir}/debuginfod-find
+%{_mandir}/man1/debuginfod-find.1*
+
+%files debuginfod-client-devel
+%defattr(-,root,root)
+%{_libdir}/pkgconfig/libdebuginfod.pc
+%{_mandir}/man3/debuginfod_*.3*
+%{_includedir}/elfutils/debuginfod.h
+%{_libdir}/libdebuginfod.so*
+
+%files debuginfod
+%defattr(-,root,root)
+%{_bindir}/debuginfod
+%config(noreplace) %verify(not md5 size mtime) %{_sysconfdir}/sysconfig/debuginfod
+%{_unitdir}/debuginfod.service
+%{_sysconfdir}/sysconfig/debuginfod
+%{_mandir}/man8/debuginfod.8*
+
+%dir %attr(0700,debuginfod,debuginfod) %{_localstatedir}/cache/debuginfod
+%verify(not md5 size mtime) %attr(0600,debuginfod,debuginfod) %{_localstatedir}/cache/debuginfod/debuginfod.sqlite
+
+%pre debuginfod
+getent group debuginfod >/dev/null || groupadd -r debuginfod
+getent passwd debuginfod >/dev/null || \
+    useradd -r -g debuginfod -d /var/cache/debuginfod -s /sbin/nologin \
+            -c "elfutils debuginfo server" debuginfod
+exit 0
+
+%post debuginfod
+%systemd_post debuginfod.service
+
+%postun debuginfod
+%systemd_postun_with_restart debuginfod.service
+
 %changelog
+* Tue Nov 26 2019 Mark Wielaard <mark@klomp.org> 0.178-1
+- debuginfod: New server, client tool and library to index and fetch
+              ELF/DWARF files addressed by build-id through HTTP.
+- doc: There are now some manual pages for functions and tools.
+- backends: The libebl libraries are no longer dynamically loaded
+            through dlopen, but are now compiled into libdw.so directly.
+- readelf: -n, --notes now takes an optional "SECTION" argument.
+           -p and -x now also handle section numbers.
+           New option --dyn-sym to show just the dynamic symbol table.
+- libcpu: Add RISC-V disassembler.
+- libdw: Abbrevs and DIEs can now be read concurrently by multiple
+         threads through the same Dwarf handle.
+- libdwfl: Will try to use debuginfod when installed as fallback to
+           retrieve ELF and DWARF debug data files by build-id.
+
 * Tue Aug 13 2019 Mark Wielaard <mark@klomp.org> 0.177-1
 - elfclassify: New tool to analyze ELF objects.
 - readelf: Print DW_AT_data_member_location as decimal offset.
diff --git a/config/eu.am b/config/eu.am
index 82acda3..6c3c444 100644
--- a/config/eu.am
+++ b/config/eu.am
@@ -79,6 +79,16 @@
 	    $(if $($(*F)_no_Wpacked_not_aligned),-Wno-packed-not-aligned,) \
 	    $($(*F)_CFLAGS)
 
+AM_CXXFLAGS = -std=c++11 -Wall -Wshadow \
+	   -Wtrampolines \
+	   $(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \
+	   $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \
+	   $(if $($(*F)_no_Werror),,-Werror) \
+	   $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \
+	   $(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \
+	   $(if $($(*F)_no_Wpacked_not_aligned),-Wno-packed-not-aligned,) \
+	   $($(*F)_CXXFLAGS)
+
 COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE))
 
 DEFS.os = -DPIC -DSHARED
diff --git a/config/libdebuginfod.pc.in b/config/libdebuginfod.pc.in
new file mode 100644
index 0000000..46722a7
--- /dev/null
+++ b/config/libdebuginfod.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: debuginfod
+Description: elfutils library to query debuginfo files from debuginfod servers
+Version: @VERSION@
+URL: http://elfutils.org/
+
+Libs: -L${libdir} -ldebuginfod
+Cflags: -I${includedir}
diff --git a/configure.ac b/configure.ac
index 9be34d1..5a2dc37 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
 dnl Process this file with autoconf to produce a configure script.
 dnl Configure input file for elfutils.                     -*-autoconf-*-
 dnl
-dnl Copyright (C) 1996-2018 Red Hat, Inc.
+dnl Copyright (C) 1996-2019 Red Hat, Inc.
 dnl
 dnl This file is part of elfutils.
 dnl
@@ -17,7 +17,7 @@
 dnl
 dnl  You should have received a copy of the GNU General Public License
 dnl  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-AC_INIT([elfutils],[0.177],[https://sourceware.org/bugzilla],[elfutils],[http://elfutils.org/])
+AC_INIT([elfutils],[0.178],[https://sourceware.org/bugzilla],[elfutils],[http://elfutils.org/])
 
 dnl Workaround for older autoconf < 2.64
 m4_ifndef([AC_PACKAGE_URL],
@@ -60,6 +60,8 @@
 dnl The RPM spec file.  We substitute a few values in the file.
 AC_CONFIG_FILES([elfutils.spec:config/elfutils.spec.in])
 
+dnl debuginfo-server client & server parts.
+AC_CONFIG_FILES([debuginfod/Makefile])
 
 AC_CANONICAL_HOST
 
@@ -297,6 +299,7 @@
 AS_HELP_STRING([--enable-gcov],[build binaries with gcov support]), [use_gcov=$enableval], [use_gcov=no])
 if test "$use_gcov" = yes; then
   CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage"
+  CXXFLAGS="$CXXFLAGS -fprofile-arcs -ftest-coverage"
   LDFLAGS="$LDFLAGS -fprofile-arcs"
 fi
 AM_CONDITIONAL(GCOV, test "$use_gcov" = yes)
@@ -335,6 +338,35 @@
 fi
 AM_CONDITIONAL(USE_VALGRIND, test "$use_valgrind" = yes)
 
+AC_ARG_WITH([valgrind],
+AS_HELP_STRING([--with-valgrind],[include directory for Valgrind headers]),
+[with_valgrind_headers=$withval], [with_valgrind_headers=no])
+if test "x$with_valgrind_headers" != xno; then
+    save_CFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS -I$with_valgrind_headers"
+    AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+      #include <valgrind/valgrind.h>
+      int main() { return 0; }
+    ]])], [ HAVE_VALGRIND_HEADERS="yes"
+            CFLAGS="$save_CFLAGS -I$with_valgrind_headers" ],
+          [ AC_MSG_ERROR([invalid valgrind include directory: $with_valgrind_headers]) ])
+fi
+
+AC_ARG_ENABLE([valgrind-annotations],
+AS_HELP_STRING([--enable-valgrind-annotations],[insert extra annotations for better valgrind support]),
+[use_vg_annotations=$enableval], [use_vg_annotations=no])
+if test "$use_vg_annotations" = yes; then
+    if test "x$HAVE_VALGRIND_HEADERS" != "xyes"; then
+      AC_MSG_CHECKING([whether Valgrind headers are available])
+      AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+        #include <valgrind/valgrind.h>
+        int main() { return 0; }
+      ]])], [ AC_MSG_RESULT([yes]) ],
+            [ AC_MSG_ERROR([valgrind annotations requested but no headers are available]) ])
+    fi
+fi
+AM_CONDITIONAL(USE_VG_ANNOTATIONS, test "$use_vg_annotations" = yes)
+
 AC_ARG_ENABLE([install-elfh],
 AS_HELP_STRING([--enable-install-elfh],[install elf.h in include dir]),
                [install_elfh=$enableval], [install_elfh=no])
@@ -538,7 +570,7 @@
 AC_CONFIG_FILES([tests/Makefile])
 
 dnl pkgconfig files
-AC_CONFIG_FILES([config/libelf.pc config/libdw.pc])
+AC_CONFIG_FILES([config/libelf.pc config/libdw.pc config/libdebuginfod.pc])
 
 # Get the definitions necessary to create the Makefiles in the po
 # subdirectories.  This is a small subset of the gettext rules.
@@ -641,6 +673,30 @@
   AC_MSG_WARN([No bunzip2, needed to run make check])
 fi
 
+# Look for libmicrohttpd, libcurl, libarchive, sqlite for debuginfo server
+# minimum versions as per rhel7.  Single --enable-* option arranges to build
+# both client and server.
+AC_ARG_ENABLE([debuginfod],AC_HELP_STRING([--enable-debuginfod], [Build debuginfod server and client]))
+AC_PROG_CXX
+AX_CXX_COMPILE_STDCXX(11, noext, optional)
+AS_IF([test "x$enable_debuginfod" != "xno"], [
+    AC_MSG_NOTICE([checking debuginfod dependencies, disable to skip])
+    enable_debuginfod=yes # presume success
+    PKG_PROG_PKG_CONFIG
+    if test "x$ac_cv_prog_ac_ct_CXX" = "x"; then enable_debuginfod=no; fi
+    PKG_CHECK_MODULES([libmicrohttpd],[libmicrohttpd >= 0.9.33],[],[enable_debuginfod=no])
+    PKG_CHECK_MODULES([libcurl],[libcurl >= 7.29.0],[],[enable_debuginfod=no])
+    PKG_CHECK_MODULES([sqlite3],[sqlite3 >= 3.7.17],[],[enable_debuginfod=no])
+    PKG_CHECK_MODULES([libarchive],[libarchive >= 3.1.2],[],[enable_debuginfod=no])
+    if test "x$enable_debuginfod" = "xno"; then
+      AC_MSG_ERROR([C++ compiler or dependencies not found, use --disable-debuginfod to disable.])
+    fi
+])
+
+AS_IF([test "x$enable_debuginfod" != "xno"],AC_DEFINE([ENABLE_DEBUGINFOD],[1],[Build debuginfod]))
+AM_CONDITIONAL([DEBUGINFOD],[test "x$enable_debuginfod" = "xyes"])
+
+
 AC_OUTPUT
 
 AC_MSG_NOTICE([
@@ -669,6 +725,8 @@
   OTHER FEATURES
     Deterministic archives by default  : ${default_ar_deterministic}
     Native language support            : ${USE_NLS}
+    Extra Valgrind annotations         : ${use_vg_annotations}
+    Debuginfod client/server support   : ${enable_debuginfod}
 
   EXTRA TEST FEATURES (used with make check)
     have bunzip2 installed (required)  : ${HAVE_BUNZIP2}
diff --git a/debuginfod/ChangeLog b/debuginfod/ChangeLog
new file mode 100644
index 0000000..8aa2944
--- /dev/null
+++ b/debuginfod/ChangeLog
@@ -0,0 +1,70 @@
+2019-11-26  Mark Wielaard  <mark@klomp.org>
+
+	* Makefile.am (BUILD_STATIC): Add needed libraries for libdw and
+	libdebuginfod.
+
+2019-11-25  Frank Ch. Eigler  <fche@redhat.com>
+
+	* debuginfod.cxx (groom): Add a sqlite3_db_release_memory()
+	at the end of periodic grooming to try to shrink the process.
+
+2019-11-24  Mark Wielaard  <mark@klomp.org>
+
+	* debuginfod.cxx (test_webapi_sleep): Removed.
+	(handler_cb): Don't check test_webapi_sleep and sleep.
+	(main): Don't set test_webapi_sleep.
+
+2019-11-24  Mark Wielaard  <mark@klomp.org>
+
+	* debuginfod.cxx (add_metric): New function.
+	(scan_source_file_path): Record metrics for
+	found_executable_total, found_debuginfo_total and
+	found_sourcerefs_total.
+	(scan_source_rpm_path): Likewise.
+
+2019-11-07  Frank Ch. Eigler  <fche@redhat.com>
+
+	* debuginfod.cxx: Add /metrics endpoint.  Add numerous
+	calls to new functions inc_metric/set_metric to populate
+	threadsafe map containing stats.  Add http content-type
+	response headers throughout.
+	(thread_main_*): Simplify counter/timer flow.
+	(main): Reorder web service shutdown to leave http running
+	as long as possible.
+	* debuginfod.8: Document it, add security caution.
+
+2019-11-06  Frank Ch. Eigler  <fche@redhat.com>
+
+	* debuginfod.cxx: Add new -L (symlink-following) mode.
+	* debuginfod.8: Document it.
+
+2019-11-04  Frank Ch. Eigler  <fche@redhat.com>
+
+	* debuginfo-client.c (debuginfod_set_progressfn): New function
+	for progress/interrupt callback.
+	(debuginfod_clean_cache, debuginfod_query_server): Call it.
+	* debuginfo.h: Declare it.
+	* debuginfod_set_progressfn.3, *_find_debuginfo.3: Document it.
+	* Makefile.am: Install it.
+	* libdebuginfod.map: Export it all under ELFUTILS_0.178 symversion.
+
+	* debuginfod-find.c: Add -v option to activate progress cb.
+	* debuginfod-find.1: Document it.
+	* debuginfod.cxx: Add $DEBUGINFOD_TEST_WEBAPI_SLEEP env var
+	to insert sleep in webapi callbacks, to help manual testing.
+
+2019-10-28  Frank Ch. Eigler  <fche@redhat.com>
+
+	* debuginfod.cxx: New file: debuginfod server.
+	* debuginfod.8: New file: man page.
+	* Makefile.am: Build it.
+
+2019-10-28  Aaron Merey  <amerey@redhat.com>
+
+	* debuginfod-client.c: New file: debuginfod client library.
+	* debuginfod.h: New file: header for same.
+	* libdebuginfod.map: New file: govern its solib exports.
+	* debuginfod-find.c: New file: command line frontend.
+	* debuginfod-find.1, debuginfod_find_source.3,
+	debuginfod_find_executable.3, debuginfod_find_debuginfo.3:
+	New man pages.
diff --git a/debuginfod/Makefile.am b/debuginfod/Makefile.am
new file mode 100644
index 0000000..52ead30
--- /dev/null
+++ b/debuginfod/Makefile.am
@@ -0,0 +1,118 @@
+## Makefile.am for libdebuginfod library subdirectory in elfutils.
+##
+## Process this file with automake to create Makefile.in
+##
+## Copyright (C) 2019 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) -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
+	   -I$(srcdir)/../libdw -I$(srcdir)/../libdwelf \
+	   $(libmicrohttpd_CFLAGS) $(libcurl_CFLAGS) $(sqlite3_CFLAGS) \
+	   $(libarchive_CFLAGS)
+VERSION = 1
+
+# Disable eu- prefixing for artifacts (binaries & man pages) in this
+# directory, since they do not conflict with binutils tools.
+program_prefix=
+program_transform_name = s,x,x,
+
+if BUILD_STATIC
+libasm = ../libasm/libasm.a
+libdw = ../libdw/libdw.a -lz $(zip_LIBS) $(libelf) $(libebl) -ldl -lpthread
+libelf = ../libelf/libelf.a -lz
+libdebuginfod = ./libdebuginfod.a $(libcurl_LIBS)
+else
+libasm = ../libasm/libasm.so
+libdw = ../libdw/libdw.so
+libelf = ../libelf/libelf.so
+libdebuginfod = ./libdebuginfod.so
+endif
+libebl = ../libebl/libebl.a
+libeu = ../lib/libeu.a
+
+AM_LDFLAGS = -Wl,-rpath-link,../libelf:../libdw:.
+
+bin_PROGRAMS = debuginfod debuginfod-find
+debuginfod_SOURCES = debuginfod.cxx
+debuginfod_LDADD = $(libdw) $(libelf) $(libeu) $(libdebuginfod) $(libmicrohttpd_LIBS) $(libcurl_LIBS) $(sqlite3_LIBS) $(libarchive_LIBS) -lpthread -ldl
+
+debuginfod_find_SOURCES = debuginfod-find.c
+debuginfod_find_LDADD = $(libeu) $(libdebuginfod)
+
+noinst_LIBRARIES = libdebuginfod.a
+noinst_LIBRARIES += libdebuginfod_pic.a
+
+libdebuginfod_a_SOURCES = debuginfod-client.c
+libdebuginfod_pic_a_SOURCES = debuginfod-client.c
+am_libdebuginfod_pic_a_OBJECTS = $(libdebuginfod_a_SOURCES:.c=.os)
+
+pkginclude_HEADERS = debuginfod.h
+
+libdebuginfod_so_LIBS = libdebuginfod_pic.a
+libdebuginfod_so_LDLIBS = $(libcurl_LIBS)
+libdebuginfod.so$(EXEEXT): $(srcdir)/libdebuginfod.map $(libdebuginfod_so_LIBS)
+	$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
+		-Wl,--soname,$@.$(VERSION) \
+		-Wl,--version-script,$<,--no-undefined \
+		-Wl,--whole-archive $(libdebuginfod_so_LIBS) -Wl,--no-whole-archive \
+		$(libdebuginfod_so_LDLIBS)
+	@$(textrel_check)
+	$(AM_V_at)ln -fs $@ $@.$(VERSION)
+
+install: install-am libdebuginfod.so
+	$(mkinstalldirs) $(DESTDIR)$(libdir)
+	$(INSTALL_PROGRAM) libdebuginfod.so $(DESTDIR)$(libdir)/libdebuginfod-$(PACKAGE_VERSION).so
+	ln -fs libdebuginfod-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libdebuginfod.so.$(VERSION)
+	ln -fs libdebuginfod.so.$(VERSION) $(DESTDIR)$(libdir)/libdebuginfod.so
+
+uninstall: uninstall-am
+	rm -f $(DESTDIR)$(libdir)/libdebuginfod-$(PACKAGE_VERSION).so
+	rm -f $(DESTDIR)$(libdir)/libdebuginfod.so.$(VERSION)
+	rm -f $(DESTDIR)$(libdir)/libdebuginfod.so
+	rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils
+
+EXTRA_DIST = libdebuginfod.map
+MOSTLYCLEANFILES = $(am_libdebuginfod_pic_a_OBJECTS) libdebuginfod.so.$(VERSION)
+CLEANFILES += $(am_libdebuginfod_pic_a_OBJECTS) libdebuginfod.so
+
+# automake std-options override: arrange to pass LD_LIBRARY_PATH
+installcheck-binPROGRAMS: $(bin_PROGRAMS)
+	bad=0; pid=$$$$; list="$(bin_PROGRAMS)"; for p in $$list; do \
+	  case ' $(AM_INSTALLCHECK_STD_OPTIONS_EXEMPT) ' in \
+	   *" $$p "* | *" $(srcdir)/$$p "*) continue;; \
+	  esac; \
+	  f=`echo "$$p" | \
+	     sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+	  for opt in --help --version; do \
+	    if LD_LIBRARY_PATH=$(DESTDIR)$(libdir) \
+	       $(DESTDIR)$(bindir)/$$f $$opt > c$${pid}_.out 2> c$${pid}_.err \
+		 && test -n "`cat c$${pid}_.out`" \
+		 && test -z "`cat c$${pid}_.err`"; then :; \
+	    else echo "$$f does not support $$opt" 1>&2; bad=1; fi; \
+	  done; \
+	done; rm -f c$${pid}_.???; exit $$bad
diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c
new file mode 100644
index 0000000..6e62b86
--- /dev/null
+++ b/debuginfod/debuginfod-client.c
@@ -0,0 +1,754 @@
+/* Retrieve ELF / DWARF / source files from the debuginfod.
+   Copyright (C) 2019 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/>.  */
+
+
+/* cargo-cult from libdwfl linux-kernel-modules.c */
+/* In case we have a bad fts we include this before config.h because it
+   can't handle _FILE_OFFSET_BITS.
+   Everything we need here is fine if its declarations just come first.
+   Also, include sys/types.h before fts. On some systems fts.h is not self
+   contained. */
+#ifdef BAD_FTS
+  #include <sys/types.h>
+  #include <fts.h>
+#endif
+
+#include "config.h"
+#include "debuginfod.h"
+#include <assert.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <fts.h>
+#include <string.h>
+#include <stdbool.h>
+#include <linux/limits.h>
+#include <time.h>
+#include <utime.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <curl/curl.h>
+
+/* If fts.h is included before config.h, its indirect inclusions may not
+   give us the right LFS aliases of these functions, so map them manually.  */
+#ifdef BAD_FTS
+  #ifdef _FILE_OFFSET_BITS
+    #define open open64
+    #define fopen fopen64
+  #endif
+#else
+  #include <sys/types.h>
+  #include <fts.h>
+#endif
+
+struct debuginfod_client
+{
+  /* Progress/interrupt callback function. */
+  debuginfod_progressfn_t progressfn;
+
+  /* Can contain all other context, like cache_path, server_urls,
+     timeout or other info gotten from environment variables, the
+     handle data, etc. So those don't have to be reparsed and
+     recreated on each request.  */
+};
+
+/* The cache_clean_interval_s file within the debuginfod cache specifies
+   how frequently the cache should be cleaned. The file's st_mtime represents
+   the time of last cleaning.  */
+static const char *cache_clean_interval_filename = "cache_clean_interval_s";
+static const time_t cache_clean_default_interval_s = 86400; /* 1 day */
+
+/* The cache_max_unused_age_s file within the debuginfod cache specifies the
+   the maximum time since last access that a file will remain in the cache.  */
+static const char *cache_max_unused_age_filename = "max_unused_age_s";
+static const time_t cache_default_max_unused_age_s = 604800; /* 1 week */
+
+/* Location of the cache of files downloaded from debuginfods.
+   The default parent directory is $HOME, or '/' if $HOME doesn't exist.  */
+static const char *cache_default_name = ".debuginfod_client_cache";
+static const char *cache_path_envvar = DEBUGINFOD_CACHE_PATH_ENV_VAR;
+
+/* URLs of debuginfods, separated by url_delim.
+   This env var must be set for debuginfod-client to run.  */
+static const char *server_urls_envvar = DEBUGINFOD_URLS_ENV_VAR;
+static const char *url_delim =  " ";
+static const char url_delim_char = ' ';
+
+/* Timeout for debuginfods, in seconds.
+   This env var must be set for debuginfod-client to run.  */
+static const char *server_timeout_envvar = DEBUGINFOD_TIMEOUT_ENV_VAR;
+static int server_timeout = 5;
+
+/* Data associated with a particular CURL easy handle. Passed to
+   the write callback.  */
+struct handle_data
+{
+  /* Cache file to be written to in case query is successful.  */
+  int fd;
+
+  /* URL queried by this handle.  */
+  char url[PATH_MAX];
+
+  /* This handle.  */
+  CURL *handle;
+
+  /* Pointer to handle that should write to fd. Initially points to NULL,
+     then points to the first handle that begins writing the target file
+     to the cache. Used to ensure that a file is not downloaded from
+     multiple servers unnecessarily.  */
+  CURL **target_handle;
+};
+
+static size_t
+debuginfod_write_callback (char *ptr, size_t size, size_t nmemb, void *data)
+{
+  ssize_t count = size * nmemb;
+
+  struct handle_data *d = (struct handle_data*)data;
+
+  /* Indicate to other handles that they can abort their transfer.  */
+  if (*d->target_handle == NULL)
+    *d->target_handle = d->handle;
+
+  /* If this handle isn't the target handle, abort transfer.  */
+  if (*d->target_handle != d->handle)
+    return -1;
+
+  return (size_t) write(d->fd, (void*)ptr, count);
+}
+
+/* Create the cache and interval file if they do not already exist.
+   Return 0 if cache and config file are initialized, otherwise return
+   the appropriate error code.  */
+static int
+debuginfod_init_cache (char *cache_path, char *interval_path, char *maxage_path)
+{
+  struct stat st;
+
+  /* If the cache and config file already exist then we are done.  */
+  if (stat(cache_path, &st) == 0 && stat(interval_path, &st) == 0)
+    return 0;
+
+  /* Create the cache and config files as necessary.  */
+  if (stat(cache_path, &st) != 0 && mkdir(cache_path, 0777) < 0)
+    return -errno;
+
+  int fd = -1;
+
+  /* init cleaning interval config file.  */
+  fd = open(interval_path, O_CREAT | O_RDWR, 0666);
+  if (fd < 0)
+    return -errno;
+
+  if (dprintf(fd, "%ld", cache_clean_default_interval_s) < 0)
+    return -errno;
+
+  /* init max age config file.  */
+  if (stat(maxage_path, &st) != 0
+      && (fd = open(maxage_path, O_CREAT | O_RDWR, 0666)) < 0)
+    return -errno;
+
+  if (dprintf(fd, "%ld", cache_default_max_unused_age_s) < 0)
+    return -errno;
+
+  return 0;
+}
+
+
+/* Delete any files that have been unmodied for a period
+   longer than $DEBUGINFOD_CACHE_CLEAN_INTERVAL_S.  */
+static int
+debuginfod_clean_cache(debuginfod_client *c,
+		       char *cache_path, char *interval_path,
+		       char *max_unused_path)
+{
+  struct stat st;
+  FILE *interval_file;
+  FILE *max_unused_file;
+
+  if (stat(interval_path, &st) == -1)
+    {
+      /* Create new interval file.  */
+      interval_file = fopen(interval_path, "w");
+
+      if (interval_file == NULL)
+        return -errno;
+
+      int rc = fprintf(interval_file, "%ld", cache_clean_default_interval_s);
+      fclose(interval_file);
+
+      if (rc < 0)
+        return -errno;
+    }
+
+  /* Check timestamp of interval file to see whether cleaning is necessary.  */
+  time_t clean_interval;
+  interval_file = fopen(interval_path, "r");
+  if (fscanf(interval_file, "%ld", &clean_interval) != 1)
+    clean_interval = cache_clean_default_interval_s;
+  fclose(interval_file);
+
+  if (time(NULL) - st.st_mtime < clean_interval)
+    /* Interval has not passed, skip cleaning.  */
+    return 0;
+
+  /* Read max unused age value from config file.  */
+  time_t max_unused_age;
+  max_unused_file = fopen(max_unused_path, "r");
+  if (max_unused_file)
+    {
+      if (fscanf(max_unused_file, "%ld", &max_unused_age) != 1)
+        max_unused_age = cache_default_max_unused_age_s;
+      fclose(max_unused_file);
+    }
+  else
+    max_unused_age = cache_default_max_unused_age_s;
+
+  char * const dirs[] = { cache_path, NULL, };
+
+  FTS *fts = fts_open(dirs, 0, NULL);
+  if (fts == NULL)
+    return -errno;
+
+  FTSENT *f;
+  long files = 0;
+  while ((f = fts_read(fts)) != NULL)
+    {
+      files++;
+      if (c->progressfn) /* inform/check progress callback */
+        if ((c->progressfn) (c, files, 0))
+          break;
+
+      switch (f->fts_info)
+        {
+        case FTS_F:
+          /* delete file if max_unused_age has been met or exceeded.  */
+          /* XXX consider extra effort to clean up old tmp files */
+          if (time(NULL) - f->fts_statp->st_atime >= max_unused_age)
+            unlink (f->fts_path);
+          break;
+
+        case FTS_DP:
+          /* Remove if empty. */
+          (void) rmdir (f->fts_path);
+          break;
+
+        default:
+          ;
+        }
+    }
+  fts_close(fts);
+
+  /* Update timestamp representing when the cache was last cleaned.  */
+  utime (interval_path, NULL);
+  return 0;
+}
+
+
+#define MAX_BUILD_ID_BYTES 64
+
+
+/* Query each of the server URLs found in $DEBUGINFOD_URLS for the file
+   with the specified build-id, type (debuginfo, executable or source)
+   and filename. filename may be NULL. If found, return a file
+   descriptor for the target, otherwise return an error code.
+*/
+static int
+debuginfod_query_server (debuginfod_client *c,
+			 const unsigned char *build_id,
+                         int build_id_len,
+                         const char *type,
+                         const char *filename,
+                         char **path)
+{
+  char *urls_envvar;
+  char *server_urls;
+  char cache_path[PATH_MAX];
+  char maxage_path[PATH_MAX*3]; /* These *3 multipliers are to shut up gcc -Wformat-truncation */
+  char interval_path[PATH_MAX*4];
+  char target_cache_dir[PATH_MAX*2];
+  char target_cache_path[PATH_MAX*4];
+  char target_cache_tmppath[PATH_MAX*5];
+  char suffix[PATH_MAX*2];
+  char build_id_bytes[MAX_BUILD_ID_BYTES * 2 + 1];
+
+  /* Copy lowercase hex representation of build_id into buf.  */
+  if ((build_id_len >= MAX_BUILD_ID_BYTES) ||
+      (build_id_len == 0 &&
+       sizeof(build_id_bytes) > MAX_BUILD_ID_BYTES*2 + 1))
+    return -EINVAL;
+  if (build_id_len == 0) /* expect clean hexadecimal */
+    strcpy (build_id_bytes, (const char *) build_id);
+  else
+    for (int i = 0; i < build_id_len; i++)
+      sprintf(build_id_bytes + (i * 2), "%02x", build_id[i]);
+
+  if (filename != NULL)
+    {
+      if (filename[0] != '/') // must start with /
+        return -EINVAL;
+
+      /* copy the filename to suffix, s,/,#,g */
+      unsigned q = 0;
+      for (unsigned fi=0; q < PATH_MAX-1; fi++)
+        switch (filename[fi])
+          {
+          case '\0':
+            suffix[q] = '\0';
+            q = PATH_MAX-1; /* escape for loop too */
+            break;
+          case '/': /* escape / to prevent dir escape */
+            suffix[q++]='#';
+            suffix[q++]='#';
+            break;
+          case '#': /* escape # to prevent /# vs #/ collisions */
+            suffix[q++]='#';
+            suffix[q++]='_';
+            break;
+          default:
+            suffix[q++]=filename[fi];
+          }
+      suffix[q] = '\0';
+      /* If the DWARF filenames are super long, this could exceed
+         PATH_MAX and truncate/collide.  Oh well, that'll teach
+         them! */
+    }
+  else
+    suffix[0] = '\0';
+
+  /* set paths needed to perform the query
+
+     example format
+     cache_path:        $HOME/.debuginfod_cache
+     target_cache_dir:  $HOME/.debuginfod_cache/0123abcd
+     target_cache_path: $HOME/.debuginfod_cache/0123abcd/debuginfo
+     target_cache_path: $HOME/.debuginfod_cache/0123abcd/source#PATH#TO#SOURCE ?
+  */
+
+  if (getenv(cache_path_envvar))
+    strcpy(cache_path, getenv(cache_path_envvar));
+  else
+    {
+      if (getenv("HOME"))
+        sprintf(cache_path, "%s/%s", getenv("HOME"), cache_default_name);
+      else
+        sprintf(cache_path, "/%s", cache_default_name);
+    }
+
+  /* avoid using snprintf here due to compiler warning.  */
+  snprintf(target_cache_dir, sizeof(target_cache_dir), "%s/%s", cache_path, build_id_bytes);
+  snprintf(target_cache_path, sizeof(target_cache_path), "%s/%s%s", target_cache_dir, type, suffix);
+  snprintf(target_cache_tmppath, sizeof(target_cache_tmppath), "%s.XXXXXX", target_cache_path);
+
+  /* XXX combine these */
+  snprintf(interval_path, sizeof(interval_path), "%s/%s", cache_path, cache_clean_interval_filename);
+  snprintf(maxage_path, sizeof(maxage_path), "%s/%s", cache_path, cache_max_unused_age_filename);
+  int rc = debuginfod_init_cache(cache_path, interval_path, maxage_path);
+  if (rc != 0)
+    goto out;
+  rc = debuginfod_clean_cache(c, cache_path, interval_path, maxage_path);
+  if (rc != 0)
+    goto out;
+
+  /* If the target is already in the cache then we are done.  */
+  int fd = open (target_cache_path, O_RDONLY);
+  if (fd >= 0)
+    {
+      /* Success!!!! */
+      if (path != NULL)
+        *path = strdup(target_cache_path);
+      return fd;
+    }
+
+
+  urls_envvar = getenv(server_urls_envvar);
+  if (urls_envvar == NULL || urls_envvar[0] == '\0')
+    {
+      rc = -ENOSYS;
+      goto out;
+    }
+
+  if (getenv(server_timeout_envvar))
+    server_timeout = atoi (getenv(server_timeout_envvar));
+
+  /* make a copy of the envvar so it can be safely modified.  */
+  server_urls = strdup(urls_envvar);
+  if (server_urls == NULL)
+    {
+      rc = -ENOMEM;
+      goto out;
+    }
+  /* thereafter, goto out0 on error*/
+
+  /* create target directory in cache if not found.  */
+  struct stat st;
+  if (stat(target_cache_dir, &st) == -1 && mkdir(target_cache_dir, 0700) < 0)
+    {
+      rc = -errno;
+      goto out0;
+    }
+
+  /* NB: write to a temporary file first, to avoid race condition of
+     multiple clients checking the cache, while a partially-written or empty
+     file is in there, being written from libcurl. */
+  fd = mkstemp (target_cache_tmppath);
+  if (fd < 0)
+    {
+      rc = -errno;
+      goto out0;
+    }
+
+  /* Count number of URLs.  */
+  int num_urls = 0;
+  for (int i = 0; server_urls[i] != '\0'; i++)
+    if (server_urls[i] != url_delim_char
+        && (i == 0 || server_urls[i - 1] == url_delim_char))
+      num_urls++;
+
+  /* Tracks which handle should write to fd. Set to the first
+     handle that is ready to write the target file to the cache.  */
+  CURL *target_handle = NULL;
+  struct handle_data *data = malloc(sizeof(struct handle_data) * num_urls);
+
+  /* Initalize handle_data with default values. */
+  for (int i = 0; i < num_urls; i++)
+    {
+      data[i].handle = NULL;
+      data[i].fd = -1;
+    }
+
+  CURLM *curlm = curl_multi_init();
+  if (curlm == NULL)
+    {
+      rc = -ENETUNREACH;
+      goto out0;
+    }
+  /* thereafter, goto out1 on error.  */
+
+  char *strtok_saveptr;
+  char *server_url = strtok_r(server_urls, url_delim, &strtok_saveptr);
+
+  /* Initialize each handle.  */
+  for (int i = 0; i < num_urls && server_url != NULL; i++)
+    {
+      data[i].fd = fd;
+      data[i].target_handle = &target_handle;
+      data[i].handle = curl_easy_init();
+
+      if (data[i].handle == NULL)
+        {
+          rc = -ENETUNREACH;
+          goto out1;
+        }
+
+      /* Build handle url. Tolerate both  http://foo:999  and
+         http://foo:999/  forms */
+      char *slashbuildid;
+      if (strlen(server_url) > 1 && server_url[strlen(server_url)-1] == '/')
+        slashbuildid = "buildid";
+      else
+        slashbuildid = "/buildid";
+
+      if (filename) /* must start with / */
+        snprintf(data[i].url, PATH_MAX, "%s%s/%s/%s%s", server_url,
+                 slashbuildid, build_id_bytes, type, filename);
+      else
+        snprintf(data[i].url, PATH_MAX, "%s%s/%s/%s", server_url,
+                 slashbuildid, build_id_bytes, type);
+
+      curl_easy_setopt(data[i].handle, CURLOPT_URL, data[i].url);
+      curl_easy_setopt(data[i].handle,
+                       CURLOPT_WRITEFUNCTION,
+                       debuginfod_write_callback);
+      curl_easy_setopt(data[i].handle, CURLOPT_WRITEDATA, (void*)&data[i]);
+      curl_easy_setopt(data[i].handle, CURLOPT_TIMEOUT, (long) server_timeout);
+      curl_easy_setopt(data[i].handle, CURLOPT_FILETIME, (long) 1);
+      curl_easy_setopt(data[i].handle, CURLOPT_FOLLOWLOCATION, (long) 1);
+      curl_easy_setopt(data[i].handle, CURLOPT_FAILONERROR, (long) 1);
+      curl_easy_setopt(data[i].handle, CURLOPT_NOSIGNAL, (long) 1);
+      curl_easy_setopt(data[i].handle, CURLOPT_AUTOREFERER, (long) 1);
+      curl_easy_setopt(data[i].handle, CURLOPT_ACCEPT_ENCODING, "");
+      curl_easy_setopt(data[i].handle, CURLOPT_USERAGENT, (void*) PACKAGE_STRING);
+
+      curl_multi_add_handle(curlm, data[i].handle);
+      server_url = strtok_r(NULL, url_delim, &strtok_saveptr);
+    }
+
+  /* Query servers in parallel.  */
+  int still_running;
+  long loops = 0;
+  do
+    {
+      CURLMcode curl_res;
+
+      if (c->progressfn) /* inform/check progress callback */
+        {
+          loops ++;
+          long pa = loops; /* default params for progress callback */
+          long pb = 0;
+          if (target_handle) /* we've committed to a server; report its download progress */
+            {
+#ifdef CURLINFO_SIZE_DOWNLOAD_T
+              curl_off_t dl;
+              curl_res = curl_easy_getinfo(target_handle,
+                                           CURLINFO_SIZE_DOWNLOAD_T,
+                                           &dl);
+              if (curl_res == 0 && dl >= 0)
+                pa = (dl > LONG_MAX ? LONG_MAX : (long)dl);
+#else
+              double dl;
+              curl_res = curl_easy_getinfo(target_handle,
+                                           CURLINFO_SIZE_DOWNLOAD,
+                                           &dl);
+              if (curl_res == 0)
+                pa = (dl > LONG_MAX ? LONG_MAX : (long)dl);
+#endif
+
+#ifdef CURLINFO_CURLINFO_CONTENT_LENGTH_DOWNLOAD_T
+              curl_off_t cl;
+              curl_res = curl_easy_getinfo(target_handle,
+                                           CURLINFO_CONTENT_LENGTH_DOWNLOAD_T,
+                                           &cl);
+              if (curl_res == 0 && cl >= 0)
+                pb = (cl > LONG_MAX ? LONG_MAX : (long)cl);
+#else
+              double cl;
+              curl_res = curl_easy_getinfo(target_handle,
+                                           CURLINFO_CONTENT_LENGTH_DOWNLOAD,
+                                           &cl);
+              if (curl_res == 0)
+                pb = (cl > LONG_MAX ? LONG_MAX : (long)cl);
+#endif
+            }
+
+          if ((*c->progressfn) (c, pa, pb))
+            break;
+        }
+
+      /* Wait 1 second, the minimum DEBUGINFOD_TIMEOUT.  */
+      curl_multi_wait(curlm, NULL, 0, 1000, NULL);
+
+      /* If the target file has been found, abort the other queries.  */
+      if (target_handle != NULL)
+        for (int i = 0; i < num_urls; i++)
+          if (data[i].handle != target_handle)
+            curl_multi_remove_handle(curlm, data[i].handle);
+
+      curl_res = curl_multi_perform(curlm, &still_running);
+      if (curl_res != CURLM_OK)
+        {
+          switch (curl_res)
+            {
+            case CURLM_CALL_MULTI_PERFORM: continue;
+            case CURLM_OUT_OF_MEMORY: rc = -ENOMEM; break;
+            default: rc = -ENETUNREACH; break;
+            }
+          goto out1;
+        }
+    } while (still_running);
+
+  /* Check whether a query was successful. If so, assign its handle
+     to verified_handle.  */
+  int num_msg;
+  rc = -ENOENT;
+  CURL *verified_handle = NULL;
+  do
+    {
+      CURLMsg *msg;
+
+      msg = curl_multi_info_read(curlm, &num_msg);
+      if (msg != NULL && msg->msg == CURLMSG_DONE)
+        {
+          if (msg->data.result != CURLE_OK)
+            {
+              /* Unsucessful query, determine error code.  */
+              switch (msg->data.result)
+                {
+                case CURLE_COULDNT_RESOLVE_HOST: rc = -EHOSTUNREACH; break; // no NXDOMAIN
+                case CURLE_URL_MALFORMAT: rc = -EINVAL; break;
+                case CURLE_COULDNT_CONNECT: rc = -ECONNREFUSED; break;
+                case CURLE_REMOTE_ACCESS_DENIED: rc = -EACCES; break;
+                case CURLE_WRITE_ERROR: rc = -EIO; break;
+                case CURLE_OUT_OF_MEMORY: rc = -ENOMEM; break;
+                case CURLE_TOO_MANY_REDIRECTS: rc = -EMLINK; break;
+                case CURLE_SEND_ERROR: rc = -ECONNRESET; break;
+                case CURLE_RECV_ERROR: rc = -ECONNRESET; break;
+                case CURLE_OPERATION_TIMEDOUT: rc = -ETIME; break;
+                default: rc = -ENOENT; break;
+                }
+            }
+          else
+            {
+              /* Query completed without an error. Confirm that the
+                 response code is 200 and set verified_handle.  */
+              long resp_code = 500;
+              CURLcode curl_res;
+
+              curl_res = curl_easy_getinfo(target_handle,
+                                           CURLINFO_RESPONSE_CODE,
+                                           &resp_code);
+
+              if (curl_res == CURLE_OK
+                  && resp_code == 200
+                  && msg->easy_handle != NULL)
+                {
+                  verified_handle = msg->easy_handle;
+                  break;
+                }
+            }
+        }
+    } while (num_msg > 0);
+
+  if (verified_handle == NULL)
+    goto out1;
+
+  /* we've got one!!!! */
+  time_t mtime;
+  CURLcode curl_res = curl_easy_getinfo(verified_handle, CURLINFO_FILETIME, (void*) &mtime);
+  if (curl_res != CURLE_OK)
+    mtime = time(NULL); /* fall back to current time */
+
+  struct timeval tvs[2];
+  tvs[0].tv_sec = tvs[1].tv_sec = mtime;
+  tvs[0].tv_usec = tvs[1].tv_usec = 0;
+  (void) futimes (fd, tvs);  /* best effort */
+
+  /* rename tmp->real */
+  rc = rename (target_cache_tmppath, target_cache_path);
+  if (rc < 0)
+    {
+      rc = -errno;
+      goto out1;
+      /* Perhaps we need not give up right away; could retry or something ... */
+    }
+
+  /* Success!!!! */
+  for (int i = 0; i < num_urls; i++)
+    curl_easy_cleanup(data[i].handle);
+
+  curl_multi_cleanup (curlm);
+  free (data);
+  free (server_urls);
+  /* don't close fd - we're returning it */
+  /* don't unlink the tmppath; it's already been renamed. */
+  if (path != NULL)
+   *path = strdup(target_cache_path);
+
+  return fd;
+
+/* error exits */
+ out1:
+  for (int i = 0; i < num_urls; i++)
+    curl_easy_cleanup(data[i].handle);
+
+  curl_multi_cleanup(curlm);
+  unlink (target_cache_tmppath);
+  (void) rmdir (target_cache_dir); /* nop if not empty */
+  free(data);
+  close (fd);
+
+ out0:
+  free (server_urls);
+
+ out:
+  return rc;
+}
+
+/* See debuginfod.h  */
+debuginfod_client  *
+debuginfod_begin (void)
+{
+  debuginfod_client *client;
+  size_t size = sizeof (struct debuginfod_client);
+  client = (debuginfod_client *) malloc (size);
+  if (client != NULL)
+    client->progressfn = NULL;
+  return client;
+}
+
+void
+debuginfod_end (debuginfod_client *client)
+{
+  free (client);
+}
+
+int
+debuginfod_find_debuginfo (debuginfod_client *client,
+			   const unsigned char *build_id, int build_id_len,
+                           char **path)
+{
+  return debuginfod_query_server(client, build_id, build_id_len,
+                                 "debuginfo", NULL, path);
+}
+
+
+/* See debuginfod.h  */
+int
+debuginfod_find_executable(debuginfod_client *client,
+			   const unsigned char *build_id, int build_id_len,
+                           char **path)
+{
+  return debuginfod_query_server(client, build_id, build_id_len,
+                                 "executable", NULL, path);
+}
+
+/* See debuginfod.h  */
+int debuginfod_find_source(debuginfod_client *client,
+			   const unsigned char *build_id, int build_id_len,
+                           const char *filename, char **path)
+{
+  return debuginfod_query_server(client, build_id, build_id_len,
+                                 "source", filename, path);
+}
+
+
+void
+debuginfod_set_progressfn(debuginfod_client *client,
+			  debuginfod_progressfn_t fn)
+{
+  client->progressfn = fn;
+}
+
+
+/* NB: these are thread-unsafe. */
+__attribute__((constructor)) attribute_hidden void libdebuginfod_ctor(void)
+{
+  curl_global_init(CURL_GLOBAL_DEFAULT);
+}
+
+/* NB: this is very thread-unsafe: it breaks other threads that are still in libcurl */
+__attribute__((destructor)) attribute_hidden void libdebuginfod_dtor(void)
+{
+  /* ... so don't do this: */
+  /* curl_global_cleanup(); */
+}
diff --git a/debuginfod/debuginfod-find.c b/debuginfod/debuginfod-find.c
new file mode 100644
index 0000000..8bd3a3d
--- /dev/null
+++ b/debuginfod/debuginfod-find.c
@@ -0,0 +1,145 @@
+/* Command-line frontend for retrieving ELF / DWARF / source files
+   from the debuginfod.
+   Copyright (C) 2019 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 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 "config.h"
+#include "printversion.h"
+#include "debuginfod.h"
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <argp.h>
+
+
+/* Name and version of program.  */
+ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
+
+/* Bug report address.  */
+ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
+
+/* Short description of program.  */
+static const char doc[] = N_("Request debuginfo-related content "
+                             "from debuginfods listed in $" DEBUGINFOD_URLS_ENV_VAR ".");
+
+/* Strings for arguments in help texts.  */
+static const char args_doc[] = N_("debuginfo BUILDID\n"
+                                  "executable BUILDID\n"
+                                  "source BUILDID /FILENAME");
+
+/* Definitions of arguments for argp functions.  */
+static const struct argp_option options[] =
+  {
+   { "verbose", 'v', NULL, 0, "Increase verbosity.", 0 },
+   { NULL, 0, NULL, 0, NULL, 0 }
+  };
+
+/* debuginfod connection handle.  */
+static debuginfod_client *client;
+
+int progressfn(debuginfod_client *c __attribute__((__unused__)),
+	       long a, long b)
+{
+  fprintf (stderr, "Progress %ld / %ld\n", a, b);
+  return 0;
+}
+
+
+static error_t parse_opt (int key, char *arg, struct argp_state *state)
+{
+  (void) arg;
+  (void) state;
+  switch (key)
+    {
+    case 'v': debuginfod_set_progressfn (client, & progressfn); break;
+    default: return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+
+/* Data structure to communicate with argp functions.  */
+static struct argp argp =
+  {
+   options, parse_opt, args_doc, doc, NULL, NULL, NULL
+  };
+
+
+
+int
+main(int argc, char** argv)
+{
+  client = debuginfod_begin ();
+  if (client == NULL)
+    {
+      fprintf(stderr, "Couldn't create debuginfod client context\n");
+      return 1;
+    }
+
+  int remaining;
+  (void) argp_parse (&argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_ARGS, &remaining, NULL);
+
+  if (argc < 2 || remaining+1 == argc) /* no arguments or at least two non-option words */
+    {
+      argp_help (&argp, stderr, ARGP_HELP_USAGE, argv[0]);
+      return 1;
+    }
+
+  int rc;
+  char *cache_name;
+
+  /* Check whether FILETYPE is valid and call the appropriate
+     debuginfod_find_* function. If FILETYPE is "source"
+     then ensure a FILENAME was also supplied as an argument.  */
+  if (strcmp(argv[remaining], "debuginfo") == 0)
+    rc = debuginfod_find_debuginfo(client,
+				   (unsigned char *)argv[remaining+1], 0,
+				   &cache_name);
+  else if (strcmp(argv[remaining], "executable") == 0)
+    rc = debuginfod_find_executable(client,
+				    (unsigned char *)argv[remaining+1], 0,
+				    &cache_name);
+  else if (strcmp(argv[remaining], "source") == 0)
+    {
+      if (remaining+2 == argc || argv[3][0] != '/')
+        {
+          fprintf(stderr, "If FILETYPE is \"source\" then absolute /FILENAME must be given\n");
+          return 1;
+        }
+      rc = debuginfod_find_source(client, (unsigned char *)argv[remaining+1],
+				  0, argv[remaining+2], &cache_name);
+    }
+  else
+    {
+      argp_help (&argp, stderr, ARGP_HELP_USAGE, argv[0]);
+      return 1;
+    }
+
+  if (rc < 0)
+    {
+      fprintf(stderr, "Server query failed: %s\n", strerror(-rc));
+      return 1;
+    }
+
+  printf("%s\n", cache_name);
+
+  free (cache_name);
+  debuginfod_end (client);
+
+  return 0;
+}
diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx
new file mode 100644
index 0000000..aa7ffcf
--- /dev/null
+++ b/debuginfod/debuginfod.cxx
@@ -0,0 +1,2688 @@
+/* Debuginfo-over-http server.
+   Copyright (C) 2019 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/>.  */
+
+
+/* cargo-cult from libdwfl linux-kernel-modules.c */
+/* In case we have a bad fts we include this before config.h because it
+   can't handle _FILE_OFFSET_BITS.
+   Everything we need here is fine if its declarations just come first.
+   Also, include sys/types.h before fts. On some systems fts.h is not self
+   contained. */
+#ifdef BAD_FTS
+  #include <sys/types.h>
+  #include <fts.h>
+#endif
+
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+extern "C" {
+#include "printversion.h"
+}
+
+#include "debuginfod.h"
+#include <dwarf.h>
+
+#include <argp.h>
+#ifdef __GNUC__
+#undef __attribute__ /* glibc bug - rhbz 1763325 */
+#endif
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <error.h>
+// #include <libintl.h> // not until it supports C++ << better
+#include <locale.h>
+#include <pthread.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <netdb.h>
+
+
+/* If fts.h is included before config.h, its indirect inclusions may not
+   give us the right LFS aliases of these functions, so map them manually.  */
+#ifdef BAD_FTS
+  #ifdef _FILE_OFFSET_BITS
+    #define open open64
+    #define fopen fopen64
+  #endif
+#else
+  #include <sys/types.h>
+  #include <fts.h>
+#endif
+
+#include <cstring>
+#include <vector>
+#include <set>
+#include <map>
+#include <string>
+#include <iostream>
+#include <iomanip>
+#include <ostream>
+#include <sstream>
+#include <mutex>
+#include <condition_variable>
+#include <thread>
+// #include <regex> // on rhel7 gcc 4.8, not competent
+#include <regex.h>
+// #include <algorithm>
+using namespace std;
+
+#include <gelf.h>
+#include <libdwelf.h>
+
+#include <microhttpd.h>
+#include <curl/curl.h>
+#include <archive.h>
+#include <archive_entry.h>
+#include <sqlite3.h>
+
+#ifdef __linux__
+#include <sys/syscall.h>
+#endif
+
+#ifdef __linux__
+#define tid() syscall(SYS_gettid)
+#else
+#define tid() pthread_self()
+#endif
+
+
+// Roll this identifier for every sqlite schema incompatiblity.
+#define BUILDIDS "buildids9"
+
+#if SQLITE_VERSION_NUMBER >= 3008000
+#define WITHOUT_ROWID "without rowid"
+#else
+#define WITHOUT_ROWID ""
+#endif
+
+static const char DEBUGINFOD_SQLITE_DDL[] =
+  "pragma foreign_keys = on;\n"
+  "pragma synchronous = 0;\n" // disable fsync()s - this cache is disposable across a machine crash
+  "pragma journal_mode = wal;\n" // https://sqlite.org/wal.html
+  "pragma wal_checkpoint = truncate;\n" // clean out any preexisting wal file
+  "pragma journal_size_limit = 0;\n" // limit steady state file (between grooming, which also =truncate's)
+  "pragma auto_vacuum = incremental;\n" // https://sqlite.org/pragma.html
+  "pragma busy_timeout = 1000;\n" // https://sqlite.org/pragma.html
+  // NB: all these are overridable with -D option
+
+  // Normalization table for interning file names
+  "create table if not exists " BUILDIDS "_files (\n"
+  "        id integer primary key not null,\n"
+  "        name text unique not null\n"
+  "        );\n"
+  // Normalization table for interning buildids
+  "create table if not exists " BUILDIDS "_buildids (\n"
+  "        id integer primary key not null,\n"
+  "        hex text unique not null);\n"
+  // Track the completion of scanning of a given file & sourcetype at given time
+  "create table if not exists " BUILDIDS "_file_mtime_scanned (\n"
+  "        mtime integer not null,\n"
+  "        file integer not null,\n"
+  "        size integer not null,\n" // in bytes
+  "        sourcetype text(1) not null\n"
+  "            check (sourcetype IN ('F', 'R')),\n"
+  "        foreign key (file) references " BUILDIDS "_files(id) on update cascade on delete cascade,\n"
+  "        primary key (file, mtime, sourcetype)\n"
+  "        ) " WITHOUT_ROWID ";\n"
+  "create table if not exists " BUILDIDS "_f_de (\n"
+  "        buildid integer not null,\n"
+  "        debuginfo_p integer not null,\n"
+  "        executable_p integer not null,\n"
+  "        file integer not null,\n"
+  "        mtime integer not null,\n"
+  "        foreign key (file) references " BUILDIDS "_files(id) on update cascade on delete cascade,\n"
+  "        foreign key (buildid) references " BUILDIDS "_buildids(id) on update cascade on delete cascade,\n"
+  "        primary key (buildid, file, mtime)\n"
+  "        ) " WITHOUT_ROWID ";\n"
+  "create table if not exists " BUILDIDS "_f_s (\n"
+  "        buildid integer not null,\n"
+  "        artifactsrc integer not null,\n"
+  "        file integer not null,\n" // NB: not necessarily entered into _mtime_scanned
+  "        mtime integer not null,\n"
+  "        foreign key (file) references " BUILDIDS "_files(id) on update cascade on delete cascade,\n"
+  "        foreign key (artifactsrc) references " BUILDIDS "_files(id) on update cascade on delete cascade,\n"
+  "        foreign key (buildid) references " BUILDIDS "_buildids(id) on update cascade on delete cascade,\n"
+  "        primary key (buildid, artifactsrc, file, mtime)\n"
+  "        ) " WITHOUT_ROWID ";\n"
+  "create table if not exists " BUILDIDS "_r_de (\n"
+  "        buildid integer not null,\n"
+  "        debuginfo_p integer not null,\n"
+  "        executable_p integer not null,\n"
+  "        file integer not null,\n"
+  "        mtime integer not null,\n"
+  "        content integer not null,\n"
+  "        foreign key (file) references " BUILDIDS "_files(id) on update cascade on delete cascade,\n"
+  "        foreign key (content) references " BUILDIDS "_files(id) on update cascade on delete cascade,\n"
+  "        foreign key (buildid) references " BUILDIDS "_buildids(id) on update cascade on delete cascade,\n"
+  "        primary key (buildid, debuginfo_p, executable_p, file, content, mtime)\n"
+  "        ) " WITHOUT_ROWID ";\n"
+  "create table if not exists " BUILDIDS "_r_sref (\n" // outgoing dwarf sourcefile references from rpm
+  "        buildid integer not null,\n"
+  "        artifactsrc integer not null,\n"
+  "        foreign key (artifactsrc) references " BUILDIDS "_files(id) on update cascade on delete cascade,\n"
+  "        foreign key (buildid) references " BUILDIDS "_buildids(id) on update cascade on delete cascade,\n"
+  "        primary key (buildid, artifactsrc)\n"
+  "        ) " WITHOUT_ROWID ";\n"
+  "create table if not exists " BUILDIDS "_r_sdef (\n" // rpm contents that may satisfy sref
+  "        file integer not null,\n"
+  "        mtime integer not null,\n"
+  "        content integer not null,\n"
+  "        foreign key (file) references " BUILDIDS "_files(id) on update cascade on delete cascade,\n"
+  "        foreign key (content) references " BUILDIDS "_files(id) on update cascade on delete cascade,\n"
+  "        primary key (content, file, mtime)\n"
+  "        ) " WITHOUT_ROWID ";\n"
+  // create views to glue together some of the above tables, for webapi D queries
+  "create view if not exists " BUILDIDS "_query_d as \n"
+  "select\n"
+  "        b.hex as buildid, n.mtime, 'F' as sourcetype, f0.name as source0, n.mtime as mtime, null as source1\n"
+  "        from " BUILDIDS "_buildids b, " BUILDIDS "_files f0, " BUILDIDS "_f_de n\n"
+  "        where b.id = n.buildid and f0.id = n.file and n.debuginfo_p = 1\n"
+  "union all select\n"
+  "        b.hex as buildid, n.mtime, 'R' as sourcetype, f0.name as source0, n.mtime as mtime, f1.name as source1\n"
+  "        from " BUILDIDS "_buildids b, " BUILDIDS "_files f0, " BUILDIDS "_files f1, " BUILDIDS "_r_de n\n"
+  "        where b.id = n.buildid and f0.id = n.file and f1.id = n.content and n.debuginfo_p = 1\n"
+  ";"
+  // ... and for E queries
+  "create view if not exists " BUILDIDS "_query_e as \n"
+  "select\n"
+  "        b.hex as buildid, n.mtime, 'F' as sourcetype, f0.name as source0, n.mtime as mtime, null as source1\n"
+  "        from " BUILDIDS "_buildids b, " BUILDIDS "_files f0, " BUILDIDS "_f_de n\n"
+  "        where b.id = n.buildid and f0.id = n.file and n.executable_p = 1\n"
+  "union all select\n"
+  "        b.hex as buildid, n.mtime, 'R' as sourcetype, f0.name as source0, n.mtime as mtime, f1.name as source1\n"
+  "        from " BUILDIDS "_buildids b, " BUILDIDS "_files f0, " BUILDIDS "_files f1, " BUILDIDS "_r_de n\n"
+  "        where b.id = n.buildid and f0.id = n.file and f1.id = n.content and n.executable_p = 1\n"
+  ";"
+  // ... and for S queries
+  "create view if not exists " BUILDIDS "_query_s as \n"
+  "select\n"
+  "        b.hex as buildid, fs.name as artifactsrc, 'F' as sourcetype, f0.name as source0, n.mtime as mtime, null as source1, null as source0ref\n"
+  "        from " BUILDIDS "_buildids b, " BUILDIDS "_files f0, " BUILDIDS "_files fs, " BUILDIDS "_f_s n\n"
+  "        where b.id = n.buildid and f0.id = n.file and fs.id = n.artifactsrc\n"
+  "union all select\n"
+  "        b.hex as buildid, f1.name as artifactsrc, 'R' as sourcetype, f0.name as source0, sd.mtime as mtime, f1.name as source1, fsref.name as source0ref\n"
+  "        from " BUILDIDS "_buildids b, " BUILDIDS "_files f0, " BUILDIDS "_files f1, " BUILDIDS "_files fsref, "
+  "        " BUILDIDS "_r_sdef sd, " BUILDIDS "_r_sref sr, " BUILDIDS "_r_de sde\n"
+  "        where b.id = sr.buildid and f0.id = sd.file and fsref.id = sde.file and f1.id = sd.content\n"
+  "        and sr.artifactsrc = sd.content and sde.buildid = sr.buildid\n"
+  ";"
+  // and for startup overview counts
+  "drop view if exists " BUILDIDS "_stats;\n"
+  "create view if not exists " BUILDIDS "_stats as\n"
+  "          select 'file d/e' as label,count(*) as quantity from " BUILDIDS "_f_de\n"
+  "union all select 'file s',count(*) from " BUILDIDS "_f_s\n"
+  "union all select 'rpm d/e',count(*) from " BUILDIDS "_r_de\n"
+  "union all select 'rpm sref',count(*) from " BUILDIDS "_r_sref\n"
+  "union all select 'rpm sdef',count(*) from " BUILDIDS "_r_sdef\n"
+  "union all select 'buildids',count(*) from " BUILDIDS "_buildids\n"
+  "union all select 'filenames',count(*) from " BUILDIDS "_files\n"
+  "union all select 'files scanned (#)',count(*) from " BUILDIDS "_file_mtime_scanned\n"
+  "union all select 'files scanned (mb)',coalesce(sum(size)/1024/1024,0) from " BUILDIDS "_file_mtime_scanned\n"
+#if SQLITE_VERSION_NUMBER >= 3016000
+  "union all select 'index db size (mb)',page_count*page_size/1024/1024 as size FROM pragma_page_count(), pragma_page_size()\n"
+#endif
+  ";\n"
+
+// schema change history & garbage collection
+//
+// XXX: we could have migration queries here to bring prior-schema
+// data over instead of just dropping it.
+//
+// buildids9: widen the mtime_scanned table
+  "" // <<< we are here
+// buildids8: slim the sref table
+  "drop table if exists buildids8_f_de;\n"
+  "drop table if exists buildids8_f_s;\n"
+  "drop table if exists buildids8_r_de;\n"
+  "drop table if exists buildids8_r_sref;\n"
+  "drop table if exists buildids8_r_sdef;\n"
+  "drop table if exists buildids8_file_mtime_scanned;\n"
+  "drop table if exists buildids8_files;\n"
+  "drop table if exists buildids8_buildids;\n"
+// buildids7: separate _norm table into dense subtype tables
+  "drop table if exists buildids7_f_de;\n"
+  "drop table if exists buildids7_f_s;\n"
+  "drop table if exists buildids7_r_de;\n"
+  "drop table if exists buildids7_r_sref;\n"
+  "drop table if exists buildids7_r_sdef;\n"
+  "drop table if exists buildids7_file_mtime_scanned;\n"
+  "drop table if exists buildids7_files;\n"
+  "drop table if exists buildids7_buildids;\n"
+// buildids6: drop bolo/rfolo again, represent sources / rpmcontents in main table
+  "drop table if exists buildids6_norm;\n"
+  "drop table if exists buildids6_files;\n"
+  "drop table if exists buildids6_buildids;\n"
+  "drop view if exists buildids6;\n"
+// buildids5: redefine srcfile1 column to be '.'-less (for rpms)
+  "drop table if exists buildids5_norm;\n"
+  "drop table if exists buildids5_files;\n"
+  "drop table if exists buildids5_buildids;\n"
+  "drop table if exists buildids5_bolo;\n"
+  "drop table if exists buildids5_rfolo;\n"
+  "drop view if exists buildids5;\n"
+// buildids4: introduce rpmfile RFOLO
+  "drop table if exists buildids4_norm;\n"
+  "drop table if exists buildids4_files;\n"
+  "drop table if exists buildids4_buildids;\n"
+  "drop table if exists buildids4_bolo;\n"
+  "drop table if exists buildids4_rfolo;\n"
+  "drop view if exists buildids4;\n"
+// buildids3*: split out srcfile BOLO
+  "drop table if exists buildids3_norm;\n"
+  "drop table if exists buildids3_files;\n"
+  "drop table if exists buildids3_buildids;\n"
+  "drop table if exists buildids3_bolo;\n"
+  "drop view if exists buildids3;\n"
+// buildids2: normalized buildid and filenames into interning tables;
+  "drop table if exists buildids2_norm;\n"
+  "drop table if exists buildids2_files;\n"
+  "drop table if exists buildids2_buildids;\n"
+  "drop view if exists buildids2;\n"
+  // buildids1: made buildid and artifacttype NULLable, to represent cached-negative
+//           lookups from sources, e.g. files or rpms that contain no buildid-indexable content
+  "drop table if exists buildids1;\n"
+// buildids: original
+  "drop table if exists buildids;\n"
+  ;
+
+static const char DEBUGINFOD_SQLITE_CLEANUP_DDL[] =
+  "pragma wal_checkpoint = truncate;\n" // clean out any preexisting wal file
+  ;
+
+
+
+
+/* Name and version of program.  */
+/* ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; */ // not this simple for C++
+
+/* Bug report address.  */
+ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
+
+/* Definitions of arguments for argp functions.  */
+static const struct argp_option options[] =
+  {
+   { NULL, 0, NULL, 0, "Scanners:", 1 },
+   { "scan-file-dir", 'F', NULL, 0, "Enable ELF/DWARF file scanning threads.", 0 },
+   { "scan-rpm-dir", 'R', NULL, 0, "Enable RPM scanning threads.", 0 },
+   // "source-oci-imageregistry"  ... 
+
+   { NULL, 0, NULL, 0, "Options:", 2 },
+   { "logical", 'L', NULL, 0, "Follow symlinks, default=ignore.", 0 },
+   { "rescan-time", 't', "SECONDS", 0, "Number of seconds to wait between rescans, 0=disable.", 0 },
+   { "groom-time", 'g', "SECONDS", 0, "Number of seconds to wait between database grooming, 0=disable.", 0 },
+   { "maxigroom", 'G', NULL, 0, "Run a complete database groom/shrink pass at startup.", 0 },
+   { "concurrency", 'c', "NUM", 0, "Limit scanning thread concurrency to NUM.", 0 },
+   { "include", 'I', "REGEX", 0, "Include files matching REGEX, default=all.", 0 },
+   { "exclude", 'X', "REGEX", 0, "Exclude files matching REGEX, default=none.", 0 },
+   { "port", 'p', "NUM", 0, "HTTP port to listen on, default 8002.", 0 },
+   { "database", 'd', "FILE", 0, "Path to sqlite database.", 0 },
+   { "ddl", 'D', "SQL", 0, "Apply extra sqlite ddl/pragma to connection.", 0 },
+   { "verbose", 'v', NULL, 0, "Increase verbosity.", 0 },
+
+   { NULL, 0, NULL, 0, NULL, 0 }
+  };
+
+/* Short description of program.  */
+static const char doc[] = "Serve debuginfo-related content across HTTP from files under PATHs.";
+
+/* Strings for arguments in help texts.  */
+static const char args_doc[] = "[PATH ...]";
+
+/* Prototype for option handler.  */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Data structure to communicate with argp functions.  */
+static struct argp argp =
+  {
+   options, parse_opt, args_doc, doc, NULL, NULL, NULL
+  };
+
+
+static string db_path;
+static sqlite3 *db;
+static unsigned verbose;
+static volatile sig_atomic_t interrupted = 0;
+static volatile sig_atomic_t sigusr1 = 0;
+static volatile sig_atomic_t sigusr2 = 0;
+static unsigned http_port = 8002;
+static unsigned rescan_s = 300;
+static unsigned groom_s = 86400;
+static unsigned maxigroom = false;
+static unsigned concurrency = std::thread::hardware_concurrency() ?: 1;
+static set<string> source_paths;
+static bool scan_files = false;
+static bool scan_rpms = false;
+static vector<string> extra_ddl;
+static regex_t file_include_regex;
+static regex_t file_exclude_regex;
+static bool traverse_logical;
+
+static void set_metric(const string& key, int64_t value);
+// static void inc_metric(const string& key);
+static void set_metric(const string& metric,
+                       const string& lname, const string& lvalue,
+                       int64_t value);
+static void inc_metric(const string& metric,
+                       const string& lname, const string& lvalue);
+static void add_metric(const string& metric,
+                       const string& lname, const string& lvalue,
+                       int64_t value);
+
+/* Handle program arguments.  */
+static error_t
+parse_opt (int key, char *arg,
+	   struct argp_state *state __attribute__ ((unused)))
+{
+  int rc;
+  switch (key)
+    {
+    case 'v': verbose ++; break;
+    case 'd': db_path = string(arg); break;
+    case 'p': http_port = (unsigned) atoi(arg);
+      if (http_port > 65535) argp_failure(state, 1, EINVAL, "port number");
+      break;
+    case 'F': scan_files = true; break;
+    case 'R': scan_rpms = true; break;
+    case 'L':
+      traverse_logical = true;
+      break;
+    case 'D': extra_ddl.push_back(string(arg)); break;
+    case 't':
+      rescan_s = (unsigned) atoi(arg);
+      break;
+    case 'g':
+      groom_s = (unsigned) atoi(arg);
+      break;
+    case 'G':
+      maxigroom = true;
+      break;
+    case 'c':
+      concurrency = (unsigned) atoi(arg);
+      if (concurrency < 1) concurrency = 1;
+      break;
+    case 'I':
+      // NB: no problem with unconditional free here - an earlier failed regcomp would exit program
+      regfree (&file_include_regex);
+      rc = regcomp (&file_include_regex, arg, REG_EXTENDED|REG_NOSUB);
+      if (rc != 0)
+        argp_failure(state, 1, EINVAL, "regular expession");
+      break;
+    case 'X':
+      regfree (&file_exclude_regex);
+      rc = regcomp (&file_exclude_regex, arg, REG_EXTENDED|REG_NOSUB);
+      if (rc != 0)
+        argp_failure(state, 1, EINVAL, "regular expession");
+      break;
+    case ARGP_KEY_ARG:
+      source_paths.insert(string(arg));
+      break;
+      // case 'h': argp_state_help (state, stderr, ARGP_HELP_LONG|ARGP_HELP_EXIT_OK);
+    default: return ARGP_ERR_UNKNOWN;
+    }
+
+  return 0;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+
+
+// represent errors that may get reported to an ostream and/or a libmicrohttpd connection
+
+struct reportable_exception
+{
+  int code;
+  string message;
+
+  reportable_exception(int c, const string& m): code(c), message(m) {}
+  reportable_exception(const string& m): code(503), message(m) {}
+  reportable_exception(): code(503), message() {}
+
+  void report(ostream& o) const; // defined under obatched() class below
+
+  int mhd_send_response(MHD_Connection* c) const {
+    MHD_Response* r = MHD_create_response_from_buffer (message.size(),
+                                                       (void*) message.c_str(),
+                                                       MHD_RESPMEM_MUST_COPY);
+    MHD_add_response_header (r, "Content-Type", "text/plain");
+    int rc = MHD_queue_response (c, code, r);
+    MHD_destroy_response (r);
+    return rc;
+  }
+};
+
+
+struct sqlite_exception: public reportable_exception
+{
+  sqlite_exception(int rc, const string& msg):
+    reportable_exception(string("sqlite3 error: ") + msg + ": " + string(sqlite3_errstr(rc) ?: "?")) {}
+};
+
+struct libc_exception: public reportable_exception
+{
+  libc_exception(int rc, const string& msg):
+    reportable_exception(string("libc error: ") + msg + ": " + string(strerror(rc) ?: "?")) {}
+};
+
+
+struct archive_exception: public reportable_exception
+{
+  archive_exception(const string& msg):
+    reportable_exception(string("libarchive error: ") + msg) {}
+  archive_exception(struct archive* a, const string& msg):
+    reportable_exception(string("libarchive error: ") + msg + ": " + string(archive_error_string(a) ?: "?")) {}
+};
+
+
+struct elfutils_exception: public reportable_exception
+{
+  elfutils_exception(int rc, const string& msg):
+    reportable_exception(string("elfutils error: ") + msg + ": " + string(elf_errmsg(rc) ?: "?")) {}
+};
+
+
+////////////////////////////////////////////////////////////////////////
+
+// a c++ counting-semaphore class ... since we're c++11 not c++20
+
+class semaphore
+{
+public:
+  semaphore (unsigned c=1): count(c) {}
+  inline void notify () {
+    unique_lock<mutex> lock(mtx);
+    count++;
+    cv.notify_one();
+  }
+  inline void wait() {
+    unique_lock<mutex> lock(mtx);
+    while (count == 0)
+      cv.wait(lock);
+    count--;
+  }
+private:
+  mutex mtx;
+  condition_variable cv;
+  unsigned count;
+};
+
+
+class semaphore_borrower
+{
+public:
+  semaphore_borrower(semaphore* s): sem(s) { sem->wait(); }
+  ~semaphore_borrower() { sem->notify(); }
+private:
+  semaphore* sem;
+};
+
+
+////////////////////////////////////////////////////////////////////////
+
+
+// Print a standard timestamp.
+static ostream&
+timestamp (ostream &o)
+{
+  char datebuf[80];
+  char *now2 = NULL;
+  time_t now_t = time(NULL);
+  struct tm *now = gmtime (&now_t);
+  if (now)
+    {
+      (void) strftime (datebuf, sizeof (datebuf), "%c", now);
+      now2 = datebuf;
+    }
+
+  return o << "[" << (now2 ? now2 : "") << "] "
+           << "(" << getpid () << "/" << tid() << "): ";
+}
+
+
+// A little class that impersonates an ostream to the extent that it can
+// take << streaming operations.  It batches up the bits into an internal
+// stringstream until it is destroyed; then flushes to the original ostream.
+// It adds a timestamp
+class obatched
+{
+private:
+  ostream& o;
+  stringstream stro;
+  static mutex lock;
+public:
+  obatched(ostream& oo, bool timestamp_p = true): o(oo)
+  {
+    if (timestamp_p)
+      timestamp(stro);
+  }
+  ~obatched()
+  {
+    unique_lock<mutex> do_not_cross_the_streams(obatched::lock);
+    o << stro.str();
+    o.flush();
+  }
+  operator ostream& () { return stro; }
+  template <typename T> ostream& operator << (const T& t) { stro << t; return stro; }
+};
+mutex obatched::lock; // just the one, since cout/cerr iostreams are not thread-safe
+
+
+void reportable_exception::report(ostream& o) const {
+  obatched(o) << message << endl;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+
+
+// RAII style sqlite prepared-statement holder that matches { } block lifetime
+
+struct sqlite_ps
+{
+private:
+  sqlite3* db;
+  const string nickname;
+  const string sql;
+  sqlite3_stmt *pp;
+
+  sqlite_ps(const sqlite_ps&); // make uncopyable
+  sqlite_ps& operator=(const sqlite_ps &); // make unassignable
+
+public:
+  sqlite_ps (sqlite3* d, const string& n, const string& s): db(d), nickname(n), sql(s) {
+    if (verbose > 4)
+      obatched(clog) << nickname << " prep " << sql << endl;
+    int rc = sqlite3_prepare_v2 (db, sql.c_str(), -1 /* to \0 */, & this->pp, NULL);
+    if (rc != SQLITE_OK)
+      throw sqlite_exception(rc, "prepare " + sql);
+  }
+
+  sqlite_ps& reset()
+  {
+    sqlite3_reset(this->pp);
+    return *this;
+  }
+
+  sqlite_ps& bind(int parameter, const string& str)
+  {
+    if (verbose > 4)
+      obatched(clog) << nickname << " bind " << parameter << "=" << str << endl;
+    int rc = sqlite3_bind_text (this->pp, parameter, str.c_str(), -1, SQLITE_TRANSIENT);
+    if (rc != SQLITE_OK)
+      throw sqlite_exception(rc, "sqlite3 bind");
+    return *this;
+  }
+
+  sqlite_ps& bind(int parameter, int64_t value)
+  {
+    if (verbose > 4)
+      obatched(clog) << nickname << " bind " << parameter << "=" << value << endl;
+    int rc = sqlite3_bind_int64 (this->pp, parameter, value);
+    if (rc != SQLITE_OK)
+      throw sqlite_exception(rc, "sqlite3 bind");
+    return *this;
+  }
+
+  sqlite_ps& bind(int parameter)
+  {
+    if (verbose > 4)
+      obatched(clog) << nickname << " bind " << parameter << "=" << "NULL" << endl;
+    int rc = sqlite3_bind_null (this->pp, parameter);
+    if (rc != SQLITE_OK)
+      throw sqlite_exception(rc, "sqlite3 bind");
+    return *this;
+  }
+
+
+  void step_ok_done() {
+    int rc = sqlite3_step (this->pp);
+    if (verbose > 4)
+      obatched(clog) << nickname << " step-ok-done(" << sqlite3_errstr(rc) << ") " << sql << endl;
+    if (rc != SQLITE_OK && rc != SQLITE_DONE && rc != SQLITE_ROW)
+      throw sqlite_exception(rc, "sqlite3 step");
+    (void) sqlite3_reset (this->pp);
+  }
+
+
+  int step() {
+    int rc = sqlite3_step (this->pp);
+    if (verbose > 4)
+      obatched(clog) << nickname << " step(" << sqlite3_errstr(rc) << ") " << sql << endl;
+    return rc;
+  }
+
+
+
+  ~sqlite_ps () { sqlite3_finalize (this->pp); }
+  operator sqlite3_stmt* () { return this->pp; }
+};
+
+
+////////////////////////////////////////////////////////////////////////
+
+// RAII style templated autocloser
+
+template <class Payload, class Ignore>
+struct defer_dtor
+{
+public:
+  typedef Ignore (*dtor_fn) (Payload);
+
+private:
+  Payload p;
+  dtor_fn fn;
+
+public:
+  defer_dtor(Payload _p, dtor_fn _fn): p(_p), fn(_fn) {}
+  ~defer_dtor() { (void) (*fn)(p); }
+
+private:
+  defer_dtor(const defer_dtor<Payload,Ignore>&); // make uncopyable
+  defer_dtor& operator=(const defer_dtor<Payload,Ignore> &); // make unassignable
+};
+
+
+
+////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+static string
+conninfo (struct MHD_Connection * conn)
+{
+  char hostname[256]; // RFC1035
+  char servname[256];
+  int sts = -1;
+
+  if (conn == 0)
+    return "internal";
+
+  /* Look up client address data. */
+  const union MHD_ConnectionInfo *u = MHD_get_connection_info (conn,
+                                                               MHD_CONNECTION_INFO_CLIENT_ADDRESS);
+  struct sockaddr *so = u ? u->client_addr : 0;
+
+  if (so && so->sa_family == AF_INET) {
+    sts = getnameinfo (so, sizeof (struct sockaddr_in), hostname, sizeof (hostname), servname,
+                       sizeof (servname), NI_NUMERICHOST | NI_NUMERICSERV);
+  } else if (so && so->sa_family == AF_INET6) {
+    sts = getnameinfo (so, sizeof (struct sockaddr_in6), hostname, sizeof (hostname),
+                       servname, sizeof (servname), NI_NUMERICHOST | NI_NUMERICSERV);
+  }
+  if (sts != 0) {
+    hostname[0] = servname[0] = '\0';
+  }
+
+  return string(hostname) + string(":") + string(servname);
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+
+static void
+add_mhd_last_modified (struct MHD_Response *resp, time_t mtime)
+{
+  struct tm *now = gmtime (&mtime);
+  if (now != NULL)
+    {
+      char datebuf[80];
+      size_t rc = strftime (datebuf, sizeof (datebuf), "%a, %d %b %Y %T GMT", now);
+      if (rc > 0 && rc < sizeof (datebuf))
+        (void) MHD_add_response_header (resp, "Last-Modified", datebuf);
+    }
+
+  (void) MHD_add_response_header (resp, "Cache-Control", "public");
+}
+
+
+
+static struct MHD_Response*
+handle_buildid_f_match (int64_t b_mtime,
+                        const string& b_source0,
+                        int *result_fd)
+{
+  int fd = open(b_source0.c_str(), O_RDONLY);
+  if (fd < 0)
+    {
+      if (verbose)
+        obatched(clog) << "cannot open " << b_source0 << endl;
+      // if still missing, a periodic groom pass will delete this buildid record
+      return 0;
+    }
+
+  // NB: use manual close(2) in error case instead of defer_dtor, because
+  // in the normal case, we want to hand the fd over to libmicrohttpd for
+  // file transfer.
+
+  struct stat s;
+  int rc = fstat(fd, &s);
+  if (rc < 0)
+    {
+      if (verbose)
+        clog << "cannot fstat " << b_source0 << endl;
+      close(fd);
+      return 0;
+    }
+
+  if ((int64_t) s.st_mtime != b_mtime)
+    {
+      if (verbose)
+        obatched(clog) << "mtime mismatch for " << b_source0 << endl;
+      close(fd);
+      return 0;
+    }
+
+  inc_metric ("http_responses_total","result","file");
+  struct MHD_Response* r = MHD_create_response_from_fd ((uint64_t) s.st_size, fd);
+  if (r == 0)
+    {
+      if (verbose)
+        obatched(clog) << "cannot create fd-response for " << b_source0 << endl;
+      close(fd);
+    }
+  else
+    {
+      MHD_add_response_header (r, "Content-Type", "application/octet-stream");
+      add_mhd_last_modified (r, s.st_mtime);
+      if (verbose > 1)
+        obatched(clog) << "serving file " << b_source0 << endl;
+      /* libmicrohttpd will close it. */
+      if (result_fd)
+        *result_fd = fd;
+    }
+
+  return r;
+}
+
+
+// quote all questionable characters of str for safe passage through a sh -c expansion.
+static string
+shell_escape(const string& str)
+{
+  string y;
+  for (auto&& x : str)
+    {
+      if (! isalnum(x) && x != '/')
+        y += "\\";
+      y += x;
+    }
+  return y;
+}
+
+
+static struct MHD_Response*
+handle_buildid_r_match (int64_t b_mtime,
+                        const string& b_source0,
+                        const string& b_source1,
+                        int *result_fd)
+{
+  struct stat fs;
+  int rc = stat (b_source0.c_str(), &fs);
+  if (rc != 0)
+    throw libc_exception (errno, string("stat ") + b_source0);
+
+  if ((int64_t) fs.st_mtime != b_mtime)
+    {
+      if (verbose)
+        obatched(clog) << "mtime mismatch for " << b_source0 << endl;
+      return 0;
+    }
+
+  string popen_cmd = string("rpm2cpio " + shell_escape(b_source0));
+  FILE* fp = popen (popen_cmd.c_str(), "r"); // "e" O_CLOEXEC?
+  if (fp == NULL)
+    throw libc_exception (errno, string("popen ") + popen_cmd);
+  defer_dtor<FILE*,int> fp_closer (fp, pclose);
+
+  struct archive *a;
+  a = archive_read_new();
+  if (a == NULL)
+    throw archive_exception("cannot create archive reader");
+  defer_dtor<struct archive*,int> archive_closer (a, archive_read_free);
+
+  rc = archive_read_support_format_cpio(a);
+  if (rc != ARCHIVE_OK)
+    throw archive_exception(a, "cannot select cpio format");
+  rc = archive_read_support_filter_all(a);
+  if (rc != ARCHIVE_OK)
+    throw archive_exception(a, "cannot select all filters");
+
+  rc = archive_read_open_FILE (a, fp);
+  if (rc != ARCHIVE_OK)
+    throw archive_exception(a, "cannot open archive from rpm2cpio pipe");
+
+  while(1) // parse cpio archive entries
+    {
+      struct archive_entry *e;
+      rc = archive_read_next_header (a, &e);
+      if (rc != ARCHIVE_OK)
+        break;
+
+      if (! S_ISREG(archive_entry_mode (e))) // skip non-files completely
+        continue;
+
+      string fn = archive_entry_pathname (e);
+      if (fn != string(".")+b_source1)
+        continue;
+
+      // extract this file to a temporary file
+      char tmppath[PATH_MAX] = "/tmp/debuginfod.XXXXXX"; // XXX: $TMP_DIR etc.
+      int fd = mkstemp (tmppath);
+      if (fd < 0)
+        throw libc_exception (errno, "cannot create temporary file");
+      unlink (tmppath); // unlink now so OS will release the file as soon as we close the fd
+
+      rc = archive_read_data_into_fd (a, fd);
+      if (rc != ARCHIVE_OK)
+        {
+          close (fd);
+          throw archive_exception(a, "cannot extract file");
+        }
+
+      inc_metric ("http_responses_total","result","rpm");
+      struct MHD_Response* r = MHD_create_response_from_fd (archive_entry_size(e), fd);
+      if (r == 0)
+        {
+          if (verbose)
+            obatched(clog) << "cannot create fd-response for " << b_source0 << endl;
+          close(fd);
+          break; // assume no chance of better luck around another iteration
+        }
+      else
+        {
+          MHD_add_response_header (r, "Content-Type", "application/octet-stream");
+          add_mhd_last_modified (r, archive_entry_mtime(e));
+          if (verbose > 1)
+            obatched(clog) << "serving rpm " << b_source0 << " file " << b_source1 << endl;
+          /* libmicrohttpd will close it. */
+          if (result_fd)
+            *result_fd = fd;
+          return r;
+        }
+    }
+
+  // XXX: rpm/file not found: delete this R entry?
+  return 0;
+}
+
+
+static struct MHD_Response*
+handle_buildid_match (int64_t b_mtime,
+                      const string& b_stype,
+                      const string& b_source0,
+                      const string& b_source1,
+                      int *result_fd)
+{
+  if (b_stype == "F")
+    return handle_buildid_f_match(b_mtime, b_source0, result_fd);
+  else if (b_stype == "R")
+    return handle_buildid_r_match(b_mtime, b_source0, b_source1, result_fd);
+  else
+    return 0;
+}
+
+
+static int
+debuginfod_find_progress (debuginfod_client *, long a, long b)
+{
+  if (verbose > 4)
+    obatched(clog) << "federated debuginfod progress=" << a << "/" << b << endl;
+
+  return interrupted;
+}
+
+
+static struct MHD_Response* handle_buildid (const string& buildid /* unsafe */,
+                                            const string& artifacttype /* unsafe */,
+                                            const string& suffix /* unsafe */,
+                                            int *result_fd
+                                            )
+{
+  // validate artifacttype
+  string atype_code;
+  if (artifacttype == "debuginfo") atype_code = "D";
+  else if (artifacttype == "executable") atype_code = "E";
+  else if (artifacttype == "source") atype_code = "S";
+  else throw reportable_exception("invalid artifacttype");
+
+  if (atype_code == "S" && suffix == "")
+     throw reportable_exception("invalid source suffix");
+
+  // validate buildid
+  if ((buildid.size() < 2) || // not empty
+      (buildid.size() % 2) || // even number
+      (buildid.find_first_not_of("0123456789abcdef") != string::npos)) // pure tasty lowercase hex
+    throw reportable_exception("invalid buildid");
+
+  if (verbose > 1)
+    obatched(clog) << "searching for buildid=" << buildid << " artifacttype=" << artifacttype
+         << " suffix=" << suffix << endl;
+
+  sqlite_ps *pp = 0;
+
+  if (atype_code == "D")
+    {
+      pp = new sqlite_ps (db, "mhd-query-d",
+                          "select mtime, sourcetype, source0, source1 from " BUILDIDS "_query_d where buildid = ? "
+                          "order by mtime desc");
+      pp->reset();
+      pp->bind(1, buildid);
+    }
+  else if (atype_code == "E")
+    {
+      pp = new sqlite_ps (db, "mhd-query-e",
+                          "select mtime, sourcetype, source0, source1 from " BUILDIDS "_query_e where buildid = ? "
+                          "order by mtime desc");
+      pp->reset();
+      pp->bind(1, buildid);
+    }
+  else if (atype_code == "S")
+    {
+      pp = new sqlite_ps (db, "mhd-query-s",
+                          "select mtime, sourcetype, source0, source1 from " BUILDIDS "_query_s where buildid = ? and artifactsrc = ? "
+                          "order by sharedprefix(source0,source0ref) desc, mtime desc");
+      pp->reset();
+      pp->bind(1, buildid);
+      pp->bind(2, suffix);
+    }
+  unique_ptr<sqlite_ps> ps_closer(pp); // release pp if exception or return
+
+  // consume all the rows
+  while (1)
+    {
+      int rc = pp->step();
+      if (rc == SQLITE_DONE) break;
+      if (rc != SQLITE_ROW)
+        throw sqlite_exception(rc, "step");
+
+      int64_t b_mtime = sqlite3_column_int64 (*pp, 0);
+      string b_stype = string((const char*) sqlite3_column_text (*pp, 1) ?: ""); /* by DDL may not be NULL */
+      string b_source0 = string((const char*) sqlite3_column_text (*pp, 2) ?: ""); /* may be NULL */
+      string b_source1 = string((const char*) sqlite3_column_text (*pp, 3) ?: ""); /* may be NULL */
+
+      if (verbose > 1)
+        obatched(clog) << "found mtime=" << b_mtime << " stype=" << b_stype
+             << " source0=" << b_source0 << " source1=" << b_source1 << endl;
+
+      // Try accessing the located match.
+      // XXX: in case of multiple matches, attempt them in parallel?
+      auto r = handle_buildid_match (b_mtime, b_stype, b_source0, b_source1, result_fd);
+      if (r)
+        return r;
+    }
+
+  // We couldn't find it in the database.  Last ditch effort
+  // is to defer to other debuginfo servers.
+
+  int fd = -1;
+  debuginfod_client *client = debuginfod_begin ();
+  if (client != NULL)
+    {
+      debuginfod_set_progressfn (client, & debuginfod_find_progress);
+
+      if (artifacttype == "debuginfo")
+	fd = debuginfod_find_debuginfo (client,
+					(const unsigned char*) buildid.c_str(),
+					0, NULL);
+      else if (artifacttype == "executable")
+	fd = debuginfod_find_executable (client,
+					 (const unsigned char*) buildid.c_str(),
+					 0, NULL);
+      else if (artifacttype == "source")
+	fd = debuginfod_find_source (client,
+				     (const unsigned char*) buildid.c_str(),
+				     0, suffix.c_str(), NULL);
+    }
+  else
+    fd = -errno; /* Set by debuginfod_begin.  */
+  debuginfod_end (client);
+
+  if (fd >= 0)
+    {
+      inc_metric ("http_responses_total","result","upstream");
+      struct stat s;
+      int rc = fstat (fd, &s);
+      if (rc == 0)
+        {
+          auto r = MHD_create_response_from_fd ((uint64_t) s.st_size, fd);
+          if (r)
+            {
+              MHD_add_response_header (r, "Content-Type", "application/octet-stream");
+              add_mhd_last_modified (r, s.st_mtime);
+              if (verbose > 1)
+                obatched(clog) << "serving file from upstream debuginfod/cache" << endl;
+              if (result_fd)
+                *result_fd = fd;
+              return r; // NB: don't close fd; libmicrohttpd will
+            }
+        }
+      close (fd);
+    }
+  else if (fd != -ENOSYS) // no DEBUGINFOD_URLS configured
+    throw libc_exception(-fd, "upstream debuginfod query failed");
+
+  throw reportable_exception(MHD_HTTP_NOT_FOUND, "not found");
+}
+
+
+////////////////////////////////////////////////////////////////////////
+
+static map<string,int64_t> metrics; // arbitrary data for /metrics query
+// NB: store int64_t since all our metrics are integers; prometheus accepts double
+static mutex metrics_lock;
+
+// utility function for assembling prometheus-compatible
+// name="escaped-value" strings
+// https://prometheus.io/docs/instrumenting/exposition_formats/
+static string
+metric_label(const string& name, const string& value)
+{
+  string x = name + "=\"";
+  for (auto&& c : value)
+    switch(c)
+      {
+      case '\\': x += "\\\\"; break;
+      case '\"': x += "\\\""; break;
+      case '\n': x += "\\n"; break;
+      default: x += c; break;
+      }
+  x += "\"";
+  return x;
+}
+
+
+// add prometheus-format metric name + label tuple (if any) + value
+
+static void
+set_metric(const string& metric, int64_t value)
+{
+  unique_lock<mutex> lock(metrics_lock);
+  metrics[metric] = value;
+}
+#if 0 /* unused */
+static void
+inc_metric(const string& metric)
+{
+  unique_lock<mutex> lock(metrics_lock);
+  metrics[metric] ++;
+}
+#endif
+static void
+set_metric(const string& metric,
+           const string& lname, const string& lvalue,
+           int64_t value)
+{
+  string key = (metric + "{" + metric_label(lname, lvalue) + "}");
+  unique_lock<mutex> lock(metrics_lock);
+  metrics[key] = value;
+}
+
+static void
+inc_metric(const string& metric,
+           const string& lname, const string& lvalue)
+{
+  string key = (metric + "{" + metric_label(lname, lvalue) + "}");
+  unique_lock<mutex> lock(metrics_lock);
+  metrics[key] ++;
+}
+static void
+add_metric(const string& metric,
+           const string& lname, const string& lvalue,
+           int64_t value)
+{
+  string key = (metric + "{" + metric_label(lname, lvalue) + "}");
+  unique_lock<mutex> lock(metrics_lock);
+  metrics[key] += value;
+}
+
+
+// and more for higher arity labels if needed
+
+
+static struct MHD_Response*
+handle_metrics ()
+{
+  stringstream o;
+  {
+    unique_lock<mutex> lock(metrics_lock);
+    for (auto&& i : metrics)
+      o << i.first << " " << i.second << endl;
+  }
+  const string& os = o.str();
+  MHD_Response* r = MHD_create_response_from_buffer (os.size(),
+                                                     (void*) os.c_str(),
+                                                     MHD_RESPMEM_MUST_COPY);
+  MHD_add_response_header (r, "Content-Type", "text/plain");
+  return r;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+
+
+/* libmicrohttpd callback */
+static int
+handler_cb (void * /*cls*/,
+            struct MHD_Connection *connection,
+            const char *url,
+            const char *method,
+            const char * /*version*/,
+            const char * /*upload_data*/,
+            size_t * /*upload_data_size*/,
+            void ** /*con_cls*/)
+{
+  struct MHD_Response *r = NULL;
+  string url_copy = url;
+
+  if (verbose)
+    obatched(clog) << conninfo(connection) << " " << method << " " << url << endl;
+
+  try
+    {
+      if (string(method) != "GET")
+        throw reportable_exception(400, "we support GET only");
+
+      /* Start decoding the URL. */
+      size_t slash1 = url_copy.find('/', 1);
+      string url1 = url_copy.substr(0, slash1); // ok even if slash1 not found
+
+      if (slash1 != string::npos && url1 == "/buildid")
+        {
+          size_t slash2 = url_copy.find('/', slash1+1);
+          if (slash2 == string::npos)
+            throw reportable_exception("/buildid/ webapi error, need buildid");
+
+          string buildid = url_copy.substr(slash1+1, slash2-slash1-1);
+
+          size_t slash3 = url_copy.find('/', slash2+1);
+          string artifacttype, suffix;
+          if (slash3 == string::npos)
+            {
+              artifacttype = url_copy.substr(slash2+1);
+              suffix = "";
+            }
+          else
+            {
+              artifacttype = url_copy.substr(slash2+1, slash3-slash2-1);
+              suffix = url_copy.substr(slash3); // include the slash in the suffix
+            }
+
+          inc_metric("http_requests_total", "type", artifacttype);
+          r = handle_buildid(buildid, artifacttype, suffix, 0); // NB: don't care about result-fd
+        }
+      else if (url1 == "/metrics")
+        {
+          inc_metric("http_requests_total", "type", "metrics");
+          r = handle_metrics();
+        }
+      else
+        throw reportable_exception("webapi error, unrecognized /operation");
+
+      if (r == 0)
+        throw reportable_exception("internal error, missing response");
+
+      int rc = MHD_queue_response (connection, MHD_HTTP_OK, r);
+      MHD_destroy_response (r);
+      return rc;
+    }
+  catch (const reportable_exception& e)
+    {
+      inc_metric("http_responses_total","result","error");
+      e.report(clog);
+      return e.mhd_send_response (connection);
+    }
+}
+
+
+////////////////////////////////////////////////////////////////////////
+// borrowed originally from src/nm.c get_local_names()
+
+static void
+dwarf_extract_source_paths (Elf *elf, set<string>& debug_sourcefiles)
+  noexcept // no exceptions - so we can simplify the altdbg resource release at end
+{
+  Dwarf* dbg = dwarf_begin_elf (elf, DWARF_C_READ, NULL);
+  if (dbg == NULL)
+    return;
+
+  Dwarf* altdbg = NULL;
+  int    altdbg_fd = -1;
+
+  // DWZ handling: if we have an unsatisfied debug-alt-link, add an
+  // empty string into the outgoing sourcefiles set, so the caller
+  // should know that our data is incomplete.
+  const char *alt_name_p;
+  const void *alt_build_id; // elfutils-owned memory
+  ssize_t sz = dwelf_dwarf_gnu_debugaltlink (dbg, &alt_name_p, &alt_build_id);
+  if (sz > 0) // got one!
+    {
+      string buildid;
+      unsigned char* build_id_bytes = (unsigned char*) alt_build_id;
+      for (ssize_t idx=0; idx<sz; idx++)
+        {
+          buildid += "0123456789abcdef"[build_id_bytes[idx] >> 4];
+          buildid += "0123456789abcdef"[build_id_bytes[idx] & 0xf];
+        }
+
+      if (verbose > 3)
+        obatched(clog) << "Need altdebug buildid=" << buildid << endl;
+
+      // but is it unsatisfied the normal elfutils ways?
+      Dwarf* alt = dwarf_getalt (dbg);
+      if (alt == NULL)
+        {
+          // Yup, unsatisfied the normal way.  Maybe we can satisfy it
+          // from our own debuginfod database.
+          int alt_fd;
+          struct MHD_Response *r = 0;
+          try
+            {
+              r = handle_buildid (buildid, "debuginfo", "", &alt_fd);
+            }
+          catch (const reportable_exception& e)
+            {
+              // swallow exceptions
+            }
+
+          // NB: this is not actually recursive!  This invokes the web-query
+          // path, which cannot get back into the scan code paths.
+          if (r)
+            {
+              // Found it!
+              altdbg_fd = dup(alt_fd); // ok if this fails, downstream failures ok
+              alt = altdbg = dwarf_begin (altdbg_fd, DWARF_C_READ);
+              // NB: must close this dwarf and this fd at the bottom of the function!
+              MHD_destroy_response (r); // will close alt_fd
+              if (alt)
+                dwarf_setalt (dbg, alt);
+            }
+        }
+      else
+        {
+          // NB: dwarf_setalt(alt) inappropriate - already done!
+          // NB: altdbg will stay 0 so nothing tries to redundantly dealloc.
+        }
+
+      if (alt)
+        {
+          if (verbose > 3)
+            obatched(clog) << "Resolved altdebug buildid=" << buildid << endl;
+        }
+      else // (alt == NULL) - signal possible presence of poor debuginfo
+        {
+          debug_sourcefiles.insert("");
+          if (verbose > 3)
+            obatched(clog) << "Unresolved altdebug buildid=" << buildid << endl;
+        }
+    }
+
+  Dwarf_Off offset = 0;
+  Dwarf_Off old_offset;
+  size_t hsize;
+
+  while (dwarf_nextcu (dbg, old_offset = offset, &offset, &hsize, NULL, NULL, NULL) == 0)
+    {
+      Dwarf_Die cudie_mem;
+      Dwarf_Die *cudie = dwarf_offdie (dbg, old_offset + hsize, &cudie_mem);
+
+      if (cudie == NULL)
+        continue;
+      if (dwarf_tag (cudie) != DW_TAG_compile_unit)
+        continue;
+
+      const char *cuname = dwarf_diename(cudie) ?: "unknown";
+
+      Dwarf_Files *files;
+      size_t nfiles;
+      if (dwarf_getsrcfiles (cudie, &files, &nfiles) != 0)
+        continue;
+
+      // extract DW_AT_comp_dir to resolve relative file names
+      const char *comp_dir = "";
+      const char *const *dirs;
+      size_t ndirs;
+      if (dwarf_getsrcdirs (files, &dirs, &ndirs) == 0 &&
+          dirs[0] != NULL)
+        comp_dir = dirs[0];
+      if (comp_dir == NULL)
+        comp_dir = "";
+
+      if (verbose > 3)
+        obatched(clog) << "searching for sources for cu=" << cuname << " comp_dir=" << comp_dir
+                       << " #files=" << nfiles << " #dirs=" << ndirs << endl;
+
+      if (comp_dir[0] == '\0' && cuname[0] != '/')
+        {
+          // This is a common symptom for dwz-compressed debug files,
+          // where the altdebug file cannot be resolved.
+          if (verbose > 3)
+            obatched(clog) << "skipping cu=" << cuname << " due to empty comp_dir" << endl;
+          continue;
+        }
+
+      for (size_t f = 1; f < nfiles; f++)
+        {
+          const char *hat = dwarf_filesrc (files, f, NULL, NULL);
+          if (hat == NULL)
+            continue;
+
+          if (string(hat) == "<built-in>") // gcc intrinsics, don't bother record
+            continue;
+
+          string waldo;
+          if (hat[0] == '/') // absolute
+            waldo = (string (hat));
+          else if (comp_dir[0] != '\0') // comp_dir relative
+            waldo = (string (comp_dir) + string("/") + string (hat));
+          else
+           {
+             obatched(clog) << "skipping hat=" << hat << " due to empty comp_dir" << endl;
+             continue;
+           }
+
+          // NB: this is the 'waldo' that a dbginfo client will have
+          // to supply for us to give them the file The comp_dir
+          // prefixing is a definite complication.  Otherwise we'd
+          // have to return a setof comp_dirs (one per CU!) with
+          // corresponding filesrc[] names, instead of one absolute
+          // resoved set.  Maybe we'll have to do that anyway.  XXX
+
+          if (verbose > 4)
+            obatched(clog) << waldo
+                           << (debug_sourcefiles.find(waldo)==debug_sourcefiles.end() ? " new" : " dup") <<  endl;
+
+          debug_sourcefiles.insert (waldo);
+        }
+    }
+
+  dwarf_end(dbg);
+  if (altdbg)
+    dwarf_end(altdbg);
+  if (altdbg_fd >= 0)
+    close(altdbg_fd);
+}
+
+
+
+static void
+elf_classify (int fd, bool &executable_p, bool &debuginfo_p, string &buildid, set<string>& debug_sourcefiles)
+{
+  Elf *elf = elf_begin (fd, ELF_C_READ_MMAP_PRIVATE, NULL);
+  if (elf == NULL)
+    return;
+
+  try // catch our types of errors and clean up the Elf* object
+    {
+      if (elf_kind (elf) != ELF_K_ELF)
+        {
+          elf_end (elf);
+          return;
+        }
+
+      GElf_Ehdr ehdr_storage;
+      GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_storage);
+      if (ehdr == NULL)
+        {
+          elf_end (elf);
+          return;
+        }
+      auto elf_type = ehdr->e_type;
+
+      const void *build_id; // elfutils-owned memory
+      ssize_t sz = dwelf_elf_gnu_build_id (elf, & build_id);
+      if (sz <= 0)
+        {
+          // It's not a diagnostic-worthy error for an elf file to lack build-id.
+          // It might just be very old.
+          elf_end (elf);
+          return;
+        }
+
+      // build_id is a raw byte array; convert to hexadecimal *lowercase*
+      unsigned char* build_id_bytes = (unsigned char*) build_id;
+      for (ssize_t idx=0; idx<sz; idx++)
+        {
+          buildid += "0123456789abcdef"[build_id_bytes[idx] >> 4];
+          buildid += "0123456789abcdef"[build_id_bytes[idx] & 0xf];
+        }
+
+      // now decide whether it's an executable - namely, any allocatable section has
+      // PROGBITS;
+      if (elf_type == ET_EXEC || elf_type == ET_DYN)
+        {
+          size_t shnum;
+          int rc = elf_getshdrnum (elf, &shnum);
+          if (rc < 0)
+            throw elfutils_exception(rc, "getshdrnum");
+
+          executable_p = false;
+          for (size_t sc = 0; sc < shnum; sc++)
+            {
+              Elf_Scn *scn = elf_getscn (elf, sc);
+              if (scn == NULL)
+                continue;
+
+              GElf_Shdr shdr_mem;
+              GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+              if (shdr == NULL)
+                continue;
+
+              // allocated (loadable / vm-addr-assigned) section with available content?
+              if ((shdr->sh_type == SHT_PROGBITS) && (shdr->sh_flags & SHF_ALLOC))
+                {
+                  if (verbose > 4)
+                    obatched(clog) << "executable due to SHF_ALLOC SHT_PROGBITS sc=" << sc << endl;
+                  executable_p = true;
+                  break; // no need to keep looking for others
+                }
+            } // iterate over sections
+        } // executable_p classification
+
+      // now decide whether it's a debuginfo - namely, if it has any .debug* or .zdebug* sections
+      // logic mostly stolen from fweimer@redhat.com's elfclassify drafts
+      size_t shstrndx;
+      int rc = elf_getshdrstrndx (elf, &shstrndx);
+      if (rc < 0)
+        throw elfutils_exception(rc, "getshdrstrndx");
+
+      Elf_Scn *scn = NULL;
+      while (true)
+        {
+          scn = elf_nextscn (elf, scn);
+          if (scn == NULL)
+            break;
+          GElf_Shdr shdr_storage;
+          GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_storage);
+          if (shdr == NULL)
+            break;
+          const char *section_name = elf_strptr (elf, shstrndx, shdr->sh_name);
+          if (section_name == NULL)
+            break;
+          if (strncmp(section_name, ".debug_line", 11) == 0 ||
+              strncmp(section_name, ".zdebug_line", 12) == 0)
+            {
+              debuginfo_p = true;
+              dwarf_extract_source_paths (elf, debug_sourcefiles);
+              break; // expecting only one .*debug_line, so no need to look for others
+            }
+          else if (strncmp(section_name, ".debug_", 7) == 0 ||
+                   strncmp(section_name, ".zdebug_", 8) == 0)
+            {
+              debuginfo_p = true;
+              // NB: don't break; need to parse .debug_line for sources
+            }
+        }
+    }
+  catch (const reportable_exception& e)
+    {
+      e.report(clog);
+    }
+  elf_end (elf);
+}
+
+
+static semaphore* scan_concurrency_sem = 0; // used to implement -c load limiting
+
+
+static void
+scan_source_file_path (const string& dir)
+{
+  obatched(clog) << "fts/file traversing " << dir << endl;
+
+  struct timeval tv_start, tv_end;
+  gettimeofday (&tv_start, NULL);
+
+  sqlite_ps ps_upsert_buildids (db, "file-buildids-intern", "insert or ignore into " BUILDIDS "_buildids VALUES (NULL, ?);");
+  sqlite_ps ps_upsert_files (db, "file-files-intern", "insert or ignore into " BUILDIDS "_files VALUES (NULL, ?);");
+  sqlite_ps ps_upsert_de (db, "file-de-upsert",
+                          "insert or ignore into " BUILDIDS "_f_de "
+                          "(buildid, debuginfo_p, executable_p, file, mtime) "
+                          "values ((select id from " BUILDIDS "_buildids where hex = ?),"
+                          "        ?,?,"
+                          "        (select id from " BUILDIDS "_files where name = ?), ?);");
+  sqlite_ps ps_upsert_s (db, "file-s-upsert",
+                         "insert or ignore into " BUILDIDS "_f_s "
+                         "(buildid, artifactsrc, file, mtime) "
+                         "values ((select id from " BUILDIDS "_buildids where hex = ?),"
+                         "        (select id from " BUILDIDS "_files where name = ?),"
+                         "        (select id from " BUILDIDS "_files where name = ?),"
+                         "        ?);");
+  sqlite_ps ps_query (db, "file-negativehit-find",
+                      "select 1 from " BUILDIDS "_file_mtime_scanned where sourcetype = 'F' and file = (select id from " BUILDIDS "_files where name = ?) and mtime = ?;");
+  sqlite_ps ps_scan_done (db, "file-scanned",
+                          "insert or ignore into " BUILDIDS "_file_mtime_scanned (sourcetype, file, mtime, size)"
+                          "values ('F', (select id from " BUILDIDS "_files where name = ?), ?, ?);");
+
+
+  char * const dirs[] = { (char*) dir.c_str(), NULL };
+
+  unsigned fts_scanned=0, fts_regex=0, fts_cached=0, fts_debuginfo=0, fts_executable=0, fts_sourcefiles=0;
+
+  FTS *fts = fts_open (dirs,
+                       (traverse_logical ? FTS_LOGICAL : FTS_PHYSICAL|FTS_XDEV)
+                       | FTS_NOCHDIR /* multithreaded */,
+                       NULL);
+  if (fts == NULL)
+    {
+      obatched(cerr) << "cannot fts_open " << dir << endl;
+      return;
+    }
+
+  FTSENT *f;
+  while ((f = fts_read (fts)) != NULL)
+    {
+      semaphore_borrower handle_one_file (scan_concurrency_sem);
+
+      fts_scanned ++;
+      if (interrupted)
+        break;
+
+      if (verbose > 2)
+        obatched(clog) << "fts/file traversing " << f->fts_path << endl;
+
+      try
+        {
+          /* Found a file.  Convert it to an absolute path, so
+             the buildid database does not have relative path
+             names that are unresolvable from a subsequent run
+             in a different cwd. */
+          char *rp = realpath(f->fts_path, NULL);
+          if (rp == NULL)
+            continue; // ignore dangling symlink or such
+          string rps = string(rp);
+          free (rp);
+
+          bool ri = !regexec (&file_include_regex, rps.c_str(), 0, 0, 0);
+          bool rx = !regexec (&file_exclude_regex, rps.c_str(), 0, 0, 0);
+          if (!ri || rx)
+            {
+              if (verbose > 3)
+                obatched(clog) << "fts/file skipped by regex " << (!ri ? "I" : "") << (rx ? "X" : "") << endl;
+              fts_regex ++;
+              continue;
+            }
+
+          switch (f->fts_info)
+            {
+            case FTS_D:
+              break;
+
+            case FTS_DP:
+              break;
+
+            case FTS_F:
+              {
+                /* See if we know of it already. */
+                int rc = ps_query
+                  .reset()
+                  .bind(1, rps)
+                  .bind(2, f->fts_statp->st_mtime)
+                  .step();
+                ps_query.reset();
+                if (rc == SQLITE_ROW) // i.e., a result, as opposed to DONE (no results)
+                  // no need to recheck a file/version we already know
+                  // specifically, no need to elf-begin a file we already determined is non-elf
+                  // (so is stored with buildid=NULL)
+                  {
+                    fts_cached ++;
+                    continue;
+                  }
+
+                bool executable_p = false, debuginfo_p = false; // E and/or D
+                string buildid;
+                set<string> sourcefiles;
+
+                int fd = open (rps.c_str(), O_RDONLY);
+                try
+                  {
+                    if (fd >= 0)
+                      elf_classify (fd, executable_p, debuginfo_p, buildid, sourcefiles);
+                    else
+                      throw libc_exception(errno, string("open ") + rps);
+                    inc_metric ("scanned_total","source","file");
+                  }
+
+                // NB: we catch exceptions here too, so that we can
+                // cache the corrupt-elf case (!executable_p &&
+                // !debuginfo_p) just below, just as if we had an
+                // EPERM error from open(2).
+
+                catch (const reportable_exception& e)
+                  {
+                    e.report(clog);
+                  }
+
+                if (fd >= 0)
+                  close (fd);
+
+                // register this file name in the interning table
+                ps_upsert_files
+                  .reset()
+                  .bind(1, rps)
+                  .step_ok_done();
+
+                if (buildid == "")
+                  {
+                    // no point storing an elf file without buildid
+                    executable_p = false;
+                    debuginfo_p = false;
+                  }
+                else
+                  {
+                    // register this build-id in the interning table
+                    ps_upsert_buildids
+                      .reset()
+                      .bind(1, buildid)
+                      .step_ok_done();
+                  }
+
+                if (executable_p)
+                  fts_executable ++;
+                if (debuginfo_p)
+                  fts_debuginfo ++;
+                if (executable_p || debuginfo_p)
+                  {
+                    ps_upsert_de
+                      .reset()
+                      .bind(1, buildid)
+                      .bind(2, debuginfo_p ? 1 : 0)
+                      .bind(3, executable_p ? 1 : 0)
+                      .bind(4, rps)
+                      .bind(5, f->fts_statp->st_mtime)
+                      .step_ok_done();
+                  }
+                if (executable_p)
+                  inc_metric("found_executable_total","source","files");
+                if (debuginfo_p)
+                  inc_metric("found_debuginfo_total","source","files");
+
+                if (sourcefiles.size() && buildid != "")
+                  {
+                    fts_sourcefiles += sourcefiles.size();
+
+                    for (auto&& dwarfsrc : sourcefiles)
+                      {
+                        char *srp = realpath(dwarfsrc.c_str(), NULL);
+                        if (srp == NULL) // also if DWZ unresolved dwarfsrc=""
+                          continue; // unresolvable files are not a serious problem
+                        // throw libc_exception(errno, "fts/file realpath " + srcpath);
+                        string srps = string(srp);
+                        free (srp);
+
+                        struct stat sfs;
+                        rc = stat(srps.c_str(), &sfs);
+                        if (rc != 0)
+                          continue;
+
+                        if (verbose > 2)
+                          obatched(clog) << "recorded buildid=" << buildid << " file=" << srps
+                                         << " mtime=" << sfs.st_mtime
+                                         << " as source " << dwarfsrc << endl;
+
+                        ps_upsert_files
+                          .reset()
+                          .bind(1, srps)
+                          .step_ok_done();
+
+                        // register the dwarfsrc name in the interning table too
+                        ps_upsert_files
+                          .reset()
+                          .bind(1, dwarfsrc)
+                          .step_ok_done();
+
+                        ps_upsert_s
+                          .reset()
+                          .bind(1, buildid)
+                          .bind(2, dwarfsrc)
+                          .bind(3, srps)
+                          .bind(4, sfs.st_mtime)
+                          .step_ok_done();
+
+			inc_metric("found_sourcerefs_total","source","files");
+                      }
+                  }
+
+                ps_scan_done
+                  .reset()
+                  .bind(1, rps)
+                  .bind(2, f->fts_statp->st_mtime)
+                  .bind(3, f->fts_statp->st_size)
+                  .step_ok_done();
+
+                if (verbose > 2)
+                  obatched(clog) << "recorded buildid=" << buildid << " file=" << rps
+                                 << " mtime=" << f->fts_statp->st_mtime << " atype="
+                                 << (executable_p ? "E" : "")
+                                 << (debuginfo_p ? "D" : "") << endl;
+              }
+              break;
+
+            case FTS_ERR:
+            case FTS_NS:
+              throw libc_exception(f->fts_errno, string("fts/file traversal ") + string(f->fts_path));
+
+            default:
+            case FTS_SL: /* ignore symlinks; seen in non-L mode only */
+              break;
+            }
+
+          if ((verbose && f->fts_info == FTS_DP) ||
+              (verbose > 1 && f->fts_info == FTS_F))
+            obatched(clog) << "fts/file traversing " << rps << ", scanned=" << fts_scanned
+                 << ", regex-skipped=" << fts_regex
+                 << ", cached=" << fts_cached << ", debuginfo=" << fts_debuginfo
+                 << ", executable=" << fts_executable << ", source=" << fts_sourcefiles << endl;
+        }
+      catch (const reportable_exception& e)
+        {
+          e.report(clog);
+        }
+    }
+  fts_close (fts);
+
+  gettimeofday (&tv_end, NULL);
+  double deltas = (tv_end.tv_sec - tv_start.tv_sec) + (tv_end.tv_usec - tv_start.tv_usec)*0.000001;
+
+  obatched(clog) << "fts/file traversed " << dir << " in " << deltas << "s, scanned=" << fts_scanned
+                 << ", regex-skipped=" << fts_regex
+                 << ", cached=" << fts_cached << ", debuginfo=" << fts_debuginfo
+                 << ", executable=" << fts_executable << ", source=" << fts_sourcefiles << endl;
+}
+
+
+static void*
+thread_main_scan_source_file_path (void* arg)
+{
+  string dir = string((const char*) arg);
+
+  unsigned rescan_timer = 0;
+  sig_atomic_t forced_rescan_count = 0;
+  set_metric("thread_timer_max", "file", dir, rescan_s);
+  set_metric("thread_tid", "file", dir, tid());
+  while (! interrupted)
+    {
+      set_metric("thread_timer", "file", dir, rescan_timer);
+      set_metric("thread_forced_total", "file", dir, forced_rescan_count);
+      if (rescan_s && rescan_timer > rescan_s)
+        rescan_timer = 0;
+      if (sigusr1 != forced_rescan_count)
+        {
+          forced_rescan_count = sigusr1;
+          rescan_timer = 0;
+        }
+      if (rescan_timer == 0)
+        try
+          {
+            set_metric("thread_working", "file", dir, time(NULL));
+            inc_metric("thread_work_total", "file", dir);
+            scan_source_file_path (dir);
+            set_metric("thread_working", "file", dir, 0);
+          }
+        catch (const sqlite_exception& e)
+          {
+            obatched(cerr) << e.message << endl;
+          }
+      sleep (1);
+      rescan_timer ++;
+    }
+
+  return 0;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+
+
+
+
+// Analyze given *.rpm file of given age; record buildids / exec/debuginfo-ness of its
+// constituent files with given upsert statements.
+static void
+rpm_classify (const string& rps, sqlite_ps& ps_upsert_buildids, sqlite_ps& ps_upsert_files,
+              sqlite_ps& ps_upsert_de, sqlite_ps& ps_upsert_sref, sqlite_ps& ps_upsert_sdef,
+              time_t mtime,
+              unsigned& fts_executable, unsigned& fts_debuginfo, unsigned& fts_sref, unsigned& fts_sdef,
+              bool& fts_sref_complete_p)
+{
+  string popen_cmd = string("rpm2cpio " + shell_escape(rps));
+  FILE* fp = popen (popen_cmd.c_str(), "r"); // "e" O_CLOEXEC?
+  if (fp == NULL)
+    throw libc_exception (errno, string("popen ") + popen_cmd);
+  defer_dtor<FILE*,int> fp_closer (fp, pclose);
+
+  struct archive *a;
+  a = archive_read_new();
+  if (a == NULL)
+    throw archive_exception("cannot create archive reader");
+  defer_dtor<struct archive*,int> archive_closer (a, archive_read_free);
+
+  int rc = archive_read_support_format_cpio(a);
+  if (rc != ARCHIVE_OK)
+    throw archive_exception(a, "cannot select cpio format");
+  rc = archive_read_support_filter_all(a);
+  if (rc != ARCHIVE_OK)
+    throw archive_exception(a, "cannot select all filters");
+
+  rc = archive_read_open_FILE (a, fp);
+  if (rc != ARCHIVE_OK)
+    throw archive_exception(a, "cannot open archive from rpm2cpio pipe");
+
+  if (verbose > 3)
+    obatched(clog) << "rpm2cpio|libarchive scanning " << rps << endl;
+
+  while(1) // parse cpio archive entries
+    {
+      try
+        {
+          struct archive_entry *e;
+          rc = archive_read_next_header (a, &e);
+          if (rc != ARCHIVE_OK)
+            break;
+
+          if (! S_ISREG(archive_entry_mode (e))) // skip non-files completely
+            continue;
+
+          string fn = archive_entry_pathname (e);
+          if (fn.size() > 1 && fn[0] == '.')
+            fn = fn.substr(1); // trim off the leading '.'
+
+          if (verbose > 3)
+            obatched(clog) << "rpm2cpio|libarchive checking " << fn << endl;
+
+          // extract this file to a temporary file
+          const char *tmpdir_env = getenv ("TMPDIR") ?: "/tmp";
+          char* tmppath = NULL;
+          rc = asprintf (&tmppath, "%s/debuginfod.XXXXXX", tmpdir_env);
+          if (rc < 0)
+            throw libc_exception (ENOMEM, "cannot allocate tmppath");
+          defer_dtor<void*,void> tmmpath_freer (tmppath, free);
+          int fd = mkstemp (tmppath);
+          if (fd < 0)
+            throw libc_exception (errno, "cannot create temporary file");
+          unlink (tmppath); // unlink now so OS will release the file as soon as we close the fd
+          defer_dtor<int,int> minifd_closer (fd, close);
+
+          rc = archive_read_data_into_fd (a, fd);
+          if (rc != ARCHIVE_OK)
+            throw archive_exception(a, "cannot extract file");
+
+          // finally ... time to run elf_classify on this bad boy and update the database
+          bool executable_p = false, debuginfo_p = false;
+          string buildid;
+          set<string> sourcefiles;
+          elf_classify (fd, executable_p, debuginfo_p, buildid, sourcefiles);
+          // NB: might throw
+
+          if (buildid != "") // intern buildid
+            {
+              ps_upsert_buildids
+                .reset()
+                .bind(1, buildid)
+                .step_ok_done();
+            }
+
+          ps_upsert_files // register this rpm constituent file name in interning table
+            .reset()
+            .bind(1, fn)
+            .step_ok_done();
+
+          if (sourcefiles.size() > 0) // sref records needed
+            {
+              // NB: we intern each source file once.  Once raw, as it
+              // appears in the DWARF file list coming back from
+              // elf_classify() - because it'll end up in the
+              // _norm.artifactsrc column.  We don't also put another
+              // version with a '.' at the front, even though that's
+              // how rpm/cpio packs names, because we hide that from
+              // the database for storage efficiency.
+
+              for (auto&& s : sourcefiles)
+                {
+                  if (s == "")
+                    {
+                      fts_sref_complete_p = false;
+                      continue;
+                    }
+
+                  ps_upsert_files
+                    .reset()
+                    .bind(1, s)
+                    .step_ok_done();
+
+                  ps_upsert_sref
+                    .reset()
+                    .bind(1, buildid)
+                    .bind(2, s)
+                    .step_ok_done();
+
+                  fts_sref ++;
+                }
+            }
+
+          if (executable_p)
+            fts_executable ++;
+          if (debuginfo_p)
+            fts_debuginfo ++;
+
+          if (executable_p || debuginfo_p)
+            {
+              ps_upsert_de
+                .reset()
+                .bind(1, buildid)
+                .bind(2, debuginfo_p ? 1 : 0)
+                .bind(3, executable_p ? 1 : 0)
+                .bind(4, rps)
+                .bind(5, mtime)
+                .bind(6, fn)
+                .step_ok_done();
+            }
+          else // potential source - sdef record
+            {
+              fts_sdef ++;
+              ps_upsert_sdef
+                .reset()
+                .bind(1, rps)
+                .bind(2, mtime)
+                .bind(3, fn)
+                .step_ok_done();
+            }
+
+          if ((verbose > 2) && (executable_p || debuginfo_p))
+            obatched(clog) << "recorded buildid=" << buildid << " rpm=" << rps << " file=" << fn
+                           << " mtime=" << mtime << " atype="
+                           << (executable_p ? "E" : "")
+                           << (debuginfo_p ? "D" : "")
+                           << " sourcefiles=" << sourcefiles.size() << endl;
+
+        }
+      catch (const reportable_exception& e)
+        {
+          e.report(clog);
+        }
+    }
+}
+
+
+
+// scan for *.rpm files
+static void
+scan_source_rpm_path (const string& dir)
+{
+  obatched(clog) << "fts/rpm traversing " << dir << endl;
+
+  sqlite_ps ps_upsert_buildids (db, "rpm-buildid-intern", "insert or ignore into " BUILDIDS "_buildids VALUES (NULL, ?);");
+  sqlite_ps ps_upsert_files (db, "rpm-file-intern", "insert or ignore into " BUILDIDS "_files VALUES (NULL, ?);");
+  sqlite_ps ps_upsert_de (db, "rpm-de-insert",
+                          "insert or ignore into " BUILDIDS "_r_de (buildid, debuginfo_p, executable_p, file, mtime, content) values ("
+                          "(select id from " BUILDIDS "_buildids where hex = ?), ?, ?, "
+                          "(select id from " BUILDIDS "_files where name = ?), ?, "
+                          "(select id from " BUILDIDS "_files where name = ?));");
+  sqlite_ps ps_upsert_sref (db, "rpm-sref-insert",
+                            "insert or ignore into " BUILDIDS "_r_sref (buildid, artifactsrc) values ("
+                            "(select id from " BUILDIDS "_buildids where hex = ?), "
+                            "(select id from " BUILDIDS "_files where name = ?));");
+  sqlite_ps ps_upsert_sdef (db, "rpm-sdef-insert",
+                            "insert or ignore into " BUILDIDS "_r_sdef (file, mtime, content) values ("
+                            "(select id from " BUILDIDS "_files where name = ?), ?,"
+                            "(select id from " BUILDIDS "_files where name = ?));");
+  sqlite_ps ps_query (db, "rpm-negativehit-query",
+                      "select 1 from " BUILDIDS "_file_mtime_scanned where "
+                      "sourcetype = 'R' and file = (select id from " BUILDIDS "_files where name = ?) and mtime = ?;");
+  sqlite_ps ps_scan_done (db, "rpm-scanned",
+                          "insert or ignore into " BUILDIDS "_file_mtime_scanned (sourcetype, file, mtime, size)"
+                          "values ('R', (select id from " BUILDIDS "_files where name = ?), ?, ?);");
+
+  char * const dirs[] = { (char*) dir.c_str(), NULL };
+
+  struct timeval tv_start, tv_end;
+  gettimeofday (&tv_start, NULL);
+  unsigned fts_scanned=0, fts_regex=0, fts_cached=0, fts_debuginfo=0;
+  unsigned fts_executable=0, fts_rpm = 0, fts_sref=0, fts_sdef=0;
+
+  FTS *fts = fts_open (dirs,
+                       (traverse_logical ? FTS_LOGICAL : FTS_PHYSICAL|FTS_XDEV)
+                       | FTS_NOCHDIR /* multithreaded */,
+                       NULL);
+  if (fts == NULL)
+    {
+      obatched(cerr) << "cannot fts_open " << dir << endl;
+      return;
+    }
+
+  FTSENT *f;
+  while ((f = fts_read (fts)) != NULL)
+    {
+      semaphore_borrower handle_one_file (scan_concurrency_sem);
+
+      fts_scanned ++;
+      if (interrupted)
+        break;
+
+      if (verbose > 2)
+        obatched(clog) << "fts/rpm traversing " << f->fts_path << endl;
+
+      try
+        {
+          /* Found a file.  Convert it to an absolute path, so
+             the buildid database does not have relative path
+             names that are unresolvable from a subsequent run
+             in a different cwd. */
+          char *rp = realpath(f->fts_path, NULL);
+          if (rp == NULL)
+            continue; // ignore dangling symlink or such
+          string rps = string(rp);
+          free (rp);
+
+          bool ri = !regexec (&file_include_regex, rps.c_str(), 0, 0, 0);
+          bool rx = !regexec (&file_exclude_regex, rps.c_str(), 0, 0, 0);
+          if (!ri || rx)
+            {
+              if (verbose > 3)
+                obatched(clog) << "fts/rpm skipped by regex " << (!ri ? "I" : "") << (rx ? "X" : "") << endl;
+              fts_regex ++;
+              continue;
+            }
+
+          switch (f->fts_info)
+            {
+            case FTS_D:
+              break;
+
+            case FTS_DP:
+              break;
+
+            case FTS_F:
+              {
+                // heuristic: reject if file name does not end with ".rpm"
+                // (alternative: try opening with librpm etc., caching)
+                string suffix = ".rpm";
+                if (rps.size() < suffix.size() ||
+                    rps.substr(rps.size()-suffix.size()) != suffix)
+                  continue;
+                fts_rpm ++;
+
+                /* See if we know of it already. */
+                int rc = ps_query
+                  .reset()
+                  .bind(1, rps)
+                  .bind(2, f->fts_statp->st_mtime)
+                  .step();
+                ps_query.reset();
+                if (rc == SQLITE_ROW) // i.e., a result, as opposed to DONE (no results)
+                  // no need to recheck a file/version we already know
+                  // specifically, no need to parse this rpm again, since we already have
+                  // it as a D or E or S record,
+                  // (so is stored with buildid=NULL)
+                  {
+                    fts_cached ++;
+                    continue;
+                  }
+
+                // intern the rpm file name
+                ps_upsert_files
+                  .reset()
+                  .bind(1, rps)
+                  .step_ok_done();
+
+                // extract the rpm contents via popen("rpm2cpio") | libarchive | loop-of-elf_classify()
+                unsigned my_fts_executable = 0, my_fts_debuginfo = 0, my_fts_sref = 0, my_fts_sdef = 0;
+                bool my_fts_sref_complete_p = true;
+                try
+                  {
+                    rpm_classify (rps,
+                                  ps_upsert_buildids, ps_upsert_files,
+                                  ps_upsert_de, ps_upsert_sref, ps_upsert_sdef, // dalt
+                                  f->fts_statp->st_mtime,
+                                  my_fts_executable, my_fts_debuginfo, my_fts_sref, my_fts_sdef,
+                                  my_fts_sref_complete_p);
+                    inc_metric ("scanned_total","source","rpm");
+                    add_metric("found_debuginfo_total","source","rpm",
+                               my_fts_debuginfo);
+                    add_metric("found_executable_total","source","rpm",
+                               my_fts_executable);
+                    add_metric("found_sourcerefs_total","source","rpm",
+                               my_fts_sref);
+                  }
+                catch (const reportable_exception& e)
+                  {
+                    e.report(clog);
+                  }
+
+                if (verbose > 2)
+                  obatched(clog) << "scanned rpm=" << rps
+                                 << " mtime=" << f->fts_statp->st_mtime
+                                 << " executables=" << my_fts_executable
+                                 << " debuginfos=" << my_fts_debuginfo
+                                 << " srefs=" << my_fts_sref
+                                 << " sdefs=" << my_fts_sdef
+                                 << endl;
+ 
+                fts_executable += my_fts_executable;
+                fts_debuginfo += my_fts_debuginfo;
+                fts_sref += my_fts_sref;
+                fts_sdef += my_fts_sdef;
+
+                if (my_fts_sref_complete_p) // leave incomplete?
+                  ps_scan_done
+                    .reset()
+                    .bind(1, rps)
+                    .bind(2, f->fts_statp->st_mtime)
+                    .bind(3, f->fts_statp->st_size)
+                    .step_ok_done();
+              }
+              break;
+
+            case FTS_ERR:
+            case FTS_NS:
+              throw libc_exception(f->fts_errno, string("fts/rpm traversal ") + string(f->fts_path));
+
+            default:
+            case FTS_SL: /* ignore symlinks; seen in non-L mode only */
+              break;
+            }
+
+          if ((verbose && f->fts_info == FTS_DP) ||
+              (verbose > 1 && f->fts_info == FTS_F))
+            obatched(clog) << "fts/rpm traversing " << rps << ", scanned=" << fts_scanned
+                           << ", regex-skipped=" << fts_regex
+                           << ", rpm=" << fts_rpm << ", cached=" << fts_cached << ", debuginfo=" << fts_debuginfo
+                           << ", executable=" << fts_executable
+                           << ", sourcerefs=" << fts_sref << ", sourcedefs=" << fts_sdef << endl;
+        }
+      catch (const reportable_exception& e)
+        {
+          e.report(clog);
+        }
+    }
+  fts_close (fts);
+
+  gettimeofday (&tv_end, NULL);
+  double deltas = (tv_end.tv_sec - tv_start.tv_sec) + (tv_end.tv_usec - tv_start.tv_usec)*0.000001;
+
+  obatched(clog) << "fts/rpm traversed " << dir << " in " << deltas << "s, scanned=" << fts_scanned
+                 << ", regex-skipped=" << fts_regex
+                 << ", rpm=" << fts_rpm << ", cached=" << fts_cached << ", debuginfo=" << fts_debuginfo
+                 << ", executable=" << fts_executable
+                 << ", sourcerefs=" << fts_sref << ", sourcedefs=" << fts_sdef << endl;
+}
+
+
+
+static void*
+thread_main_scan_source_rpm_path (void* arg)
+{
+  string dir = string((const char*) arg);
+
+  unsigned rescan_timer = 0;
+  sig_atomic_t forced_rescan_count = 0;
+  set_metric("thread_timer_max", "rpm", dir, rescan_s);
+  set_metric("thread_tid", "rpm", dir, tid());
+  while (! interrupted)
+    {
+      set_metric("thread_timer", "rpm", dir, rescan_timer);
+      set_metric("thread_forced_total", "rpm", dir, forced_rescan_count);
+      if (rescan_s && rescan_timer > rescan_s)
+        rescan_timer = 0;
+      if (sigusr1 != forced_rescan_count)
+        {
+          forced_rescan_count = sigusr1;
+          rescan_timer = 0;
+        }
+      if (rescan_timer == 0)
+        try
+          {
+            set_metric("thread_working", "rpm", dir, time(NULL));
+            inc_metric("thread_work_total", "rpm", dir);
+            scan_source_rpm_path (dir);
+            set_metric("thread_working", "rpm", dir, 0);
+          }
+        catch (const sqlite_exception& e)
+          {
+            obatched(cerr) << e.message << endl;
+          }
+      sleep (1);
+      rescan_timer ++;
+    }
+
+  return 0;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+
+static void
+database_stats_report()
+{
+  sqlite_ps ps_query (db, "database-overview",
+                      "select label,quantity from " BUILDIDS "_stats");
+
+  obatched(clog) << "database record counts:" << endl;
+  while (1)
+    {
+      int rc = sqlite3_step (ps_query);
+      if (rc == SQLITE_DONE) break;
+      if (rc != SQLITE_ROW)
+        throw sqlite_exception(rc, "step");
+
+      obatched(clog)
+        << right << setw(20) << ((const char*) sqlite3_column_text(ps_query, 0) ?: (const char*) "NULL")
+        << " "
+        << (sqlite3_column_text(ps_query, 1) ?: (const unsigned char*) "NULL")
+        << endl;
+
+      set_metric("groom", "statistic",
+                 ((const char*) sqlite3_column_text(ps_query, 0) ?: (const char*) "NULL"),
+                 (sqlite3_column_double(ps_query, 1)));
+    }
+}
+
+
+// Do a round of database grooming that might take many minutes to run.
+void groom()
+{
+  obatched(clog) << "grooming database" << endl;
+
+  struct timeval tv_start, tv_end;
+  gettimeofday (&tv_start, NULL);
+
+  // scan for files that have disappeared
+  sqlite_ps files (db, "check old files", "select s.mtime, s.file, f.name from "
+                       BUILDIDS "_file_mtime_scanned s, " BUILDIDS "_files f "
+                       "where f.id = s.file");
+  sqlite_ps files_del_f_de (db, "nuke f_de", "delete from " BUILDIDS "_f_de where file = ? and mtime = ?");
+  sqlite_ps files_del_r_de (db, "nuke r_de", "delete from " BUILDIDS "_r_de where file = ? and mtime = ?");
+  sqlite_ps files_del_scan (db, "nuke f_m_s", "delete from " BUILDIDS "_file_mtime_scanned "
+                            "where file = ? and mtime = ?");
+  files.reset();
+  while(1)
+    {
+      int rc = files.step();
+      if (rc != SQLITE_ROW)
+        break;
+
+      int64_t mtime = sqlite3_column_int64 (files, 0);
+      int64_t fileid = sqlite3_column_int64 (files, 1);
+      const char* filename = ((const char*) sqlite3_column_text (files, 2) ?: "");
+      struct stat s;
+      rc = stat(filename, &s);
+      if (rc < 0 || (mtime != (int64_t) s.st_mtime))
+        {
+          if (verbose > 2)
+            obatched(clog) << "groom: forgetting file=" << filename << " mtime=" << mtime << endl;
+          files_del_f_de.reset().bind(1,fileid).bind(2,mtime).step_ok_done();
+          files_del_r_de.reset().bind(1,fileid).bind(2,mtime).step_ok_done();
+          files_del_scan.reset().bind(1,fileid).bind(2,mtime).step_ok_done();
+        }
+    }
+  files.reset();
+
+  // delete buildids with no references in _r_de or _f_de tables;
+  // cascades to _r_sref & _f_s records
+  sqlite_ps buildids_del (db, "nuke orphan buildids",
+                          "delete from " BUILDIDS "_buildids "
+                          "where not exists (select 1 from " BUILDIDS "_f_de d where " BUILDIDS "_buildids.id = d.buildid) "
+                          "and not exists (select 1 from " BUILDIDS "_r_de d where " BUILDIDS "_buildids.id = d.buildid)");
+  buildids_del.reset().step_ok_done();
+
+  // NB: "vacuum" is too heavy for even daily runs: it rewrites the entire db, so is done as maxigroom -G
+  sqlite_ps g1 (db, "incremental vacuum", "pragma incremental_vacuum");
+  g1.reset().step_ok_done();
+  sqlite_ps g2 (db, "optimize", "pragma optimize");
+  g2.reset().step_ok_done();
+  sqlite_ps g3 (db, "wal checkpoint", "pragma wal_checkpoint=truncate");
+  g3.reset().step_ok_done();
+
+  database_stats_report();
+
+  sqlite3_db_release_memory(db); // shrink the process if possible
+
+  gettimeofday (&tv_end, NULL);
+  double deltas = (tv_end.tv_sec - tv_start.tv_sec) + (tv_end.tv_usec - tv_start.tv_usec)*0.000001;
+
+  obatched(clog) << "groomed database in " << deltas << "s" << endl;
+}
+
+
+static void*
+thread_main_groom (void* /*arg*/)
+{
+  unsigned groom_timer = 0;
+  sig_atomic_t forced_groom_count = 0;
+  set_metric("thread_timer_max", "role", "groom", groom_s);
+  set_metric("thread_tid", "role", "groom", tid());
+  while (! interrupted)
+    {
+      set_metric("thread_timer", "role", "groom", groom_timer);
+      set_metric("thread_forced_total", "role", "groom", forced_groom_count);      
+      if (groom_s && groom_timer > groom_s)
+        groom_timer = 0;
+      if (sigusr2 != forced_groom_count)
+        {
+          forced_groom_count = sigusr2;
+          groom_timer = 0;
+        }
+      if (groom_timer == 0)
+        try
+          {
+            set_metric("thread_working", "role", "groom", time(NULL));
+            inc_metric("thread_work_total", "role", "groom");
+            groom ();
+            set_metric("thread_working", "role", "groom", 0);
+          }
+        catch (const sqlite_exception& e)
+          {
+            obatched(cerr) << e.message << endl;
+          }
+      sleep (1);
+      groom_timer ++;
+    }
+
+  return 0;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+
+
+static void
+signal_handler (int /* sig */)
+{
+  interrupted ++;
+
+  if (db)
+    sqlite3_interrupt (db);
+
+  // NB: don't do anything else in here
+}
+
+static void
+sigusr1_handler (int /* sig */)
+{
+   sigusr1 ++;
+  // NB: don't do anything else in here
+}
+
+static void
+sigusr2_handler (int /* sig */)
+{
+   sigusr2 ++;
+  // NB: don't do anything else in here
+}
+
+
+
+
+
+// A user-defined sqlite function, to score the sharedness of the
+// prefix of two strings.  This is used to compare candidate debuginfo
+// / source-rpm names, so that the closest match
+// (directory-topology-wise closest) is found.  This is important in
+// case the same sref (source file name) is in many -debuginfo or
+// -debugsource RPMs, such as when multiple versions/releases of the
+// same package are in the database.
+
+static void sqlite3_sharedprefix_fn (sqlite3_context* c, int argc, sqlite3_value** argv)
+{
+  if (argc != 2)
+    sqlite3_result_error(c, "expect 2 string arguments", -1);
+  else if ((sqlite3_value_type(argv[0]) != SQLITE_TEXT) ||
+           (sqlite3_value_type(argv[1]) != SQLITE_TEXT))
+    sqlite3_result_null(c);
+  else
+    {
+      const unsigned char* a = sqlite3_value_text (argv[0]);
+      const unsigned char* b = sqlite3_value_text (argv[1]);
+      int i = 0;
+      while (*a++ == *b++)
+        i++;
+      sqlite3_result_int (c, i);
+    }
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  (void) setlocale (LC_ALL, "");
+  (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
+  (void) textdomain (PACKAGE_TARNAME);
+
+  /* Tell the library which version we are expecting.  */
+  elf_version (EV_CURRENT);
+
+  /* Set computed default values. */
+  db_path = string(getenv("HOME") ?: "/") + string("/.debuginfod.sqlite"); /* XDG? */
+  int rc = regcomp (& file_include_regex, ".*", REG_EXTENDED|REG_NOSUB); // match everything
+  if (rc != 0)
+    error (EXIT_FAILURE, 0, "regcomp failure: %d", rc);
+  rc = regcomp (& file_exclude_regex, "^$", REG_EXTENDED|REG_NOSUB); // match nothing
+  if (rc != 0)
+    error (EXIT_FAILURE, 0, "regcomp failure: %d", rc);
+
+  /* Parse and process arguments.  */
+  int remaining;
+  argp_program_version_hook = print_version; // this works
+  (void) argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &remaining, NULL);
+  if (remaining != argc)
+      error (EXIT_FAILURE, 0,
+             "unexpected argument: %s", argv[remaining]);
+
+  if (!scan_rpms && !scan_files && source_paths.size()>0)
+    obatched(clog) << "warning: without -F and/or -R, ignoring PATHs" << endl;
+
+  (void) signal (SIGPIPE, SIG_IGN); // microhttpd can generate it incidentally, ignore
+  (void) signal (SIGINT, signal_handler); // ^C
+  (void) signal (SIGHUP, signal_handler); // EOF
+  (void) signal (SIGTERM, signal_handler); // systemd
+  (void) signal (SIGUSR1, sigusr1_handler); // end-user
+  (void) signal (SIGUSR2, sigusr2_handler); // end-user
+
+  // do this before any threads start
+  scan_concurrency_sem = new semaphore(concurrency);
+
+  /* Get database ready. */
+  rc = sqlite3_open_v2 (db_path.c_str(), &db, (SQLITE_OPEN_READWRITE
+                                               |SQLITE_OPEN_CREATE
+                                               |SQLITE_OPEN_FULLMUTEX), /* thread-safe */
+                        NULL);
+  if (rc == SQLITE_CORRUPT)
+    {
+      (void) unlink (db_path.c_str());
+      error (EXIT_FAILURE, 0,
+             "cannot open %s, deleted database: %s", db_path.c_str(), sqlite3_errmsg(db));
+    }
+  else if (rc)
+    {
+      error (EXIT_FAILURE, 0,
+             "cannot open %s, consider deleting database: %s", db_path.c_str(), sqlite3_errmsg(db));
+    }
+
+  obatched(clog) << "opened database " << db_path << endl;
+  obatched(clog) << "sqlite version " << sqlite3_version << endl;
+
+  // add special string-prefix-similarity function used in rpm sref/sdef resolution
+  rc = sqlite3_create_function(db, "sharedprefix", 2, SQLITE_UTF8, NULL,
+                               & sqlite3_sharedprefix_fn, NULL, NULL);
+  if (rc != SQLITE_OK)
+    error (EXIT_FAILURE, 0,
+           "cannot create sharedprefix( function: %s", sqlite3_errmsg(db));
+
+  if (verbose > 3)
+    obatched(clog) << "ddl: " << DEBUGINFOD_SQLITE_DDL << endl;
+  rc = sqlite3_exec (db, DEBUGINFOD_SQLITE_DDL, NULL, NULL, NULL);
+  if (rc != SQLITE_OK)
+    {
+      error (EXIT_FAILURE, 0,
+             "cannot run database schema ddl: %s", sqlite3_errmsg(db));
+    }
+
+  // Start httpd server threads.  Separate pool for IPv4 and IPv6, in
+  // case the host only has one protocol stack.
+  MHD_Daemon *d4 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+#if MHD_VERSION >= 0x00095300
+                                     | MHD_USE_INTERNAL_POLLING_THREAD
+#else
+                                     | MHD_USE_SELECT_INTERNALLY
+#endif
+                                     | MHD_USE_DEBUG, /* report errors to stderr */
+                                     http_port,
+                                     NULL, NULL, /* default accept policy */
+                                     handler_cb, NULL, /* handler callback */
+                                     MHD_OPTION_END);
+  MHD_Daemon *d6 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+#if MHD_VERSION >= 0x00095300
+                                     | MHD_USE_INTERNAL_POLLING_THREAD
+#else
+                                     | MHD_USE_SELECT_INTERNALLY
+#endif
+                                     | MHD_USE_IPv6
+                                     | MHD_USE_DEBUG, /* report errors to stderr */
+                                     http_port,
+                                     NULL, NULL, /* default accept policy */
+                                     handler_cb, NULL, /* handler callback */
+                                     MHD_OPTION_END);
+
+  if (d4 == NULL && d6 == NULL) // neither ipv4 nor ipv6? boo
+    {
+      sqlite3 *database = db;
+      db = 0; // for signal_handler not to freak
+      sqlite3_close (database);
+      error (EXIT_FAILURE, 0, "cannot start http server at port %d", http_port);
+    }
+
+  obatched(clog) << "started http server on "
+                 << (d4 != NULL ? "IPv4 " : "")
+                 << (d6 != NULL ? "IPv6 " : "")
+                 << "port=" << http_port << endl;
+
+  // add maxigroom sql if -G given
+  if (maxigroom)
+    {
+      obatched(clog) << "maxigrooming database, please wait." << endl;
+      extra_ddl.push_back("create index if not exists " BUILDIDS "_r_sref_arc on " BUILDIDS "_r_sref(artifactsrc);");
+      extra_ddl.push_back("delete from " BUILDIDS "_r_sdef where not exists (select 1 from " BUILDIDS "_r_sref b where " BUILDIDS "_r_sdef.content = b.artifactsrc);");
+      extra_ddl.push_back("drop index if exists " BUILDIDS "_r_sref_arc;");
+
+      // NB: we don't maxigroom the _files interning table.  It'd require a temp index on all the
+      // tables that have file foreign-keys, which is a lot.
+
+      // NB: with =delete, may take up 3x disk space total during vacuum process
+      //     vs.  =off (only 2x but may corrupt database if program dies mid-vacuum)
+      //     vs.  =wal (>3x observed, but safe)
+      extra_ddl.push_back("pragma journal_mode=delete;");
+      extra_ddl.push_back("vacuum;");
+      extra_ddl.push_back("pragma journal_mode=wal;");
+    }
+
+  // run extra -D sql if given
+  for (auto&& i: extra_ddl)
+    {
+      if (verbose > 1)
+        obatched(clog) << "extra ddl:\n" << i << endl;
+      rc = sqlite3_exec (db, i.c_str(), NULL, NULL, NULL);
+      if (rc != SQLITE_OK && rc != SQLITE_DONE && rc != SQLITE_ROW)
+        error (0, 0,
+               "warning: cannot run database extra ddl %s: %s", i.c_str(), sqlite3_errmsg(db));
+    }
+
+  if (maxigroom)
+    obatched(clog) << "maxigroomed database" << endl;
+
+
+  obatched(clog) << "search concurrency " << concurrency << endl;
+  obatched(clog) << "rescan time " << rescan_s << endl;
+  obatched(clog) << "groom time " << groom_s << endl;
+  const char* du = getenv(DEBUGINFOD_URLS_ENV_VAR);
+  if (du && du[0] != '\0') // set to non-empty string?
+    obatched(clog) << "upstream debuginfod servers: " << du << endl;
+
+  vector<pthread_t> source_file_scanner_threads;
+  vector<pthread_t> source_rpm_scanner_threads;
+  pthread_t groom_thread;
+
+  rc = pthread_create (& groom_thread, NULL, thread_main_groom, NULL);
+  if (rc < 0)
+    error (0, 0, "warning: cannot spawn thread (%d) to groom database\n", rc);
+ 
+  if (scan_files) for (auto&& it : source_paths)
+    {
+      pthread_t pt;
+      rc = pthread_create (& pt, NULL, thread_main_scan_source_file_path, (void*) it.c_str());
+      if (rc < 0)
+        error (0, 0, "warning: cannot spawn thread (%d) to scan source files %s\n", rc, it.c_str());
+      else
+        source_file_scanner_threads.push_back(pt);
+    }
+
+  if (scan_rpms) for (auto&& it : source_paths)
+    {
+      pthread_t pt;
+      rc = pthread_create (& pt, NULL, thread_main_scan_source_rpm_path, (void*) it.c_str());
+      if (rc < 0)
+        error (0, 0, "warning: cannot spawn thread (%d) to scan source rpms %s\n", rc, it.c_str());
+      else
+        source_rpm_scanner_threads.push_back(pt);
+    }
+
+  /* Trivial main loop! */
+  set_metric("ready", 1);
+  while (! interrupted)
+    pause ();
+  set_metric("ready", 0);
+
+  if (verbose)
+    obatched(clog) << "stopping" << endl;
+
+  /* Join any source scanning threads. */
+  for (auto&& it : source_file_scanner_threads)
+    pthread_join (it, NULL);
+  for (auto&& it : source_rpm_scanner_threads)
+    pthread_join (it, NULL);
+  pthread_join (groom_thread, NULL);
+  
+  /* Stop all the web service threads. */
+  if (d4) MHD_stop_daemon (d4);
+  if (d6) MHD_stop_daemon (d6);
+
+  /* With all threads known dead, we can clean up the global resources. */
+  delete scan_concurrency_sem;
+  rc = sqlite3_exec (db, DEBUGINFOD_SQLITE_CLEANUP_DDL, NULL, NULL, NULL);
+  if (rc != SQLITE_OK)
+    {
+      error (0, 0,
+             "warning: cannot run database cleanup ddl: %s", sqlite3_errmsg(db));
+    }
+
+  // NB: no problem with unconditional free here - an earlier failed regcomp would exit program
+  (void) regfree (& file_include_regex);
+  (void) regfree (& file_exclude_regex);
+
+  sqlite3 *database = db;
+  db = 0; // for signal_handler not to freak
+  (void) sqlite3_close (database);
+
+  return 0;
+}
diff --git a/debuginfod/debuginfod.h b/debuginfod/debuginfod.h
new file mode 100644
index 0000000..6b1b1cc
--- /dev/null
+++ b/debuginfod/debuginfod.h
@@ -0,0 +1,85 @@
+/* External declarations for the libdebuginfod client library.
+   Copyright (C) 2019 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 _DEBUGINFOD_CLIENT_H
+#define _DEBUGINFOD_CLIENT_H 1
+
+/* Names of environment variables that control the client logic. */
+#define DEBUGINFOD_URLS_ENV_VAR "DEBUGINFOD_URLS"
+#define DEBUGINFOD_CACHE_PATH_ENV_VAR "DEBUGINFOD_CACHE_PATH"
+#define DEBUGINFOD_TIMEOUT_ENV_VAR "DEBUGINFOD_TIMEOUT"
+
+/* Handle for debuginfod-client connection.  */
+typedef struct debuginfod_client debuginfod_client;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Create a handle for a new debuginfod-client session.  */
+debuginfod_client *debuginfod_begin (void);
+
+/* Query the urls contained in $DEBUGINFOD_URLS for a file with
+   the specified type and build id.  If build_id_len == 0, the
+   build_id is supplied as a lowercase hexadecimal string; otherwise
+   it is a binary blob of given legnth.
+
+   If successful, return a file descriptor to the target, otherwise
+   return a posix error code.  If successful, set *path to a
+   strdup'd copy of the name of the same file in the cache.
+   Caller must free() it later. */
+  
+int debuginfod_find_debuginfo (debuginfod_client *client,
+			       const unsigned char *build_id,
+                               int build_id_len,
+                               char **path);
+
+int debuginfod_find_executable (debuginfod_client *client,
+				const unsigned char *build_id,
+                                int build_id_len,
+                                char **path);
+
+int debuginfod_find_source (debuginfod_client *client,
+			    const unsigned char *build_id,
+                            int build_id_len,
+                            const char *filename,
+                            char **path);
+
+typedef int (*debuginfod_progressfn_t)(debuginfod_client *c, long a, long b);
+void debuginfod_set_progressfn(debuginfod_client *c,
+			       debuginfod_progressfn_t fn);
+
+/* Release debuginfod client connection context handle.  */
+void debuginfod_end (debuginfod_client *client);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _DEBUGINFOD_CLIENT_H */
diff --git a/debuginfod/libdebuginfod.map b/debuginfod/libdebuginfod.map
new file mode 100644
index 0000000..0d26f93
--- /dev/null
+++ b/debuginfod/libdebuginfod.map
@@ -0,0 +1,10 @@
+ELFUTILS_0 { };
+ELFUTILS_0.178 {
+  global:
+  debuginfod_begin;
+  debuginfod_end;
+  debuginfod_find_debuginfo;
+  debuginfod_find_executable;
+  debuginfod_find_source;
+  debuginfod_set_progressfn;
+} ELFUTILS_0;
diff --git a/doc/Makefile.am b/doc/Makefile.am
index d6f3eca..b5db01f 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1,7 +1,7 @@
 ## Process this file with automake to create Makefile.in
 ## Configure input file for elfutils.
 ##
-## Copyright (C) 1996-2001, 2002, 2005 Red Hat, Inc.
+## Copyright (C) 1996-2001, 2002, 2005, 2019 Red Hat, Inc.
 ## This file is part of elfutils.
 ##
 ## This file is free software; you can redistribute it and/or modify
@@ -19,3 +19,12 @@
 EXTRA_DIST = COPYING-GFDL README
 dist_man1_MANS=readelf.1 elfclassify.1
 notrans_dist_man3_MANS=elf_update.3 elf_getdata.3 elf_clone.3 elf_begin.3
+notrans_dist_man8_MANS=
+notrans_dist_man1_MANS=
+
+if DEBUGINFOD
+notrans_dist_man8_MANS += debuginfod.8
+notrans_dist_man3_MANS += debuginfod_find_debuginfo.3 debuginfod_find_source.3 debuginfod_find_executable.3 debuginfod_set_progressfn.3
+notrans_dist_man1_MANS += debuginfod-find.1
+endif
+
diff --git a/doc/debuginfod-find.1 b/doc/debuginfod-find.1
new file mode 100644
index 0000000..a759ecb
--- /dev/null
+++ b/doc/debuginfod-find.1
@@ -0,0 +1,144 @@
+'\"! tbl | nroff \-man
+'\" t macro stdmacro
+
+.de SAMPLE
+.br
+.RS 0
+.nf
+.nh
+..
+.de ESAMPLE
+.hy
+.fi
+.RE
+..
+
+.TH DEBUGINFOD-FIND 1
+.SH NAME
+debuginfod-find \- request debuginfo-related data
+
+.SH SYNOPSIS
+.B debuginfod-find [\fIOPTION\fP]... debuginfo \fIBUILDID\fP
+
+.B debuginfod-find [\fIOPTION\fP]... executable \fIBUILDID\fP
+
+.B debuginfod-find [\fIOPTION\fP]... source \fIBUILDID\fP \fI/FILENAME\fP
+
+.SH DESCRIPTION
+\fBdebuginfod-find\fP queries one or more \fBdebuginfod\fP servers for
+debuginfo-related data.  In case of a match, it saves the the
+requested file into a local cache, prints the file name to standard
+output, and exits with a success status of 0.  In case of any error,
+it exits with a failure status and an error message to standard error.
+
+.\" Much of the following text is duplicated with debuginfod.8
+
+The debuginfod system uses buildids to identify debuginfo-related data.
+These are stored as binary notes in ELF/DWARF files, and are
+represented as lowercase hexadecimal.  For example, for a program
+/bin/ls, look at the ELF note GNU_BUILD_ID:
+
+.SAMPLE
+% readelf -n /bin/ls | grep -A4 build.id
+Note section [ 4] '.note.gnu.buildid' of 36 bytes at offset 0x340:
+Owner          Data size  Type
+GNU                   20  GNU_BUILD_ID
+Build ID: 8713b9c3fb8a720137a4a08b325905c7aaf8429d
+.ESAMPLE
+
+Then the hexadecimal BUILDID is simply:
+
+.SAMPLE
+8713b9c3fb8a720137a4a08b325905c7aaf8429d
+.ESAMPLE
+
+.SS debuginfo \fIBUILDID\fP
+
+If the given buildid is known to a server, this request will result
+in a binary object that contains the customary \fB.*debug_*\fP
+sections.  This may be a split debuginfo file as created by
+\fBstrip\fP, or it may be an original unstripped executable.
+
+.SS executable \fIBUILDID\fP
+
+If the given buildid is known to the server, this request will result
+in a binary object that contains the normal executable segments.  This
+may be a executable stripped by \fBstrip\fP, or it may be an original
+unstripped executable.  \fBET_DYN\fP shared libraries are considered
+to be a type of executable.
+
+.SS source \fIBUILDID\fP \fI/SOURCE/FILE\fP
+
+If the given buildid is known to the server, this request will result
+in a binary object that contains the source file mentioned.  The path
+should be absolute.  Relative path names commonly appear in the DWARF
+file's source directory, but these paths are relative to
+individual compilation unit AT_comp_dir paths, and yet an executable
+is made up of multiple CUs.  Therefore, to disambiguate, debuginfod
+expects source queries to prefix relative path names with the CU
+compilation-directory, followed by a mandatory "/".
+
+Note: the user should not elide \fB../\fP or \fB/./\fP or extraneous
+\fB///\fP sorts of path components in the directory names, because if
+this is how those names appear in the DWARF files, that is what
+debuginfod needs to see too.
+
+For example:
+.TS
+l l.
+#include <stdio.h>	source BUILDID /usr/include/stdio.h
+/path/to/foo.c	source BUILDID /path/to/foo.c
+\../bar/foo.c AT_comp_dir=/zoo/	source BUILDID /zoo//../bar/foo.c
+.TE
+
+.SH "OPTIONS"
+
+.TP
+.B "\-v"
+Increase verbosity, including printing frequent download-progress messages.
+
+
+.SH "SECURITY"
+
+debuginfod-find \fBdoes not\fP include any particular security
+features.  It trusts that the binaries returned by the debuginfod(s)
+are accurate.  Therefore, the list of servers should include only
+trustworthy ones.  If accessed across HTTP rather than HTTPS, the
+network should be trustworthy.  Authentication information through
+the internal \fIlibcurl\fP library is not currently enabled, except
+for the basic plaintext \%\fIhttp[s]://userid:password@hostname/\fP style.
+(The debuginfod server does not perform authentication, but a front-end
+proxy server could.)
+
+.SH "ENVIRONMENT VARIABLES"
+
+.TP 21
+.B DEBUGINFOD_URLS
+This environment variable contains a list of URL prefixes for trusted
+debuginfod instances.  Alternate URL prefixes are separated by space.
+
+.TP 21
+.B DEBUGINFOD_TIMEOUT
+This environment variable governs the timeout for each debuginfod HTTP
+connection.  A server that fails to respond within this many seconds
+is skipped.  The default is 5.
+
+.TP 21
+.B DEBUGINFOD_CACHE_PATH
+This environment variable governs the location of the cache where
+downloaded files are kept.  It is cleaned periodically as this program
+is reexecuted.  Cache management parameters may be set by files under
+this directory: see the \fBdebuginfod_find_debuginfo(3)\fP man page
+for details.  The default is $HOME/.debuginfod_client_cache.
+
+.SH "FILES"
+.LP
+.PD .1v
+.TP 20
+.B $HOME/.debuginfod_client_cache
+Default cache directory.
+.PD
+
+.SH "SEE ALSO"
+.I "debuginfod(8)"
+.I "debuginfod_find_debuginfod(3)"
diff --git a/doc/debuginfod.8 b/doc/debuginfod.8
new file mode 100644
index 0000000..210550e
--- /dev/null
+++ b/doc/debuginfod.8
@@ -0,0 +1,387 @@
+'\"! tbl | nroff \-man
+'\" t macro stdmacro
+
+.de SAMPLE
+.br
+.RS 0
+.nf
+.nh
+..
+.de ESAMPLE
+.hy
+.fi
+.RE
+..
+
+.TH DEBUGINFOD 8
+.SH NAME
+debuginfod \- debuginfo-related http file-server daemon
+
+.SH SYNOPSIS
+.B debuginfod
+[\fIOPTION\fP]... [\fIPATH\fP]...
+
+.SH DESCRIPTION
+\fBdebuginfod\fP serves debuginfo-related artifacts over HTTP.  It
+periodically scans a set of directories for ELF/DWARF files and their
+associated source code, as well as RPM files containing the above, to
+build an index by their buildid.  This index is used when remote
+clients use the HTTP webapi, to fetch these files by the same buildid.
+
+If a debuginfod cannot service a given buildid artifact request
+itself, and it is configured with information about upstream
+debuginfod servers, it queries them for the same information, just as
+\fBdebuginfod-find\fP would.  If successful, it locally caches then
+relays the file content to the original requester.
+
+If the \fB\-F\fP option is given, each listed PATH creates a thread to
+scan for matching ELF/DWARF/source files under the given physical
+directory.  Source files are matched with DWARF files based on the
+AT_comp_dir (compilation directory) attributes inside it.  Duplicate
+directories are ignored.  You may use a file name for a PATH, but
+source code indexing may be incomplete; prefer using a directory that
+contains the binaries.  Caution: source files listed in the DWARF may
+be a path \fIanywhere\fP in the file system, and debuginfod will
+readily serve their content on demand.  (Imagine a doctored DWARF file
+that lists \fI/etc/passwd\fP as a source file.)  If this is a concern,
+audit your binaries with tools such as:
+
+.SAMPLE
+% eu-readelf -wline BINARY | sed -n '/^Directory.table/,/^File.name.table/p'
+or
+% eu-readelf -wline BINARY | sed -n '/^Directory.table/,/^Line.number/p'
+or even use debuginfod itself:
+% debuginfod -vvv -d :memory: -F BINARY 2>&1 | grep 'recorded.*source'
+^C
+.ESAMPLE
+
+If the \fB\-R\fP option is given each listed PATH creates a thread to
+scan for ELF/DWARF/source files contained in matching RPMs under the
+given physical directory.  Duplicate directories are ignored.  You may
+use a file name for a PATH, but source code indexing may be
+incomplete; prefer using a directory that contains normal RPMs
+alongside debuginfo/debugsource RPMs.  Because of complications such
+as DWZ-compressed debuginfo, may require \fItwo\fP scan passes to
+identify all source code.  Source files for RPMs are only served
+from other RPMs, so the caution for \-F does not apply.
+
+If no PATH is listed, or neither \-F nor \-R option is given, then
+\fBdebuginfod\fP will simply serve content that it scanned into its
+index in previous runs: the data is cumulative.
+
+File names must match extended regular expressions given by the \-I
+option and not the \-X option (if any) in order to be considered.
+
+
+.SH OPTIONS
+
+.TP
+.B "\-F"
+Activate ELF/DWARF file scanning threads.  The default is off.
+
+.TP
+.B "\-R"
+Activate RPM file scanning threads.  The default is off.
+
+.TP
+.B "\-d FILE" "\-\-database=FILE"
+Set the path of the sqlite database used to store the index.  This
+file is disposable in the sense that a later rescan will repopulate
+data.  It will contain absolute file path names, so it may not be
+portable across machines.  It may be frequently read/written, so it
+should be on a fast filesytem.  It should not be shared across
+machines or users, to maximize sqlite locking performance.  The
+default database file is $HOME/.debuginfod.sqlite.
+
+.TP
+.B "\-D SQL" "\-\-ddl=SQL"
+Execute given sqlite statement after the database is opened and
+initialized as extra DDL (SQL data definition language).  This may be
+useful to tune performance-related pragmas or indexes.  May be
+repeated.  The default is nothing extra.
+
+.TP
+.B "\-p NUM" "\-\-port=NUM"
+Set the TCP port number on which debuginfod should listen, to service
+HTTP requests.  Both IPv4 and IPV6 sockets are opened, if possible.
+The webapi is documented below.  The default port number is 8002.
+
+.TP
+.B "\-I REGEX"  "\-\-include=REGEX"  "\-X REGEX"  "\-\-exclude=REGEX"
+Govern the inclusion and exclusion of file names under the search
+paths.  The regular expressions are interpreted as unanchored POSIX
+extended REs, thus may include alternation.  They are evaluated
+against the full path of each file, based on its \fBrealpath(3)\fP
+canonicalization.  By default, all files are included and none are
+excluded.  A file that matches both include and exclude REGEX is
+excluded.  (The \fIcontents\fP of RPM files are not subject to
+inclusion or exclusion filtering: they are all processed.)
+
+.TP
+.B "\-t SECONDS"  "\-\-rescan\-time=SECONDS"
+Set the rescan time for the file and RPM directories.  This is the
+amount of time the scanning threads will wait after finishing a scan,
+before doing it again.  A rescan for unchanged files is fast (because
+the index also stores the file mtimes).  A time of zero is acceptable,
+and means that only one initial scan should performed.  The default
+rescan time is 300 seconds.  Receiving a SIGUSR1 signal triggers a new
+scan, independent of the rescan time (including if it was zero).
+
+.TP
+.B "\-g SECONDS" "\-\-groom\-time=SECONDS"
+Set the groom time for the index database.  This is the amount of time
+the grooming thread will wait after finishing a grooming pass before
+doing it again.  A groom operation quickly rescans all previously
+scanned files, only to see if they are still present and current, so
+it can deindex obsolete files.  See also the \fIDATA MANAGEMENT\fP
+section.  The default groom time is 86400 seconds (1 day).  A time of
+zero is acceptable, and means that only one initial groom should be
+performed.  Receiving a SIGUSR2 signal triggers a new grooming pass,
+independent of the groom time (including if it was zero).
+
+.TP
+.B "\-G"
+Run an extraordinary maximal-grooming pass at debuginfod startup.
+This pass can take considerable time, because it tries to remove any
+debuginfo-unrelated content from the RPM-related parts of the index.
+It should not be run if any recent RPM-related indexing operations
+were aborted early.  It can take considerable space, because it
+finishes up with an sqlite "vacuum" operation, which repacks the
+database file by triplicating it temporarily.  The default is not to
+do maximal-grooming.  See also the \fIDATA MANAGEMENT\fP section.
+
+.TP
+.B "\-c NUM"  "\-\-concurrency=NUM"
+Set the concurrency limit for all the scanning threads.  While many
+threads may be spawned to cover all the given PATHs, only NUM may
+concurrently do CPU-intensive operations like parsing an ELF file
+or an RPM.  The default is the number of processors on the system;
+the minimum is 1.
+
+.TP
+.B "\-L"
+Traverse symbolic links encountered during traversal of the PATHs,
+including across devices - as in \fIfind\ -L\fP.  The default is to
+traverse the physical directory structure only, stay on the same
+device, and ignore symlinks - as in \fIfind\ -P\ -xdev\fP.  Caution: a
+loops in the symbolic directory tree might lead to \fIinfinite
+traversal\fP.
+
+.TP
+.B "\-v"
+Increase verbosity of logging to the standard error file descriptor.
+May be repeated to increase details.  The default verbosity is 0.
+
+.SH WEBAPI
+
+.\" Much of the following text is duplicated with debuginfod-find.1
+
+debuginfod's webapi resembles ordinary file service, where a GET
+request with a path containing a known buildid results in a file.
+Unknown buildid / request combinations result in HTTP error codes.
+This file service resemblance is intentional, so that an installation
+can take advantage of standard HTTP management infrastructure.
+
+There are three requests.  In each case, the buildid is encoded as a
+lowercase hexadecimal string.  For example, for a program \fI/bin/ls\fP,
+look at the ELF note GNU_BUILD_ID:
+
+.SAMPLE
+% readelf -n /bin/ls | grep -A4 build.id
+Note section [ 4] '.note.gnu.buildid' of 36 bytes at offset 0x340:
+Owner          Data size  Type
+GNU                   20  GNU_BUILD_ID
+Build ID: 8713b9c3fb8a720137a4a08b325905c7aaf8429d
+.ESAMPLE
+
+Then the hexadecimal BUILDID is simply:
+
+.SAMPLE
+8713b9c3fb8a720137a4a08b325905c7aaf8429d
+.ESAMPLE
+
+.SS /buildid/\fIBUILDID\fP/debuginfo
+
+If the given buildid is known to the server, this request will result
+in a binary object that contains the customary \fB.*debug_*\fP
+sections.  This may be a split debuginfo file as created by
+\fBstrip\fP, or it may be an original unstripped executable.
+
+.SS /buildid/\fIBUILDID\fP/executable
+
+If the given buildid is known to the server, this request will result
+in a binary object that contains the normal executable segments.  This
+may be a executable stripped by \fBstrip\fP, or it may be an original
+unstripped executable.  \fBET_DYN\fP shared libraries are considered
+to be a type of executable.
+
+.SS /buildid/\fIBUILDID\fP/source\fI/SOURCE/FILE\fP
+
+If the given buildid is known to the server, this request will result
+in a binary object that contains the source file mentioned.  The path
+should be absolute.  Relative path names commonly appear in the DWARF
+file's source directory, but these paths are relative to
+individual compilation unit AT_comp_dir paths, and yet an executable
+is made up of multiple CUs.  Therefore, to disambiguate, debuginfod
+expects source queries to prefix relative path names with the CU
+compilation-directory, followed by a mandatory "/".
+
+Note: contrary to RFC 3986, the client should not elide \fB../\fP or
+\fB/./\fP or extraneous \fB///\fP sorts of path components in the
+directory names, because if this is how those names appear in the
+DWARF files, that is what debuginfod needs to see too.
+
+For example:
+.TS
+l l.
+#include <stdio.h>	/buildid/BUILDID/source/usr/include/stdio.h
+/path/to/foo.c	/buildid/BUILDID/source/path/to/foo.c
+\../bar/foo.c AT_comp_dir=/zoo/	/buildid/BUILDID/source/zoo//../bar/foo.c
+.TE
+
+.SS /metrics
+
+This endpoint returns a Prometheus formatted text/plain dump of a
+variety of statistics about the operation of the debuginfod server.
+The exact set of metrics and their meanings may change in future
+versions.  Caution: configuration information (path names, versions)
+may be disclosed.
+
+.SH DATA MANAGEMENT
+
+debuginfod stores its index in an sqlite database in a densely packed
+set of interlinked tables.  While the representation is as efficient
+as we have been able to make it, it still takes a considerable amount
+of data to record all debuginfo-related data of potentially a great
+many files.  This section offers some advice about the implications.
+
+As a general explanation for size, consider that debuginfod indexes
+ELF/DWARF files, it stores their names and referenced source file
+names, and buildids will be stored.  When indexing RPMs, it stores
+every file name \fIof or in\fP an RPM, every buildid, plus every
+source file name referenced from a DWARF file.  (Indexing RPMs takes
+more space because the source files often reside in separate
+subpackages that may not be indexed at the same pass, so extra
+metadata has to be kept.)
+
+Getting down to numbers, in the case of Fedora RPMs (essentially,
+gzip-compressed cpio files), the sqlite index database tends to be
+from 0.5% to 3% of their size.  It's larger for binaries that are
+assembled out of a great many source files, or packages that carry
+much debuginfo-unrelated content.  It may be even larger during the
+indexing phase due to temporary sqlite write-ahead-logging files;
+these are checkpointed (cleaned out and removed) at shutdown.  It may
+be helpful to apply tight \-I or \-X regular-expression constraints to
+exclude files from scanning that you know have no debuginfo-relevant
+content.
+
+As debuginfod runs, it periodically rescans its target directories,
+and any new content found is added to the database.  Old content, such
+as data for files that have disappeared or that have been replaced
+with newer versions is removed at a periodic \fIgrooming\fP pass.
+This means that the sqlite files grow fast during initial indexing,
+slowly during index rescans, and periodically shrink during grooming.
+There is also an optional one-shot \fImaximal grooming\fP pass is
+available.  It removes information debuginfo-unrelated data from the
+RPM content index such as file names found in RPMs ("rpm sdef"
+records) that are not referred to as source files from any binaries
+find in RPMs ("rpm sref" records).  This can save considerable disk
+space.  However, it is slow and temporarily requires up to twice the
+database size as free space.  Worse: it may result in missing
+source-code info if the RPM traversals were interrupted, so the not
+all source file references were known.  Use it rarely to polish a
+complete index.
+
+You should ensure that ample disk space remains available.  (The flood
+of error messages on -ENOSPC is ugly and nagging.  But, like for most
+other errors, debuginfod will resume when resources permit.)  If
+necessary, debuginfod can be stopped, the database file moved or
+removed, and debuginfod restarted.
+
+sqlite offers several performance-related options in the form of
+pragmas.  Some may be useful to fine-tune the defaults plus the
+debuginfod extras.  The \-D option may be useful to tell debuginfod to
+execute the given bits of SQL after the basic schema creation
+commands.  For example, the "synchronous", "cache_size",
+"auto_vacuum", "threads", "journal_mode" pragmas may be fun to tweak
+via \-D, if you're searching for peak performance.  The "optimize",
+"wal_checkpoint" pragmas may be useful to run periodically, outside
+debuginfod.  The default settings are performance- rather than
+reliability-oriented, so a hardware crash might corrupt the database.
+In these cases, it may be necessary to manually delete the sqlite
+database and start over.
+
+As debuginfod changes in the future, we may have no choice but to
+change the database schema in an incompatible manner.  If this
+happens, new versions of debuginfod will issue SQL statements to
+\fIdrop\fP all prior schema & data, and start over.  So, disk space
+will not be wasted for retaining a no-longer-useable dataset.
+
+In summary, if your system can bear a 0.5%-3% index-to-RPM-dataset
+size ratio, and slow growth afterwards, you should not need to
+worry about disk space.  If a system crash corrupts the database,
+or you want to force debuginfod to reset and start over, simply
+erase the sqlite file before restarting debuginfod.
+
+
+.SH SECURITY
+
+debuginfod \fBdoes not\fP include any particular security features.
+While it is robust with respect to inputs, some abuse is possible.  It
+forks a new thread for each incoming HTTP request, which could lead to
+a denial-of-service in terms of RAM, CPU, disk I/O, or network I/O.
+If this is a problem, users are advised to install debuginfod with a
+HTTPS reverse-proxy front-end that enforces site policies for
+firewalling, authentication, integrity, authorization, and load
+control.  The \fI/metrics\fP webapi endpoint is probably not
+appropriate for disclosure to the public.
+
+When relaying queries to upstream debuginfods, debuginfod \fBdoes not\fP
+include any particular security features.  It trusts that the binaries
+returned by the debuginfods are accurate.  Therefore, the list of
+servers should include only trustworthy ones.  If accessed across HTTP
+rather than HTTPS, the network should be trustworthy.  Authentication
+information through the internal \fIlibcurl\fP library is not currently
+enabled.
+
+
+.SH "ENVIRONMENT VARIABLES"
+
+.TP 21
+.B DEBUGINFOD_URLS
+This environment variable contains a list of URL prefixes for trusted
+debuginfod instances.  Alternate URL prefixes are separated by space.
+Avoid referential loops that cause a server to contact itself, directly
+or indirectly - the results would be hilarious.
+
+.TP 21
+.B DEBUGINFOD_TIMEOUT
+This environment variable governs the timeout for each debuginfod HTTP
+connection.  A server that fails to respond within this many seconds
+is skipped.  The default is 5.
+
+.TP 21
+.B DEBUGINFOD_CACHE_PATH
+This environment variable governs the location of the cache where
+downloaded files are kept.  It is cleaned periodically as this
+program is reexecuted.  The default is $HOME/.debuginfod_client_cache.
+.\" XXX describe cache eviction policy
+
+.SH FILES
+.LP
+.PD .1v
+.TP 20
+.B $HOME/.debuginfod.sqlite
+Default database file.
+.PD
+
+.TP 20
+.B $HOME/.debuginfod_client_cache
+Default cache directory for content from upstream debuginfods.
+.PD
+
+
+.SH "SEE ALSO"
+.I "debuginfod-find(1)"
+.I "sqlite3(1)"
+.I \%https://prometheus.io/docs/instrumenting/exporters/
diff --git a/doc/debuginfod_begin.3 b/doc/debuginfod_begin.3
new file mode 100644
index 0000000..1627993
--- /dev/null
+++ b/doc/debuginfod_begin.3
@@ -0,0 +1 @@
+.so man3/debuginfod_find_debuginfo.3
diff --git a/doc/debuginfod_end.3 b/doc/debuginfod_end.3
new file mode 100644
index 0000000..1627993
--- /dev/null
+++ b/doc/debuginfod_end.3
@@ -0,0 +1 @@
+.so man3/debuginfod_find_debuginfo.3
diff --git a/doc/debuginfod_find_debuginfo.3 b/doc/debuginfod_find_debuginfo.3
new file mode 100644
index 0000000..be8eed0
--- /dev/null
+++ b/doc/debuginfod_find_debuginfo.3
@@ -0,0 +1,242 @@
+'\"! tbl | nroff \-man
+'\" t macro stdmacro
+
+.de SAMPLE
+.br
+.RS 0
+.nf
+.nh
+..
+.de ESAMPLE
+.hy
+.fi
+.RE
+..
+
+.TH DEBUGINFOD_FIND_* 3
+.SH NAME
+debuginfod_find_debuginfo \- request debuginfo from debuginfod
+
+.SH SYNOPSIS
+.nf
+.B #include <elfutils/debuginfod.h>
+.PP
+.BI "debuginfod_client *debuginfod_begin(void);"
+.BI "void debuginfod_end(debuginfod_client *" client ");"
+
+.BI "int debuginfod_find_debuginfo(debuginfod_client *" client ","
+.BI "                              const unsigned char *" build_id ","
+.BI "                              int " build_id_len ","
+.BI "                              char ** " path ");"
+.BI "int debuginfod_find_executable(debuginfod_client *" client ","
+.BI "                               const unsigned char *" build_id ","
+.BI "                               int " build_id_len ","
+.BI "                               char ** " path ");"
+.BI "int debuginfod_find_source(debuginfod_client *" client ","
+.BI "                           const unsigned char *" build_id ","
+.BI "                           int " build_id_len ","
+.BI "                           const char *" filename ","
+.BI "                           char ** " path ");"
+
+.BI "typedef int (*debuginfo_progressfn_t)(debuginfod_client *" client ","
+.BI "                                      long a, long b);"
+.BI "void debuginfod_set_progressfn(debuginfod_client *" client ","
+.BI "                               debuginfo_progressfn_t " progressfn ");"
+
+Link with \fB-ldebuginfod\fP.
+
+.SH DESCRIPTION
+
+.BR debuginfod_begin ()
+creates a \fBdebuginfod_client\fP connection handle that should be used
+with all other calls.
+.BR debuginfod_end ()
+should be called on the \fBclient\fP handle to release all state and
+storage when done.
+
+.BR debuginfod_find_debuginfo (),
+.BR debuginfod_find_executable (),
+and
+.BR debuginfod_find_source ()
+query the debuginfod server URLs contained in
+.BR $DEBUGINFOD_URLS
+(see below) for the debuginfo, executable or source file with the
+given \fIbuild_id\fP. \fIbuild_id\fP should be a pointer to either
+a null-terminated, lowercase hex string or a binary blob. If
+\fIbuild_id\fP is given as a hex string, \fIbuild_id_len\fP should
+be 0. Otherwise \fIbuild_id_len\fP should be the number of bytes in
+the binary blob.
+
+.BR debuginfod_find_source ()
+also requries a \fIfilename\fP in order to specify a particular
+source file. \fIfilename\fP should be an absolute path that includes
+the compilation directory of the CU associated with the source file.
+Relative path names commonly appear in the DWARF file's source directory,
+but these paths are relative to individual compilation unit AT_comp_dir
+paths, and yet an executable is made up of multiple CUs. Therefore, to
+disambiguate, debuginfod expects source queries to prefix relative path
+names with the CU compilation-directory, followed by a mandatory "/".
+
+Note: the caller should not elide \fB../\fP or \fB/./\fP or extraneous
+\fB///\fP sorts of path components in the directory names, because if
+this is how those names appear in the DWARF files, that is what
+debuginfod needs to see too.
+
+If \fIpath\fP is not NULL and the query is successful, \fIpath\fP is set
+to the path of the file in the cache. The caller must \fBfree\fP() this value.
+
+The URLs in \fB$DEBUGINFOD_URLS\fP may be queried in parallel. As soon
+as a debuginfod server begins transferring the target file all of the
+connections to the other servers are closed.
+
+A \fBclient\fP handle should be used from only one thread at a time.
+
+.SH "RETURN VALUE"
+
+\fBdebuginfod_begin\fP returns the \fBdebuginfod_client\fP handle to
+use with all other calls.  On error \fBNULL\fP will be returned and
+\fBerrno\fP will be set.
+
+If a find family function is successful, the resulting file is saved
+to the client cache and a file descriptor to that file is returned.
+The caller needs to \fBclose\fP() this descriptor.  Otherwise, a
+negative error code is returned.
+
+.SH "PROGRESS CALLBACK"
+
+As the \fBdebuginfod_find_*\fP() functions may block for seconds or
+longer, a progress callback function is called periodically, if
+configured with
+.BR debuginfod_set_progressfn ().
+This function sets a new progress callback function (or NULL) for the
+client handle.
+
+The given callback function is called from the context of each thread
+that is invoking any of the other lookup functions.  It is given two
+numeric parameters that, if thought of as a numerator \fIa\fP and
+denominator \fIb\fP, together represent a completion fraction
+\fIa/b\fP.  The denominator may be zero initially, until a quantity
+such as an exact download size becomes known.
+
+The progress callback function is also the supported way to
+\fIinterrupt\fP the download operation.  (The library does \fInot\fP
+modify or trigger signals.)  The progress callback must return 0 to
+continue the work, or any other value to stop work as soon as
+possible.  Consequently, the \fBdebuginfod_find_*\fP() function will
+likely return with an error, but might still succeed.
+
+
+.SH "CACHE"
+If the query is successful, the \fBdebuginfod_find_*\fP() functions save
+the target file to a local cache. The location of the cache is controlled
+by the \fB$DEBUGINFOD_CACHE_PATH\fP environment variable (see below).
+Cleaning of the cache is controlled by the \fIcache_clean_interval_s\fP
+and \fImax_unused_age_s\fP files, which are found in the
+\fB$DEBUGINFOD_CACHE_PATH\fP directory. \fIcache_clean_interval_s\fP controls
+how frequently the cache is traversed for cleaning and \fImax_unused_age_s\fP
+controls how long a file can go unused (fstat(2) atime) before it's
+removed from the cache during cleaning. These files should contain only an
+ASCII decimal integer representing the interval or max unused age in seconds.
+The default is one day and one week, respectively.  Values of zero mean "immediately".
+
+.SH "SECURITY"
+.BR debuginfod_find_debuginfo (),
+.BR debuginfod_find_executable (),
+and
+.BR debuginfod_find_source ()
+\fBdo not\fP include any particular security
+features.  They trust that the binaries returned by the debuginfod(s)
+are accurate.  Therefore, the list of servers should include only
+trustworthy ones.  If accessed across HTTP rather than HTTPS, the
+network should be trustworthy.  Passing user authentication information
+through the internal \fIlibcurl\fP library is not currently enabled, except
+for the basic plaintext \%\fIhttp[s]://userid:password@hostname/\fP style.
+(The debuginfod server does not perform authentication, but a front-end
+proxy server could.)
+
+.SH "ENVIRONMENT VARIABLES"
+
+.TP 21
+.B DEBUGINFOD_URLS
+This environment variable contains a list of URL prefixes for trusted
+debuginfod instances.  Alternate URL prefixes are separated by space.
+
+.TP 21
+.B DEBUGINFOD_TIMEOUT
+This environment variable governs the timeout for each debuginfod HTTP
+connection.  A server that fails to respond within this many seconds
+is skipped.  The default is 5.
+
+.TP 21
+.B DEBUGINFOD_CACHE_PATH
+This environment variable governs the location of the cache where
+downloaded files are kept.  It is cleaned periodically as this
+program is reexecuted.  The default is $HOME/.debuginfod_client_cache.
+
+.SH "ERRORS"
+The following list is not comprehensive. Error codes may also
+originate from calls to various C Library functions.
+
+.TP
+.BR EACCESS
+Denied access to resource located at the URL.
+
+.TP
+.BR ECONNREFUSED
+Unable to connect to remote host.
+
+.TP
+.BR ECONNRESET
+Unable to either send or recieve network data.
+
+.TP
+.BR EHOSTUNREACH
+Unable to resolve remote host.
+
+.TP
+.BR EINVAL
+One or more arguments are incorrectly formatted. \fIbuild_id\fP may
+be too long (greater than 256 characters), \fIfilename\fP may not
+be an absolute path or a debuginfod URL is malformed.
+
+.TP
+.BR EIO
+Unable to write data received from server to local file.
+
+.TP
+.BR EMLINK
+Too many HTTP redirects.
+
+.TP
+.BR ENETUNREACH
+Unable to initialize network connection.
+
+.TP
+.BR ENOENT
+Could not find the resource located at URL. Often this error code
+indicates that a debuginfod server was successfully contacted but
+the server could not find the target file.
+
+.TP
+.BR ENOMEM
+System is unable to allocate resources.
+
+.TP
+.BR ENOSYS
+\fB$DEBUGINFOD_URLS\fP is not defined.
+
+.TP
+.BR ETIME
+Query failed due to timeout. \fB$DEBUGINFOD_TIMEOUT\fP controls
+the timeout duration. See debuginfod(8) for more information.
+
+.SH "FILES"
+.LP
+.PD .1v
+.TP 20
+.B $HOME/.debuginfod_client_cache
+Default cache directory.
+.PD
+
+.SH "SEE ALSO"
+.I "debuginfod(8)"
diff --git a/doc/debuginfod_find_executable.3 b/doc/debuginfod_find_executable.3
new file mode 100644
index 0000000..1627993
--- /dev/null
+++ b/doc/debuginfod_find_executable.3
@@ -0,0 +1 @@
+.so man3/debuginfod_find_debuginfo.3
diff --git a/doc/debuginfod_find_source.3 b/doc/debuginfod_find_source.3
new file mode 100644
index 0000000..1627993
--- /dev/null
+++ b/doc/debuginfod_find_source.3
@@ -0,0 +1 @@
+.so man3/debuginfod_find_debuginfo.3
diff --git a/doc/debuginfod_set_progressfn.3 b/doc/debuginfod_set_progressfn.3
new file mode 100644
index 0000000..1627993
--- /dev/null
+++ b/doc/debuginfod_set_progressfn.3
@@ -0,0 +1 @@
+.so man3/debuginfod_find_debuginfo.3
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 3799c3a..51c7984 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,8 @@
+2019-08-25  Srđan Milaković  <sm108@rice.edu>
+
+	* dynamicsizehash_concurrent.{c,h}: New files.
+	* Makefile.am (noinst_HEADERS): Added dynamicsizehash_concurrent.h.
+
 2019-08-25  Jonathon Anderson  <jma14@rice.edu>
 
 	* stdatomic-fbsd.h: New file, taken from FreeBSD.
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 3086cf0..97bf732 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -39,8 +39,8 @@
 
 noinst_HEADERS = fixedsizehash.h libeu.h system.h dynamicsizehash.h list.h \
 		 eu-config.h color.h printversion.h bpf.h \
-		 atomics.h stdatomic-fbsd.h
-EXTRA_DIST = dynamicsizehash.c
+		 atomics.h stdatomic-fbsd.h dynamicsizehash_concurrent.h
+EXTRA_DIST = dynamicsizehash.c dynamicsizehash_concurrent.c
 
 if !GPROF
 xmalloc_CFLAGS = -ffunction-sections
diff --git a/lib/dynamicsizehash_concurrent.c b/lib/dynamicsizehash_concurrent.c
new file mode 100644
index 0000000..2d53bec
--- /dev/null
+++ b/lib/dynamicsizehash_concurrent.c
@@ -0,0 +1,482 @@
+/* Copyright (C) 2000-2019 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Srdan Milakovic <sm108@rice.edu>, 2019.
+   Derived from Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   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 <assert.h>
+#include <stdlib.h>
+#include <system.h>
+#include <pthread.h>
+
+/* Before including this file the following macros must be defined:
+
+   NAME      name of the hash table structure.
+   TYPE      data type of the hash table entries
+ */
+
+
+static size_t
+lookup (NAME *htab, HASHTYPE hval)
+{
+  /* First hash function: simply take the modul but prevent zero.  Small values
+      can skip the division, which helps performance when this is common.  */
+  size_t idx = 1 + (hval < htab->size ? hval : hval % htab->size);
+
+  HASHTYPE hash;
+
+  hash = atomic_load_explicit(&htab->table[idx].hashval,
+                              memory_order_acquire);
+  if (hash == hval)
+    return idx;
+  else if (hash == 0)
+    return 0;
+
+  /* Second hash function as suggested in [Knuth].  */
+  HASHTYPE second_hash = 1 + hval % (htab->size - 2);
+
+  for(;;)
+    {
+      if (idx <= second_hash)
+          idx = htab->size + idx - second_hash;
+      else
+          idx -= second_hash;
+
+      hash = atomic_load_explicit(&htab->table[idx].hashval,
+                                  memory_order_acquire);
+      if (hash == hval)
+	return idx;
+      else if (hash == 0)
+	return 0;
+    }
+}
+
+static int
+insert_helper (NAME *htab, HASHTYPE hval, TYPE val)
+{
+  /* First hash function: simply take the modul but prevent zero.  Small values
+      can skip the division, which helps performance when this is common.  */
+  size_t idx = 1 + (hval < htab->size ? hval : hval % htab->size);
+
+  TYPE val_ptr;
+  HASHTYPE hash;
+
+  hash = atomic_load_explicit(&htab->table[idx].hashval,
+                              memory_order_acquire);
+  if (hash == hval)
+    return -1;
+  else if (hash == 0)
+    {
+      val_ptr = NULL;
+      atomic_compare_exchange_strong_explicit(&htab->table[idx].val_ptr,
+                                              (uintptr_t *) &val_ptr,
+                                              (uintptr_t) val,
+                                              memory_order_acquire,
+                                              memory_order_acquire);
+
+      if (val_ptr == NULL)
+        {
+          atomic_store_explicit(&htab->table[idx].hashval, hval,
+                                memory_order_release);
+          return 0;
+        }
+      else
+        {
+          do
+            {
+              hash = atomic_load_explicit(&htab->table[idx].hashval,
+                                          memory_order_acquire);
+            }
+          while (hash == 0);
+          if (hash == hval)
+            return -1;
+        }
+    }
+
+  /* Second hash function as suggested in [Knuth].  */
+  HASHTYPE second_hash = 1 + hval % (htab->size - 2);
+
+  for(;;)
+    {
+      if (idx <= second_hash)
+          idx = htab->size + idx - second_hash;
+      else
+          idx -= second_hash;
+
+      hash = atomic_load_explicit(&htab->table[idx].hashval,
+                                  memory_order_acquire);
+      if (hash == hval)
+        return -1;
+      else if (hash == 0)
+        {
+          val_ptr = NULL;
+          atomic_compare_exchange_strong_explicit(&htab->table[idx].val_ptr,
+                                                  (uintptr_t *) &val_ptr,
+                                                  (uintptr_t) val,
+                                                  memory_order_acquire,
+                                                  memory_order_acquire);
+
+          if (val_ptr == NULL)
+            {
+              atomic_store_explicit(&htab->table[idx].hashval, hval,
+                                    memory_order_release);
+              return 0;
+            }
+          else
+            {
+              do
+                {
+                  hash = atomic_load_explicit(&htab->table[idx].hashval,
+                                              memory_order_acquire);
+                }
+              while (hash == 0);
+              if (hash == hval)
+                return -1;
+            }
+        }
+    }
+}
+
+#define NO_RESIZING 0u
+#define ALLOCATING_MEMORY 1u
+#define MOVING_DATA 3u
+#define CLEANING 2u
+
+#define STATE_BITS 2u
+#define STATE_INCREMENT (1u << STATE_BITS)
+#define STATE_MASK (STATE_INCREMENT - 1)
+#define GET_STATE(A) ((A) & STATE_MASK)
+
+#define IS_NO_RESIZE_OR_CLEANING(A) (((A) & 0x1u) == 0)
+
+#define GET_ACTIVE_WORKERS(A) ((A) >> STATE_BITS)
+
+#define INITIALIZATION_BLOCK_SIZE 256
+#define MOVE_BLOCK_SIZE 256
+#define CEIL(A, B) (((A) + (B) - 1) / (B))
+
+/* Initializes records and copies the data from the old table.
+   It can share work with other threads */
+static void resize_helper(NAME *htab, int blocking)
+{
+  size_t num_old_blocks = CEIL(htab->old_size, MOVE_BLOCK_SIZE);
+  size_t num_new_blocks = CEIL(htab->size, INITIALIZATION_BLOCK_SIZE);
+
+  size_t my_block;
+  size_t num_finished_blocks = 0;
+
+  while ((my_block = atomic_fetch_add_explicit(&htab->next_init_block, 1,
+                                                memory_order_acquire))
+                                                    < num_new_blocks)
+    {
+      size_t record_it = my_block * INITIALIZATION_BLOCK_SIZE;
+      size_t record_end = (my_block + 1) * INITIALIZATION_BLOCK_SIZE;
+      if (record_end > htab->size)
+          record_end = htab->size;
+
+      while (record_it++ != record_end)
+        {
+          atomic_init(&htab->table[record_it].hashval, (uintptr_t) NULL);
+          atomic_init(&htab->table[record_it].val_ptr, (uintptr_t) NULL);
+        }
+
+      num_finished_blocks++;
+    }
+
+  atomic_fetch_add_explicit(&htab->num_initialized_blocks,
+                            num_finished_blocks, memory_order_release);
+  while (atomic_load_explicit(&htab->num_initialized_blocks,
+                              memory_order_acquire) != num_new_blocks);
+
+  /* All block are initialized, start moving */
+  num_finished_blocks = 0;
+  while ((my_block = atomic_fetch_add_explicit(&htab->next_move_block, 1,
+                                                memory_order_acquire))
+                                                    < num_old_blocks)
+    {
+      size_t record_it = my_block * MOVE_BLOCK_SIZE;
+      size_t record_end = (my_block + 1) * MOVE_BLOCK_SIZE;
+      if (record_end > htab->old_size)
+          record_end = htab->old_size;
+
+      while (record_it++ != record_end)
+        {
+          TYPE val_ptr = (TYPE) atomic_load_explicit(
+              &htab->old_table[record_it].val_ptr,
+              memory_order_acquire);
+          if (val_ptr == NULL)
+              continue;
+
+          HASHTYPE hashval = atomic_load_explicit(
+              &htab->old_table[record_it].hashval,
+              memory_order_acquire);
+          assert(hashval);
+
+          insert_helper(htab, hashval, val_ptr);
+        }
+
+      num_finished_blocks++;
+    }
+
+  atomic_fetch_add_explicit(&htab->num_moved_blocks, num_finished_blocks,
+                            memory_order_release);
+
+  if (blocking)
+      while (atomic_load_explicit(&htab->num_moved_blocks,
+                                  memory_order_acquire) != num_old_blocks);
+}
+
+static void
+resize_master(NAME *htab)
+{
+  htab->old_size = htab->size;
+  htab->old_table = htab->table;
+
+  htab->size = next_prime(htab->size * 2);
+  htab->table = malloc((1 + htab->size) * sizeof(htab->table[0]));
+  assert(htab->table);
+
+  /* Change state from ALLOCATING_MEMORY to MOVING_DATA */
+  atomic_fetch_xor_explicit(&htab->resizing_state,
+                            ALLOCATING_MEMORY ^ MOVING_DATA,
+                            memory_order_release);
+
+  resize_helper(htab, 1);
+
+  /* Change state from MOVING_DATA to CLEANING */
+  size_t resize_state = atomic_fetch_xor_explicit(&htab->resizing_state,
+                                                  MOVING_DATA ^ CLEANING,
+                                                  memory_order_acq_rel);
+  while (GET_ACTIVE_WORKERS(resize_state) != 0)
+      resize_state = atomic_load_explicit(&htab->resizing_state,
+                                          memory_order_acquire);
+
+  /* There are no more active workers */
+  atomic_store_explicit(&htab->next_init_block, 0, memory_order_relaxed);
+  atomic_store_explicit(&htab->num_initialized_blocks, 0,
+                        memory_order_relaxed);
+
+  atomic_store_explicit(&htab->next_move_block, 0, memory_order_relaxed);
+  atomic_store_explicit(&htab->num_moved_blocks, 0, memory_order_relaxed);
+
+  free(htab->old_table);
+
+  /* Change state to NO_RESIZING */
+  atomic_fetch_xor_explicit(&htab->resizing_state, CLEANING ^ NO_RESIZING,
+                            memory_order_relaxed);
+
+}
+
+static void
+resize_worker(NAME *htab)
+{
+  size_t resize_state = atomic_load_explicit(&htab->resizing_state,
+                                              memory_order_acquire);
+
+  /* If the resize has finished */
+  if (IS_NO_RESIZE_OR_CLEANING(resize_state))
+      return;
+
+  /* Register as worker and check if the resize has finished in the meantime*/
+  resize_state = atomic_fetch_add_explicit(&htab->resizing_state,
+                                            STATE_INCREMENT,
+                                            memory_order_acquire);
+  if (IS_NO_RESIZE_OR_CLEANING(resize_state))
+    {
+      atomic_fetch_sub_explicit(&htab->resizing_state, STATE_INCREMENT,
+                                memory_order_relaxed);
+      return;
+    }
+
+  /* Wait while the new table is being allocated. */
+  while (GET_STATE(resize_state) == ALLOCATING_MEMORY)
+      resize_state = atomic_load_explicit(&htab->resizing_state,
+                                          memory_order_acquire);
+
+  /* Check if the resize is done */
+  assert(GET_STATE(resize_state) != NO_RESIZING);
+  if (GET_STATE(resize_state) == CLEANING)
+    {
+      atomic_fetch_sub_explicit(&htab->resizing_state, STATE_INCREMENT,
+                                memory_order_relaxed);
+      return;
+    }
+
+  resize_helper(htab, 0);
+
+  /* Deregister worker */
+  atomic_fetch_sub_explicit(&htab->resizing_state, STATE_INCREMENT,
+                            memory_order_release);
+}
+
+
+int
+#define INIT(name) _INIT (name)
+#define _INIT(name) \
+  name##_init
+INIT(NAME) (NAME *htab, size_t init_size)
+{
+  /* We need the size to be a prime.  */
+  init_size = next_prime (init_size);
+
+  /* Initialize the data structure.  */
+  htab->size = init_size;
+  atomic_init(&htab->filled, 0);
+  atomic_init(&htab->resizing_state, 0);
+
+  atomic_init(&htab->next_init_block, 0);
+  atomic_init(&htab->num_initialized_blocks, 0);
+
+  atomic_init(&htab->next_move_block, 0);
+  atomic_init(&htab->num_moved_blocks, 0);
+
+  pthread_rwlock_init(&htab->resize_rwl, NULL);
+
+  htab->table = (void *) malloc ((init_size + 1) * sizeof (htab->table[0]));
+  if (htab->table == NULL)
+      return -1;
+
+  for (size_t i = 0; i <= init_size; i++)
+    {
+      atomic_init(&htab->table[i].hashval, (uintptr_t) NULL);
+      atomic_init(&htab->table[i].val_ptr, (uintptr_t) NULL);
+    }
+
+  return 0;
+}
+
+
+int
+#define FREE(name) _FREE (name)
+#define _FREE(name) \
+name##_free
+FREE(NAME) (NAME *htab)
+{
+  pthread_rwlock_destroy(&htab->resize_rwl);
+  free (htab->table);
+  return 0;
+}
+
+
+int
+#define INSERT(name) _INSERT (name)
+#define _INSERT(name) \
+name##_insert
+INSERT(NAME) (NAME *htab, HASHTYPE hval, TYPE data)
+{
+  int incremented = 0;
+
+  for(;;)
+    {
+      while (pthread_rwlock_tryrdlock(&htab->resize_rwl) != 0)
+          resize_worker(htab);
+
+      size_t filled;
+      if (!incremented)
+        {
+          filled = atomic_fetch_add_explicit(&htab->filled, 1,
+                                              memory_order_acquire);
+          incremented = 1;
+        }
+      else
+        {
+          filled = atomic_load_explicit(&htab->filled,
+                                        memory_order_acquire);
+        }
+
+
+      if (100 * filled > 90 * htab->size)
+        {
+          /* Table is filled more than 90%.  Resize the table.  */
+
+          size_t resizing_state = atomic_load_explicit(&htab->resizing_state,
+                                                        memory_order_acquire);
+          if (resizing_state == 0 &&
+              atomic_compare_exchange_strong_explicit(&htab->resizing_state,
+                                                      &resizing_state,
+                                                      ALLOCATING_MEMORY,
+                                                      memory_order_acquire,
+                                                      memory_order_acquire))
+            {
+              /* Master thread */
+              pthread_rwlock_unlock(&htab->resize_rwl);
+
+              pthread_rwlock_wrlock(&htab->resize_rwl);
+              resize_master(htab);
+              pthread_rwlock_unlock(&htab->resize_rwl);
+
+            }
+          else
+            {
+              /* Worker thread */
+              pthread_rwlock_unlock(&htab->resize_rwl);
+              resize_worker(htab);
+            }
+        }
+      else
+        {
+          /* Lock acquired, no need for resize*/
+          break;
+        }
+    }
+
+  int ret_val = insert_helper(htab, hval, data);
+  if (ret_val == -1)
+      atomic_fetch_sub_explicit(&htab->filled, 1, memory_order_relaxed);
+  pthread_rwlock_unlock(&htab->resize_rwl);
+  return ret_val;
+}
+
+
+
+TYPE
+#define FIND(name) _FIND (name)
+#define _FIND(name) \
+  name##_find
+FIND(NAME) (NAME *htab, HASHTYPE hval)
+{
+  while (pthread_rwlock_tryrdlock(&htab->resize_rwl) != 0)
+      resize_worker(htab);
+
+  size_t idx;
+
+  /* Make the hash data nonzero.  */
+  hval = hval ?: 1;
+  idx = lookup(htab, hval);
+
+  if (idx == 0)
+    {
+      pthread_rwlock_unlock(&htab->resize_rwl);
+      return NULL;
+    }
+
+  /* get a copy before unlocking the lock */
+  TYPE ret_val = (TYPE) atomic_load_explicit(&htab->table[idx].val_ptr,
+                                             memory_order_relaxed);
+
+  pthread_rwlock_unlock(&htab->resize_rwl);
+  return ret_val;
+}
diff --git a/lib/dynamicsizehash_concurrent.h b/lib/dynamicsizehash_concurrent.h
new file mode 100644
index 0000000..73e66e9
--- /dev/null
+++ b/lib/dynamicsizehash_concurrent.h
@@ -0,0 +1,118 @@
+/* Copyright (C) 2000-2019 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Srdan Milakovic <sm108@rice.edu>, 2019.
+   Derived from Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   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 <stddef.h>
+#include <pthread.h>
+#include "atomics.h"
+/* Before including this file the following macros must be defined:
+
+   NAME      name of the hash table structure.
+   TYPE      data type of the hash table entries
+
+   The following macros if present select features:
+
+   ITERATE   iterating over the table entries is possible
+   HASHTYPE  integer type for hash values, default unsigned long int
+ */
+
+
+
+#ifndef HASHTYPE
+# define HASHTYPE unsigned long int
+#endif
+
+#ifndef RESIZE_BLOCK_SIZE
+# define RESIZE_BLOCK_SIZE 256
+#endif
+
+/* Defined separately.  */
+extern size_t next_prime (size_t seed);
+
+
+/* Table entry type.  */
+#define _DYNHASHCONENTTYPE(name)       \
+  typedef struct name##_ent         \
+  {                                 \
+    _Atomic(HASHTYPE) hashval;      \
+    atomic_uintptr_t val_ptr;       \
+  } name##_ent
+#define DYNHASHENTTYPE(name) _DYNHASHCONENTTYPE (name)
+DYNHASHENTTYPE (NAME);
+
+/* Type of the dynamic hash table data structure.  */
+#define _DYNHASHCONTYPE(name) \
+typedef struct                                     \
+{                                                  \
+  size_t size;                                     \
+  size_t old_size;                                 \
+  atomic_size_t filled;                            \
+  name##_ent *table;                               \
+  name##_ent *old_table;                           \
+  atomic_size_t resizing_state;                    \
+  atomic_size_t next_init_block;                   \
+  atomic_size_t num_initialized_blocks;            \
+  atomic_size_t next_move_block;                   \
+  atomic_size_t num_moved_blocks;                  \
+  pthread_rwlock_t resize_rwl;                     \
+} name
+#define DYNHASHTYPE(name) _DYNHASHCONTYPE (name)
+DYNHASHTYPE (NAME);
+
+
+
+#define _FUNCTIONS(name)                                            \
+/* Initialize the hash table.  */                                   \
+extern int name##_init (name *htab, size_t init_size);              \
+                                                                    \
+/* Free resources allocated for hash table.  */                     \
+extern int name##_free (name *htab);                                \
+                                                                    \
+/* Insert new entry.  */                                            \
+extern int name##_insert (name *htab, HASHTYPE hval, TYPE data);    \
+                                                                    \
+/* Find entry in hash table.  */                                    \
+extern TYPE name##_find (name *htab, HASHTYPE hval);
+#define FUNCTIONS(name) _FUNCTIONS (name)
+FUNCTIONS (NAME)
+
+
+#ifndef NO_UNDEF
+# undef DYNHASHENTTYPE
+# undef DYNHASHTYPE
+# undef FUNCTIONS
+# undef _FUNCTIONS
+# undef XFUNCTIONS
+# undef _XFUNCTIONS
+# undef NAME
+# undef TYPE
+# undef ITERATE
+# undef COMPARE
+# undef FIRST
+# undef NEXT
+#endif
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index b1f73bc..59f33f9 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,37 @@
+2019-10-28  Aaron Merey  <amerey@redhat.com>
+
+	* Makefile.am (libdw_so_LDLIBS): Add -ldl for libdebuginfod.so dlopen.
+
+2019-11-10  Mark Wielaard  <mark@klomp.org>
+
+	* libdwP.h (libdw_unalloc): New define.
+	(libdw_typed_unalloc): Likewise.
+	(__libdw_thread_tail): New function declaration.
+	* libdw_alloc.c (__libdw_thread_tail): New function.
+	* dwarf_getabbrev.c (__libdw_getabbrev): Call libdw_typed_unalloc
+	when reading invalid data or when hash collission detected.
+
+2019-10-28  Jonathon Anderson  <jma14@rice.edu>
+
+	* libdw_alloc.c: Added __libdw_alloc_tail.
+	(__libdw_allocate): Switch to use the mem_tails array.
+	* libdwP.h (Dwarf): Likewise.
+	* dwarf_begin_elf.c (dwarf_begin_elf): Support for above.
+	* dwarf_end.c (dwarf_end): Likewise.
+	* atomics.h: Add support for thread_local.
+
+2019-10-28  Mark Wielaard  <mark@klomp.org>
+
+	* dwarf_sig8_hash.h: Include libdw.h. Remove COMPARE. Include
+	dynamicsizehash_concurrent.h.
+	* dwarf_sig8_hash.c: Include dynamicsizehash_concurrent.c.
+	* dwarf_formref_die.c (dwarf_formref_die): Drop NULL argument to
+	Dwarf_Sig8_Hash_find.
+
+2019-08-26  Srđan Milaković  <sm108@rice.edu@rice.edu>
+
+	* dwarf_abbrev_hash.{c,h}: Use the *_concurrent hash table.
+
 2019-11-01  Jonathon Anderson  <jma14@rice.edu>
 
 	* dwarf_begin_elf.c (valid_p): Switch calloc for malloc for fake CUs.
diff --git a/libdw/Makefile.am b/libdw/Makefile.am
index ce793e9..33b5838 100644
--- a/libdw/Makefile.am
+++ b/libdw/Makefile.am
@@ -109,7 +109,7 @@
 		../libcpu/libcpu_pic.a libdw_pic.a ../libdwelf/libdwelf_pic.a \
 		../libdwfl/libdwfl_pic.a
 libdw_so_DEPS = ../lib/libeu.a ../libelf/libelf.so
-libdw_so_LDLIBS = $(libdw_so_DEPS) -lz $(argp_LDADD) $(zip_LIBS) -pthread
+libdw_so_LDLIBS = $(libdw_so_DEPS) -ldl -lz $(argp_LDADD) $(zip_LIBS) -pthread
 libdw_so_SOURCES =
 libdw.so$(EXEEXT): $(srcdir)/libdw.map $(libdw_so_LIBS) $(libdw_so_DEPS)
 	$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
diff --git a/libdw/dwarf_abbrev_hash.c b/libdw/dwarf_abbrev_hash.c
index f52f5ad..c254814 100644
--- a/libdw/dwarf_abbrev_hash.c
+++ b/libdw/dwarf_abbrev_hash.c
@@ -38,7 +38,7 @@
 #define next_prime __libdwarf_next_prime
 extern size_t next_prime (size_t) attribute_hidden;
 
-#include <dynamicsizehash.c>
+#include <dynamicsizehash_concurrent.c>
 
 #undef next_prime
 #define next_prime attribute_hidden __libdwarf_next_prime
diff --git a/libdw/dwarf_abbrev_hash.h b/libdw/dwarf_abbrev_hash.h
index d2f02cc..a368c59 100644
--- a/libdw/dwarf_abbrev_hash.h
+++ b/libdw/dwarf_abbrev_hash.h
@@ -32,8 +32,7 @@
 
 #define NAME Dwarf_Abbrev_Hash
 #define TYPE Dwarf_Abbrev *
-#define COMPARE(a, b) (0)
 
-#include <dynamicsizehash.h>
+#include <dynamicsizehash_concurrent.h>
 
 #endif	/* dwarf_abbrev_hash.h */
diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c
index 8c11684..8534308 100644
--- a/libdw/dwarf_begin_elf.c
+++ b/libdw/dwarf_begin_elf.c
@@ -430,13 +430,14 @@
      actual allocation.  */
   result->mem_default_size = mem_default_size;
   result->oom_handler = __libdw_oom;
-  if (pthread_key_create (&result->mem_key, NULL) != 0)
+  if (pthread_rwlock_init(&result->mem_rwl, NULL) != 0)
     {
       free (result);
-      __libdw_seterrno (DWARF_E_NOMEM); /* no memory or max pthread keys.  */
+      __libdw_seterrno (DWARF_E_NOMEM); /* no memory.  */
       return NULL;
     }
-  atomic_init (&result->mem_tail, (uintptr_t)NULL);
+  result->mem_stacks = 0;
+  result->mem_tails = NULL;
 
   if (cmd == DWARF_C_READ || cmd == DWARF_C_RDWR)
     {
diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c
index 7e194a5..77f537a 100644
--- a/libdw/dwarf_end.c
+++ b/libdw/dwarf_end.c
@@ -100,17 +100,19 @@
       tdestroy (dwarf->split_tree, noop_free);
 
       /* Free the internally allocated memory.  */
-      struct libdw_memblock *memp;
-      memp = (struct libdw_memblock *) (atomic_load_explicit
-					(&dwarf->mem_tail,
-					 memory_order_relaxed));
-      while (memp != NULL)
-	{
-	  struct libdw_memblock *prevp = memp->prev;
-	  free (memp);
-	  memp = prevp;
-	}
-      pthread_key_delete (dwarf->mem_key);
+      for (size_t i = 0; i < dwarf->mem_stacks; i++)
+        {
+          struct libdw_memblock *memp = dwarf->mem_tails[i];
+          while (memp != NULL)
+	    {
+	      struct libdw_memblock *prevp = memp->prev;
+	      free (memp);
+	      memp = prevp;
+	    }
+        }
+      if (dwarf->mem_tails != NULL)
+        free (dwarf->mem_tails);
+      pthread_rwlock_destroy (&dwarf->mem_rwl);
 
       /* Free the pubnames helper structure.  */
       free (dwarf->pubnames_sets);
diff --git a/libdw/dwarf_formref_die.c b/libdw/dwarf_formref_die.c
index f196331..48ba819 100644
--- a/libdw/dwarf_formref_die.c
+++ b/libdw/dwarf_formref_die.c
@@ -83,7 +83,7 @@
 	 have to match in the type unit headers.  */
 
       uint64_t sig = read_8ubyte_unaligned (cu->dbg, attr->valp);
-      cu = Dwarf_Sig8_Hash_find (&cu->dbg->sig8_hash, sig, NULL);
+      cu = Dwarf_Sig8_Hash_find (&cu->dbg->sig8_hash, sig);
       if (cu == NULL)
 	{
 	  /* Not seen before.  We have to scan through the type units.
diff --git a/libdw/dwarf_getabbrev.c b/libdw/dwarf_getabbrev.c
index 6a7e981..13bee49 100644
--- a/libdw/dwarf_getabbrev.c
+++ b/libdw/dwarf_getabbrev.c
@@ -83,7 +83,7 @@
   bool foundit = false;
   Dwarf_Abbrev *abb = NULL;
   if (cu == NULL
-      || (abb = Dwarf_Abbrev_Hash_find (&cu->abbrev_hash, code, NULL)) == NULL)
+      || (abb = Dwarf_Abbrev_Hash_find (&cu->abbrev_hash, code)) == NULL)
     {
       if (result == NULL)
 	abb = libdw_typed_alloc (dbg, Dwarf_Abbrev);
@@ -99,6 +99,8 @@
 	  /* A duplicate abbrev code at a different offset,
 	     that should never happen.  */
 	invalid:
+	  if (! foundit)
+	    libdw_typed_unalloc (dbg, Dwarf_Abbrev);
 	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
 	  return NULL;
 	}
@@ -148,7 +150,13 @@
 
   /* Add the entry to the hash table.  */
   if (cu != NULL && ! foundit)
-    (void) Dwarf_Abbrev_Hash_insert (&cu->abbrev_hash, abb->code, abb);
+    if (Dwarf_Abbrev_Hash_insert (&cu->abbrev_hash, abb->code, abb) == -1)
+      {
+	/* The entry was already in the table, remove the one we just
+	   created and get the one already inserted.  */
+	libdw_typed_unalloc (dbg, Dwarf_Abbrev);
+	abb = Dwarf_Abbrev_Hash_find (&cu->abbrev_hash, code);
+      }
 
  out:
   return abb;
diff --git a/libdw/dwarf_sig8_hash.c b/libdw/dwarf_sig8_hash.c
index 043cac7..777f9eb 100644
--- a/libdw/dwarf_sig8_hash.c
+++ b/libdw/dwarf_sig8_hash.c
@@ -38,4 +38,4 @@
 #define next_prime __libdwarf_next_prime
 extern size_t next_prime (size_t) attribute_hidden;
 
-#include <dynamicsizehash.c>
+#include <dynamicsizehash_concurrent.c>
diff --git a/libdw/dwarf_sig8_hash.h b/libdw/dwarf_sig8_hash.h
index 705ffbc..c399919 100644
--- a/libdw/dwarf_sig8_hash.h
+++ b/libdw/dwarf_sig8_hash.h
@@ -29,10 +29,15 @@
 #ifndef _DWARF_SIG8_HASH_H
 #define _DWARF_SIG8_HASH_H	1
 
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdw.h"
+
 #define NAME Dwarf_Sig8_Hash
 #define TYPE struct Dwarf_CU *
-#define COMPARE(a, b) (0)
 
-#include <dynamicsizehash.h>
+#include <dynamicsizehash_concurrent.h>
 
 #endif	/* dwarf_sig8_hash.h */
diff --git a/libdw/dwarf_tag.c b/libdw/dwarf_tag.c
index 331eaa0..d784970 100644
--- a/libdw/dwarf_tag.c
+++ b/libdw/dwarf_tag.c
@@ -45,7 +45,7 @@
     return DWARF_END_ABBREV;
 
   /* See whether the entry is already in the hash table.  */
-  abb = Dwarf_Abbrev_Hash_find (&cu->abbrev_hash, code, NULL);
+  abb = Dwarf_Abbrev_Hash_find (&cu->abbrev_hash, code);
   if (abb == NULL)
     while (cu->last_abbrev_offset != (size_t) -1l)
       {
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index ad2599e..36c2acd 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -149,17 +149,6 @@
 
 #include "dwarf_sig8_hash.h"
 
-/* Structure for internal memory handling.  This is basically a simplified
-   reimplementation of obstacks.  Unfortunately the standard obstack
-   implementation is not usable in libraries.  */
-struct libdw_memblock
-{
-  size_t size;
-  size_t remaining;
-  struct libdw_memblock *prev;
-  char mem[0];
-};
-
 /* This is the structure representing the debugging state.  */
 struct Dwarf
 {
@@ -231,11 +220,22 @@
   /* Similar for addrx/constx, which will come from .debug_addr section.  */
   struct Dwarf_CU *fake_addr_cu;
 
-  /* Internal memory handling.  Each thread allocates separately and only
-     allocates from its own blocks, while all the blocks are pushed atomically
-     onto a unified stack for easy deallocation.  */
-  pthread_key_t mem_key;
-  atomic_uintptr_t mem_tail;
+  /* Supporting lock for internal memory handling.  Ensures threads that have
+     an entry in the mem_tails array are not disturbed by new threads doing
+     allocations for this Dwarf.  */
+  pthread_rwlock_t mem_rwl;
+
+  /* Internal memory handling.  This is basically a simplified thread-local
+     reimplementation of obstacks.  Unfortunately the standard obstack
+     implementation is not usable in libraries.  */
+  size_t mem_stacks;
+  struct libdw_memblock
+  {
+    size_t size;
+    size_t remaining;
+    struct libdw_memblock *prev;
+    char mem[0];
+  } **mem_tails;
 
   /* Default size of allocated memory blocks.  */
   size_t mem_default_size;
@@ -578,34 +578,44 @@
 extern void __libdw_seterrno (int value) internal_function;
 
 
-/* Memory handling, the easy parts.  This macro does not do nor need to do any
-   locking for proper concurrent operation.  */
+/* Memory handling, the easy parts.  */
 #define libdw_alloc(dbg, type, tsize, cnt) \
-  ({ struct libdw_memblock *_tail = pthread_getspecific (dbg->mem_key);       \
-     size_t _req = (tsize) * (cnt);					      \
-     type *_result;							      \
-     if (unlikely (_tail == NULL))					      \
-       _result = (type *) __libdw_allocate (dbg, _req, __alignof (type));     \
+  ({ struct libdw_memblock *_tail = __libdw_alloc_tail(dbg);		      \
+     size_t _required = (tsize) * (cnt);				      \
+     type *_result = (type *) (_tail->mem + (_tail->size - _tail->remaining));\
+     size_t _padding = ((__alignof (type)				      \
+			 - ((uintptr_t) _result & (__alignof (type) - 1)))    \
+			& (__alignof (type) - 1));			      \
+     if (unlikely (_tail->remaining < _required + _padding))		      \
+       _result = (type *) __libdw_allocate (dbg, _required, __alignof (type));\
      else								      \
        {								      \
-	 _result = (type *) (_tail->mem + (_tail->size - _tail->remaining));  \
-	 size_t _padding = ((__alignof (type)				      \
-			    - ((uintptr_t) _result & (__alignof (type) - 1))) \
-			       & (__alignof (type) - 1));		      \
-	 if (unlikely (_tail->remaining < _req + _padding))		      \
-	   _result = (type *) __libdw_allocate (dbg, _req, __alignof (type)); \
-	 else								      \
-	   {								      \
-	     _req += _padding;						      \
-	     _result = (type *) ((char *) _result + _padding);		      \
-	     _tail->remaining -= _req;					      \
-	   }								      \
+	 _required += _padding;						      \
+	 _result = (type *) ((char *) _result + _padding);		      \
+	 _tail->remaining -= _required;					      \
        }								      \
      _result; })
 
 #define libdw_typed_alloc(dbg, type) \
   libdw_alloc (dbg, type, sizeof (type), 1)
 
+/* Can only be used to undo the last libdw_alloc.  */
+#define libdw_unalloc(dbg, type, tsize, cnt) \
+  ({ struct libdw_memblock *_tail = __libdw_thread_tail (dbg);		      \
+     size_t _required = (tsize) * (cnt);				      \
+     /* We cannot know the padding, it is lost.  */			      \
+     _tail->remaining += _required; })					      \
+
+#define libdw_typed_unalloc(dbg, type) \
+  libdw_unalloc (dbg, type, sizeof (type), 1)
+
+/* Callback to choose a thread-local memory allocation stack.  */
+extern struct libdw_memblock *__libdw_alloc_tail (Dwarf* dbg)
+     __nonnull_attribute__ (1);
+
+extern struct libdw_memblock *__libdw_thread_tail (Dwarf* dbg)
+     __nonnull_attribute__ (1);
+
 /* Callback to allocate more.  */
 extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align)
      __attribute__ ((__malloc__)) __nonnull_attribute__ (1);
diff --git a/libdw/libdw_alloc.c b/libdw/libdw_alloc.c
index f2e74d1..e0281a3 100644
--- a/libdw/libdw_alloc.c
+++ b/libdw/libdw_alloc.c
@@ -35,7 +35,79 @@
 #include <stdlib.h>
 #include "libdwP.h"
 #include "system.h"
+#include "atomics.h"
+#if USE_VG_ANNOTATIONS == 1
+#include <helgrind.h>
+#else
+#define ANNOTATE_HAPPENS_BEFORE(X)
+#define ANNOTATE_HAPPENS_AFTER(X)
+#endif
 
+#define THREAD_ID_UNSET ((size_t) -1)
+static __thread size_t thread_id = THREAD_ID_UNSET;
+static atomic_size_t next_id = ATOMIC_VAR_INIT(0);
+
+struct libdw_memblock *
+__libdw_alloc_tail (Dwarf *dbg)
+{
+  if (thread_id == THREAD_ID_UNSET)
+    thread_id = atomic_fetch_add (&next_id, 1);
+
+  pthread_rwlock_rdlock (&dbg->mem_rwl);
+  if (thread_id >= dbg->mem_stacks)
+    {
+      pthread_rwlock_unlock (&dbg->mem_rwl);
+      pthread_rwlock_wrlock (&dbg->mem_rwl);
+
+      /* Another thread may have already reallocated. In theory using an
+         atomic would be faster, but given that this only happens once per
+         thread per Dwarf, some minor slowdown should be fine.  */
+      if (thread_id >= dbg->mem_stacks)
+        {
+          dbg->mem_tails = realloc (dbg->mem_tails, (thread_id+1)
+                                    * sizeof (struct libdw_memblock *));
+          if (dbg->mem_tails == NULL)
+            {
+              pthread_rwlock_unlock (&dbg->mem_rwl);
+              dbg->oom_handler();
+            }
+          for (size_t i = dbg->mem_stacks; i <= thread_id; i++)
+            dbg->mem_tails[i] = NULL;
+          dbg->mem_stacks = thread_id + 1;
+          ANNOTATE_HAPPENS_BEFORE (&dbg->mem_tails);
+        }
+
+      pthread_rwlock_unlock (&dbg->mem_rwl);
+      pthread_rwlock_rdlock (&dbg->mem_rwl);
+    }
+
+  /* At this point, we have an entry in the tail array.  */
+  ANNOTATE_HAPPENS_AFTER (&dbg->mem_tails);
+  struct libdw_memblock *result = dbg->mem_tails[thread_id];
+  if (result == NULL)
+    {
+      result = malloc (dbg->mem_default_size);
+      result->size = dbg->mem_default_size
+                     - offsetof (struct libdw_memblock, mem);
+      result->remaining = result->size;
+      result->prev = NULL;
+      dbg->mem_tails[thread_id] = result;
+    }
+  pthread_rwlock_unlock (&dbg->mem_rwl);
+  return result;
+}
+
+/* Can only be called after a allocation for this thread has already
+   been done, to possibly undo it.  */
+struct libdw_memblock *
+__libdw_thread_tail (Dwarf *dbg)
+{
+  struct libdw_memblock *result;
+  pthread_rwlock_rdlock (&dbg->mem_rwl);
+  result = dbg->mem_tails[thread_id];
+  pthread_rwlock_unlock (&dbg->mem_rwl);
+  return result;
+}
 
 void *
 __libdw_allocate (Dwarf *dbg, size_t minsize, size_t align)
@@ -52,10 +124,10 @@
   newp->size = size - offsetof (struct libdw_memblock, mem);
   newp->remaining = (uintptr_t) newp + size - (result + minsize);
 
-  newp->prev = (struct libdw_memblock*)atomic_exchange_explicit(
-      &dbg->mem_tail, (uintptr_t)newp, memory_order_relaxed);
-  if (pthread_setspecific (dbg->mem_key, newp) != 0)
-    dbg->oom_handler ();
+  pthread_rwlock_rdlock (&dbg->mem_rwl);
+  newp->prev = dbg->mem_tails[thread_id];
+  dbg->mem_tails[thread_id] = newp;
+  pthread_rwlock_unlock (&dbg->mem_rwl);
 
   return (void *) result;
 }
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 07a1e8d..b822218 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,9 @@
+2019-10-28  Aaron Merey  <amerey@redhat.com>
+
+	* dwfl_build_id_find_elf.c (dwfl_build_id_find_elf): Call debuginfod
+	client functions via dlopen to look for elf/dwarf files as fallback.
+	* find-debuginfo.c (dwfl_standard_find_debuginfo): Ditto.
+
 2019-10-07  Omar Sandoval  <osandov@fb.com>
 
 	* dwfl_frame.c (dwfl_getthreads): Get rid of unnecessary
diff --git a/libdwfl/Makefile.am b/libdwfl/Makefile.am
index 89ca92e..47bd62a 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)/../libdwelf
+	   -I$(srcdir)/../libdw -I$(srcdir)/../libdwelf -I$(srcdir)/../debuginfod
 VERSION = 1
 
 noinst_LIBRARIES = libdwfl.a
@@ -39,6 +39,7 @@
 
 pkginclude_HEADERS = libdwfl.h
 
+
 libdwfl_a_SOURCES = dwfl_begin.c dwfl_end.c dwfl_error.c dwfl_version.c \
 		    dwfl_module.c dwfl_report_elf.c relocate.c \
 		    dwfl_module_build_id.c dwfl_module_report_build_id.c \
@@ -69,7 +70,7 @@
 		    link_map.c core-file.c open.c image-header.c \
 		    dwfl_frame.c frame_unwind.c dwfl_frame_pc.c \
 		    linux-pid-attach.c linux-core-attach.c dwfl_frame_regs.c \
-		    gzip.c
+		    gzip.c debuginfod-client.c
 
 if BZLIB
 libdwfl_a_SOURCES += bzip2.c
diff --git a/libdwfl/debuginfod-client.c b/libdwfl/debuginfod-client.c
new file mode 100644
index 0000000..ee604ad
--- /dev/null
+++ b/libdwfl/debuginfod-client.c
@@ -0,0 +1,131 @@
+/* Try to get an ELF or debug file through the debuginfod.
+   Copyright (C) 2019 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 "libdwflP.h"
+#include <dlfcn.h>
+
+static __typeof__ (debuginfod_begin) *fp_debuginfod_begin;
+static __typeof__ (debuginfod_find_executable) *fp_debuginfod_find_executable;
+static __typeof__ (debuginfod_find_debuginfo) *fp_debuginfod_find_debuginfo;
+static __typeof__ (debuginfod_end) *fp_debuginfod_end;
+
+/* NB: this is slightly thread-unsafe */
+
+static debuginfod_client *
+get_client (Dwfl *dwfl)
+{
+  if (dwfl->debuginfod != NULL)
+    return dwfl->debuginfod;
+
+  if (fp_debuginfod_begin != NULL)
+    {
+      dwfl->debuginfod = (*fp_debuginfod_begin) ();
+      return dwfl->debuginfod;
+    }
+
+  return NULL;
+}
+
+int
+__libdwfl_debuginfod_find_executable (Dwfl *dwfl,
+				      const unsigned char *build_id_bits,
+				      size_t build_id_len)
+{
+  int fd = -1;
+  if (build_id_len > 0)
+    {
+      debuginfod_client *c = get_client (dwfl);
+      if (c != NULL)
+	fd = (*fp_debuginfod_find_executable) (c, build_id_bits,
+					       build_id_len, NULL);
+    }
+
+  return fd;
+}
+
+int
+__libdwfl_debuginfod_find_debuginfo (Dwfl *dwfl,
+				     const unsigned char *build_id_bits,
+				     size_t build_id_len)
+{
+  int fd = -1;
+  if (build_id_len > 0)
+    {
+      debuginfod_client *c = get_client (dwfl);
+      if (c != NULL)
+	fd = (*fp_debuginfod_find_debuginfo) (c, build_id_bits,
+					      build_id_len, NULL);
+    }
+
+  return fd;
+}
+
+void
+__libdwfl_debuginfod_end (debuginfod_client *c)
+{
+  if (c != NULL)
+    (*fp_debuginfod_end) (c);
+}
+
+/* Try to get the libdebuginfod library functions to make sure
+   everything is initialized early.  */
+void __attribute__ ((constructor))
+__libdwfl_debuginfod_init (void)
+{
+  void *debuginfod_so = dlopen("libdebuginfod-" VERSION ".so", RTLD_LAZY);
+
+  if (debuginfod_so == NULL)
+    debuginfod_so = dlopen("libdebuginfod.so", RTLD_LAZY);
+
+  if (debuginfod_so != NULL)
+    {
+      fp_debuginfod_begin = dlsym (debuginfod_so, "debuginfod_begin");
+      fp_debuginfod_find_executable = dlsym (debuginfod_so,
+					     "debuginfod_find_executable");
+      fp_debuginfod_find_debuginfo = dlsym (debuginfod_so,
+					    "debuginfod_find_debuginfo");
+      fp_debuginfod_end = dlsym (debuginfod_so, "debuginfod_end");
+
+      /* We either get them all, or we get none.  */
+      if (fp_debuginfod_begin == NULL
+	  || fp_debuginfod_find_executable == NULL
+	  || fp_debuginfod_find_debuginfo == NULL
+	  || fp_debuginfod_end == NULL)
+	{
+	  fp_debuginfod_begin = NULL;
+	  fp_debuginfod_find_executable = NULL;
+	  fp_debuginfod_find_debuginfo = NULL;
+	  fp_debuginfod_end = NULL;
+	  dlclose (debuginfod_so);
+	}
+    }
+}
diff --git a/libdwfl/dwfl_build_id_find_elf.c b/libdwfl/dwfl_build_id_find_elf.c
index cc6c3f6..4e56143 100644
--- a/libdwfl/dwfl_build_id_find_elf.c
+++ b/libdwfl/dwfl_build_id_find_elf.c
@@ -1,5 +1,5 @@
 /* Find an ELF file for a module from its build ID.
-   Copyright (C) 2007-2010, 2014, 2015 Red Hat, Inc.
+   Copyright (C) 2007-2010, 2014, 2015, 2019 Red Hat, Inc.
    This file is part of elfutils.
 
    This file is free software; you can redistribute it and/or modify
@@ -187,7 +187,17 @@
       free (*file_name);
       *file_name = NULL;
     }
-  else if (errno == 0 && mod->build_id_len > 0)
+  else
+    {
+      /* If all else fails and a build-id is available, query the
+	 debuginfo-server if enabled.  */
+      if (fd < 0 && mod->build_id_len > 0)
+	fd = __libdwfl_debuginfod_find_executable (mod->dwfl,
+						   mod->build_id_bits,
+						   mod->build_id_len);
+    }
+
+  if (fd < 0 && errno == 0 && mod->build_id_len > 0)
     /* Setting this with no file yet loaded is a marker that
        the build ID is authoritative even if we also know a
        putative *FILE_NAME.  */
diff --git a/libdwfl/dwfl_end.c b/libdwfl/dwfl_end.c
index 74ee9e0..4f6c722 100644
--- a/libdwfl/dwfl_end.c
+++ b/libdwfl/dwfl_end.c
@@ -39,6 +39,8 @@
   if (dwfl == NULL)
     return;
 
+  __libdwfl_debuginfod_end (dwfl->debuginfod);
+
   if (dwfl->process)
     __libdwfl_process_free (dwfl->process);
 
diff --git a/libdwfl/find-debuginfo.c b/libdwfl/find-debuginfo.c
index 9267788..4085764 100644
--- a/libdwfl/find-debuginfo.c
+++ b/libdwfl/find-debuginfo.c
@@ -1,5 +1,5 @@
 /* Standard find_debuginfo callback for libdwfl.
-   Copyright (C) 2005-2010, 2014, 2015 Red Hat, Inc.
+   Copyright (C) 2005-2010, 2014, 2015, 2019 Red Hat, Inc.
    This file is part of elfutils.
 
    This file is free software; you can redistribute it and/or modify
@@ -359,7 +359,8 @@
      other than just by finding nothing, that's all we do.  */
   const unsigned char *bits;
   GElf_Addr vaddr;
-  if (INTUSE(dwfl_module_build_id) (mod, &bits, &vaddr) > 0)
+  int bits_len;
+  if ((bits_len = INTUSE(dwfl_module_build_id) (mod, &bits, &vaddr)) > 0)
     {
       /* Dropping most arguments means we cannot rely on them in
 	 dwfl_build_id_find_debuginfo.  But leave it that way since
@@ -397,6 +398,9 @@
       free (canon);
     }
 
+  if (fd < 0 && bits_len > 0)
+    fd = __libdwfl_debuginfod_find_debuginfo (mod->dwfl, bits, bits_len);
+
   return fd;
 }
 INTDEF (dwfl_standard_find_debuginfo)
diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h
index 6b2d486..f631f94 100644
--- a/libdwfl/libdwflP.h
+++ b/libdwfl/libdwflP.h
@@ -40,6 +40,7 @@
 
 #include "../libdw/libdwP.h"	/* We need its INTDECLs.  */
 #include "../libdwelf/libdwelfP.h"
+#include "../debuginfod/debuginfod.h"
 
 typedef struct Dwfl_Process Dwfl_Process;
 
@@ -114,6 +115,7 @@
 struct Dwfl
 {
   const Dwfl_Callbacks *callbacks;
+  debuginfod_client *debuginfod;
 
   Dwfl_Module *modulelist;    /* List in order used by full traversals.  */
 
@@ -634,6 +636,19 @@
 extern bool __libdwfl_dynamic_vaddr_get (Elf *elf, GElf_Addr *vaddrp)
   internal_function;
 
+/* Internal interface to libdebuginfod (if installed).  */
+int
+__libdwfl_debuginfod_find_executable (Dwfl *dwfl,
+				      const unsigned char *build_id_bits,
+				      size_t build_id_len);
+int
+__libdwfl_debuginfod_find_debuginfo (Dwfl *dwfl,
+				     const unsigned char *build_id_bits,
+				     size_t build_id_len);
+void
+__libdwfl_debuginfod_end (debuginfod_client *c);
+
+
 /* These are working nicely for --core, but are not ready to be
    exported interfaces quite yet.  */
 
diff --git a/m4/ChangeLog b/m4/ChangeLog
index 9ee06d7..8ab0ff3 100644
--- a/m4/ChangeLog
+++ b/m4/ChangeLog
@@ -1,3 +1,7 @@
+2019-10-28  Aaron Merey  <amerey@redhat.com>
+
+	* ax_check_compile_flag.m4, ax_cxx_compile_stdcxx.m4: New files.
+
 2015-05-01  Mark Wielaard  <mjw@redhat.com>
 
 	* zip.m4: Explicitly set with_ to no, if not yes.
diff --git a/m4/Makefile.am b/m4/Makefile.am
index 3b0e114..ae7a565 100644
--- a/m4/Makefile.am
+++ b/m4/Makefile.am
@@ -18,4 +18,4 @@
 ##
 
 ##m4-files-begin
-EXTRA_DIST = codeset.m4 gettext.m4 iconv.m4 lcmessage.m4 progtest.m4 zip.m4
+EXTRA_DIST = codeset.m4 gettext.m4 iconv.m4 lcmessage.m4 progtest.m4 zip.m4 ax_check_compile_flag.m4 ax_cxx_compile_stdcxx.m4
diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4
new file mode 100644
index 0000000..ca36397
--- /dev/null
+++ b/m4/ax_check_compile_flag.m4
@@ -0,0 +1,74 @@
+# ===========================================================================
+#   http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
+#
+# DESCRIPTION
+#
+#   Check whether the given FLAG works with the current language's compiler
+#   or gives an error.  (Warnings, however, are ignored)
+#
+#   ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+#   success/failure.
+#
+#   If EXTRA-FLAGS is defined, it is added to the current language's default
+#   flags (e.g. CFLAGS) when the check is done.  The check is thus made with
+#   the flags: "CFLAGS EXTRA-FLAGS FLAG".  This can for example be used to
+#   force the compiler to issue an error when a bad flag is given.
+#
+#   INPUT gives an alternative input source to AC_COMPILE_IFELSE.
+#
+#   NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+#   macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+#   Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+#   This program 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.
+#
+#   This program 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/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 4
+
+AC_DEFUN([AX_CHECK_COMPILE_FLAG],
+[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
+AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
+  ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
+  _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
+  AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
+    [AS_VAR_SET(CACHEVAR,[yes])],
+    [AS_VAR_SET(CACHEVAR,[no])])
+  _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
+AS_VAR_IF(CACHEVAR,yes,
+  [m4_default([$2], :)],
+  [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_COMPILE_FLAGS
diff --git a/m4/ax_cxx_compile_stdcxx.m4 b/m4/ax_cxx_compile_stdcxx.m4
new file mode 100644
index 0000000..8adc765
--- /dev/null
+++ b/m4/ax_cxx_compile_stdcxx.m4
@@ -0,0 +1,556 @@
+# ===========================================================================
+#   http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
+#
+# DESCRIPTION
+#
+#   Check for baseline language coverage in the compiler for the specified
+#   version of the C++ standard.  If necessary, add switches to CXX to
+#   enable support.  VERSION may be '11' (for the C++11 standard) or '14'
+#   (for the C++14 standard).
+#
+#   The second argument, if specified, indicates whether you insist on an
+#   extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
+#   -std=c++11).  If neither is specified, you get whatever works, with
+#   preference for an extended mode.
+#
+#   The third argument, if specified 'mandatory' or if left unspecified,
+#   indicates that baseline support for the specified C++ standard is
+#   required and that the macro should error out if no mode with that
+#   support is found.  If specified 'optional', then configuration proceeds
+#   regardless, after defining HAVE_CXX${VERSION} if and only if a
+#   supporting mode is found.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
+#   Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
+#   Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
+#   Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
+#   Copyright (c) 2015 Paul Norman <penorman@mac.com>
+#   Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.  This file is offered as-is, without any
+#   warranty.
+
+#serial 3
+
+dnl  This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
+dnl  (serial version number 13).
+
+AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
+  m4_if([$1], [11], [],
+        [$1], [14], [],
+        [$1], [17], [m4_fatal([support for C++17 not yet implemented in AX_CXX_COMPILE_STDCXX])],
+        [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
+  m4_if([$2], [], [],
+        [$2], [ext], [],
+        [$2], [noext], [],
+        [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
+  m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
+        [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
+        [$3], [optional], [ax_cxx_compile_cxx$1_required=false],
+        [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
+  AC_LANG_PUSH([C++])dnl
+  ac_success=no
+  AC_CACHE_CHECK(whether $CXX supports C++$1 features by default,
+  ax_cv_cxx_compile_cxx$1,
+  [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
+    [ax_cv_cxx_compile_cxx$1=yes],
+    [ax_cv_cxx_compile_cxx$1=no])])
+  if test x$ax_cv_cxx_compile_cxx$1 = xyes; then
+    ac_success=yes
+  fi
+
+  m4_if([$2], [noext], [], [dnl
+  if test x$ac_success = xno; then
+    for switch in -std=gnu++$1 -std=gnu++0x; do
+      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
+      AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
+                     $cachevar,
+        [ac_save_CXX="$CXX"
+         CXX="$CXX $switch"
+         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
+          [eval $cachevar=yes],
+          [eval $cachevar=no])
+         CXX="$ac_save_CXX"])
+      if eval test x\$$cachevar = xyes; then
+        CXX="$CXX $switch"
+        ac_success=yes
+        break
+      fi
+    done
+  fi])
+
+  m4_if([$2], [ext], [], [dnl
+  if test x$ac_success = xno; then
+    dnl HP's aCC needs +std=c++11 according to:
+    dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
+    dnl Cray's crayCC needs "-h std=c++11"
+    for switch in -std=c++$1 -std=c++0x +std=c++$1 "-h std=c++$1"; do
+      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
+      AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
+                     $cachevar,
+        [ac_save_CXX="$CXX"
+         CXX="$CXX $switch"
+         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
+          [eval $cachevar=yes],
+          [eval $cachevar=no])
+         CXX="$ac_save_CXX"])
+      if eval test x\$$cachevar = xyes; then
+        CXX="$CXX $switch"
+        ac_success=yes
+        break
+      fi
+    done
+  fi])
+  AC_LANG_POP([C++])
+  if test x$ax_cxx_compile_cxx$1_required = xtrue; then
+    if test x$ac_success = xno; then
+      AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
+    fi
+  fi
+  if test x$ac_success = xno; then
+    HAVE_CXX$1=0
+    AC_MSG_NOTICE([No compiler with C++$1 support was found])
+  else
+    HAVE_CXX$1=1
+    AC_DEFINE(HAVE_CXX$1,1,
+              [define if the compiler supports basic C++$1 syntax])
+  fi
+  AC_SUBST(HAVE_CXX$1)
+])
+
+
+dnl  Test body for checking C++11 support
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
+  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
+)
+
+
+dnl  Test body for checking C++14 support
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
+  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
+  _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
+)
+
+
+dnl  Tests for new features in C++11
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
+
+// If the compiler admits that it is not ready for C++11, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201103L
+
+#error "This is not a C++11 compiler"
+
+#else
+
+namespace cxx11
+{
+
+  namespace test_static_assert
+  {
+
+    template <typename T>
+    struct check
+    {
+      static_assert(sizeof(int) <= sizeof(T), "not big enough");
+    };
+
+  }
+
+  namespace test_final_override
+  {
+
+    struct Base
+    {
+      virtual void f() {}
+    };
+
+    struct Derived : public Base
+    {
+      virtual void f() override {}
+    };
+
+  }
+
+  namespace test_double_right_angle_brackets
+  {
+
+    template < typename T >
+    struct check {};
+
+    typedef check<void> single_type;
+    typedef check<check<void>> double_type;
+    typedef check<check<check<void>>> triple_type;
+    typedef check<check<check<check<void>>>> quadruple_type;
+
+  }
+
+  namespace test_decltype
+  {
+
+    int
+    f()
+    {
+      int a = 1;
+      decltype(a) b = 2;
+      return a + b;
+    }
+
+  }
+
+  namespace test_type_deduction
+  {
+
+    template < typename T1, typename T2 >
+    struct is_same
+    {
+      static const bool value = false;
+    };
+
+    template < typename T >
+    struct is_same<T, T>
+    {
+      static const bool value = true;
+    };
+
+    template < typename T1, typename T2 >
+    auto
+    add(T1 a1, T2 a2) -> decltype(a1 + a2)
+    {
+      return a1 + a2;
+    }
+
+    int
+    test(const int c, volatile int v)
+    {
+      static_assert(is_same<int, decltype(0)>::value == true, "");
+      static_assert(is_same<int, decltype(c)>::value == false, "");
+      static_assert(is_same<int, decltype(v)>::value == false, "");
+      auto ac = c;
+      auto av = v;
+      auto sumi = ac + av + 'x';
+      auto sumf = ac + av + 1.0;
+      static_assert(is_same<int, decltype(ac)>::value == true, "");
+      static_assert(is_same<int, decltype(av)>::value == true, "");
+      static_assert(is_same<int, decltype(sumi)>::value == true, "");
+      static_assert(is_same<int, decltype(sumf)>::value == false, "");
+      static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
+      return (sumf > 0.0) ? sumi : add(c, v);
+    }
+
+  }
+
+  namespace test_noexcept
+  {
+
+    int f() { return 0; }
+    int g() noexcept { return 0; }
+
+    static_assert(noexcept(f()) == false, "");
+    static_assert(noexcept(g()) == true, "");
+
+  }
+
+  namespace test_constexpr
+  {
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
+    {
+      return *s ? strlen_c_r(s + 1, acc + 1) : acc;
+    }
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c(const CharT *const s) noexcept
+    {
+      return strlen_c_r(s, 0UL);
+    }
+
+    static_assert(strlen_c("") == 0UL, "");
+    static_assert(strlen_c("1") == 1UL, "");
+    static_assert(strlen_c("example") == 7UL, "");
+    static_assert(strlen_c("another\0example") == 7UL, "");
+
+  }
+
+  namespace test_rvalue_references
+  {
+
+    template < int N >
+    struct answer
+    {
+      static constexpr int value = N;
+    };
+
+    answer<1> f(int&)       { return answer<1>(); }
+    answer<2> f(const int&) { return answer<2>(); }
+    answer<3> f(int&&)      { return answer<3>(); }
+
+    void
+    test()
+    {
+      int i = 0;
+      const int c = 0;
+      static_assert(decltype(f(i))::value == 1, "");
+      static_assert(decltype(f(c))::value == 2, "");
+      static_assert(decltype(f(0))::value == 3, "");
+    }
+
+  }
+
+  namespace test_uniform_initialization
+  {
+
+    struct test
+    {
+      static const int zero {};
+      static const int one {1};
+    };
+
+    static_assert(test::zero == 0, "");
+    static_assert(test::one == 1, "");
+
+  }
+
+  namespace test_lambdas
+  {
+
+    void
+    test1()
+    {
+      auto lambda1 = [](){};
+      auto lambda2 = lambda1;
+      lambda1();
+      lambda2();
+    }
+
+    int
+    test2()
+    {
+      auto a = [](int i, int j){ return i + j; }(1, 2);
+      auto b = []() -> int { return '0'; }();
+      auto c = [=](){ return a + b; }();
+      auto d = [&](){ return c; }();
+      auto e = [a, &b](int x) mutable {
+        const auto identity = [](int y){ return y; };
+        for (auto i = 0; i < a; ++i)
+          a += b--;
+        return x + identity(a + b);
+      }(0);
+      return a + b + c + d + e;
+    }
+
+    int
+    test3()
+    {
+      const auto nullary = [](){ return 0; };
+      const auto unary = [](int x){ return x; };
+      using nullary_t = decltype(nullary);
+      using unary_t = decltype(unary);
+      const auto higher1st = [](nullary_t f){ return f(); };
+      const auto higher2nd = [unary](nullary_t f1){
+        return [unary, f1](unary_t f2){ return f2(unary(f1())); };
+      };
+      return higher1st(nullary) + higher2nd(nullary)(unary);
+    }
+
+  }
+
+  namespace test_variadic_templates
+  {
+
+    template <int...>
+    struct sum;
+
+    template <int N0, int... N1toN>
+    struct sum<N0, N1toN...>
+    {
+      static constexpr auto value = N0 + sum<N1toN...>::value;
+    };
+
+    template <>
+    struct sum<>
+    {
+      static constexpr auto value = 0;
+    };
+
+    static_assert(sum<>::value == 0, "");
+    static_assert(sum<1>::value == 1, "");
+    static_assert(sum<23>::value == 23, "");
+    static_assert(sum<1, 2>::value == 3, "");
+    static_assert(sum<5, 5, 11>::value == 21, "");
+    static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
+
+  }
+
+  // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
+  // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
+  // because of this.
+  namespace test_template_alias_sfinae
+  {
+
+    struct foo {};
+
+    template<typename T>
+    using member = typename T::member_type;
+
+    template<typename T>
+    void func(...) {}
+
+    template<typename T>
+    void func(member<T>*) {}
+
+    void test();
+
+    void test() { func<foo>(0); }
+
+  }
+
+}  // namespace cxx11
+
+#endif  // __cplusplus >= 201103L
+
+]])
+
+
+dnl  Tests for new features in C++14
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
+
+// If the compiler admits that it is not ready for C++14, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201402L
+
+#error "This is not a C++14 compiler"
+
+#else
+
+namespace cxx14
+{
+
+  namespace test_polymorphic_lambdas
+  {
+
+    int
+    test()
+    {
+      const auto lambda = [](auto&&... args){
+        const auto istiny = [](auto x){
+          return (sizeof(x) == 1UL) ? 1 : 0;
+        };
+        const int aretiny[] = { istiny(args)... };
+        return aretiny[0];
+      };
+      return lambda(1, 1L, 1.0f, '1');
+    }
+
+  }
+
+  namespace test_binary_literals
+  {
+
+    constexpr auto ivii = 0b0000000000101010;
+    static_assert(ivii == 42, "wrong value");
+
+  }
+
+  namespace test_generalized_constexpr
+  {
+
+    template < typename CharT >
+    constexpr unsigned long
+    strlen_c(const CharT *const s) noexcept
+    {
+      auto length = 0UL;
+      for (auto p = s; *p; ++p)
+        ++length;
+      return length;
+    }
+
+    static_assert(strlen_c("") == 0UL, "");
+    static_assert(strlen_c("x") == 1UL, "");
+    static_assert(strlen_c("test") == 4UL, "");
+    static_assert(strlen_c("another\0test") == 7UL, "");
+
+  }
+
+  namespace test_lambda_init_capture
+  {
+
+    int
+    test()
+    {
+      auto x = 0;
+      const auto lambda1 = [a = x](int b){ return a + b; };
+      const auto lambda2 = [a = lambda1(x)](){ return a; };
+      return lambda2();
+    }
+
+  }
+
+  namespace test_digit_seperators
+  {
+
+    constexpr auto ten_million = 100'000'000;
+    static_assert(ten_million == 100000000, "");
+
+  }
+
+  namespace test_return_type_deduction
+  {
+
+    auto f(int& x) { return x; }
+    decltype(auto) g(int& x) { return x; }
+
+    template < typename T1, typename T2 >
+    struct is_same
+    {
+      static constexpr auto value = false;
+    };
+
+    template < typename T >
+    struct is_same<T, T>
+    {
+      static constexpr auto value = true;
+    };
+
+    int
+    test()
+    {
+      auto x = 0;
+      static_assert(is_same<int, decltype(f(x))>::value, "");
+      static_assert(is_same<int&, decltype(g(x))>::value, "");
+      return x;
+    }
+
+  }
+
+}  // namespace cxx14
+
+#endif  // __cplusplus >= 201402L
+
+]])
diff --git a/po/ChangeLog b/po/ChangeLog
index 1d20239..884b166 100644
--- a/po/ChangeLog
+++ b/po/ChangeLog
@@ -1,3 +1,7 @@
+2019-11-26  Mark Wielaard  <mark@klomp.org>
+
+	* *.po: Update for 0.178.
+
 2019-08-13  Mark Wielaard  <mark@klomp.org>
 
 	* *.po: Update for 0.177.
diff --git a/po/de.po b/po/de.po
index 9772dac..a9b6897 100644
--- a/po/de.po
+++ b/po/de.po
@@ -11,7 +11,7 @@
 msgstr ""
 "Project-Id-Version: elfutils VERSION\n"
 "Report-Msgid-Bugs-To: https://sourceware.org/bugzilla/\n"
-"POT-Creation-Date: 2019-08-28 13:23+0200\n"
+"POT-Creation-Date: 2019-11-26 09:48+0100\n"
 "PO-Revision-Date: 2009-06-29 15:15+0200\n"
 "Last-Translator: Michael Münch <micm@fedoraproject.org>\n"
 "Language-Team: German\n"
@@ -27,7 +27,7 @@
 "colorize the output.  WHEN defaults to 'always' or can be 'auto' or 'never'"
 msgstr ""
 
-#: lib/color.c:127
+#: lib/color.c:129
 #, c-format
 msgid ""
 "%s: invalid argument '%s' for '--color'\n"
@@ -37,7 +37,7 @@
 "  - 'auto', 'tty', 'if-tty'\n"
 msgstr ""
 
-#: lib/color.c:190 src/objdump.c:726
+#: lib/color.c:194 src/objdump.c:728
 #, fuzzy, c-format
 msgid "cannot allocate memory"
 msgstr "konnte Verzeichnis nicht erstellen: %s"
@@ -54,18 +54,18 @@
 "GARANTIE,\n"
 "auch nicht für Marktgängigkeit oder Eignung für einen Bestimmten Zweck.\n"
 
-#: lib/xmalloc.c:52 lib/xmalloc.c:65 lib/xmalloc.c:77 src/readelf.c:3437
-#: src/readelf.c:11386 src/unstrip.c:2350 src/unstrip.c:2556
+#: lib/xmalloc.c:52 lib/xmalloc.c:65 lib/xmalloc.c:77 src/readelf.c:3449
+#: src/readelf.c:11398 src/unstrip.c:2393 src/unstrip.c:2599
 #, c-format
 msgid "memory exhausted"
 msgstr "Kein Speicher mehr verfügbar"
 
-#: libasm/asm_error.c:65 libdw/dwarf_error.c:57 libdwfl/libdwflP.h:50
+#: libasm/asm_error.c:65 libdw/dwarf_error.c:57 libdwfl/libdwflP.h:51
 #: libelf/elf_error.c:60
 msgid "no error"
 msgstr "kein Fehler"
 
-#: libasm/asm_error.c:66 libdw/dwarf_error.c:67 libdwfl/libdwflP.h:52
+#: libasm/asm_error.c:66 libdw/dwarf_error.c:67 libdwfl/libdwflP.h:53
 #: libelf/elf_error.c:91
 msgid "out of memory"
 msgstr "nicht genügend Speicher"
@@ -102,7 +102,7 @@
 msgid "no backend support available"
 msgstr "keine Backend-Unterstützung verfügbar"
 
-#: libasm/asm_error.c:83 libdw/dwarf_error.c:58 libdwfl/libdwflP.h:51
+#: libasm/asm_error.c:83 libdw/dwarf_error.c:58 libdwfl/libdwflP.h:52
 #: libelf/elf_error.c:63
 msgid "unknown error"
 msgstr "unbekannter Fehler"
@@ -218,7 +218,7 @@
 msgid "invalid directory index"
 msgstr "ungültiger Verzeichnisindex"
 
-#: libdw/dwarf_error.c:87 libdwfl/libdwflP.h:71
+#: libdw/dwarf_error.c:87 libdwfl/libdwflP.h:72
 msgid "address out of range"
 msgstr "Außerhalb des Adressbereiches"
 
@@ -249,7 +249,7 @@
 msgid "invalid address range index"
 msgstr "Ungültiger Adressbereichs Index"
 
-#: libdw/dwarf_error.c:94 libdwfl/libdwflP.h:72
+#: libdw/dwarf_error.c:94 libdwfl/libdwflP.h:73
 msgid "no matching address range"
 msgstr "Kein passender Adressbereich"
 
@@ -298,7 +298,7 @@
 msgid ".debug_addr section missing"
 msgstr ".debug_line Sektion fehlt"
 
-#: libdwfl/argp-std.c:50 src/stack.c:638 src/unstrip.c:2497
+#: libdwfl/argp-std.c:50 src/stack.c:638 src/unstrip.c:2540
 msgid "Input selection options:"
 msgstr "Eingabeauswahloptionen:"
 
@@ -363,165 +363,165 @@
 msgid "No modules recognized in core file"
 msgstr "Keine Module in der Kerndatei gefunden"
 
-#: libdwfl/libdwflP.h:53
+#: libdwfl/libdwflP.h:54
 msgid "See errno"
 msgstr ""
 
-#: libdwfl/libdwflP.h:54
+#: libdwfl/libdwflP.h:55
 msgid "See elf_errno"
 msgstr ""
 
-#: libdwfl/libdwflP.h:55
+#: libdwfl/libdwflP.h:56
 msgid "See dwarf_errno"
 msgstr ""
 
-#: libdwfl/libdwflP.h:56
+#: libdwfl/libdwflP.h:57
 msgid "See ebl_errno (XXX missing)"
 msgstr ""
 
-#: libdwfl/libdwflP.h:57
+#: libdwfl/libdwflP.h:58
 msgid "gzip decompression failed"
 msgstr ""
 
-#: libdwfl/libdwflP.h:58
+#: libdwfl/libdwflP.h:59
 msgid "bzip2 decompression failed"
 msgstr ""
 
-#: libdwfl/libdwflP.h:59
+#: libdwfl/libdwflP.h:60
 msgid "LZMA decompression failed"
 msgstr ""
 
-#: libdwfl/libdwflP.h:60
+#: libdwfl/libdwflP.h:61
 msgid "no support library found for machine"
 msgstr ""
 
-#: libdwfl/libdwflP.h:61
+#: libdwfl/libdwflP.h:62
 msgid "Callbacks missing for ET_REL file"
 msgstr ""
 
-#: libdwfl/libdwflP.h:62
+#: libdwfl/libdwflP.h:63
 msgid "Unsupported relocation type"
 msgstr ""
 
-#: libdwfl/libdwflP.h:63
+#: libdwfl/libdwflP.h:64
 msgid "r_offset is bogus"
 msgstr ""
 
-#: libdwfl/libdwflP.h:64 libelf/elf_error.c:115 libelf/elf_error.c:175
+#: libdwfl/libdwflP.h:65 libelf/elf_error.c:115 libelf/elf_error.c:175
 msgid "offset out of range"
 msgstr "Offset ausserhalb des Bereichs"
 
-#: libdwfl/libdwflP.h:65
+#: libdwfl/libdwflP.h:66
 #, fuzzy
 msgid "relocation refers to undefined symbol"
 msgstr "Zeige Grösse der definierten Symbole"
 
-#: libdwfl/libdwflP.h:66
+#: libdwfl/libdwflP.h:67
 msgid "Callback returned failure"
 msgstr ""
 
-#: libdwfl/libdwflP.h:67
+#: libdwfl/libdwflP.h:68
 #, fuzzy
 msgid "No DWARF information found"
 msgstr "keine DWARF Information"
 
-#: libdwfl/libdwflP.h:68
+#: libdwfl/libdwflP.h:69
 msgid "No symbol table found"
 msgstr ""
 
-#: libdwfl/libdwflP.h:69
+#: libdwfl/libdwflP.h:70
 #, fuzzy
 msgid "No ELF program headers"
 msgstr "Programm-Köpfe anzeigen"
 
-#: libdwfl/libdwflP.h:70
+#: libdwfl/libdwflP.h:71
 msgid "address range overlaps an existing module"
 msgstr ""
 
-#: libdwfl/libdwflP.h:73
+#: libdwfl/libdwflP.h:74
 msgid "image truncated"
 msgstr ""
 
-#: libdwfl/libdwflP.h:74
+#: libdwfl/libdwflP.h:75
 #, fuzzy
 msgid "ELF file opened"
 msgstr "keine ELF Datei"
 
-#: libdwfl/libdwflP.h:75
+#: libdwfl/libdwflP.h:76
 #, fuzzy
 msgid "not a valid ELF file"
 msgstr "Ungültige ELF Datei"
 
-#: libdwfl/libdwflP.h:76
+#: libdwfl/libdwflP.h:77
 #, fuzzy
 msgid "cannot handle DWARF type description"
 msgstr "konnte Elf-Deskriptor nicht erzeugen: %s"
 
-#: libdwfl/libdwflP.h:77
+#: libdwfl/libdwflP.h:78
 msgid "ELF file does not match build ID"
 msgstr ""
 
-#: libdwfl/libdwflP.h:78
+#: libdwfl/libdwflP.h:79
 #, fuzzy
 msgid "corrupt .gnu.prelink_undo section data"
 msgstr "konnte Abschnittsdaten nicht holen: %s"
 
-#: libdwfl/libdwflP.h:79
+#: libdwfl/libdwflP.h:80
 msgid "Internal error due to ebl"
 msgstr ""
 
-#: libdwfl/libdwflP.h:80
+#: libdwfl/libdwflP.h:81
 msgid "Missing data in core file"
 msgstr ""
 
-#: libdwfl/libdwflP.h:81
+#: libdwfl/libdwflP.h:82
 #, fuzzy
 msgid "Invalid register"
 msgstr "ungültiger Parameter"
 
-#: libdwfl/libdwflP.h:82
+#: libdwfl/libdwflP.h:83
 msgid "Error reading process memory"
 msgstr ""
 
-#: libdwfl/libdwflP.h:83
+#: libdwfl/libdwflP.h:84
 msgid "Couldn't find architecture of any ELF"
 msgstr ""
 
-#: libdwfl/libdwflP.h:84
+#: libdwfl/libdwflP.h:85
 msgid "Error parsing /proc filesystem"
 msgstr ""
 
-#: libdwfl/libdwflP.h:85
+#: libdwfl/libdwflP.h:86
 #, fuzzy
 msgid "Invalid DWARF"
 msgstr "DWARF ungültig"
 
-#: libdwfl/libdwflP.h:86
+#: libdwfl/libdwflP.h:87
 msgid "Unsupported DWARF"
 msgstr ""
 
-#: libdwfl/libdwflP.h:87
+#: libdwfl/libdwflP.h:88
 msgid "Unable to find more threads"
 msgstr ""
 
-#: libdwfl/libdwflP.h:88
+#: libdwfl/libdwflP.h:89
 msgid "Dwfl already has attached state"
 msgstr ""
 
-#: libdwfl/libdwflP.h:89
+#: libdwfl/libdwflP.h:90
 msgid "Dwfl has no attached state"
 msgstr ""
 
-#: libdwfl/libdwflP.h:90
+#: libdwfl/libdwflP.h:91
 msgid "Unwinding not supported for this architecture"
 msgstr ""
 
-#: libdwfl/libdwflP.h:91
+#: libdwfl/libdwflP.h:92
 #, fuzzy
 msgid "Invalid argument"
 msgstr "ungültiger Parameter"
 
-#: libdwfl/libdwflP.h:92
+#: libdwfl/libdwflP.h:93
 #, fuzzy
 msgid "Not an ET_CORE ELF file"
 msgstr "Ungültige ELF Datei"
@@ -627,7 +627,7 @@
 msgid "invalid size of destination operand"
 msgstr "ungültige Grösse des Ziel-Operanden"
 
-#: libelf/elf_error.c:87 src/readelf.c:6154
+#: libelf/elf_error.c:87 src/readelf.c:6166
 #, c-format
 msgid "invalid encoding"
 msgstr "ungültige Kodierung"
@@ -715,8 +715,8 @@
 msgid "invalid section header"
 msgstr "ungültiger Abschnitts-Header"
 
-#: libelf/elf_error.c:191 src/readelf.c:9902 src/readelf.c:10502
-#: src/readelf.c:10603 src/readelf.c:10785
+#: libelf/elf_error.c:191 src/readelf.c:9914 src/readelf.c:10514
+#: src/readelf.c:10615 src/readelf.c:10797
 #, c-format
 msgid "invalid data"
 msgstr "Ungültige Daten"
@@ -1375,7 +1375,7 @@
 
 #: src/elfcmp.c:734 src/findtextrel.c:205 src/nm.c:364 src/ranlib.c:141
 #: src/size.c:272 src/strings.c:185 src/strip.c:984 src/strip.c:1021
-#: src/unstrip.c:2146 src/unstrip.c:2175
+#: src/unstrip.c:2189 src/unstrip.c:2218
 #, c-format
 msgid "cannot open '%s'"
 msgstr "'%s' kann nicht geöffnet werden"
@@ -1468,7 +1468,7 @@
 msgstr "konnte Abschnittsdaten nicht holen: %s"
 
 #. Strings for arguments in help texts.
-#: src/elfcompress.c:1336 src/elflint.c:77 src/readelf.c:153
+#: src/elfcompress.c:1336 src/elflint.c:77 src/readelf.c:158
 msgid "FILE..."
 msgstr "DATEI..."
 
@@ -1499,14 +1499,14 @@
 msgid "Pedantic checking of ELF files compliance with gABI/psABI spec."
 msgstr ""
 
-#: src/elflint.c:154 src/readelf.c:360
-#, c-format
-msgid "cannot open input file"
+#: src/elflint.c:154 src/readelf.c:368
+#, fuzzy, c-format
+msgid "cannot open input file '%s'"
 msgstr "Kann Eingabedatei nicht öffnen"
 
 #: src/elflint.c:161
-#, c-format
-msgid "cannot generate Elf descriptor: %s\n"
+#, fuzzy, c-format
+msgid "cannot generate Elf descriptor for '%s': %s\n"
 msgstr "kann Elf-Deskriptor nicht erzeugen: %s\n"
 
 #: src/elflint.c:180
@@ -1518,7 +1518,7 @@
 msgid "No errors"
 msgstr "Keine Fehler"
 
-#: src/elflint.c:219 src/readelf.c:563
+#: src/elflint.c:219 src/readelf.c:575
 msgid "Missing file name.\n"
 msgstr "Dateiname fehlt.\n"
 
@@ -3474,12 +3474,12 @@
 msgid "cannot create search tree"
 msgstr "Kann Suchbaum nicht erstellen"
 
-#: src/nm.c:746 src/nm.c:1205 src/objdump.c:777 src/readelf.c:623
-#: src/readelf.c:1435 src/readelf.c:1586 src/readelf.c:1787 src/readelf.c:1993
-#: src/readelf.c:2183 src/readelf.c:2361 src/readelf.c:2437 src/readelf.c:2695
-#: src/readelf.c:2771 src/readelf.c:2858 src/readelf.c:3456 src/readelf.c:3506
-#: src/readelf.c:3569 src/readelf.c:11218 src/readelf.c:12403
-#: src/readelf.c:12614 src/readelf.c:12682 src/size.c:398 src/size.c:470
+#: src/nm.c:746 src/nm.c:1205 src/objdump.c:779 src/readelf.c:635
+#: src/readelf.c:1447 src/readelf.c:1598 src/readelf.c:1799 src/readelf.c:2005
+#: src/readelf.c:2195 src/readelf.c:2373 src/readelf.c:2449 src/readelf.c:2707
+#: src/readelf.c:2783 src/readelf.c:2870 src/readelf.c:3468 src/readelf.c:3518
+#: src/readelf.c:3581 src/readelf.c:11230 src/readelf.c:12415
+#: src/readelf.c:12626 src/readelf.c:12695 src/size.c:398 src/size.c:470
 #: src/strip.c:1038
 #, c-format
 msgid "cannot get section header string table index"
@@ -3523,12 +3523,12 @@
 msgstr "%s: entry size in section `%s' is not what we expect"
 
 #. XXX Add machine specific object file types.
-#: src/nm.c:1526
+#: src/nm.c:1527
 #, c-format
 msgid "%s%s%s%s: Invalid operation"
 msgstr "%s%s%s%s: Ungültige Operation"
 
-#: src/nm.c:1583
+#: src/nm.c:1584
 #, c-format
 msgid "%s%s%s: no symbols"
 msgstr "%s%s%s: keine Symbole"
@@ -3563,7 +3563,7 @@
 msgid "Show information from FILEs (a.out by default)."
 msgstr ""
 
-#: src/objdump.c:218 src/readelf.c:568
+#: src/objdump.c:218 src/readelf.c:580
 msgid "No operation specified.\n"
 msgstr "Keine Operation angegeben.\n"
 
@@ -3572,11 +3572,11 @@
 msgid "while close `%s'"
 msgstr ""
 
-#: src/objdump.c:363 src/readelf.c:2088 src/readelf.c:2280
+#: src/objdump.c:363 src/readelf.c:2100 src/readelf.c:2292
 msgid "INVALID SYMBOL"
 msgstr ""
 
-#: src/objdump.c:378 src/readelf.c:2122 src/readelf.c:2316
+#: src/objdump.c:378 src/readelf.c:2134 src/readelf.c:2328
 msgid "INVALID SECTION"
 msgstr ""
 
@@ -3627,508 +3627,513 @@
 msgid "error while freeing sub-ELF descriptor: %s"
 msgstr ""
 
-#: src/readelf.c:94
+#: src/readelf.c:97
 #, fuzzy
 msgid "ELF input selection:"
 msgstr "Eingabeauswahloptionen:"
 
-#: src/readelf.c:96
+#: src/readelf.c:99
 msgid ""
 "Use the named SECTION (default .gnu_debugdata) as (compressed) ELF input data"
 msgstr ""
 
-#: src/readelf.c:99
+#: src/readelf.c:102
 msgid ""
 "Used with -w to find the skeleton Compile Units in FILE associated with the "
 "Split Compile units in a .dwo input file"
 msgstr ""
 
-#: src/readelf.c:101
+#: src/readelf.c:104
 #, fuzzy
 msgid "ELF output selection:"
 msgstr "Eingabeauswahloptionen:"
 
-#: src/readelf.c:103
+#: src/readelf.c:106
 msgid "All these plus -p .strtab -p .dynstr -p .comment"
 msgstr ""
 
-#: src/readelf.c:104
+#: src/readelf.c:107
 msgid "Display the dynamic segment"
 msgstr ""
 
-#: src/readelf.c:105
+#: src/readelf.c:108
 msgid "Display the ELF file header"
 msgstr ""
 
-#: src/readelf.c:107
+#: src/readelf.c:110
 msgid "Display histogram of bucket list lengths"
 msgstr ""
 
-#: src/readelf.c:108
+#: src/readelf.c:111
 msgid "Display the program headers"
 msgstr "Programm-Köpfe anzeigen"
 
-#: src/readelf.c:110
+#: src/readelf.c:113
 msgid "Display relocations"
 msgstr "Relocations anzeigen"
 
-#: src/readelf.c:111
+#: src/readelf.c:114
 #, fuzzy
 msgid "Display the section groups"
 msgstr "Programm-Köpfe anzeigen"
 
-#: src/readelf.c:112
+#: src/readelf.c:115
 #, fuzzy
 msgid "Display the sections' headers"
 msgstr "Programm-Köpfe anzeigen"
 
-#: src/readelf.c:115
+#: src/readelf.c:118
 #, fuzzy
 msgid "Display the symbol table sections"
 msgstr "Symboltabelle anzeigen"
 
-#: src/readelf.c:116
+#: src/readelf.c:120
+#, fuzzy
+msgid "Display (only) the dynamic symbol table"
+msgstr "Zeige nur externe Symbole"
+
+#: src/readelf.c:121
 msgid "Display versioning information"
 msgstr "Versionierungsinformationen anzeigen"
 
-#: src/readelf.c:117
+#: src/readelf.c:122
 #, fuzzy
 msgid "Display the ELF notes"
 msgstr "Kernnotizen anzeigen"
 
-#: src/readelf.c:119
+#: src/readelf.c:124
 #, fuzzy
 msgid "Display architecture specific information, if any"
 msgstr "Architekturspezifische Informationen anzeigen (falls vorhanden)"
 
-#: src/readelf.c:121
+#: src/readelf.c:126
 msgid "Display sections for exception handling"
 msgstr "Abschnitte für Ausnahmebehandlung anzeigen"
 
-#: src/readelf.c:123
+#: src/readelf.c:128
 msgid "Additional output selection:"
 msgstr ""
 
-#: src/readelf.c:125
+#: src/readelf.c:130
 msgid ""
 "Display DWARF section content.  SECTION can be one of abbrev, addr, aranges, "
 "decodedaranges, frame, gdb_index, info, info+, loc, line, decodedline, "
 "ranges, pubnames, str, macinfo, macro or exception"
 msgstr ""
 
-#: src/readelf.c:129
+#: src/readelf.c:134
 msgid "Dump the uninterpreted contents of SECTION, by number or name"
 msgstr ""
 
-#: src/readelf.c:131
+#: src/readelf.c:136
 msgid "Print string contents of sections"
 msgstr ""
 
-#: src/readelf.c:134
+#: src/readelf.c:139
 msgid "Display the symbol index of an archive"
 msgstr "Symbolindex des Archivs anzeigen"
 
-#: src/readelf.c:136
+#: src/readelf.c:141
 msgid "Output control:"
 msgstr "Ausgabekontrolle:"
 
-#: src/readelf.c:138
+#: src/readelf.c:143
 msgid "Do not find symbol names for addresses in DWARF data"
 msgstr "Keine symbolischen Namen für Adressen in DWARF-Daten suchen"
 
-#: src/readelf.c:140
+#: src/readelf.c:145
 #, fuzzy
 msgid ""
 "Display just offsets instead of resolving values to addresses in DWARF data"
 msgstr "Keine symbolischen Namen für Adressen in DWARF-Daten suchen"
 
-#: src/readelf.c:142
+#: src/readelf.c:147
 msgid "Ignored for compatibility (lines always wide)"
 msgstr ""
 
-#: src/readelf.c:144
+#: src/readelf.c:149
 msgid ""
 "Show compression information for compressed sections (when used with -S); "
 "decompress section before dumping data (when used with -p or -x)"
 msgstr ""
 
 #. Short description of program.
-#: src/readelf.c:149
+#: src/readelf.c:154
 msgid "Print information from ELF file in human-readable form."
 msgstr "Informationen aus der ELF-Datei in menschenlesbarer Form ausgeben."
 
 #. Look up once.
-#: src/readelf.c:342
+#: src/readelf.c:350
 msgid "yes"
 msgstr "ja"
 
-#: src/readelf.c:343
+#: src/readelf.c:351
 msgid "no"
 msgstr "nein"
 
-#: src/readelf.c:536
+#: src/readelf.c:548
 #, c-format
 msgid "Unknown DWARF debug section `%s'.\n"
 msgstr ""
 
-#: src/readelf.c:607 src/readelf.c:718
+#: src/readelf.c:619 src/readelf.c:730
 #, c-format
 msgid "cannot generate Elf descriptor: %s"
 msgstr "konnte Elf-Deskriptor nicht erzeugen: %s"
 
-#: src/readelf.c:614 src/readelf.c:941 src/strip.c:1133
+#: src/readelf.c:626 src/readelf.c:953 src/strip.c:1133
 #, c-format
 msgid "cannot determine number of sections: %s"
 msgstr ""
 
-#: src/readelf.c:632 src/readelf.c:1251 src/readelf.c:1459
+#: src/readelf.c:644 src/readelf.c:1263 src/readelf.c:1471
 #, c-format
 msgid "cannot get section: %s"
 msgstr ""
 
-#: src/readelf.c:641 src/readelf.c:1258 src/readelf.c:1467 src/readelf.c:12634
-#: src/unstrip.c:395 src/unstrip.c:426 src/unstrip.c:481 src/unstrip.c:600
-#: src/unstrip.c:621 src/unstrip.c:661 src/unstrip.c:873 src/unstrip.c:1204
-#: src/unstrip.c:1331 src/unstrip.c:1355 src/unstrip.c:1398 src/unstrip.c:1462
-#: src/unstrip.c:1636 src/unstrip.c:1770 src/unstrip.c:1913 src/unstrip.c:2008
+#: src/readelf.c:653 src/readelf.c:1270 src/readelf.c:1479 src/readelf.c:12646
+#: src/unstrip.c:395 src/unstrip.c:426 src/unstrip.c:485 src/unstrip.c:604
+#: src/unstrip.c:625 src/unstrip.c:665 src/unstrip.c:881 src/unstrip.c:1212
+#: src/unstrip.c:1339 src/unstrip.c:1363 src/unstrip.c:1419 src/unstrip.c:1483
+#: src/unstrip.c:1658 src/unstrip.c:1809 src/unstrip.c:1952 src/unstrip.c:2051
 #, c-format
 msgid "cannot get section header: %s"
 msgstr ""
 
-#: src/readelf.c:649
+#: src/readelf.c:661
 #, fuzzy, c-format
 msgid "cannot get section name"
 msgstr "konnte Abschnittsdaten nicht holen: %s"
 
-#: src/readelf.c:658 src/readelf.c:6564 src/readelf.c:10490 src/readelf.c:10592
-#: src/readelf.c:10770
+#: src/readelf.c:670 src/readelf.c:6576 src/readelf.c:10502 src/readelf.c:10604
+#: src/readelf.c:10782
 #, c-format
 msgid "cannot get %s content: %s"
 msgstr ""
 
-#: src/readelf.c:674
+#: src/readelf.c:686
 #, fuzzy, c-format
 msgid "cannot create temp file '%s'"
 msgstr "neue Datei konnte nicht angelegt werden"
 
-#: src/readelf.c:683
+#: src/readelf.c:695
 #, fuzzy, c-format
 msgid "cannot write section data"
 msgstr "konnte Abschnittsdaten nicht holen: %s"
 
-#: src/readelf.c:689 src/readelf.c:706 src/readelf.c:735
+#: src/readelf.c:701 src/readelf.c:718 src/readelf.c:747
 #, c-format
 msgid "error while closing Elf descriptor: %s"
 msgstr ""
 
-#: src/readelf.c:696
+#: src/readelf.c:708
 #, fuzzy, c-format
 msgid "error while rewinding file descriptor"
 msgstr "Fehler beim Schliessen des Elf-Desktriptor: %s\n"
 
-#: src/readelf.c:730
+#: src/readelf.c:742
 #, c-format
 msgid "'%s' is not an archive, cannot print archive index"
 msgstr ""
 
-#: src/readelf.c:834
+#: src/readelf.c:846
 #, c-format
 msgid "cannot stat input file"
 msgstr ""
 
-#: src/readelf.c:836
+#: src/readelf.c:848
 #, c-format
 msgid "input file is empty"
 msgstr ""
 
-#: src/readelf.c:838
+#: src/readelf.c:850
 #, c-format
 msgid "failed reading '%s': %s"
 msgstr "Konnte '%s' nicht lesen: %s"
 
-#: src/readelf.c:867
+#: src/readelf.c:879
 #, fuzzy, c-format
 msgid "No such section '%s' in '%s'"
 msgstr "konnte Abschnittsdaten nicht holen: %s"
 
-#: src/readelf.c:926
+#: src/readelf.c:938
 #, c-format
 msgid "cannot read ELF header: %s"
 msgstr ""
 
-#: src/readelf.c:934
+#: src/readelf.c:946
 #, c-format
 msgid "cannot create EBL handle"
 msgstr ""
 
-#: src/readelf.c:947
+#: src/readelf.c:959
 #, fuzzy, c-format
 msgid "cannot determine number of program headers: %s"
 msgstr "konnte Programm-Kopf nicht erstellen: %s"
 
-#: src/readelf.c:979
+#: src/readelf.c:991
 #, fuzzy, c-format
 msgid "cannot read ELF: %s"
 msgstr "Konnte %s: %s nicht lesen"
 
-#: src/readelf.c:1040
+#: src/readelf.c:1052
 msgid "NONE (None)"
 msgstr ""
 
-#: src/readelf.c:1041
+#: src/readelf.c:1053
 msgid "REL (Relocatable file)"
 msgstr ""
 
-#: src/readelf.c:1042
+#: src/readelf.c:1054
 msgid "EXEC (Executable file)"
 msgstr ""
 
-#: src/readelf.c:1043
+#: src/readelf.c:1055
 msgid "DYN (Shared object file)"
 msgstr ""
 
-#: src/readelf.c:1044
+#: src/readelf.c:1056
 msgid "CORE (Core file)"
 msgstr ""
 
-#: src/readelf.c:1049
+#: src/readelf.c:1061
 #, c-format
 msgid "OS Specific: (%x)\n"
 msgstr ""
 
 #. && e_type <= ET_HIPROC always true
-#: src/readelf.c:1051
+#: src/readelf.c:1063
 #, c-format
 msgid "Processor Specific: (%x)\n"
 msgstr ""
 
-#: src/readelf.c:1061
+#: src/readelf.c:1073
 msgid ""
 "ELF Header:\n"
 "  Magic:  "
 msgstr ""
 
-#: src/readelf.c:1065
+#: src/readelf.c:1077
 #, c-format
 msgid ""
 "\n"
 "  Class:                             %s\n"
 msgstr ""
 
-#: src/readelf.c:1070
+#: src/readelf.c:1082
 #, fuzzy, c-format
 msgid "  Data:                              %s\n"
 msgstr "  Daten:                             %s\n"
 
-#: src/readelf.c:1076
+#: src/readelf.c:1088
 #, c-format
 msgid "  Ident Version:                     %hhd %s\n"
 msgstr ""
 
-#: src/readelf.c:1078 src/readelf.c:1100
+#: src/readelf.c:1090 src/readelf.c:1112
 msgid "(current)"
 msgstr "(aktuell)"
 
-#: src/readelf.c:1082
+#: src/readelf.c:1094
 #, c-format
 msgid "  OS/ABI:                            %s\n"
 msgstr ""
 
-#: src/readelf.c:1085
+#: src/readelf.c:1097
 #, c-format
 msgid "  ABI Version:                       %hhd\n"
 msgstr ""
 
-#: src/readelf.c:1088
+#: src/readelf.c:1100
 msgid "  Type:                              "
 msgstr "  Typ:                               "
 
-#: src/readelf.c:1093
+#: src/readelf.c:1105
 #, c-format
 msgid "  Machine:                           %s\n"
 msgstr ""
 
-#: src/readelf.c:1095
+#: src/readelf.c:1107
 #, fuzzy, c-format
 msgid "  Machine:                           <unknown>: 0x%x\n"
 msgstr "  Daten:                             %s\n"
 
-#: src/readelf.c:1098
+#: src/readelf.c:1110
 #, c-format
 msgid "  Version:                           %d %s\n"
 msgstr ""
 
-#: src/readelf.c:1102
+#: src/readelf.c:1114
 #, c-format
 msgid "  Entry point address:               %#<PRIx64>\n"
 msgstr ""
 
-#: src/readelf.c:1105
+#: src/readelf.c:1117
 #, c-format
 msgid "  Start of program headers:          %<PRId64> %s\n"
 msgstr ""
 
-#: src/readelf.c:1106 src/readelf.c:1109
+#: src/readelf.c:1118 src/readelf.c:1121
 msgid "(bytes into file)"
 msgstr ""
 
-#: src/readelf.c:1108
-#, c-format
-msgid "  Start of section headers:          %<PRId64> %s\n"
-msgstr ""
-
-#: src/readelf.c:1111
-#, c-format
-msgid "  Flags:                             %s\n"
-msgstr ""
-
-#: src/readelf.c:1114
-#, c-format
-msgid "  Size of this header:               %<PRId16> %s\n"
-msgstr ""
-
-#: src/readelf.c:1115 src/readelf.c:1118 src/readelf.c:1135
-msgid "(bytes)"
-msgstr "(Bytes)"
-
-#: src/readelf.c:1117
-#, c-format
-msgid "  Size of program header entries:    %<PRId16> %s\n"
-msgstr ""
-
 #: src/readelf.c:1120
 #, c-format
+msgid "  Start of section headers:          %<PRId64> %s\n"
+msgstr ""
+
+#: src/readelf.c:1123
+#, c-format
+msgid "  Flags:                             %s\n"
+msgstr ""
+
+#: src/readelf.c:1126
+#, c-format
+msgid "  Size of this header:               %<PRId16> %s\n"
+msgstr ""
+
+#: src/readelf.c:1127 src/readelf.c:1130 src/readelf.c:1147
+msgid "(bytes)"
+msgstr "(Bytes)"
+
+#: src/readelf.c:1129
+#, c-format
+msgid "  Size of program header entries:    %<PRId16> %s\n"
+msgstr ""
+
+#: src/readelf.c:1132
+#, c-format
 msgid "  Number of program headers entries: %<PRId16>"
 msgstr ""
 
-#: src/readelf.c:1127
+#: src/readelf.c:1139
 #, c-format
 msgid " (%<PRIu32> in [0].sh_info)"
 msgstr ""
 
-#: src/readelf.c:1130 src/readelf.c:1147 src/readelf.c:1161
+#: src/readelf.c:1142 src/readelf.c:1159 src/readelf.c:1173
 msgid " ([0] not available)"
 msgstr ""
 
-#: src/readelf.c:1134
+#: src/readelf.c:1146
 #, c-format
 msgid "  Size of section header entries:    %<PRId16> %s\n"
 msgstr ""
 
-#: src/readelf.c:1137
+#: src/readelf.c:1149
 #, c-format
 msgid "  Number of section headers entries: %<PRId16>"
 msgstr ""
 
-#: src/readelf.c:1144
+#: src/readelf.c:1156
 #, c-format
 msgid " (%<PRIu32> in [0].sh_size)"
 msgstr ""
 
 #. We managed to get the zeroth section.
-#: src/readelf.c:1157
+#: src/readelf.c:1169
 #, c-format
 msgid " (%<PRIu32> in [0].sh_link)"
 msgstr ""
 
-#: src/readelf.c:1165
+#: src/readelf.c:1177
 #, c-format
 msgid ""
 "  Section header string table index: XINDEX%s\n"
 "\n"
 msgstr ""
 
-#: src/readelf.c:1169
+#: src/readelf.c:1181
 #, c-format
 msgid ""
 "  Section header string table index: %<PRId16>\n"
 "\n"
 msgstr ""
 
-#: src/readelf.c:1216 src/readelf.c:1424
+#: src/readelf.c:1228 src/readelf.c:1436
 #, fuzzy, c-format
 msgid "cannot get number of sections: %s"
 msgstr "konnte Programm-Kopf nicht erstellen: %s"
 
-#: src/readelf.c:1219
+#: src/readelf.c:1231
 #, fuzzy, c-format
 msgid ""
 "There are %zd section headers, starting at offset %#<PRIx64>:\n"
 "\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:1228
+#: src/readelf.c:1240
 #, fuzzy, c-format
 msgid "cannot get section header string table index: %s"
 msgstr "konnte Abschnittsdaten nicht holen: %s"
 
-#: src/readelf.c:1231
+#: src/readelf.c:1243
 msgid "Section Headers:"
 msgstr ""
 
-#: src/readelf.c:1234
+#: src/readelf.c:1246
 msgid ""
 "[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk "
 "Inf Al"
 msgstr ""
 
-#: src/readelf.c:1236
+#: src/readelf.c:1248
 msgid ""
 "[Nr] Name                 Type         Addr             Off      Size     ES "
 "Flags Lk Inf Al"
 msgstr ""
 
-#: src/readelf.c:1241
+#: src/readelf.c:1253
 msgid "     [Compression  Size   Al]"
 msgstr ""
 
-#: src/readelf.c:1243
+#: src/readelf.c:1255
 msgid "     [Compression  Size     Al]"
 msgstr ""
 
-#: src/readelf.c:1319
+#: src/readelf.c:1331
 #, c-format
 msgid "bad compression header for section %zd: %s"
 msgstr ""
 
-#: src/readelf.c:1330
+#: src/readelf.c:1342
 #, c-format
 msgid "bad gnu compressed size for section %zd: %s"
 msgstr ""
 
-#: src/readelf.c:1348
+#: src/readelf.c:1360
 msgid "Program Headers:"
 msgstr "Programm-Köpfe:"
 
-#: src/readelf.c:1350
+#: src/readelf.c:1362
 msgid ""
 "  Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align"
 msgstr ""
 
-#: src/readelf.c:1353
+#: src/readelf.c:1365
 msgid ""
 "  Type           Offset   VirtAddr           PhysAddr           FileSiz  "
 "MemSiz   Flg Align"
 msgstr ""
 
-#: src/readelf.c:1410
+#: src/readelf.c:1422
 #, c-format
 msgid "\t[Requesting program interpreter: %s]\n"
 msgstr ""
 
-#: src/readelf.c:1437
+#: src/readelf.c:1449
 msgid ""
 "\n"
 " Section to Segment mapping:\n"
 "  Segment Sections..."
 msgstr ""
 
-#: src/readelf.c:1448 src/unstrip.c:2067 src/unstrip.c:2109 src/unstrip.c:2116
+#: src/readelf.c:1460 src/unstrip.c:2110 src/unstrip.c:2152 src/unstrip.c:2159
 #, c-format
 msgid "cannot get program header: %s"
 msgstr ""
 
-#: src/readelf.c:1594
+#: src/readelf.c:1606
 #, c-format
 msgid ""
 "\n"
@@ -4139,7 +4144,7 @@
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/readelf.c:1599
+#: src/readelf.c:1611
 #, c-format
 msgid ""
 "\n"
@@ -4150,31 +4155,31 @@
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/readelf.c:1607
+#: src/readelf.c:1619
 msgid "<INVALID SYMBOL>"
 msgstr ""
 
-#: src/readelf.c:1621
+#: src/readelf.c:1633
 msgid "<INVALID SECTION>"
 msgstr ""
 
-#: src/readelf.c:1644 src/readelf.c:2371 src/readelf.c:3472 src/readelf.c:12505
-#: src/readelf.c:12512 src/readelf.c:12556 src/readelf.c:12563
+#: src/readelf.c:1656 src/readelf.c:2383 src/readelf.c:3484 src/readelf.c:12517
+#: src/readelf.c:12524 src/readelf.c:12568 src/readelf.c:12575
 msgid "Couldn't uncompress section"
 msgstr ""
 
-#: src/readelf.c:1649 src/readelf.c:2376 src/readelf.c:3477
+#: src/readelf.c:1661 src/readelf.c:2388 src/readelf.c:3489
 #, fuzzy, c-format
 msgid "cannot get section [%zd] header: %s"
 msgstr "konnte Abschnittsdaten nicht holen: %s"
 
-#: src/readelf.c:1793 src/readelf.c:2443 src/readelf.c:2701 src/readelf.c:2777
-#: src/readelf.c:3081 src/readelf.c:3155 src/readelf.c:5352
+#: src/readelf.c:1805 src/readelf.c:2455 src/readelf.c:2713 src/readelf.c:2789
+#: src/readelf.c:3093 src/readelf.c:3167 src/readelf.c:5364
 #, fuzzy, c-format
 msgid "invalid sh_link value in section %zu"
 msgstr "ungültige .debug_line Sektion"
 
-#: src/readelf.c:1796
+#: src/readelf.c:1808
 #, c-format
 msgid ""
 "\n"
@@ -4187,43 +4192,43 @@
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/readelf.c:1806
+#: src/readelf.c:1818
 msgid "  Type              Value\n"
 msgstr ""
 
-#: src/readelf.c:1830
+#: src/readelf.c:1842
 #, c-format
 msgid "Shared library: [%s]\n"
 msgstr ""
 
-#: src/readelf.c:1835
+#: src/readelf.c:1847
 #, c-format
 msgid "Library soname: [%s]\n"
 msgstr ""
 
-#: src/readelf.c:1840
+#: src/readelf.c:1852
 #, c-format
 msgid "Library rpath: [%s]\n"
 msgstr ""
 
-#: src/readelf.c:1845
+#: src/readelf.c:1857
 #, c-format
 msgid "Library runpath: [%s]\n"
 msgstr ""
 
-#: src/readelf.c:1865
+#: src/readelf.c:1877
 #, c-format
 msgid "%<PRId64> (bytes)\n"
 msgstr ""
 
-#: src/readelf.c:1978 src/readelf.c:2168
+#: src/readelf.c:1990 src/readelf.c:2180
 #, c-format
 msgid ""
 "\n"
 "Invalid symbol table at offset %#0<PRIx64>\n"
 msgstr ""
 
-#: src/readelf.c:1996 src/readelf.c:2186
+#: src/readelf.c:2008 src/readelf.c:2198
 #, c-format
 msgid ""
 "\n"
@@ -4242,7 +4247,7 @@
 #. The .rela.dyn section does not refer to a specific section but
 #. instead of section index zero.  Do not try to print a section
 #. name.
-#: src/readelf.c:2011 src/readelf.c:2201
+#: src/readelf.c:2023 src/readelf.c:2213
 #, c-format
 msgid ""
 "\n"
@@ -4253,29 +4258,29 @@
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/readelf.c:2021
+#: src/readelf.c:2033
 msgid "  Offset      Type                 Value       Name\n"
 msgstr ""
 
-#: src/readelf.c:2023
+#: src/readelf.c:2035
 msgid "  Offset              Type                 Value               Name\n"
 msgstr ""
 
-#: src/readelf.c:2076 src/readelf.c:2087 src/readelf.c:2100 src/readelf.c:2121
-#: src/readelf.c:2133 src/readelf.c:2267 src/readelf.c:2279 src/readelf.c:2293
-#: src/readelf.c:2315 src/readelf.c:2328
+#: src/readelf.c:2088 src/readelf.c:2099 src/readelf.c:2112 src/readelf.c:2133
+#: src/readelf.c:2145 src/readelf.c:2279 src/readelf.c:2291 src/readelf.c:2305
+#: src/readelf.c:2327 src/readelf.c:2340
 msgid "<INVALID RELOC>"
 msgstr ""
 
-#: src/readelf.c:2211
+#: src/readelf.c:2223
 msgid "  Offset      Type            Value       Addend Name\n"
 msgstr ""
 
-#: src/readelf.c:2213
+#: src/readelf.c:2225
 msgid "  Offset              Type            Value               Addend Name\n"
 msgstr ""
 
-#: src/readelf.c:2451
+#: src/readelf.c:2463
 #, c-format
 msgid ""
 "\n"
@@ -4286,40 +4291,40 @@
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/readelf.c:2456
+#: src/readelf.c:2468
 #, c-format
 msgid " %lu local symbol  String table: [%2u] '%s'\n"
 msgid_plural " %lu local symbols  String table: [%2u] '%s'\n"
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/readelf.c:2464
+#: src/readelf.c:2476
 msgid "  Num:    Value   Size Type    Bind   Vis          Ndx Name\n"
 msgstr ""
 
-#: src/readelf.c:2466
+#: src/readelf.c:2478
 msgid "  Num:            Value   Size Type    Bind   Vis          Ndx Name\n"
 msgstr ""
 
-#: src/readelf.c:2486
+#: src/readelf.c:2498
 #, c-format
 msgid "%5u: %0*<PRIx64> %6<PRId64> %-7s %-6s %-9s %6s %s"
 msgstr ""
 
-#: src/readelf.c:2574
+#: src/readelf.c:2586
 #, c-format
 msgid "bad dynamic symbol"
 msgstr ""
 
-#: src/readelf.c:2656
+#: src/readelf.c:2668
 msgid "none"
 msgstr "keine"
 
-#: src/readelf.c:2673
+#: src/readelf.c:2685
 msgid "| <unknown>"
 msgstr "| <unbekannt>"
 
-#: src/readelf.c:2704
+#: src/readelf.c:2716
 #, c-format
 msgid ""
 "\n"
@@ -4332,17 +4337,17 @@
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/readelf.c:2725
+#: src/readelf.c:2737
 #, fuzzy, c-format
 msgid "  %#06x: Version: %hu  File: %s  Cnt: %hu\n"
 msgstr "  %#06x: Version: %hu  Datei: %s  Cnt: %hu\n"
 
-#: src/readelf.c:2738
+#: src/readelf.c:2750
 #, c-format
 msgid "  %#06x: Name: %s  Flags: %s  Version: %hu\n"
 msgstr "  %#06x: Name: %s  Flags: %s  Version: %hu\n"
 
-#: src/readelf.c:2781
+#: src/readelf.c:2793
 #, c-format
 msgid ""
 "\n"
@@ -4355,18 +4360,18 @@
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/readelf.c:2809
+#: src/readelf.c:2821
 #, c-format
 msgid "  %#06x: Version: %hd  Flags: %s  Index: %hd  Cnt: %hd  Name: %s\n"
 msgstr ""
 
-#: src/readelf.c:2824
+#: src/readelf.c:2836
 #, c-format
 msgid "  %#06x: Parent %d: %s\n"
 msgstr ""
 
 #. Print the header.
-#: src/readelf.c:3085
+#: src/readelf.c:3097
 #, c-format
 msgid ""
 "\n"
@@ -4379,15 +4384,15 @@
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/readelf.c:3113
+#: src/readelf.c:3125
 msgid "   0 *local*                     "
 msgstr "   0 *lokal*                     "
 
-#: src/readelf.c:3118
+#: src/readelf.c:3130
 msgid "   1 *global*                    "
 msgstr "   1 *global*                    "
 
-#: src/readelf.c:3160
+#: src/readelf.c:3172
 #, c-format
 msgid ""
 "\n"
@@ -4402,66 +4407,66 @@
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/readelf.c:3182
+#: src/readelf.c:3194
 #, no-c-format
 msgid " Length  Number  % of total  Coverage\n"
 msgstr ""
 
-#: src/readelf.c:3184
+#: src/readelf.c:3196
 #, c-format
 msgid "      0  %6<PRIu32>      %5.1f%%\n"
 msgstr "      0  %6<PRIu32>      %5.1f%%\n"
 
-#: src/readelf.c:3191
+#: src/readelf.c:3203
 #, c-format
 msgid "%7d  %6<PRIu32>      %5.1f%%    %5.1f%%\n"
 msgstr "%7d  %6<PRIu32>      %5.1f%%    %5.1f%%\n"
 
-#: src/readelf.c:3204
+#: src/readelf.c:3216
 #, c-format
 msgid ""
 " Average number of tests:   successful lookup: %f\n"
 "\t\t\t  unsuccessful lookup: %f\n"
 msgstr ""
 
-#: src/readelf.c:3222 src/readelf.c:3286 src/readelf.c:3352
+#: src/readelf.c:3234 src/readelf.c:3298 src/readelf.c:3364
 #, c-format
 msgid "cannot get data for section %d: %s"
 msgstr ""
 
-#: src/readelf.c:3230
+#: src/readelf.c:3242
 #, fuzzy, c-format
 msgid "invalid data in sysv.hash section %d"
 msgstr "ungültige .debug_line Sektion"
 
-#: src/readelf.c:3259
+#: src/readelf.c:3271
 #, fuzzy, c-format
 msgid "invalid chain in sysv.hash section %d"
 msgstr "ungültige .debug_line Sektion"
 
-#: src/readelf.c:3294
+#: src/readelf.c:3306
 #, fuzzy, c-format
 msgid "invalid data in sysv.hash64 section %d"
 msgstr "ungültige .debug_line Sektion"
 
-#: src/readelf.c:3325
+#: src/readelf.c:3337
 #, fuzzy, c-format
 msgid "invalid chain in sysv.hash64 section %d"
 msgstr "ungültige .debug_line Sektion"
 
-#: src/readelf.c:3361
+#: src/readelf.c:3373
 #, fuzzy, c-format
 msgid "invalid data in gnu.hash section %d"
 msgstr "ungültige .debug_line Sektion"
 
-#: src/readelf.c:3428
+#: src/readelf.c:3440
 #, c-format
 msgid ""
 " Symbol Bias: %u\n"
 " Bitmask Size: %zu bytes  %<PRIuFAST32>%% bits set  2nd hash shift: %u\n"
 msgstr ""
 
-#: src/readelf.c:3517
+#: src/readelf.c:3529
 #, c-format
 msgid ""
 "\n"
@@ -4472,13 +4477,13 @@
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/readelf.c:3531
+#: src/readelf.c:3543
 msgid ""
 "       Library                       Time Stamp          Checksum Version "
 "Flags"
 msgstr ""
 
-#: src/readelf.c:3583
+#: src/readelf.c:3595
 #, c-format
 msgid ""
 "\n"
@@ -4486,102 +4491,102 @@
 "%#0<PRIx64>:\n"
 msgstr ""
 
-#: src/readelf.c:3600
+#: src/readelf.c:3612
 msgid "  Owner          Size\n"
 msgstr ""
 
-#: src/readelf.c:3629
+#: src/readelf.c:3641
 #, c-format
 msgid "  %-13s  %4<PRIu32>\n"
 msgstr "  %-13s  %4<PRIu32>\n"
 
 #. Unknown subsection, print and skip.
-#: src/readelf.c:3668
+#: src/readelf.c:3680
 #, c-format
 msgid "    %-4u %12<PRIu32>\n"
 msgstr "    %-4u %12<PRIu32>\n"
 
 #. Tag_File
-#: src/readelf.c:3673
+#: src/readelf.c:3685
 #, c-format
 msgid "    File: %11<PRIu32>\n"
 msgstr "    File: %11<PRIu32>\n"
 
-#: src/readelf.c:3722
+#: src/readelf.c:3734
 #, c-format
 msgid "      %s: %<PRId64>, %s\n"
 msgstr "      %s: %<PRId64>, %s\n"
 
-#: src/readelf.c:3725
+#: src/readelf.c:3737
 #, c-format
 msgid "      %s: %<PRId64>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:3728
+#: src/readelf.c:3740
 #, c-format
 msgid "      %s: %s\n"
 msgstr "      %s: %s\n"
 
-#: src/readelf.c:3738
+#: src/readelf.c:3750
 #, c-format
 msgid "      %u: %<PRId64>\n"
 msgstr "      %u: %<PRId64>\n"
 
-#: src/readelf.c:3741
+#: src/readelf.c:3753
 #, c-format
 msgid "      %u: %s\n"
 msgstr "      %u: %s\n"
 
-#: src/readelf.c:3811
+#: src/readelf.c:3823
 #, fuzzy, c-format
 msgid "sprintf failure"
 msgstr "mprotect fehlgeschlagen"
 
-#: src/readelf.c:4293
+#: src/readelf.c:4305
 msgid "empty block"
 msgstr ""
 
-#: src/readelf.c:4296
+#: src/readelf.c:4308
 #, c-format
 msgid "%zu byte block:"
 msgstr ""
 
-#: src/readelf.c:4774
+#: src/readelf.c:4786
 #, c-format
 msgid "%*s[%2<PRIuMAX>] %s  <TRUNCATED>\n"
 msgstr ""
 
-#: src/readelf.c:4838
+#: src/readelf.c:4850
 #, c-format
 msgid "%s %#<PRIx64> used with different address sizes"
 msgstr ""
 
-#: src/readelf.c:4845
+#: src/readelf.c:4857
 #, c-format
 msgid "%s %#<PRIx64> used with different offset sizes"
 msgstr ""
 
-#: src/readelf.c:4852
+#: src/readelf.c:4864
 #, c-format
 msgid "%s %#<PRIx64> used with different base addresses"
 msgstr ""
 
-#: src/readelf.c:4859
+#: src/readelf.c:4871
 #, c-format
 msgid "%s %#<PRIx64> used with different attribute %s and %s"
 msgstr ""
 
-#: src/readelf.c:4956
+#: src/readelf.c:4968
 #, c-format
 msgid " [%6tx]  <UNUSED GARBAGE IN REST OF SECTION>\n"
 msgstr ""
 
-#: src/readelf.c:4964
+#: src/readelf.c:4976
 #, c-format
 msgid " [%6tx]  <UNUSED GARBAGE> ... %<PRIu64> bytes ...\n"
 msgstr ""
 
-#: src/readelf.c:5042
+#: src/readelf.c:5054
 #, c-format
 msgid ""
 "\n"
@@ -4589,79 +4594,79 @@
 " [ Code]\n"
 msgstr ""
 
-#: src/readelf.c:5050
+#: src/readelf.c:5062
 #, c-format
 msgid ""
 "\n"
 "Abbreviation section at offset %<PRIu64>:\n"
 msgstr ""
 
-#: src/readelf.c:5063
+#: src/readelf.c:5075
 #, c-format
 msgid " *** error while reading abbreviation: %s\n"
 msgstr ""
 
-#: src/readelf.c:5079
+#: src/readelf.c:5091
 #, c-format
 msgid " [%5u] offset: %<PRId64>, children: %s, tag: %s\n"
 msgstr ""
 
-#: src/readelf.c:5112 src/readelf.c:5421 src/readelf.c:5588 src/readelf.c:5973
-#: src/readelf.c:6574 src/readelf.c:8311 src/readelf.c:8997 src/readelf.c:9433
-#: src/readelf.c:9678 src/readelf.c:9844 src/readelf.c:10231
-#: src/readelf.c:10291
+#: src/readelf.c:5124 src/readelf.c:5433 src/readelf.c:5600 src/readelf.c:5985
+#: src/readelf.c:6586 src/readelf.c:8323 src/readelf.c:9009 src/readelf.c:9445
+#: src/readelf.c:9690 src/readelf.c:9856 src/readelf.c:10243
+#: src/readelf.c:10303
 #, c-format
 msgid ""
 "\n"
 "DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
 msgstr ""
 
-#: src/readelf.c:5125
+#: src/readelf.c:5137
 #, fuzzy, c-format
 msgid "cannot get .debug_addr section data: %s"
 msgstr "konnte Abschnittsdaten nicht holen: %s"
 
-#: src/readelf.c:5225 src/readelf.c:5249 src/readelf.c:5633 src/readelf.c:9042
+#: src/readelf.c:5237 src/readelf.c:5261 src/readelf.c:5645 src/readelf.c:9054
 #, fuzzy, c-format
 msgid " Length:         %8<PRIu64>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:5227 src/readelf.c:5264 src/readelf.c:5646 src/readelf.c:9055
+#: src/readelf.c:5239 src/readelf.c:5276 src/readelf.c:5658 src/readelf.c:9067
 #, fuzzy, c-format
 msgid " DWARF version:  %8<PRIu16>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:5228 src/readelf.c:5273 src/readelf.c:5655 src/readelf.c:9064
+#: src/readelf.c:5240 src/readelf.c:5285 src/readelf.c:5667 src/readelf.c:9076
 #, fuzzy, c-format
 msgid " Address size:   %8<PRIu64>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:5230 src/readelf.c:5283 src/readelf.c:5665 src/readelf.c:9074
+#: src/readelf.c:5242 src/readelf.c:5295 src/readelf.c:5677 src/readelf.c:9086
 #, fuzzy, c-format
 msgid " Segment size:   %8<PRIu64>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:5268 src/readelf.c:5650 src/readelf.c:9059 src/readelf.c:10423
+#: src/readelf.c:5280 src/readelf.c:5662 src/readelf.c:9071 src/readelf.c:10435
 #, fuzzy, c-format
 msgid "Unknown version"
 msgstr "unbekannte Version"
 
-#: src/readelf.c:5278 src/readelf.c:5491 src/readelf.c:5660 src/readelf.c:9069
+#: src/readelf.c:5290 src/readelf.c:5503 src/readelf.c:5672 src/readelf.c:9081
 #, fuzzy, c-format
 msgid "unsupported address size"
 msgstr "Kein Adress-Wert"
 
-#: src/readelf.c:5289 src/readelf.c:5502 src/readelf.c:5670 src/readelf.c:9079
+#: src/readelf.c:5301 src/readelf.c:5514 src/readelf.c:5682 src/readelf.c:9091
 #, c-format
 msgid "unsupported segment size"
 msgstr ""
 
-#: src/readelf.c:5342 src/readelf.c:5416
+#: src/readelf.c:5354 src/readelf.c:5428
 #, c-format
 msgid "cannot get .debug_aranges content: %s"
 msgstr ""
 
-#: src/readelf.c:5357
+#: src/readelf.c:5369
 #, c-format
 msgid ""
 "\n"
@@ -4672,241 +4677,241 @@
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/readelf.c:5388
+#: src/readelf.c:5400
 #, c-format
 msgid " [%*zu] ???\n"
 msgstr " [%*zu] ???\n"
 
-#: src/readelf.c:5390
+#: src/readelf.c:5402
 #, c-format
 msgid ""
 " [%*zu] start: %0#*<PRIx64>, length: %5<PRIu64>, CU DIE offset: %6<PRId64>\n"
 msgstr ""
 
-#: src/readelf.c:5434 src/readelf.c:8338
+#: src/readelf.c:5446 src/readelf.c:8350
 #, c-format
 msgid ""
 "\n"
 "Table at offset %zu:\n"
 msgstr ""
 
-#: src/readelf.c:5438 src/readelf.c:5614 src/readelf.c:6598 src/readelf.c:8349
-#: src/readelf.c:9023
+#: src/readelf.c:5450 src/readelf.c:5626 src/readelf.c:6610 src/readelf.c:8361
+#: src/readelf.c:9035
 #, c-format
 msgid "invalid data in section [%zu] '%s'"
 msgstr ""
 
-#: src/readelf.c:5454
+#: src/readelf.c:5466
 #, fuzzy, c-format
 msgid ""
 "\n"
 " Length:        %6<PRIu64>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:5466
+#: src/readelf.c:5478
 #, fuzzy, c-format
 msgid " DWARF version: %6<PRIuFAST16>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:5470
+#: src/readelf.c:5482
 #, c-format
 msgid "unsupported aranges version"
 msgstr ""
 
-#: src/readelf.c:5481
+#: src/readelf.c:5493
 #, fuzzy, c-format
 msgid " CU offset:     %6<PRIx64>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:5487
+#: src/readelf.c:5499
 #, c-format
 msgid " Address size:  %6<PRIu64>\n"
 msgstr ""
 
-#: src/readelf.c:5498
+#: src/readelf.c:5510
 #, c-format
 msgid ""
 " Segment size:  %6<PRIu64>\n"
 "\n"
 msgstr ""
 
-#: src/readelf.c:5553
+#: src/readelf.c:5565
 #, c-format
 msgid "   %zu padding bytes\n"
 msgstr ""
 
-#: src/readelf.c:5597
+#: src/readelf.c:5609
 #, fuzzy, c-format
 msgid "cannot get .debug_rnglists content: %s"
 msgstr "konnte Programm-Kopf nicht erstellen: %s"
 
-#: src/readelf.c:5620 src/readelf.c:9029
+#: src/readelf.c:5632 src/readelf.c:9041
 #, fuzzy, c-format
 msgid ""
 "Table at Offset 0x%<PRIx64>:\n"
 "\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:5675 src/readelf.c:9084
+#: src/readelf.c:5687 src/readelf.c:9096
 #, fuzzy, c-format
 msgid " Offset entries: %8<PRIu64>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:5691 src/readelf.c:9100
+#: src/readelf.c:5703 src/readelf.c:9112
 #, c-format
 msgid " Unknown CU base: "
 msgstr ""
 
-#: src/readelf.c:5693 src/readelf.c:9102
+#: src/readelf.c:5705 src/readelf.c:9114
 #, c-format
 msgid " CU [%6<PRIx64>] base: "
 msgstr ""
 
-#: src/readelf.c:5699 src/readelf.c:9108
+#: src/readelf.c:5711 src/readelf.c:9120
 #, c-format
 msgid " Not associated with a CU.\n"
 msgstr ""
 
-#: src/readelf.c:5710 src/readelf.c:9119
+#: src/readelf.c:5722 src/readelf.c:9131
 #, c-format
 msgid "too many offset entries for unit length"
 msgstr ""
 
-#: src/readelf.c:5714 src/readelf.c:9123
+#: src/readelf.c:5726 src/readelf.c:9135
 #, fuzzy, c-format
 msgid "  Offsets starting at 0x%<PRIx64>:\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:5766
+#: src/readelf.c:5778
 #, fuzzy, c-format
 msgid "invalid range list data"
 msgstr "Ungültige Daten"
 
-#: src/readelf.c:5951 src/readelf.c:9411
+#: src/readelf.c:5963 src/readelf.c:9423
 #, c-format
 msgid ""
 "   %zu padding bytes\n"
 "\n"
 msgstr ""
 
-#: src/readelf.c:5968
+#: src/readelf.c:5980
 #, c-format
 msgid "cannot get .debug_ranges content: %s"
 msgstr ""
 
-#: src/readelf.c:6004 src/readelf.c:9466
+#: src/readelf.c:6016 src/readelf.c:9478
 #, c-format
 msgid ""
 "\n"
 " Unknown CU base: "
 msgstr ""
 
-#: src/readelf.c:6006 src/readelf.c:9468
+#: src/readelf.c:6018 src/readelf.c:9480
 #, c-format
 msgid ""
 "\n"
 " CU [%6<PRIx64>] base: "
 msgstr ""
 
-#: src/readelf.c:6015 src/readelf.c:9494 src/readelf.c:9520
+#: src/readelf.c:6027 src/readelf.c:9506 src/readelf.c:9532
 #, c-format
 msgid " [%6tx]  <INVALID DATA>\n"
 msgstr ""
 
-#: src/readelf.c:6036 src/readelf.c:9600
+#: src/readelf.c:6048 src/readelf.c:9612
 #, c-format
 msgid ""
 " [%6tx] base address\n"
 "          "
 msgstr ""
 
-#: src/readelf.c:6044 src/readelf.c:9608
+#: src/readelf.c:6056 src/readelf.c:9620
 #, fuzzy, c-format
 msgid " [%6tx] empty list\n"
 msgstr " [%6tx]  %s..%s\n"
 
-#: src/readelf.c:6299
+#: src/readelf.c:6311
 msgid "         <INVALID DATA>\n"
 msgstr ""
 
-#: src/readelf.c:6552
+#: src/readelf.c:6564
 #, fuzzy, c-format
 msgid "cannot get ELF: %s"
 msgstr "ELF Kopf konnte nicht ausgelesen werden"
 
-#: src/readelf.c:6570
+#: src/readelf.c:6582
 #, c-format
 msgid ""
 "\n"
 "Call frame information section [%2zu] '%s' at offset %#<PRIx64>:\n"
 msgstr ""
 
-#: src/readelf.c:6620
+#: src/readelf.c:6632
 #, c-format
 msgid ""
 "\n"
 " [%6tx] Zero terminator\n"
 msgstr ""
 
-#: src/readelf.c:6721 src/readelf.c:6875
+#: src/readelf.c:6733 src/readelf.c:6887
 #, fuzzy, c-format
 msgid "invalid augmentation length"
 msgstr "ungültige Abschnittsausrichtung"
 
-#: src/readelf.c:6736
+#: src/readelf.c:6748
 msgid "FDE address encoding: "
 msgstr ""
 
-#: src/readelf.c:6742
+#: src/readelf.c:6754
 msgid "LSDA pointer encoding: "
 msgstr ""
 
-#: src/readelf.c:6852
+#: src/readelf.c:6864
 #, c-format
 msgid " (offset: %#<PRIx64>)"
 msgstr ""
 
-#: src/readelf.c:6859
+#: src/readelf.c:6871
 #, c-format
 msgid " (end offset: %#<PRIx64>)"
 msgstr ""
 
-#: src/readelf.c:6896
+#: src/readelf.c:6908
 #, c-format
 msgid "   %-26sLSDA pointer: %#<PRIx64>\n"
 msgstr ""
 
-#: src/readelf.c:6981
+#: src/readelf.c:6993
 #, c-format
 msgid "DIE [%<PRIx64>] cannot get attribute code: %s"
 msgstr ""
 
-#: src/readelf.c:6991
+#: src/readelf.c:7003
 #, c-format
 msgid "DIE [%<PRIx64>] cannot get attribute form: %s"
 msgstr ""
 
-#: src/readelf.c:7013
+#: src/readelf.c:7025
 #, c-format
 msgid "DIE [%<PRIx64>] cannot get attribute '%s' (%s) value: %s"
 msgstr ""
 
-#: src/readelf.c:7343
+#: src/readelf.c:7355
 #, fuzzy, c-format
 msgid "invalid file (%<PRId64>): %s"
 msgstr "Ungültige Datei"
 
-#: src/readelf.c:7347
+#: src/readelf.c:7359
 #, fuzzy, c-format
 msgid "no srcfiles for CU [%<PRIx64>]"
 msgstr "unbekannte Form %<PRIx64>"
 
-#: src/readelf.c:7351
+#: src/readelf.c:7363
 #, fuzzy, c-format
 msgid "couldn't get DWARF CU: %s"
 msgstr "ELF Kopf konnte nicht ausgelesen werden"
 
-#: src/readelf.c:7664
+#: src/readelf.c:7676
 #, c-format
 msgid ""
 "\n"
@@ -4914,12 +4919,12 @@
 " [Offset]\n"
 msgstr ""
 
-#: src/readelf.c:7714
+#: src/readelf.c:7726
 #, fuzzy, c-format
 msgid "cannot get next unit: %s"
 msgstr "konnte Abschnittsdaten nicht holen: %s"
 
-#: src/readelf.c:7733
+#: src/readelf.c:7745
 #, c-format
 msgid ""
 " Type unit at offset %<PRIu64>:\n"
@@ -4928,7 +4933,7 @@
 " Type signature: %#<PRIx64>, Type offset: %#<PRIx64> [%<PRIx64>]\n"
 msgstr ""
 
-#: src/readelf.c:7745
+#: src/readelf.c:7757
 #, c-format
 msgid ""
 " Compilation unit at offset %<PRIu64>:\n"
@@ -4936,37 +4941,37 @@
 "%<PRIu8>, Offset size: %<PRIu8>\n"
 msgstr ""
 
-#: src/readelf.c:7755 src/readelf.c:7918
+#: src/readelf.c:7767 src/readelf.c:7930
 #, c-format
 msgid " Unit type: %s (%<PRIu8>)"
 msgstr ""
 
-#: src/readelf.c:7782
+#: src/readelf.c:7794
 #, c-format
 msgid "unknown version (%d) or unit type (%d)"
 msgstr ""
 
-#: src/readelf.c:7811
+#: src/readelf.c:7823
 #, c-format
 msgid "cannot get DIE offset: %s"
 msgstr ""
 
-#: src/readelf.c:7820
+#: src/readelf.c:7832
 #, fuzzy, c-format
 msgid "cannot get tag of DIE at offset [%<PRIx64>] in section '%s': %s"
 msgstr "konnte Programm-Kopf nicht erstellen: %s"
 
-#: src/readelf.c:7858
+#: src/readelf.c:7870
 #, c-format
 msgid "cannot get next DIE: %s\n"
 msgstr ""
 
-#: src/readelf.c:7866
+#: src/readelf.c:7878
 #, c-format
 msgid "cannot get next DIE: %s"
 msgstr ""
 
-#: src/readelf.c:7910
+#: src/readelf.c:7922
 #, c-format
 msgid ""
 " Split compilation unit at offset %<PRIu64>:\n"
@@ -4974,7 +4979,7 @@
 "%<PRIu8>, Offset size: %<PRIu8>\n"
 msgstr ""
 
-#: src/readelf.c:7962
+#: src/readelf.c:7974
 #, c-format
 msgid ""
 "\n"
@@ -4982,18 +4987,18 @@
 "\n"
 msgstr ""
 
-#: src/readelf.c:8294
+#: src/readelf.c:8306
 #, fuzzy, c-format
 msgid "unknown form: %s"
 msgstr "unbekannte Form %<PRIx64>"
 
-#: src/readelf.c:8325
+#: src/readelf.c:8337
 #, c-format
 msgid "cannot get line data section data: %s"
 msgstr ""
 
 #. Print what we got so far.
-#: src/readelf.c:8427
+#: src/readelf.c:8439
 #, c-format
 msgid ""
 "\n"
@@ -5012,171 +5017,171 @@
 "Opcodes:\n"
 msgstr ""
 
-#: src/readelf.c:8449
+#: src/readelf.c:8461
 #, fuzzy, c-format
 msgid "cannot handle .debug_line version: %u\n"
 msgstr "ungültige .debug_line Sektion"
 
-#: src/readelf.c:8457
+#: src/readelf.c:8469
 #, fuzzy, c-format
 msgid "cannot handle address size: %u\n"
 msgstr "Kein Adress-Wert"
 
-#: src/readelf.c:8465
+#: src/readelf.c:8477
 #, c-format
 msgid "cannot handle segment selector size: %u\n"
 msgstr ""
 
-#: src/readelf.c:8475
+#: src/readelf.c:8487
 #, c-format
 msgid "invalid data at offset %tu in section [%zu] '%s'"
 msgstr ""
 
-#: src/readelf.c:8490
+#: src/readelf.c:8502
 #, c-format
 msgid "  [%*<PRIuFAST8>]  %hhu argument\n"
 msgid_plural "  [%*<PRIuFAST8>]  %hhu arguments\n"
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/readelf.c:8501
+#: src/readelf.c:8513
 msgid ""
 "\n"
 "Directory table:"
 msgstr ""
 
-#: src/readelf.c:8507 src/readelf.c:8584
+#: src/readelf.c:8519 src/readelf.c:8596
 #, fuzzy, c-format
 msgid "      ["
 msgstr "      %s: %s\n"
 
-#: src/readelf.c:8578
+#: src/readelf.c:8590
 msgid ""
 "\n"
 "File name table:"
 msgstr ""
 
-#: src/readelf.c:8639
+#: src/readelf.c:8651
 msgid " Entry Dir   Time      Size      Name"
 msgstr ""
 
-#: src/readelf.c:8676
+#: src/readelf.c:8688
 msgid ""
 "\n"
 "Line number statements:"
 msgstr ""
 
-#: src/readelf.c:8699
+#: src/readelf.c:8711
 #, c-format
 msgid "invalid maximum operations per instruction is zero"
 msgstr ""
 
-#: src/readelf.c:8733
+#: src/readelf.c:8745
 #, c-format
 msgid " special opcode %u: address+%u = "
 msgstr ""
 
-#: src/readelf.c:8737
+#: src/readelf.c:8749
 #, c-format
 msgid ", op_index = %u, line%+d = %zu\n"
 msgstr ""
 
-#: src/readelf.c:8740
+#: src/readelf.c:8752
 #, c-format
 msgid ", line%+d = %zu\n"
 msgstr ""
 
-#: src/readelf.c:8758
+#: src/readelf.c:8770
 #, c-format
 msgid " extended opcode %u: "
 msgstr ""
 
-#: src/readelf.c:8763
+#: src/readelf.c:8775
 msgid " end of sequence"
 msgstr ""
 
-#: src/readelf.c:8781
+#: src/readelf.c:8793
 #, fuzzy, c-format
 msgid " set address to "
 msgstr "Außerhalb des Adressbereiches"
 
-#: src/readelf.c:8809
+#: src/readelf.c:8821
 #, c-format
 msgid " define new file: dir=%u, mtime=%<PRIu64>, length=%<PRIu64>, name=%s\n"
 msgstr ""
 
-#: src/readelf.c:8823
+#: src/readelf.c:8835
 #, c-format
 msgid " set discriminator to %u\n"
 msgstr ""
 
 #. Unknown, ignore it.
-#: src/readelf.c:8828
+#: src/readelf.c:8840
 #, fuzzy
 msgid " unknown opcode"
 msgstr "unbekannter Typ"
 
 #. Takes no argument.
-#: src/readelf.c:8840
+#: src/readelf.c:8852
 msgid " copy"
 msgstr ""
 
-#: src/readelf.c:8851
+#: src/readelf.c:8863
 #, c-format
 msgid " advance address by %u to "
 msgstr ""
 
-#: src/readelf.c:8855 src/readelf.c:8916
+#: src/readelf.c:8867 src/readelf.c:8928
 #, c-format
 msgid ", op_index to %u"
 msgstr ""
 
-#: src/readelf.c:8867
+#: src/readelf.c:8879
 #, c-format
 msgid " advance line by constant %d to %<PRId64>\n"
 msgstr ""
 
-#: src/readelf.c:8877
+#: src/readelf.c:8889
 #, c-format
 msgid " set file to %<PRIu64>\n"
 msgstr ""
 
-#: src/readelf.c:8888
+#: src/readelf.c:8900
 #, c-format
 msgid " set column to %<PRIu64>\n"
 msgstr ""
 
-#: src/readelf.c:8895
+#: src/readelf.c:8907
 #, c-format
 msgid " set '%s' to %<PRIuFAST8>\n"
 msgstr ""
 
 #. Takes no argument.
-#: src/readelf.c:8901
+#: src/readelf.c:8913
 msgid " set basic block flag"
 msgstr ""
 
-#: src/readelf.c:8912
+#: src/readelf.c:8924
 #, c-format
 msgid " advance address by constant %u to "
 msgstr ""
 
-#: src/readelf.c:8932
+#: src/readelf.c:8944
 #, c-format
 msgid " advance address by fixed value %u to \n"
 msgstr ""
 
 #. Takes no argument.
-#: src/readelf.c:8942
+#: src/readelf.c:8954
 msgid " set prologue end flag"
 msgstr ""
 
 #. Takes no argument.
-#: src/readelf.c:8947
+#: src/readelf.c:8959
 msgid " set epilogue begin flag"
 msgstr ""
 
-#: src/readelf.c:8957
+#: src/readelf.c:8969
 #, c-format
 msgid " set isa to %u\n"
 msgstr ""
@@ -5184,103 +5189,103 @@
 #. This is a new opcode the generator but not we know about.
 #. Read the parameters associated with it but then discard
 #. everything.  Read all the parameters for this opcode.
-#: src/readelf.c:8966
+#: src/readelf.c:8978
 #, c-format
 msgid " unknown opcode with %<PRIu8> parameter:"
 msgid_plural " unknown opcode with %<PRIu8> parameters:"
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/readelf.c:9006
+#: src/readelf.c:9018
 #, fuzzy, c-format
 msgid "cannot get .debug_loclists content: %s"
 msgstr "konnte Eintrag aus der Symboltabelle nicht holen: %s"
 
-#: src/readelf.c:9175
+#: src/readelf.c:9187
 #, fuzzy, c-format
 msgid "invalid loclists data"
 msgstr "Ungültige Daten"
 
-#: src/readelf.c:9428
+#: src/readelf.c:9440
 #, c-format
 msgid "cannot get .debug_loc content: %s"
 msgstr ""
 
-#: src/readelf.c:9635 src/readelf.c:10679
+#: src/readelf.c:9647 src/readelf.c:10691
 msgid "   <INVALID DATA>\n"
 msgstr ""
 
-#: src/readelf.c:9690 src/readelf.c:9853
+#: src/readelf.c:9702 src/readelf.c:9865
 #, c-format
 msgid "cannot get macro information section data: %s"
 msgstr ""
 
-#: src/readelf.c:9770
+#: src/readelf.c:9782
 #, c-format
 msgid "%*s*** non-terminated string at end of section"
 msgstr ""
 
-#: src/readelf.c:9793
+#: src/readelf.c:9805
 #, c-format
 msgid "%*s*** missing DW_MACINFO_start_file argument at end of section"
 msgstr ""
 
-#: src/readelf.c:9894
+#: src/readelf.c:9906
 #, fuzzy, c-format
 msgid " Offset:             0x%<PRIx64>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:9906
+#: src/readelf.c:9918
 #, fuzzy, c-format
 msgid " Version:            %<PRIu16>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:9912 src/readelf.c:10799
+#: src/readelf.c:9924 src/readelf.c:10811
 #, c-format
 msgid "  unknown version, cannot parse section\n"
 msgstr ""
 
-#: src/readelf.c:9919
+#: src/readelf.c:9931
 #, fuzzy, c-format
 msgid " Flag:               0x%<PRIx8>"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:9948
+#: src/readelf.c:9960
 #, c-format
 msgid " Offset length:      %<PRIu8>\n"
 msgstr ""
 
-#: src/readelf.c:9956
+#: src/readelf.c:9968
 #, c-format
 msgid " .debug_line offset: 0x%<PRIx64>\n"
 msgstr ""
 
-#: src/readelf.c:9981
+#: src/readelf.c:9993
 #, c-format
 msgid "  extension opcode table, %<PRIu8> items:\n"
 msgstr ""
 
-#: src/readelf.c:9988
+#: src/readelf.c:10000
 #, c-format
 msgid "    [%<PRIx8>]"
 msgstr ""
 
-#: src/readelf.c:10000
+#: src/readelf.c:10012
 #, c-format
 msgid " %<PRIu8> arguments:"
 msgstr ""
 
-#: src/readelf.c:10015
+#: src/readelf.c:10027
 #, c-format
 msgid " no arguments."
 msgstr ""
 
-#: src/readelf.c:10216
+#: src/readelf.c:10228
 #, c-format
 msgid " [%5d] DIE offset: %6<PRId64>, CU DIE offset: %6<PRId64>, name: %s\n"
 msgstr ""
 
-#: src/readelf.c:10260
+#: src/readelf.c:10272
 #, c-format
 msgid ""
 "\n"
@@ -5288,72 +5293,72 @@
 " %*s  String\n"
 msgstr ""
 
-#: src/readelf.c:10275
+#: src/readelf.c:10287
 #, c-format
 msgid " *** error, missing string terminator\n"
 msgstr ""
 
-#: src/readelf.c:10304
+#: src/readelf.c:10316
 #, fuzzy, c-format
 msgid "cannot get .debug_str_offsets section data: %s"
 msgstr "konnte Abschnittsdaten nicht holen: %s"
 
-#: src/readelf.c:10403
+#: src/readelf.c:10415
 #, fuzzy, c-format
 msgid " Length:        %8<PRIu64>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:10405
+#: src/readelf.c:10417
 #, fuzzy, c-format
 msgid " Offset size:   %8<PRIu8>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:10419
+#: src/readelf.c:10431
 #, fuzzy, c-format
 msgid " DWARF version: %8<PRIu16>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:10428
+#: src/readelf.c:10440
 #, fuzzy, c-format
 msgid " Padding:       %8<PRIx16>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:10482
+#: src/readelf.c:10494
 #, c-format
 msgid ""
 "\n"
 "Call frame search table section [%2zu] '.eh_frame_hdr':\n"
 msgstr ""
 
-#: src/readelf.c:10584
+#: src/readelf.c:10596
 #, c-format
 msgid ""
 "\n"
 "Exception handling table section [%2zu] '.gcc_except_table':\n"
 msgstr ""
 
-#: src/readelf.c:10607
+#: src/readelf.c:10619
 #, c-format
 msgid " LPStart encoding:    %#x "
 msgstr ""
 
-#: src/readelf.c:10619
+#: src/readelf.c:10631
 #, c-format
 msgid " TType encoding:      %#x "
 msgstr ""
 
-#: src/readelf.c:10634
+#: src/readelf.c:10646
 #, c-format
 msgid " Call site encoding:  %#x "
 msgstr ""
 
-#: src/readelf.c:10647
+#: src/readelf.c:10659
 msgid ""
 "\n"
 " Call site table:"
 msgstr ""
 
-#: src/readelf.c:10661
+#: src/readelf.c:10673
 #, c-format
 msgid ""
 " [%4u] Call site start:   %#<PRIx64>\n"
@@ -5362,142 +5367,142 @@
 "        Action:            %u\n"
 msgstr ""
 
-#: src/readelf.c:10734
+#: src/readelf.c:10746
 #, c-format
 msgid "invalid TType encoding"
 msgstr ""
 
-#: src/readelf.c:10761
+#: src/readelf.c:10773
 #, c-format
 msgid ""
 "\n"
 "GDB section [%2zu] '%s' at offset %#<PRIx64> contains %<PRId64> bytes :\n"
 msgstr ""
 
-#: src/readelf.c:10790
+#: src/readelf.c:10802
 #, fuzzy, c-format
 msgid " Version:         %<PRId32>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:10808
+#: src/readelf.c:10820
 #, c-format
 msgid " CU offset:       %#<PRIx32>\n"
 msgstr ""
 
-#: src/readelf.c:10815
+#: src/readelf.c:10827
 #, c-format
 msgid " TU offset:       %#<PRIx32>\n"
 msgstr ""
 
-#: src/readelf.c:10822
+#: src/readelf.c:10834
 #, c-format
 msgid " address offset:  %#<PRIx32>\n"
 msgstr ""
 
-#: src/readelf.c:10829
+#: src/readelf.c:10841
 #, c-format
 msgid " symbol offset:   %#<PRIx32>\n"
 msgstr ""
 
-#: src/readelf.c:10836
+#: src/readelf.c:10848
 #, c-format
 msgid " constant offset: %#<PRIx32>\n"
 msgstr ""
 
-#: src/readelf.c:10850
+#: src/readelf.c:10862
 #, c-format
 msgid ""
 "\n"
 " CU list at offset %#<PRIx32> contains %zu entries:\n"
 msgstr ""
 
-#: src/readelf.c:10875
+#: src/readelf.c:10887
 #, c-format
 msgid ""
 "\n"
 " TU list at offset %#<PRIx32> contains %zu entries:\n"
 msgstr ""
 
-#: src/readelf.c:10904
+#: src/readelf.c:10916
 #, c-format
 msgid ""
 "\n"
 " Address list at offset %#<PRIx32> contains %zu entries:\n"
 msgstr ""
 
-#: src/readelf.c:10936
+#: src/readelf.c:10948
 #, c-format
 msgid ""
 "\n"
 " Symbol table at offset %#<PRIx32> contains %zu slots:\n"
 msgstr ""
 
-#: src/readelf.c:11074
+#: src/readelf.c:11086
 #, c-format
 msgid "cannot get debug context descriptor: %s"
 msgstr ""
 
-#: src/readelf.c:11437 src/readelf.c:12059 src/readelf.c:12170
-#: src/readelf.c:12228
+#: src/readelf.c:11449 src/readelf.c:12071 src/readelf.c:12182
+#: src/readelf.c:12240
 #, c-format
 msgid "cannot convert core note data: %s"
 msgstr ""
 
-#: src/readelf.c:11800
+#: src/readelf.c:11812
 #, c-format
 msgid ""
 "\n"
 "%*s... <repeats %u more times> ..."
 msgstr ""
 
-#: src/readelf.c:12307
+#: src/readelf.c:12319
 msgid "  Owner          Data size  Type\n"
 msgstr ""
 
-#: src/readelf.c:12336
+#: src/readelf.c:12348
 #, c-format
 msgid "  %-13.*s  %9<PRId32>  %s\n"
 msgstr ""
 
-#: src/readelf.c:12388
+#: src/readelf.c:12400
 #, fuzzy, c-format
 msgid "cannot get content of note: %s"
 msgstr "Konnte Inhalt von %s: %s nicht lesen"
 
-#: src/readelf.c:12422
+#: src/readelf.c:12434
 #, c-format
 msgid ""
 "\n"
 "Note section [%2zu] '%s' of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
 msgstr ""
 
-#: src/readelf.c:12445
+#: src/readelf.c:12457
 #, c-format
 msgid ""
 "\n"
 "Note segment of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
 msgstr ""
 
-#: src/readelf.c:12492
+#: src/readelf.c:12504
 #, fuzzy, c-format
 msgid ""
 "\n"
 "Section [%zu] '%s' has no data to dump.\n"
 msgstr "konnte Abschnittsdaten nicht holen: %s"
 
-#: src/readelf.c:12519 src/readelf.c:12570
+#: src/readelf.c:12531 src/readelf.c:12582
 #, fuzzy, c-format
 msgid "cannot get data for section [%zu] '%s': %s"
 msgstr "konnte Abschnittsdaten nicht holen: %s"
 
-#: src/readelf.c:12524
+#: src/readelf.c:12536
 #, c-format
 msgid ""
 "\n"
 "Hex dump of section [%zu] '%s', %<PRIu64> bytes at offset %#0<PRIx64>:\n"
 msgstr ""
 
-#: src/readelf.c:12529
+#: src/readelf.c:12541
 #, c-format
 msgid ""
 "\n"
@@ -5505,21 +5510,21 @@
 "%#0<PRIx64>:\n"
 msgstr ""
 
-#: src/readelf.c:12543
+#: src/readelf.c:12555
 #, fuzzy, c-format
 msgid ""
 "\n"
 "Section [%zu] '%s' has no strings to dump.\n"
 msgstr "konnte Abschnittsdaten nicht holen: %s"
 
-#: src/readelf.c:12575
+#: src/readelf.c:12587
 #, c-format
 msgid ""
 "\n"
 "String section [%zu] '%s' contains %<PRIu64> bytes at offset %#0<PRIx64>:\n"
 msgstr ""
 
-#: src/readelf.c:12580
+#: src/readelf.c:12592
 #, c-format
 msgid ""
 "\n"
@@ -5527,45 +5532,45 @@
 "offset %#0<PRIx64>:\n"
 msgstr ""
 
-#: src/readelf.c:12629
+#: src/readelf.c:12641
 #, c-format
 msgid ""
 "\n"
 "section [%lu] does not exist"
 msgstr ""
 
-#: src/readelf.c:12658
+#: src/readelf.c:12671
 #, c-format
 msgid ""
 "\n"
 "section '%s' does not exist"
 msgstr ""
 
-#: src/readelf.c:12715
+#: src/readelf.c:12728
 #, c-format
 msgid "cannot get symbol index of archive '%s': %s"
 msgstr ""
 
-#: src/readelf.c:12718
+#: src/readelf.c:12731
 #, c-format
 msgid ""
 "\n"
 "Archive '%s' has no symbol index\n"
 msgstr ""
 
-#: src/readelf.c:12722
+#: src/readelf.c:12735
 #, c-format
 msgid ""
 "\n"
 "Index of archive '%s' has %zu entries:\n"
 msgstr ""
 
-#: src/readelf.c:12740
+#: src/readelf.c:12753
 #, fuzzy, c-format
 msgid "cannot extract member at offset %zu in '%s': %s"
 msgstr "konnte Programm-Kopf nicht erstellen: %s"
 
-#: src/readelf.c:12745
+#: src/readelf.c:12758
 #, c-format
 msgid "Archive member '%s' contains:\n"
 msgstr ""
@@ -6153,7 +6158,7 @@
 msgid "cannot get shdrstrndx:%s"
 msgstr "konnte Abschnittsdaten nicht holen: %s"
 
-#: src/unstrip.c:248 src/unstrip.c:2038
+#: src/unstrip.c:248 src/unstrip.c:2081
 #, c-format
 msgid "cannot get ELF header: %s"
 msgstr ""
@@ -6173,12 +6178,12 @@
 msgid "cannot copy ELF header: %s"
 msgstr ""
 
-#: src/unstrip.c:269 src/unstrip.c:2056 src/unstrip.c:2099
+#: src/unstrip.c:269 src/unstrip.c:2099 src/unstrip.c:2142
 #, fuzzy, c-format
 msgid "cannot get number of program headers: %s"
 msgstr "konnte Programm-Kopf nicht erstellen: %s"
 
-#: src/unstrip.c:274 src/unstrip.c:2060
+#: src/unstrip.c:274 src/unstrip.c:2103
 #, c-format
 msgid "cannot create program headers: %s"
 msgstr "konnte Programm-Kopf nicht erstellen: %s"
@@ -6193,12 +6198,12 @@
 msgid "cannot copy section header: %s"
 msgstr ""
 
-#: src/unstrip.c:293 src/unstrip.c:1669
+#: src/unstrip.c:293 src/unstrip.c:1703
 #, c-format
 msgid "cannot get section data: %s"
 msgstr "konnte Abschnittsdaten nicht holen: %s"
 
-#: src/unstrip.c:295 src/unstrip.c:1671
+#: src/unstrip.c:295 src/unstrip.c:1705
 #, c-format
 msgid "cannot copy section data: %s"
 msgstr "konnte Abschnittsdaten nicht kopieren: %s"
@@ -6208,14 +6213,14 @@
 msgid "cannot create directory '%s'"
 msgstr "konnte Verzeichnis nicht erstellen: %s"
 
-#: src/unstrip.c:391 src/unstrip.c:647 src/unstrip.c:681 src/unstrip.c:847
-#: src/unstrip.c:1706
+#: src/unstrip.c:391 src/unstrip.c:651 src/unstrip.c:685 src/unstrip.c:853
+#: src/unstrip.c:1745
 #, c-format
 msgid "cannot get symbol table entry: %s"
 msgstr "konnte Eintrag aus der Symboltabelle nicht holen: %s"
 
-#: src/unstrip.c:407 src/unstrip.c:650 src/unstrip.c:671 src/unstrip.c:684
-#: src/unstrip.c:1727 src/unstrip.c:1922 src/unstrip.c:1946
+#: src/unstrip.c:407 src/unstrip.c:654 src/unstrip.c:675 src/unstrip.c:688
+#: src/unstrip.c:1766 src/unstrip.c:1961 src/unstrip.c:1985
 #, c-format
 msgid "cannot update symbol table: %s"
 msgstr "konnte Symboltabelle nicht aktualisieren: %s"
@@ -6225,228 +6230,243 @@
 msgid "cannot update section header: %s"
 msgstr ""
 
-#: src/unstrip.c:459 src/unstrip.c:473
+#: src/unstrip.c:463 src/unstrip.c:477
 #, c-format
 msgid "cannot update relocation: %s"
 msgstr ""
 
-#: src/unstrip.c:570
+#: src/unstrip.c:574
 #, c-format
 msgid "cannot get symbol version: %s"
 msgstr ""
 
-#: src/unstrip.c:583
+#: src/unstrip.c:587
 #, c-format
 msgid "unexpected section type in [%zu] with sh_link to symtab"
 msgstr ""
 
-#: src/unstrip.c:853
+#: src/unstrip.c:842
+#, fuzzy, c-format
+msgid "cannot get symbol section data: %s"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: src/unstrip.c:844
+#, fuzzy, c-format
+msgid "cannot get string section data: %s"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: src/unstrip.c:861
 #, fuzzy, c-format
 msgid "invalid string offset in symbol [%zu]"
 msgstr "ungültiger Offset %zu für Symbol %s"
 
-#: src/unstrip.c:1011 src/unstrip.c:1402
+#: src/unstrip.c:1019 src/unstrip.c:1423
 #, fuzzy, c-format
 msgid "cannot read section [%zu] name: %s"
 msgstr "konnte Abschnittsdaten nicht holen: %s"
 
-#: src/unstrip.c:1026
+#: src/unstrip.c:1034
 #, fuzzy, c-format
 msgid "bad sh_link for group section: %s"
 msgstr "ungültige .debug_line Sektion"
 
-#: src/unstrip.c:1032
+#: src/unstrip.c:1040
 #, fuzzy, c-format
 msgid "couldn't get shdr for group section: %s"
 msgstr "konnte Versionierungsabschnitt nicht erstellen: %s"
 
-#: src/unstrip.c:1037
+#: src/unstrip.c:1045
 #, fuzzy, c-format
 msgid "bad data for group symbol section: %s"
 msgstr "ungültige .debug_line Sektion"
 
-#: src/unstrip.c:1043
+#: src/unstrip.c:1051
 #, fuzzy, c-format
 msgid "couldn't get symbol for group section: %s"
 msgstr "konnte Programm-Kopf nicht erstellen: %s"
 
-#: src/unstrip.c:1048
+#: src/unstrip.c:1056
 #, fuzzy, c-format
 msgid "bad symbol name for group section: %s"
 msgstr "konnte Programm-Kopf nicht erstellen: %s"
 
-#: src/unstrip.c:1090 src/unstrip.c:1109 src/unstrip.c:1147
+#: src/unstrip.c:1098 src/unstrip.c:1117 src/unstrip.c:1155
 #, c-format
 msgid "cannot read '.gnu.prelink_undo' section: %s"
 msgstr ""
 
-#: src/unstrip.c:1127
+#: src/unstrip.c:1135
 #, c-format
 msgid "overflow with shnum = %zu in '%s' section"
 msgstr ""
 
-#: src/unstrip.c:1138
+#: src/unstrip.c:1146
 #, c-format
 msgid "invalid contents in '%s' section"
 msgstr ""
 
-#: src/unstrip.c:1194 src/unstrip.c:1528
+#: src/unstrip.c:1202 src/unstrip.c:1549
 #, fuzzy, c-format
 msgid "cannot find matching section for [%zu] '%s'"
 msgstr "konnte Abschnittsdaten nicht holen: %s"
 
-#: src/unstrip.c:1319 src/unstrip.c:1335 src/unstrip.c:1607 src/unstrip.c:1881
+#: src/unstrip.c:1327 src/unstrip.c:1343 src/unstrip.c:1629 src/unstrip.c:1920
 #, c-format
 msgid "cannot add section name to string table: %s"
 msgstr ""
 
-#: src/unstrip.c:1344
+#: src/unstrip.c:1352
 #, c-format
 msgid "cannot update section header string table data: %s"
 msgstr ""
 
-#: src/unstrip.c:1373 src/unstrip.c:1377
+#: src/unstrip.c:1381 src/unstrip.c:1385
 #, c-format
 msgid "cannot get section header string table section index: %s"
 msgstr ""
 
-#: src/unstrip.c:1381 src/unstrip.c:1385 src/unstrip.c:1622
+#: src/unstrip.c:1389 src/unstrip.c:1393 src/unstrip.c:1644
 #, c-format
 msgid "cannot get section count: %s"
 msgstr ""
 
-#: src/unstrip.c:1388
+#: src/unstrip.c:1396
 #, c-format
 msgid "more sections in stripped file than debug file -- arguments reversed?"
 msgstr ""
 
-#: src/unstrip.c:1450 src/unstrip.c:1543
+#: src/unstrip.c:1400
+#, c-format
+msgid "no sections in stripped file"
+msgstr ""
+
+#: src/unstrip.c:1471 src/unstrip.c:1564
 #, c-format
 msgid "cannot read section header string table: %s"
 msgstr ""
 
-#: src/unstrip.c:1601
+#: src/unstrip.c:1623
 #, c-format
 msgid "cannot add new section: %s"
 msgstr ""
 
-#: src/unstrip.c:1714
+#: src/unstrip.c:1753
 #, fuzzy, c-format
 msgid "symbol [%zu] has invalid section index"
 msgstr "ungültiger Abschnittsindex"
 
-#: src/unstrip.c:1746
+#: src/unstrip.c:1785
 #, fuzzy, c-format
 msgid "group has invalid section index [%zd]"
 msgstr "ungültiger Abschnittsindex"
 
-#: src/unstrip.c:2017
+#: src/unstrip.c:2060
 #, fuzzy, c-format
 msgid "cannot read section data: %s"
 msgstr "konnte Abschnittsdaten nicht holen: %s"
 
-#: src/unstrip.c:2046
+#: src/unstrip.c:2089
 #, c-format
 msgid "cannot update ELF header: %s"
 msgstr ""
 
-#: src/unstrip.c:2070
+#: src/unstrip.c:2113
 #, c-format
 msgid "cannot update program header: %s"
 msgstr "konnte Programm-Kopf nicht aktualisieren: %s"
 
-#: src/unstrip.c:2075 src/unstrip.c:2157
+#: src/unstrip.c:2118 src/unstrip.c:2200
 #, c-format
 msgid "cannot write output file: %s"
 msgstr ""
 
-#: src/unstrip.c:2126
+#: src/unstrip.c:2169
 #, c-format
 msgid "DWARF data not adjusted for prelinking bias; consider prelink -u"
 msgstr ""
 
-#: src/unstrip.c:2129
+#: src/unstrip.c:2172
 #, c-format
 msgid ""
 "DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"
 msgstr ""
 
-#: src/unstrip.c:2148 src/unstrip.c:2199 src/unstrip.c:2211 src/unstrip.c:2297
+#: src/unstrip.c:2191 src/unstrip.c:2242 src/unstrip.c:2254 src/unstrip.c:2340
 #, c-format
 msgid "cannot create ELF descriptor: %s"
 msgstr ""
 
-#: src/unstrip.c:2190
+#: src/unstrip.c:2233
 msgid "WARNING: "
 msgstr ""
 
-#: src/unstrip.c:2192
+#: src/unstrip.c:2235
 msgid ", use --force"
 msgstr ""
 
-#: src/unstrip.c:2215
+#: src/unstrip.c:2258
 msgid "ELF header identification (e_ident) different"
 msgstr ""
 
-#: src/unstrip.c:2218
+#: src/unstrip.c:2261
 msgid "ELF header type (e_type) different"
 msgstr ""
 
-#: src/unstrip.c:2221
+#: src/unstrip.c:2264
 msgid "ELF header machine type (e_machine) different"
 msgstr ""
 
-#: src/unstrip.c:2224
+#: src/unstrip.c:2267
 msgid "stripped program header (e_phnum) smaller than unstripped"
 msgstr ""
 
-#: src/unstrip.c:2254
+#: src/unstrip.c:2297
 #, c-format
 msgid "cannot find stripped file for module '%s': %s"
 msgstr ""
 
-#: src/unstrip.c:2258
+#: src/unstrip.c:2301
 #, c-format
 msgid "cannot open stripped file '%s' for module '%s': %s"
 msgstr ""
 
-#: src/unstrip.c:2273
+#: src/unstrip.c:2316
 #, c-format
 msgid "cannot find debug file for module '%s': %s"
 msgstr ""
 
-#: src/unstrip.c:2277
+#: src/unstrip.c:2320
 #, c-format
 msgid "cannot open debug file '%s' for module '%s': %s"
 msgstr ""
 
-#: src/unstrip.c:2290
+#: src/unstrip.c:2333
 #, c-format
 msgid "module '%s' file '%s' is not stripped"
 msgstr ""
 
-#: src/unstrip.c:2321
+#: src/unstrip.c:2364
 #, c-format
 msgid "cannot cache section addresses for module '%s': %s"
 msgstr ""
 
-#: src/unstrip.c:2454
+#: src/unstrip.c:2497
 #, c-format
 msgid "no matching modules found"
 msgstr "kein passendes Modul gefunden"
 
-#: src/unstrip.c:2463
+#: src/unstrip.c:2506
 #, c-format
 msgid "matched more than one module"
 msgstr "mehr als ein passendes Modul"
 
-#: src/unstrip.c:2507
+#: src/unstrip.c:2550
 msgid ""
 "STRIPPED-FILE DEBUG-FILE\n"
 "[MODULE...]"
 msgstr ""
 
-#: src/unstrip.c:2508
+#: src/unstrip.c:2551
 msgid ""
 "Combine stripped files with separate symbols and debug information.\n"
 "\n"
diff --git a/po/es.po b/po/es.po
index 9b1ce7a..0d32a5d 100644
--- a/po/es.po
+++ b/po/es.po
@@ -10,7 +10,7 @@
 msgstr ""
 "Project-Id-Version: elfutils.master.es\n"
 "Report-Msgid-Bugs-To: https://sourceware.org/bugzilla/\n"
-"POT-Creation-Date: 2019-08-28 13:23+0200\n"
+"POT-Creation-Date: 2019-11-26 09:48+0100\n"
 "PO-Revision-Date: 2011-01-10 15:17-0300\n"
 "Last-Translator: Claudio Rodrigo Pereyra Diaz <claudiorodrigo@pereyradiaz."
 "com.ar>\n"
@@ -29,7 +29,7 @@
 "colorize the output.  WHEN defaults to 'always' or can be 'auto' or 'never'"
 msgstr ""
 
-#: lib/color.c:127
+#: lib/color.c:129
 #, c-format
 msgid ""
 "%s: invalid argument '%s' for '--color'\n"
@@ -39,7 +39,7 @@
 "  - 'auto', 'tty', 'if-tty'\n"
 msgstr ""
 
-#: lib/color.c:190 src/objdump.c:726
+#: lib/color.c:194 src/objdump.c:728
 #, fuzzy, c-format
 msgid "cannot allocate memory"
 msgstr "No se puede asignar sección PLT: %s"
@@ -57,18 +57,18 @@
 "garantía, ni siquiera para SU COMERCIALIZACIÓN o PARA SER USADO CON UN FIN "
 "DETERMINADO.\n"
 
-#: lib/xmalloc.c:52 lib/xmalloc.c:65 lib/xmalloc.c:77 src/readelf.c:3437
-#: src/readelf.c:11386 src/unstrip.c:2350 src/unstrip.c:2556
+#: lib/xmalloc.c:52 lib/xmalloc.c:65 lib/xmalloc.c:77 src/readelf.c:3449
+#: src/readelf.c:11398 src/unstrip.c:2393 src/unstrip.c:2599
 #, c-format
 msgid "memory exhausted"
 msgstr "memoria agotada"
 
-#: libasm/asm_error.c:65 libdw/dwarf_error.c:57 libdwfl/libdwflP.h:50
+#: libasm/asm_error.c:65 libdw/dwarf_error.c:57 libdwfl/libdwflP.h:51
 #: libelf/elf_error.c:60
 msgid "no error"
 msgstr "ningún error"
 
-#: libasm/asm_error.c:66 libdw/dwarf_error.c:67 libdwfl/libdwflP.h:52
+#: libasm/asm_error.c:66 libdw/dwarf_error.c:67 libdwfl/libdwflP.h:53
 #: libelf/elf_error.c:91
 msgid "out of memory"
 msgstr "memoria agotada"
@@ -105,7 +105,7 @@
 msgid "no backend support available"
 msgstr "No hay soporte de segundo plano"
 
-#: libasm/asm_error.c:83 libdw/dwarf_error.c:58 libdwfl/libdwflP.h:51
+#: libasm/asm_error.c:83 libdw/dwarf_error.c:58 libdwfl/libdwflP.h:52
 #: libelf/elf_error.c:63
 msgid "unknown error"
 msgstr "error desconocido"
@@ -221,7 +221,7 @@
 msgid "invalid directory index"
 msgstr "Índice de directorio inválido"
 
-#: libdw/dwarf_error.c:87 libdwfl/libdwflP.h:71
+#: libdw/dwarf_error.c:87 libdwfl/libdwflP.h:72
 msgid "address out of range"
 msgstr "dirección fuera de rango"
 
@@ -252,7 +252,7 @@
 msgid "invalid address range index"
 msgstr "Índice de dirección de rango inválido"
 
-#: libdw/dwarf_error.c:94 libdwfl/libdwflP.h:72
+#: libdw/dwarf_error.c:94 libdwfl/libdwflP.h:73
 msgid "no matching address range"
 msgstr "dirección de rango no coincidente"
 
@@ -300,7 +300,7 @@
 msgid ".debug_addr section missing"
 msgstr ".debug_ranges section faltante"
 
-#: libdwfl/argp-std.c:50 src/stack.c:638 src/unstrip.c:2497
+#: libdwfl/argp-std.c:50 src/stack.c:638 src/unstrip.c:2540
 msgid "Input selection options:"
 msgstr "Opciones de selección de entrada:"
 
@@ -367,159 +367,159 @@
 msgid "No modules recognized in core file"
 msgstr "No hay módulos reconocidos en el archivo core"
 
-#: libdwfl/libdwflP.h:53
+#: libdwfl/libdwflP.h:54
 msgid "See errno"
 msgstr "Ve errno"
 
-#: libdwfl/libdwflP.h:54
+#: libdwfl/libdwflP.h:55
 msgid "See elf_errno"
 msgstr "Ver elf_errno"
 
-#: libdwfl/libdwflP.h:55
+#: libdwfl/libdwflP.h:56
 msgid "See dwarf_errno"
 msgstr "Ver dwarf_errno"
 
-#: libdwfl/libdwflP.h:56
+#: libdwfl/libdwflP.h:57
 msgid "See ebl_errno (XXX missing)"
 msgstr "Ver ebl_errno (no se encuentra XXX)"
 
-#: libdwfl/libdwflP.h:57
+#: libdwfl/libdwflP.h:58
 msgid "gzip decompression failed"
 msgstr "falló la descompresión gzip"
 
-#: libdwfl/libdwflP.h:58
+#: libdwfl/libdwflP.h:59
 msgid "bzip2 decompression failed"
 msgstr "falló la descompresión bzip2"
 
-#: libdwfl/libdwflP.h:59
+#: libdwfl/libdwflP.h:60
 msgid "LZMA decompression failed"
 msgstr "falló la descompresión LZMA"
 
-#: libdwfl/libdwflP.h:60
+#: libdwfl/libdwflP.h:61
 msgid "no support library found for machine"
 msgstr "no se ha encontrado una biblioteca de soporte para la máquina"
 
-#: libdwfl/libdwflP.h:61
+#: libdwfl/libdwflP.h:62
 msgid "Callbacks missing for ET_REL file"
 msgstr "No se encuentran rellamadas para el archivo ET_REL"
 
-#: libdwfl/libdwflP.h:62
+#: libdwfl/libdwflP.h:63
 msgid "Unsupported relocation type"
 msgstr "Tipo de reubicación no soportada"
 
-#: libdwfl/libdwflP.h:63
+#: libdwfl/libdwflP.h:64
 msgid "r_offset is bogus"
 msgstr "r_offset se encuentra inutilizable"
 
-#: libdwfl/libdwflP.h:64 libelf/elf_error.c:115 libelf/elf_error.c:175
+#: libdwfl/libdwflP.h:65 libelf/elf_error.c:115 libelf/elf_error.c:175
 msgid "offset out of range"
 msgstr "desplazamiento fuera de rango"
 
-#: libdwfl/libdwflP.h:65
+#: libdwfl/libdwflP.h:66
 msgid "relocation refers to undefined symbol"
 msgstr "la reubicación hace referencia a un símbolo no definido"
 
-#: libdwfl/libdwflP.h:66
+#: libdwfl/libdwflP.h:67
 msgid "Callback returned failure"
 msgstr "La rellamada devolvió un fallo"
 
-#: libdwfl/libdwflP.h:67
+#: libdwfl/libdwflP.h:68
 msgid "No DWARF information found"
 msgstr "No se ha encontrado una información DWARF"
 
-#: libdwfl/libdwflP.h:68
+#: libdwfl/libdwflP.h:69
 msgid "No symbol table found"
 msgstr "No se ha encontrado una tabla simbólica"
 
-#: libdwfl/libdwflP.h:69
+#: libdwfl/libdwflP.h:70
 msgid "No ELF program headers"
 msgstr "No existen encabezados de programa ELF"
 
-#: libdwfl/libdwflP.h:70
+#: libdwfl/libdwflP.h:71
 msgid "address range overlaps an existing module"
 msgstr "el rango de dirección se superpone con un módulo existente"
 
-#: libdwfl/libdwflP.h:73
+#: libdwfl/libdwflP.h:74
 msgid "image truncated"
 msgstr "imagen truncada"
 
-#: libdwfl/libdwflP.h:74
+#: libdwfl/libdwflP.h:75
 msgid "ELF file opened"
 msgstr "Archivo ELF abierto"
 
-#: libdwfl/libdwflP.h:75
+#: libdwfl/libdwflP.h:76
 msgid "not a valid ELF file"
 msgstr "no es un archivo ELF válido"
 
-#: libdwfl/libdwflP.h:76
+#: libdwfl/libdwflP.h:77
 msgid "cannot handle DWARF type description"
 msgstr "no es posible manipular tipo de descripción DWARF"
 
-#: libdwfl/libdwflP.h:77
+#: libdwfl/libdwflP.h:78
 msgid "ELF file does not match build ID"
 msgstr "El archivo ELF no coincide con el ID construido"
 
-#: libdwfl/libdwflP.h:78
+#: libdwfl/libdwflP.h:79
 #, fuzzy
 msgid "corrupt .gnu.prelink_undo section data"
 msgstr "no se puede leer sección '.gnu.prelink_undo': %s"
 
-#: libdwfl/libdwflP.h:79
+#: libdwfl/libdwflP.h:80
 msgid "Internal error due to ebl"
 msgstr ""
 
-#: libdwfl/libdwflP.h:80
+#: libdwfl/libdwflP.h:81
 msgid "Missing data in core file"
 msgstr ""
 
-#: libdwfl/libdwflP.h:81
+#: libdwfl/libdwflP.h:82
 #, fuzzy
 msgid "Invalid register"
 msgstr "Parámetro inválido"
 
-#: libdwfl/libdwflP.h:82
+#: libdwfl/libdwflP.h:83
 msgid "Error reading process memory"
 msgstr ""
 
-#: libdwfl/libdwflP.h:83
+#: libdwfl/libdwflP.h:84
 msgid "Couldn't find architecture of any ELF"
 msgstr ""
 
-#: libdwfl/libdwflP.h:84
+#: libdwfl/libdwflP.h:85
 msgid "Error parsing /proc filesystem"
 msgstr ""
 
-#: libdwfl/libdwflP.h:85
+#: libdwfl/libdwflP.h:86
 #, fuzzy
 msgid "Invalid DWARF"
 msgstr "DWARF inválido"
 
-#: libdwfl/libdwflP.h:86
+#: libdwfl/libdwflP.h:87
 msgid "Unsupported DWARF"
 msgstr ""
 
-#: libdwfl/libdwflP.h:87
+#: libdwfl/libdwflP.h:88
 msgid "Unable to find more threads"
 msgstr ""
 
-#: libdwfl/libdwflP.h:88
+#: libdwfl/libdwflP.h:89
 msgid "Dwfl already has attached state"
 msgstr ""
 
-#: libdwfl/libdwflP.h:89
+#: libdwfl/libdwflP.h:90
 msgid "Dwfl has no attached state"
 msgstr ""
 
-#: libdwfl/libdwflP.h:90
+#: libdwfl/libdwflP.h:91
 msgid "Unwinding not supported for this architecture"
 msgstr ""
 
-#: libdwfl/libdwflP.h:91
+#: libdwfl/libdwflP.h:92
 #, fuzzy
 msgid "Invalid argument"
 msgstr "Parámetro inválido"
 
-#: libdwfl/libdwflP.h:92
+#: libdwfl/libdwflP.h:93
 #, fuzzy
 msgid "Not an ET_CORE ELF file"
 msgstr "no es un archivo ELF válido"
@@ -625,7 +625,7 @@
 msgid "invalid size of destination operand"
 msgstr "tamaño inválido del operando destino"
 
-#: libelf/elf_error.c:87 src/readelf.c:6154
+#: libelf/elf_error.c:87 src/readelf.c:6166
 #, c-format
 msgid "invalid encoding"
 msgstr "codificación inválida"
@@ -711,8 +711,8 @@
 msgid "invalid section header"
 msgstr "encabezamiento de sección inválida"
 
-#: libelf/elf_error.c:191 src/readelf.c:9902 src/readelf.c:10502
-#: src/readelf.c:10603 src/readelf.c:10785
+#: libelf/elf_error.c:191 src/readelf.c:9914 src/readelf.c:10514
+#: src/readelf.c:10615 src/readelf.c:10797
 #, c-format
 msgid "invalid data"
 msgstr "datos inválidos"
@@ -1382,7 +1382,7 @@
 
 #: src/elfcmp.c:734 src/findtextrel.c:205 src/nm.c:364 src/ranlib.c:141
 #: src/size.c:272 src/strings.c:185 src/strip.c:984 src/strip.c:1021
-#: src/unstrip.c:2146 src/unstrip.c:2175
+#: src/unstrip.c:2189 src/unstrip.c:2218
 #, c-format
 msgid "cannot open '%s'"
 msgstr "Imposible abrir '%s'"
@@ -1477,7 +1477,7 @@
 "Sección [%2zu] '%s': dirección de secciones de datos de hilo-local no cero\n"
 
 #. Strings for arguments in help texts.
-#: src/elfcompress.c:1336 src/elflint.c:77 src/readelf.c:153
+#: src/elfcompress.c:1336 src/elflint.c:77 src/readelf.c:158
 msgid "FILE..."
 msgstr "FICHERO..."
 
@@ -1510,14 +1510,14 @@
 msgid "Pedantic checking of ELF files compliance with gABI/psABI spec."
 msgstr "Chequeo minucioso de ficheros ELF de acuerdo con gABI/psABI "
 
-#: src/elflint.c:154 src/readelf.c:360
-#, c-format
-msgid "cannot open input file"
+#: src/elflint.c:154 src/readelf.c:368
+#, fuzzy, c-format
+msgid "cannot open input file '%s'"
 msgstr "no se puede abrir el fichero de entrada"
 
 #: src/elflint.c:161
-#, c-format
-msgid "cannot generate Elf descriptor: %s\n"
+#, fuzzy, c-format
+msgid "cannot generate Elf descriptor for '%s': %s\n"
 msgstr "no se puede crear descriptor ELF: %s\n"
 
 #: src/elflint.c:180
@@ -1529,7 +1529,7 @@
 msgid "No errors"
 msgstr "No hay errores"
 
-#: src/elflint.c:219 src/readelf.c:563
+#: src/elflint.c:219 src/readelf.c:575
 msgid "Missing file name.\n"
 msgstr "Falta el nombre de archivo.\n"
 
@@ -3774,12 +3774,12 @@
 msgid "cannot create search tree"
 msgstr "No se puede crear el árbol de búsqueda"
 
-#: src/nm.c:746 src/nm.c:1205 src/objdump.c:777 src/readelf.c:623
-#: src/readelf.c:1435 src/readelf.c:1586 src/readelf.c:1787 src/readelf.c:1993
-#: src/readelf.c:2183 src/readelf.c:2361 src/readelf.c:2437 src/readelf.c:2695
-#: src/readelf.c:2771 src/readelf.c:2858 src/readelf.c:3456 src/readelf.c:3506
-#: src/readelf.c:3569 src/readelf.c:11218 src/readelf.c:12403
-#: src/readelf.c:12614 src/readelf.c:12682 src/size.c:398 src/size.c:470
+#: src/nm.c:746 src/nm.c:1205 src/objdump.c:779 src/readelf.c:635
+#: src/readelf.c:1447 src/readelf.c:1598 src/readelf.c:1799 src/readelf.c:2005
+#: src/readelf.c:2195 src/readelf.c:2373 src/readelf.c:2449 src/readelf.c:2707
+#: src/readelf.c:2783 src/readelf.c:2870 src/readelf.c:3468 src/readelf.c:3518
+#: src/readelf.c:3581 src/readelf.c:11230 src/readelf.c:12415
+#: src/readelf.c:12626 src/readelf.c:12695 src/size.c:398 src/size.c:470
 #: src/strip.c:1038
 #, c-format
 msgid "cannot get section header string table index"
@@ -3827,12 +3827,12 @@
 "%s: el tamaño de la entrada en la sección `%s' no es el que esperábamos "
 
 #. XXX Add machine specific object file types.
-#: src/nm.c:1526
+#: src/nm.c:1527
 #, c-format
 msgid "%s%s%s%s: Invalid operation"
 msgstr "%s%s%s%s: Operación inválida"
 
-#: src/nm.c:1583
+#: src/nm.c:1584
 #, c-format
 msgid "%s%s%s: no symbols"
 msgstr "%s%s%s: No hay símbolos"
@@ -3867,7 +3867,7 @@
 msgid "Show information from FILEs (a.out by default)."
 msgstr "Muestra información de FICHEROS (a.out por defecto)."
 
-#: src/objdump.c:218 src/readelf.c:568
+#: src/objdump.c:218 src/readelf.c:580
 msgid "No operation specified.\n"
 msgstr "No se especificó una operación.\n"
 
@@ -3876,11 +3876,11 @@
 msgid "while close `%s'"
 msgstr "mientras cierra `%s'"
 
-#: src/objdump.c:363 src/readelf.c:2088 src/readelf.c:2280
+#: src/objdump.c:363 src/readelf.c:2100 src/readelf.c:2292
 msgid "INVALID SYMBOL"
 msgstr "SÍMBOLO INVÁLIDO"
 
-#: src/objdump.c:378 src/readelf.c:2122 src/readelf.c:2316
+#: src/objdump.c:378 src/readelf.c:2134 src/readelf.c:2328
 msgid "INVALID SECTION"
 msgstr "SECCIÓN INVÁLIDA"
 
@@ -3934,85 +3934,90 @@
 msgid "error while freeing sub-ELF descriptor: %s"
 msgstr "error al liberar descriptor sub-ELF: %s"
 
-#: src/readelf.c:94
+#: src/readelf.c:97
 #, fuzzy
 msgid "ELF input selection:"
 msgstr "Selección de salida de ELF:"
 
-#: src/readelf.c:96
+#: src/readelf.c:99
 msgid ""
 "Use the named SECTION (default .gnu_debugdata) as (compressed) ELF input data"
 msgstr ""
 
-#: src/readelf.c:99
+#: src/readelf.c:102
 msgid ""
 "Used with -w to find the skeleton Compile Units in FILE associated with the "
 "Split Compile units in a .dwo input file"
 msgstr ""
 
-#: src/readelf.c:101
+#: src/readelf.c:104
 msgid "ELF output selection:"
 msgstr "Selección de salida de ELF:"
 
-#: src/readelf.c:103
+#: src/readelf.c:106
 msgid "All these plus -p .strtab -p .dynstr -p .comment"
 msgstr "Todo esto mas -p .strtab -p .dynstr -p .comment"
 
-#: src/readelf.c:104
+#: src/readelf.c:107
 msgid "Display the dynamic segment"
 msgstr "Mostrar el segmento dinámico"
 
-#: src/readelf.c:105
+#: src/readelf.c:108
 msgid "Display the ELF file header"
 msgstr "Mostrar el encabezamiento del fichero ELF"
 
-#: src/readelf.c:107
+#: src/readelf.c:110
 msgid "Display histogram of bucket list lengths"
 msgstr "Mostrar histograma de las longitudes de las listas de cubetas"
 
-#: src/readelf.c:108
+#: src/readelf.c:111
 msgid "Display the program headers"
 msgstr "Mostrar encabezamientos de programa"
 
-#: src/readelf.c:110
+#: src/readelf.c:113
 msgid "Display relocations"
 msgstr "Mostrar reubicaciones"
 
-#: src/readelf.c:111
+#: src/readelf.c:114
 #, fuzzy
 msgid "Display the section groups"
 msgstr "Mostrar los encabezados de las secciones"
 
-#: src/readelf.c:112
+#: src/readelf.c:115
 msgid "Display the sections' headers"
 msgstr "Mostrar los encabezados de las secciones"
 
-#: src/readelf.c:115
+#: src/readelf.c:118
 #, fuzzy
 msgid "Display the symbol table sections"
 msgstr "Mostrar la tabla de símbolos"
 
-#: src/readelf.c:116
+#: src/readelf.c:120
+#, fuzzy
+msgid "Display (only) the dynamic symbol table"
+msgstr "Mostrar sólo símbolos externos"
+
+#: src/readelf.c:121
 msgid "Display versioning information"
 msgstr "Mostrar información de versión"
 
-#: src/readelf.c:117
+#: src/readelf.c:122
 msgid "Display the ELF notes"
 msgstr "Mostrar las notas ELF"
 
-#: src/readelf.c:119
+#: src/readelf.c:124
 msgid "Display architecture specific information, if any"
 msgstr "Mostrar información específica de la arquitectura (si es que la hay)"
 
-#: src/readelf.c:121
+#: src/readelf.c:126
 msgid "Display sections for exception handling"
 msgstr "Muestra secciones para manejo de excepciones"
 
-#: src/readelf.c:123
+#: src/readelf.c:128
 msgid "Additional output selection:"
 msgstr "Selección de salida adicional:"
 
-#: src/readelf.c:125
+#: src/readelf.c:130
 #, fuzzy
 msgid ""
 "Display DWARF section content.  SECTION can be one of abbrev, addr, aranges, "
@@ -4023,197 +4028,197 @@
 "siguiente: abbrev, aranges, frame, info, loc, line, ranges, pubnames, str, "
 "macinfo, o exception"
 
-#: src/readelf.c:129
+#: src/readelf.c:134
 msgid "Dump the uninterpreted contents of SECTION, by number or name"
 msgstr "Vuelca los contenidos no interpretados de SECCIÓN, por número o nombre"
 
-#: src/readelf.c:131
+#: src/readelf.c:136
 msgid "Print string contents of sections"
 msgstr "Imprime contenido de cadena de secciones"
 
-#: src/readelf.c:134
+#: src/readelf.c:139
 msgid "Display the symbol index of an archive"
 msgstr "Muestra el índice de símbolos de un archivo"
 
-#: src/readelf.c:136
+#: src/readelf.c:141
 msgid "Output control:"
 msgstr "Control de salida:"
 
-#: src/readelf.c:138
+#: src/readelf.c:143
 msgid "Do not find symbol names for addresses in DWARF data"
 msgstr ""
 "No se encuentran los nombres de símbolos para direcciones en datos DWARF"
 
-#: src/readelf.c:140
+#: src/readelf.c:145
 #, fuzzy
 msgid ""
 "Display just offsets instead of resolving values to addresses in DWARF data"
 msgstr ""
 "No se encuentran los nombres de símbolos para direcciones en datos DWARF"
 
-#: src/readelf.c:142
+#: src/readelf.c:147
 msgid "Ignored for compatibility (lines always wide)"
 msgstr ""
 
-#: src/readelf.c:144
+#: src/readelf.c:149
 msgid ""
 "Show compression information for compressed sections (when used with -S); "
 "decompress section before dumping data (when used with -p or -x)"
 msgstr ""
 
 #. Short description of program.
-#: src/readelf.c:149
+#: src/readelf.c:154
 msgid "Print information from ELF file in human-readable form."
 msgstr ""
 "Imprimir información del fichero ELF en una forma comprensible para los "
 "seres humanos."
 
 #. Look up once.
-#: src/readelf.c:342
+#: src/readelf.c:350
 msgid "yes"
 msgstr "sí"
 
-#: src/readelf.c:343
+#: src/readelf.c:351
 msgid "no"
 msgstr "no"
 
-#: src/readelf.c:536
+#: src/readelf.c:548
 #, c-format
 msgid "Unknown DWARF debug section `%s'.\n"
 msgstr "Sección de depuración DWARF desconocida `%s'.\n"
 
-#: src/readelf.c:607 src/readelf.c:718
+#: src/readelf.c:619 src/readelf.c:730
 #, c-format
 msgid "cannot generate Elf descriptor: %s"
 msgstr "no se puede crear descriptor ELF: %s"
 
-#: src/readelf.c:614 src/readelf.c:941 src/strip.c:1133
+#: src/readelf.c:626 src/readelf.c:953 src/strip.c:1133
 #, c-format
 msgid "cannot determine number of sections: %s"
 msgstr "no se pudieron determinar el número de secciones: %s"
 
-#: src/readelf.c:632 src/readelf.c:1251 src/readelf.c:1459
+#: src/readelf.c:644 src/readelf.c:1263 src/readelf.c:1471
 #, c-format
 msgid "cannot get section: %s"
 msgstr "No se puede encontrar la sección: %s"
 
-#: src/readelf.c:641 src/readelf.c:1258 src/readelf.c:1467 src/readelf.c:12634
-#: src/unstrip.c:395 src/unstrip.c:426 src/unstrip.c:481 src/unstrip.c:600
-#: src/unstrip.c:621 src/unstrip.c:661 src/unstrip.c:873 src/unstrip.c:1204
-#: src/unstrip.c:1331 src/unstrip.c:1355 src/unstrip.c:1398 src/unstrip.c:1462
-#: src/unstrip.c:1636 src/unstrip.c:1770 src/unstrip.c:1913 src/unstrip.c:2008
+#: src/readelf.c:653 src/readelf.c:1270 src/readelf.c:1479 src/readelf.c:12646
+#: src/unstrip.c:395 src/unstrip.c:426 src/unstrip.c:485 src/unstrip.c:604
+#: src/unstrip.c:625 src/unstrip.c:665 src/unstrip.c:881 src/unstrip.c:1212
+#: src/unstrip.c:1339 src/unstrip.c:1363 src/unstrip.c:1419 src/unstrip.c:1483
+#: src/unstrip.c:1658 src/unstrip.c:1809 src/unstrip.c:1952 src/unstrip.c:2051
 #, c-format
 msgid "cannot get section header: %s"
 msgstr "No se puede obtener encabezamiento de sección: %s"
 
-#: src/readelf.c:649
+#: src/readelf.c:661
 #, fuzzy, c-format
 msgid "cannot get section name"
 msgstr "no se puede obtener encabezamiento de sección\n"
 
-#: src/readelf.c:658 src/readelf.c:6564 src/readelf.c:10490 src/readelf.c:10592
-#: src/readelf.c:10770
+#: src/readelf.c:670 src/readelf.c:6576 src/readelf.c:10502 src/readelf.c:10604
+#: src/readelf.c:10782
 #, c-format
 msgid "cannot get %s content: %s"
 msgstr "No se puede obtener el contenido %s: %s"
 
-#: src/readelf.c:674
+#: src/readelf.c:686
 #, fuzzy, c-format
 msgid "cannot create temp file '%s'"
 msgstr "no se puede crear fichero nuevo '%s': %s"
 
-#: src/readelf.c:683
+#: src/readelf.c:695
 #, fuzzy, c-format
 msgid "cannot write section data"
 msgstr "no se puede leer la sección de datos: %s"
 
-#: src/readelf.c:689 src/readelf.c:706 src/readelf.c:735
+#: src/readelf.c:701 src/readelf.c:718 src/readelf.c:747
 #, c-format
 msgid "error while closing Elf descriptor: %s"
 msgstr "error al cerrar el descriptor ELF: %s"
 
-#: src/readelf.c:696
+#: src/readelf.c:708
 #, fuzzy, c-format
 msgid "error while rewinding file descriptor"
 msgstr "error al cerrar el descriptor ELF: %s"
 
-#: src/readelf.c:730
+#: src/readelf.c:742
 #, c-format
 msgid "'%s' is not an archive, cannot print archive index"
 msgstr "'%s' no es un archivo, no se puede imprimir índice de archivo"
 
-#: src/readelf.c:834
+#: src/readelf.c:846
 #, c-format
 msgid "cannot stat input file"
 msgstr "no sepudo stat archivo de entrada"
 
-#: src/readelf.c:836
+#: src/readelf.c:848
 #, c-format
 msgid "input file is empty"
 msgstr "archivo de entrada vacío"
 
-#: src/readelf.c:838
+#: src/readelf.c:850
 #, c-format
 msgid "failed reading '%s': %s"
 msgstr "Falló lectura de '%s': %s"
 
-#: src/readelf.c:867
+#: src/readelf.c:879
 #, fuzzy, c-format
 msgid "No such section '%s' in '%s'"
 msgstr "No se puede obtener contenido de sección %zu en '%s': %s"
 
-#: src/readelf.c:926
+#: src/readelf.c:938
 #, c-format
 msgid "cannot read ELF header: %s"
 msgstr "no se pudo leer encabezamiento ELF: %s"
 
-#: src/readelf.c:934
+#: src/readelf.c:946
 #, c-format
 msgid "cannot create EBL handle"
 msgstr "no se puede crear EBL"
 
-#: src/readelf.c:947
+#: src/readelf.c:959
 #, c-format
 msgid "cannot determine number of program headers: %s"
 msgstr "no se pudo determinar la cantidad de encabezados de programa: %s"
 
-#: src/readelf.c:979
+#: src/readelf.c:991
 #, fuzzy, c-format
 msgid "cannot read ELF: %s"
 msgstr "no sepuede leer %s: %s"
 
-#: src/readelf.c:1040
+#: src/readelf.c:1052
 msgid "NONE (None)"
 msgstr "NONE (Ninguno)"
 
-#: src/readelf.c:1041
+#: src/readelf.c:1053
 msgid "REL (Relocatable file)"
 msgstr "REL (Fichero reubicable)"
 
-#: src/readelf.c:1042
+#: src/readelf.c:1054
 msgid "EXEC (Executable file)"
 msgstr "EXEC (Fichero ejecutable)"
 
-#: src/readelf.c:1043
+#: src/readelf.c:1055
 msgid "DYN (Shared object file)"
 msgstr "DYN (Fichero objeto compartido)"
 
-#: src/readelf.c:1044
+#: src/readelf.c:1056
 msgid "CORE (Core file)"
 msgstr "CORE (Fichero núcleo)"
 
-#: src/readelf.c:1049
+#: src/readelf.c:1061
 #, c-format
 msgid "OS Specific: (%x)\n"
 msgstr "OS Specific: (%x)\n"
 
 #. && e_type <= ET_HIPROC always true
-#: src/readelf.c:1051
+#: src/readelf.c:1063
 #, c-format
 msgid "Processor Specific: (%x)\n"
 msgstr "Específico del procesador: (%x)\n"
 
-#: src/readelf.c:1061
+#: src/readelf.c:1073
 msgid ""
 "ELF Header:\n"
 "  Magic:  "
@@ -4221,7 +4226,7 @@
 "Encabezamiento ELF:\n"
 "  Mágico:  "
 
-#: src/readelf.c:1065
+#: src/readelf.c:1077
 #, c-format
 msgid ""
 "\n"
@@ -4230,125 +4235,125 @@
 "\n"
 "  Clase:                             %s\n"
 
-#: src/readelf.c:1070
+#: src/readelf.c:1082
 #, c-format
 msgid "  Data:                              %s\n"
 msgstr "  Datos:                             %s\n"
 
-#: src/readelf.c:1076
+#: src/readelf.c:1088
 #, c-format
 msgid "  Ident Version:                     %hhd %s\n"
 msgstr "  Versión ident:                     %hhd %s\n"
 
-#: src/readelf.c:1078 src/readelf.c:1100
+#: src/readelf.c:1090 src/readelf.c:1112
 msgid "(current)"
 msgstr "(actual)"
 
-#: src/readelf.c:1082
+#: src/readelf.c:1094
 #, c-format
 msgid "  OS/ABI:                            %s\n"
 msgstr "  OS/ABI:                            %s\n"
 
-#: src/readelf.c:1085
+#: src/readelf.c:1097
 #, c-format
 msgid "  ABI Version:                       %hhd\n"
 msgstr "  Versión ABI:                       %hhd\n"
 
-#: src/readelf.c:1088
+#: src/readelf.c:1100
 msgid "  Type:                              "
 msgstr "  Tipo:                              "
 
-#: src/readelf.c:1093
+#: src/readelf.c:1105
 #, c-format
 msgid "  Machine:                           %s\n"
 msgstr "  Máquina:                           %s\n"
 
-#: src/readelf.c:1095
+#: src/readelf.c:1107
 #, fuzzy, c-format
 msgid "  Machine:                           <unknown>: 0x%x\n"
 msgstr "  Máquina:                           %s\n"
 
-#: src/readelf.c:1098
+#: src/readelf.c:1110
 #, c-format
 msgid "  Version:                           %d %s\n"
 msgstr "  Versión:                           %d %s\n"
 
-#: src/readelf.c:1102
+#: src/readelf.c:1114
 #, c-format
 msgid "  Entry point address:               %#<PRIx64>\n"
 msgstr "  Dirección de punto de entrada:               %#<PRIx64>\n"
 
-#: src/readelf.c:1105
+#: src/readelf.c:1117
 #, c-format
 msgid "  Start of program headers:          %<PRId64> %s\n"
 msgstr "  Inicio de encabezamientos de programa:          %<PRId64> %s\n"
 
-#: src/readelf.c:1106 src/readelf.c:1109
+#: src/readelf.c:1118 src/readelf.c:1121
 msgid "(bytes into file)"
 msgstr " (bytes en el archivo)"
 
-#: src/readelf.c:1108
+#: src/readelf.c:1120
 #, c-format
 msgid "  Start of section headers:          %<PRId64> %s\n"
 msgstr "  Inicio de encabezamientos de sección:          %<PRId64> %s\n"
 
-#: src/readelf.c:1111
+#: src/readelf.c:1123
 #, c-format
 msgid "  Flags:                             %s\n"
 msgstr "  Indicadores:                             %s\n"
 
-#: src/readelf.c:1114
+#: src/readelf.c:1126
 #, c-format
 msgid "  Size of this header:               %<PRId16> %s\n"
 msgstr "  Tamaño de este encabezamiento:               %<PRId16> %s\n"
 
-#: src/readelf.c:1115 src/readelf.c:1118 src/readelf.c:1135
+#: src/readelf.c:1127 src/readelf.c:1130 src/readelf.c:1147
 msgid "(bytes)"
 msgstr "(bytes)"
 
-#: src/readelf.c:1117
+#: src/readelf.c:1129
 #, c-format
 msgid "  Size of program header entries:    %<PRId16> %s\n"
 msgstr ""
 "  Tamaño de las entradas en encabezamiento del programa:    %<PRId16> %s\n"
 
-#: src/readelf.c:1120
+#: src/readelf.c:1132
 #, c-format
 msgid "  Number of program headers entries: %<PRId16>"
 msgstr "  Cantidad de entradas de encabezados de programa: %<PRId16>"
 
-#: src/readelf.c:1127
+#: src/readelf.c:1139
 #, c-format
 msgid " (%<PRIu32> in [0].sh_info)"
 msgstr " (%<PRIu32> in [0].sh_info)"
 
-#: src/readelf.c:1130 src/readelf.c:1147 src/readelf.c:1161
+#: src/readelf.c:1142 src/readelf.c:1159 src/readelf.c:1173
 msgid " ([0] not available)"
 msgstr " ([0] no disponible)"
 
-#: src/readelf.c:1134
+#: src/readelf.c:1146
 #, c-format
 msgid "  Size of section header entries:    %<PRId16> %s\n"
 msgstr ""
 "  Tamaño de las entradas en el encabezamiento de sección:    %<PRId16> %s\n"
 
-#: src/readelf.c:1137
+#: src/readelf.c:1149
 #, c-format
 msgid "  Number of section headers entries: %<PRId16>"
 msgstr "  Cantidad de entradas en los encabezamientos de sección: %<PRId16>"
 
-#: src/readelf.c:1144
+#: src/readelf.c:1156
 #, c-format
 msgid " (%<PRIu32> in [0].sh_size)"
 msgstr " (%<PRIu32> en [0].sh_size)"
 
 #. We managed to get the zeroth section.
-#: src/readelf.c:1157
+#: src/readelf.c:1169
 #, c-format
 msgid " (%<PRIu32> in [0].sh_link)"
 msgstr " (%<PRIu32> en [0].sh_link)"
 
-#: src/readelf.c:1165
+#: src/readelf.c:1177
 #, c-format
 msgid ""
 "  Section header string table index: XINDEX%s\n"
@@ -4357,19 +4362,19 @@
 "  Índice de tabla de cadenas de sección de encabezamiento de : XINDEX%s\n"
 "\n"
 
-#: src/readelf.c:1169
+#: src/readelf.c:1181
 #, c-format
 msgid ""
 "  Section header string table index: %<PRId16>\n"
 "\n"
 msgstr "  Índice de tabla de cadenas de sección de encabezamiento: %<PRId16>\n"
 
-#: src/readelf.c:1216 src/readelf.c:1424
+#: src/readelf.c:1228 src/readelf.c:1436
 #, fuzzy, c-format
 msgid "cannot get number of sections: %s"
 msgstr "no se pudieron determinar el número de secciones: %s"
 
-#: src/readelf.c:1219
+#: src/readelf.c:1231
 #, fuzzy, c-format
 msgid ""
 "There are %zd section headers, starting at offset %#<PRIx64>:\n"
@@ -4378,16 +4383,16 @@
 "Hay %d encabezamientos de sección, comenzando en compensación %#<PRIx64>:\n"
 "\n"
 
-#: src/readelf.c:1228
+#: src/readelf.c:1240
 #, fuzzy, c-format
 msgid "cannot get section header string table index: %s"
 msgstr "no se puede obtener índice de cadena de encabezamiento de sección"
 
-#: src/readelf.c:1231
+#: src/readelf.c:1243
 msgid "Section Headers:"
 msgstr "encabezamientos de sección:"
 
-#: src/readelf.c:1234
+#: src/readelf.c:1246
 msgid ""
 "[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk "
 "Inf Al"
@@ -4395,7 +4400,7 @@
 "[Nr] Nombre            Tipo            Dirección    Off    Tamaño    Inf Al "
 "Enlace banderas ES"
 
-#: src/readelf.c:1236
+#: src/readelf.c:1248
 msgid ""
 "[Nr] Name                 Type         Addr             Off      Size     ES "
 "Flags Lk Inf Al"
@@ -4403,36 +4408,36 @@
 "[Nr] Name                 Type         Addr             Off      Size     ES "
 "Flags Lk Inf Al"
 
-#: src/readelf.c:1241
+#: src/readelf.c:1253
 msgid "     [Compression  Size   Al]"
 msgstr ""
 
-#: src/readelf.c:1243
+#: src/readelf.c:1255
 msgid "     [Compression  Size     Al]"
 msgstr ""
 
-#: src/readelf.c:1319
+#: src/readelf.c:1331
 #, fuzzy, c-format
 msgid "bad compression header for section %zd: %s"
 msgstr "No se puede obtener el encabezamiento de sección %zu: %s"
 
-#: src/readelf.c:1330
+#: src/readelf.c:1342
 #, fuzzy, c-format
 msgid "bad gnu compressed size for section %zd: %s"
 msgstr "No se pueden obtener datos para la sección %d: %s"
 
-#: src/readelf.c:1348
+#: src/readelf.c:1360
 msgid "Program Headers:"
 msgstr "encabezamientos de programa:"
 
-#: src/readelf.c:1350
+#: src/readelf.c:1362
 msgid ""
 "  Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align"
 msgstr ""
 "  Tipo           Compensación  Dirección Virtual       Dirección "
 "Física       Tamaño de Fichero  Tamaño de Memoria     Alineación de bandera"
 
-#: src/readelf.c:1353
+#: src/readelf.c:1365
 msgid ""
 "  Type           Offset   VirtAddr           PhysAddr           FileSiz  "
 "MemSiz   Flg Align"
@@ -4440,12 +4445,12 @@
 "  Tipo          Compensación  Dirección Virtual            Dirección "
 "Física          Tamaño de Fichero  Tamaño de Memoria   Alineación de bandera"
 
-#: src/readelf.c:1410
+#: src/readelf.c:1422
 #, c-format
 msgid "\t[Requesting program interpreter: %s]\n"
 msgstr "\t[Solicitando intérprete de programa: %s]\n"
 
-#: src/readelf.c:1437
+#: src/readelf.c:1449
 msgid ""
 "\n"
 " Section to Segment mapping:\n"
@@ -4455,12 +4460,12 @@
 " Sección para asignación de segmento:\n"
 "  Secciones de segmento..."
 
-#: src/readelf.c:1448 src/unstrip.c:2067 src/unstrip.c:2109 src/unstrip.c:2116
+#: src/readelf.c:1460 src/unstrip.c:2110 src/unstrip.c:2152 src/unstrip.c:2159
 #, c-format
 msgid "cannot get program header: %s"
 msgstr "no se puede obtener memoria para encabezamiento del programa: %s"
 
-#: src/readelf.c:1594
+#: src/readelf.c:1606
 #, c-format
 msgid ""
 "\n"
@@ -4475,7 +4480,7 @@
 "\n"
 "Grupo de sección COMDAT [%2zu] '%s' con firma '%s' contiene entradas %zu:\n"
 
-#: src/readelf.c:1599
+#: src/readelf.c:1611
 #, c-format
 msgid ""
 "\n"
@@ -4490,31 +4495,31 @@
 "\n"
 "Grupo de sección [%2zu] '%s' con firma '%s' contiene entradas %zu:\n"
 
-#: src/readelf.c:1607
+#: src/readelf.c:1619
 msgid "<INVALID SYMBOL>"
 msgstr "<SÍMBOLO INVÁLIDO>"
 
-#: src/readelf.c:1621
+#: src/readelf.c:1633
 msgid "<INVALID SECTION>"
 msgstr "<SECCIÓN INVÁLIDA>"
 
-#: src/readelf.c:1644 src/readelf.c:2371 src/readelf.c:3472 src/readelf.c:12505
-#: src/readelf.c:12512 src/readelf.c:12556 src/readelf.c:12563
+#: src/readelf.c:1656 src/readelf.c:2383 src/readelf.c:3484 src/readelf.c:12517
+#: src/readelf.c:12524 src/readelf.c:12568 src/readelf.c:12575
 msgid "Couldn't uncompress section"
 msgstr ""
 
-#: src/readelf.c:1649 src/readelf.c:2376 src/readelf.c:3477
+#: src/readelf.c:1661 src/readelf.c:2388 src/readelf.c:3489
 #, fuzzy, c-format
 msgid "cannot get section [%zd] header: %s"
 msgstr "No se puede obtener encabezamiento de sección: %s"
 
-#: src/readelf.c:1793 src/readelf.c:2443 src/readelf.c:2701 src/readelf.c:2777
-#: src/readelf.c:3081 src/readelf.c:3155 src/readelf.c:5352
+#: src/readelf.c:1805 src/readelf.c:2455 src/readelf.c:2713 src/readelf.c:2789
+#: src/readelf.c:3093 src/readelf.c:3167 src/readelf.c:5364
 #, fuzzy, c-format
 msgid "invalid sh_link value in section %zu"
 msgstr ".debug_line section inválida"
 
-#: src/readelf.c:1796
+#: src/readelf.c:1808
 #, c-format
 msgid ""
 "\n"
@@ -4535,36 +4540,36 @@
 " Dirección: %#0*<PRIx64>  Compensación: %#08<PRIx64>  Enlace a sección: "
 "[%2u] '%s'\n"
 
-#: src/readelf.c:1806
+#: src/readelf.c:1818
 msgid "  Type              Value\n"
 msgstr "  Tipo              Valor\n"
 
-#: src/readelf.c:1830
+#: src/readelf.c:1842
 #, c-format
 msgid "Shared library: [%s]\n"
 msgstr "Biblioteca compartida: [%s]\n"
 
-#: src/readelf.c:1835
+#: src/readelf.c:1847
 #, c-format
 msgid "Library soname: [%s]\n"
 msgstr "Nombre-so de la biblioteca: [%s]\n"
 
-#: src/readelf.c:1840
+#: src/readelf.c:1852
 #, c-format
 msgid "Library rpath: [%s]\n"
 msgstr "Rpath de la biblioteca: [%s]\n"
 
-#: src/readelf.c:1845
+#: src/readelf.c:1857
 #, c-format
 msgid "Library runpath: [%s]\n"
 msgstr "Ruta de ejecución de la biblioteca: [%s]\n"
 
-#: src/readelf.c:1865
+#: src/readelf.c:1877
 #, c-format
 msgid "%<PRId64> (bytes)\n"
 msgstr "%<PRId64> (bytes)\n"
 
-#: src/readelf.c:1978 src/readelf.c:2168
+#: src/readelf.c:1990 src/readelf.c:2180
 #, c-format
 msgid ""
 "\n"
@@ -4573,7 +4578,7 @@
 "\n"
 "Tabla de símbolos inválida en compensación %#0<PRIx64>\n"
 
-#: src/readelf.c:1996 src/readelf.c:2186
+#: src/readelf.c:2008 src/readelf.c:2198
 #, c-format
 msgid ""
 "\n"
@@ -4598,7 +4603,7 @@
 #. The .rela.dyn section does not refer to a specific section but
 #. instead of section index zero.  Do not try to print a section
 #. name.
-#: src/readelf.c:2011 src/readelf.c:2201
+#: src/readelf.c:2023 src/readelf.c:2213
 #, c-format
 msgid ""
 "\n"
@@ -4615,29 +4620,29 @@
 "Sección de reubicación [%2u] '%s' en compensación %#0<PRIx64> contiene "
 "entradas %d:\n"
 
-#: src/readelf.c:2021
+#: src/readelf.c:2033
 msgid "  Offset      Type                 Value       Name\n"
 msgstr "   Compensación           Tipo               Valor      Nombre\n"
 
-#: src/readelf.c:2023
+#: src/readelf.c:2035
 msgid "  Offset              Type                 Value               Name\n"
 msgstr "    Compensación           Tipo               Valor           Nombre\n"
 
-#: src/readelf.c:2076 src/readelf.c:2087 src/readelf.c:2100 src/readelf.c:2121
-#: src/readelf.c:2133 src/readelf.c:2267 src/readelf.c:2279 src/readelf.c:2293
-#: src/readelf.c:2315 src/readelf.c:2328
+#: src/readelf.c:2088 src/readelf.c:2099 src/readelf.c:2112 src/readelf.c:2133
+#: src/readelf.c:2145 src/readelf.c:2279 src/readelf.c:2291 src/readelf.c:2305
+#: src/readelf.c:2327 src/readelf.c:2340
 msgid "<INVALID RELOC>"
 msgstr "<REUBIC INVÁLIDA>"
 
-#: src/readelf.c:2211
+#: src/readelf.c:2223
 msgid "  Offset      Type            Value       Addend Name\n"
 msgstr "    Compensación            Tipo               Valor    Nombre Adend\n"
 
-#: src/readelf.c:2213
+#: src/readelf.c:2225
 msgid "  Offset              Type            Value               Addend Name\n"
 msgstr "    Compensación            Tipo               Valor   Nombre Adend\n"
 
-#: src/readelf.c:2451
+#: src/readelf.c:2463
 #, c-format
 msgid ""
 "\n"
@@ -4652,40 +4657,40 @@
 "\n"
 "La tabla de símbolos [%2u] '%s' contiene entradas %u:\n"
 
-#: src/readelf.c:2456
+#: src/readelf.c:2468
 #, c-format
 msgid " %lu local symbol  String table: [%2u] '%s'\n"
 msgid_plural " %lu local symbols  String table: [%2u] '%s'\n"
 msgstr[0] "símbolos locales %lu Tabla de cadena: [%2u] '%s'\n"
 msgstr[1] " Símbolos locales %lu Tabla de cadenas: [%2u] '%s'\n"
 
-#: src/readelf.c:2464
+#: src/readelf.c:2476
 msgid "  Num:    Value   Size Type    Bind   Vis          Ndx Name\n"
 msgstr "  Núm:    Valor       Tamaño Tipo    Unión  Vis          Nombre Ndx\n"
 
-#: src/readelf.c:2466
+#: src/readelf.c:2478
 msgid "  Num:            Value   Size Type    Bind   Vis          Ndx Name\n"
 msgstr "   Num:    Valor          Tamaño Tipo    Unión  Vis      Nombre Ndx\n"
 
-#: src/readelf.c:2486
+#: src/readelf.c:2498
 #, c-format
 msgid "%5u: %0*<PRIx64> %6<PRId64> %-7s %-6s %-9s %6s %s"
 msgstr "%5u: %0*<PRIx64> %6<PRId64> %-7s %-6s %-9s %6s %s"
 
-#: src/readelf.c:2574
+#: src/readelf.c:2586
 #, c-format
 msgid "bad dynamic symbol"
 msgstr "símbolo dinámico erróneo"
 
-#: src/readelf.c:2656
+#: src/readelf.c:2668
 msgid "none"
 msgstr "nada"
 
-#: src/readelf.c:2673
+#: src/readelf.c:2685
 msgid "| <unknown>"
 msgstr "| <desconocido>"
 
-#: src/readelf.c:2704
+#: src/readelf.c:2716
 #, c-format
 msgid ""
 "\n"
@@ -4706,17 +4711,17 @@
 " Dirección: %#0*<PRIx64>  Compensación: %#08<PRIx64>  Enlace a sección: "
 "[%2u] '%s'\n"
 
-#: src/readelf.c:2725
+#: src/readelf.c:2737
 #, c-format
 msgid "  %#06x: Version: %hu  File: %s  Cnt: %hu\n"
 msgstr "  %#06x: Versión: %hu  Fichero: %s  Conteo: %hu\n"
 
-#: src/readelf.c:2738
+#: src/readelf.c:2750
 #, c-format
 msgid "  %#06x: Name: %s  Flags: %s  Version: %hu\n"
 msgstr "  %#06x: Nombre: %s  Banderas: %s  Versión: %hu\n"
 
-#: src/readelf.c:2781
+#: src/readelf.c:2793
 #, c-format
 msgid ""
 "\n"
@@ -4737,19 +4742,19 @@
 " Dirección: %#0*<PRIx64>  Compensación: %#08<PRIx64>  Enlace a sección: "
 "[%2u] '%s'\n"
 
-#: src/readelf.c:2809
+#: src/readelf.c:2821
 #, c-format
 msgid "  %#06x: Version: %hd  Flags: %s  Index: %hd  Cnt: %hd  Name: %s\n"
 msgstr ""
 "  %#06x: Versión: %hd  Banderas: %s  Índice: %hd  Conteo: %hd  Nombre: %s\n"
 
-#: src/readelf.c:2824
+#: src/readelf.c:2836
 #, c-format
 msgid "  %#06x: Parent %d: %s\n"
 msgstr "  %#06x: Principal %d: %s\n"
 
 #. Print the header.
-#: src/readelf.c:3085
+#: src/readelf.c:3097
 #, c-format
 msgid ""
 "\n"
@@ -4770,15 +4775,15 @@
 " Dirección: %#0*<PRIx64>  Compensación: %#08<PRIx64>  Enlace a sección: "
 "[%2u] '%s'"
 
-#: src/readelf.c:3113
+#: src/readelf.c:3125
 msgid "   0 *local*                     "
 msgstr "   0 *local*                     "
 
-#: src/readelf.c:3118
+#: src/readelf.c:3130
 msgid "   1 *global*                    "
 msgstr "   1 *global*                    "
 
-#: src/readelf.c:3160
+#: src/readelf.c:3172
 #, c-format
 msgid ""
 "\n"
@@ -4803,22 +4808,22 @@
 " Dirección: %#0*<PRIx64>  Compensación: %#08<PRIx64>  Enlace a sección: "
 "[%2u] '%s'\n"
 
-#: src/readelf.c:3182
+#: src/readelf.c:3194
 #, no-c-format
 msgid " Length  Number  % of total  Coverage\n"
 msgstr " Longitud  Número  % of total  Cobertura\n"
 
-#: src/readelf.c:3184
+#: src/readelf.c:3196
 #, c-format
 msgid "      0  %6<PRIu32>      %5.1f%%\n"
 msgstr "      0  %6<PRIu32>      %5.1f%%\n"
 
-#: src/readelf.c:3191
+#: src/readelf.c:3203
 #, c-format
 msgid "%7d  %6<PRIu32>      %5.1f%%    %5.1f%%\n"
 msgstr "%7d  %6<PRIu32>      %5.1f%%    %5.1f%%\n"
 
-#: src/readelf.c:3204
+#: src/readelf.c:3216
 #, c-format
 msgid ""
 " Average number of tests:   successful lookup: %f\n"
@@ -4827,37 +4832,37 @@
 " Número promedio de pruebas:   búsqueda exitosa: %f\n"
 "                          búsqueda sin éxito: %f\n"
 
-#: src/readelf.c:3222 src/readelf.c:3286 src/readelf.c:3352
+#: src/readelf.c:3234 src/readelf.c:3298 src/readelf.c:3364
 #, c-format
 msgid "cannot get data for section %d: %s"
 msgstr "No se pueden obtener datos para la sección %d: %s"
 
-#: src/readelf.c:3230
+#: src/readelf.c:3242
 #, fuzzy, c-format
 msgid "invalid data in sysv.hash section %d"
 msgstr "Datos inválidos en sección [%zu] '%s'"
 
-#: src/readelf.c:3259
+#: src/readelf.c:3271
 #, fuzzy, c-format
 msgid "invalid chain in sysv.hash section %d"
 msgstr "Datos inválidos en sección [%zu] '%s'"
 
-#: src/readelf.c:3294
+#: src/readelf.c:3306
 #, fuzzy, c-format
 msgid "invalid data in sysv.hash64 section %d"
 msgstr "Datos inválidos en sección [%zu] '%s'"
 
-#: src/readelf.c:3325
+#: src/readelf.c:3337
 #, fuzzy, c-format
 msgid "invalid chain in sysv.hash64 section %d"
 msgstr "Datos inválidos en sección [%zu] '%s'"
 
-#: src/readelf.c:3361
+#: src/readelf.c:3373
 #, fuzzy, c-format
 msgid "invalid data in gnu.hash section %d"
 msgstr "Datos inválidos en sección [%zu] '%s'"
 
-#: src/readelf.c:3428
+#: src/readelf.c:3440
 #, c-format
 msgid ""
 " Symbol Bias: %u\n"
@@ -4867,7 +4872,7 @@
 " Tamaño de Bitmask: %zu bytes  %<PRIuFAST32>%% bits establecen segundo "
 "cambio de dispersión: %u\n"
 
-#: src/readelf.c:3517
+#: src/readelf.c:3529
 #, c-format
 msgid ""
 "\n"
@@ -4884,7 +4889,7 @@
 "Sección de lista de biblioteca [%2zu] '%s' en compensación %#0<PRIx64> "
 "contiene entradas %d:\n"
 
-#: src/readelf.c:3531
+#: src/readelf.c:3543
 msgid ""
 "       Library                       Time Stamp          Checksum Version "
 "Flags"
@@ -4892,7 +4897,7 @@
 "       Biblioteca                       Marca de tiempo          Indicadores "
 "de versión de suma de verificación"
 
-#: src/readelf.c:3583
+#: src/readelf.c:3595
 #, c-format
 msgid ""
 "\n"
@@ -4903,102 +4908,102 @@
 "Sección de atributos de objeto [%2zu] '%s' de %<PRIu64> bytes con "
 "desplazamiento %#0<PRIx64>:\n"
 
-#: src/readelf.c:3600
+#: src/readelf.c:3612
 msgid "  Owner          Size\n"
 msgstr "  Propietario          Tamaño\n"
 
-#: src/readelf.c:3629
+#: src/readelf.c:3641
 #, c-format
 msgid "  %-13s  %4<PRIu32>\n"
 msgstr "  %-13s  %4<PRIu32>\n"
 
 #. Unknown subsection, print and skip.
-#: src/readelf.c:3668
+#: src/readelf.c:3680
 #, c-format
 msgid "    %-4u %12<PRIu32>\n"
 msgstr "    %-4u %12<PRIu32>\n"
 
 #. Tag_File
-#: src/readelf.c:3673
+#: src/readelf.c:3685
 #, c-format
 msgid "    File: %11<PRIu32>\n"
 msgstr "    File: %11<PRIu32>\n"
 
-#: src/readelf.c:3722
+#: src/readelf.c:3734
 #, c-format
 msgid "      %s: %<PRId64>, %s\n"
 msgstr "      %s: %<PRId64>, %s\n"
 
-#: src/readelf.c:3725
+#: src/readelf.c:3737
 #, c-format
 msgid "      %s: %<PRId64>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:3728
+#: src/readelf.c:3740
 #, c-format
 msgid "      %s: %s\n"
 msgstr "      %s: %s\n"
 
-#: src/readelf.c:3738
+#: src/readelf.c:3750
 #, c-format
 msgid "      %u: %<PRId64>\n"
 msgstr "      %u: %<PRId64>\n"
 
-#: src/readelf.c:3741
+#: src/readelf.c:3753
 #, c-format
 msgid "      %u: %s\n"
 msgstr "      %u: %s\n"
 
-#: src/readelf.c:3811
+#: src/readelf.c:3823
 #, fuzzy, c-format
 msgid "sprintf failure"
 msgstr "mprotect falló"
 
-#: src/readelf.c:4293
+#: src/readelf.c:4305
 msgid "empty block"
 msgstr "bloque vacío"
 
-#: src/readelf.c:4296
+#: src/readelf.c:4308
 #, c-format
 msgid "%zu byte block:"
 msgstr "bloque de byte %zu:"
 
-#: src/readelf.c:4774
+#: src/readelf.c:4786
 #, fuzzy, c-format
 msgid "%*s[%2<PRIuMAX>] %s  <TRUNCATED>\n"
 msgstr "%*s[%4<PRIuMAX>] %s  <TRUNCATED>\n"
 
-#: src/readelf.c:4838
+#: src/readelf.c:4850
 #, c-format
 msgid "%s %#<PRIx64> used with different address sizes"
 msgstr "%s %#<PRIx64> utilizado con direcciones de diferente tamaño"
 
-#: src/readelf.c:4845
+#: src/readelf.c:4857
 #, c-format
 msgid "%s %#<PRIx64> used with different offset sizes"
 msgstr "%s %#<PRIx64> utilizado con offsetr de diferente tamaño"
 
-#: src/readelf.c:4852
+#: src/readelf.c:4864
 #, fuzzy, c-format
 msgid "%s %#<PRIx64> used with different base addresses"
 msgstr "%s %#<PRIx64> utilizado con direcciones de diferente tamaño"
 
-#: src/readelf.c:4859
+#: src/readelf.c:4871
 #, fuzzy, c-format
 msgid "%s %#<PRIx64> used with different attribute %s and %s"
 msgstr "%s %#<PRIx64> utilizado con direcciones de diferente tamaño"
 
-#: src/readelf.c:4956
+#: src/readelf.c:4968
 #, c-format
 msgid " [%6tx]  <UNUSED GARBAGE IN REST OF SECTION>\n"
 msgstr " [%6tx] <MATERIAL INUTIL SIN UTILIZAR EN EL RESTO DE LA SECCION>\n"
 
-#: src/readelf.c:4964
+#: src/readelf.c:4976
 #, c-format
 msgid " [%6tx]  <UNUSED GARBAGE> ... %<PRIu64> bytes ...\n"
 msgstr " [%6tx]  <MATERIAL INUTIL NO UTILIZADO> ... %<PRIu64> bytes ...\n"
 
-#: src/readelf.c:5042
+#: src/readelf.c:5054
 #, c-format
 msgid ""
 "\n"
@@ -5009,7 +5014,7 @@
 "Sección DWARF [%2zu] '%s' en compensación %#<PRIx64>:\n"
 " [ Código]\n"
 
-#: src/readelf.c:5050
+#: src/readelf.c:5062
 #, c-format
 msgid ""
 "\n"
@@ -5018,20 +5023,20 @@
 "\n"
 "Sección de abreviatura en compensación %<PRIu64>:\n"
 
-#: src/readelf.c:5063
+#: src/readelf.c:5075
 #, c-format
 msgid " *** error while reading abbreviation: %s\n"
 msgstr " *** error en lectura de abreviatura: %s\n"
 
-#: src/readelf.c:5079
+#: src/readelf.c:5091
 #, c-format
 msgid " [%5u] offset: %<PRId64>, children: %s, tag: %s\n"
 msgstr " [%5u] compensación: %<PRId64>, hijos: %s, etiqueta: %s\n"
 
-#: src/readelf.c:5112 src/readelf.c:5421 src/readelf.c:5588 src/readelf.c:5973
-#: src/readelf.c:6574 src/readelf.c:8311 src/readelf.c:8997 src/readelf.c:9433
-#: src/readelf.c:9678 src/readelf.c:9844 src/readelf.c:10231
-#: src/readelf.c:10291
+#: src/readelf.c:5124 src/readelf.c:5433 src/readelf.c:5600 src/readelf.c:5985
+#: src/readelf.c:6586 src/readelf.c:8323 src/readelf.c:9009 src/readelf.c:9445
+#: src/readelf.c:9690 src/readelf.c:9856 src/readelf.c:10243
+#: src/readelf.c:10303
 #, c-format
 msgid ""
 "\n"
@@ -5040,52 +5045,52 @@
 "\n"
 "Sección DWARF [%2zu] '%s' en compensación %#<PRIx64>:\n"
 
-#: src/readelf.c:5125
+#: src/readelf.c:5137
 #, fuzzy, c-format
 msgid "cannot get .debug_addr section data: %s"
 msgstr "no se pueden obtener datos de sección: %s"
 
-#: src/readelf.c:5225 src/readelf.c:5249 src/readelf.c:5633 src/readelf.c:9042
+#: src/readelf.c:5237 src/readelf.c:5261 src/readelf.c:5645 src/readelf.c:9054
 #, fuzzy, c-format
 msgid " Length:         %8<PRIu64>\n"
 msgstr " (compensación: %#<PRIx64>)"
 
-#: src/readelf.c:5227 src/readelf.c:5264 src/readelf.c:5646 src/readelf.c:9055
+#: src/readelf.c:5239 src/readelf.c:5276 src/readelf.c:5658 src/readelf.c:9067
 #, fuzzy, c-format
 msgid " DWARF version:  %8<PRIu16>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:5228 src/readelf.c:5273 src/readelf.c:5655 src/readelf.c:9064
+#: src/readelf.c:5240 src/readelf.c:5285 src/readelf.c:5667 src/readelf.c:9076
 #, fuzzy, c-format
 msgid " Address size:   %8<PRIu64>\n"
 msgstr " (fin de compensación: %#<PRIx64>)"
 
-#: src/readelf.c:5230 src/readelf.c:5283 src/readelf.c:5665 src/readelf.c:9074
+#: src/readelf.c:5242 src/readelf.c:5295 src/readelf.c:5677 src/readelf.c:9086
 #, fuzzy, c-format
 msgid " Segment size:   %8<PRIu64>\n"
 msgstr " establecer archivo a %<PRIu64>\n"
 
-#: src/readelf.c:5268 src/readelf.c:5650 src/readelf.c:9059 src/readelf.c:10423
+#: src/readelf.c:5280 src/readelf.c:5662 src/readelf.c:9071 src/readelf.c:10435
 #, fuzzy, c-format
 msgid "Unknown version"
 msgstr "versión desconocida"
 
-#: src/readelf.c:5278 src/readelf.c:5491 src/readelf.c:5660 src/readelf.c:9069
+#: src/readelf.c:5290 src/readelf.c:5503 src/readelf.c:5672 src/readelf.c:9081
 #, fuzzy, c-format
 msgid "unsupported address size"
 msgstr "no hay valor de dirección"
 
-#: src/readelf.c:5289 src/readelf.c:5502 src/readelf.c:5670 src/readelf.c:9079
+#: src/readelf.c:5301 src/readelf.c:5514 src/readelf.c:5682 src/readelf.c:9091
 #, c-format
 msgid "unsupported segment size"
 msgstr ""
 
-#: src/readelf.c:5342 src/readelf.c:5416
+#: src/readelf.c:5354 src/readelf.c:5428
 #, c-format
 msgid "cannot get .debug_aranges content: %s"
 msgstr "no se ha podido obtener contenido de .debug_aranges: %s"
 
-#: src/readelf.c:5357
+#: src/readelf.c:5369
 #, c-format
 msgid ""
 "\n"
@@ -5100,12 +5105,12 @@
 "\n"
 "Sección DWARF [%2zu] '%s' en compensación %#<PRIx64> contiene entradas %zu:\n"
 
-#: src/readelf.c:5388
+#: src/readelf.c:5400
 #, c-format
 msgid " [%*zu] ???\n"
 msgstr " [%*zu] ???\n"
 
-#: src/readelf.c:5390
+#: src/readelf.c:5402
 #, c-format
 msgid ""
 " [%*zu] start: %0#*<PRIx64>, length: %5<PRIu64>, CU DIE offset: %6<PRId64>\n"
@@ -5113,7 +5118,7 @@
 " Inicio [%*zu]: %0#*<PRIx64>, longitud: %5<PRIu64>, compensación CU DIE: "
 "%6<PRId64>\n"
 
-#: src/readelf.c:5434 src/readelf.c:8338
+#: src/readelf.c:5446 src/readelf.c:8350
 #, fuzzy, c-format
 msgid ""
 "\n"
@@ -5122,152 +5127,152 @@
 "\n"
 "Tabla en compensación %Zu:\n"
 
-#: src/readelf.c:5438 src/readelf.c:5614 src/readelf.c:6598 src/readelf.c:8349
-#: src/readelf.c:9023
+#: src/readelf.c:5450 src/readelf.c:5626 src/readelf.c:6610 src/readelf.c:8361
+#: src/readelf.c:9035
 #, c-format
 msgid "invalid data in section [%zu] '%s'"
 msgstr "Datos inválidos en sección [%zu] '%s'"
 
-#: src/readelf.c:5454
+#: src/readelf.c:5466
 #, fuzzy, c-format
 msgid ""
 "\n"
 " Length:        %6<PRIu64>\n"
 msgstr " (compensación: %#<PRIx64>)"
 
-#: src/readelf.c:5466
+#: src/readelf.c:5478
 #, fuzzy, c-format
 msgid " DWARF version: %6<PRIuFAST16>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:5470
+#: src/readelf.c:5482
 #, c-format
 msgid "unsupported aranges version"
 msgstr ""
 
-#: src/readelf.c:5481
+#: src/readelf.c:5493
 #, fuzzy, c-format
 msgid " CU offset:     %6<PRIx64>\n"
 msgstr " (compensación: %#<PRIx64>)"
 
-#: src/readelf.c:5487
+#: src/readelf.c:5499
 #, fuzzy, c-format
 msgid " Address size:  %6<PRIu64>\n"
 msgstr " (fin de compensación: %#<PRIx64>)"
 
-#: src/readelf.c:5498
+#: src/readelf.c:5510
 #, fuzzy, c-format
 msgid ""
 " Segment size:  %6<PRIu64>\n"
 "\n"
 msgstr " establecer archivo a %<PRIu64>\n"
 
-#: src/readelf.c:5553
+#: src/readelf.c:5565
 #, c-format
 msgid "   %zu padding bytes\n"
 msgstr ""
 
-#: src/readelf.c:5597
+#: src/readelf.c:5609
 #, fuzzy, c-format
 msgid "cannot get .debug_rnglists content: %s"
 msgstr "no se ha podido obtener contenido de .debug_ranges: %s"
 
-#: src/readelf.c:5620 src/readelf.c:9029
+#: src/readelf.c:5632 src/readelf.c:9041
 #, fuzzy, c-format
 msgid ""
 "Table at Offset 0x%<PRIx64>:\n"
 "\n"
 msgstr " (fin de compensación: %#<PRIx64>)"
 
-#: src/readelf.c:5675 src/readelf.c:9084
+#: src/readelf.c:5687 src/readelf.c:9096
 #, fuzzy, c-format
 msgid " Offset entries: %8<PRIu64>\n"
 msgstr " (compensación: %#<PRIx64>)"
 
-#: src/readelf.c:5691 src/readelf.c:9100
+#: src/readelf.c:5703 src/readelf.c:9112
 #, c-format
 msgid " Unknown CU base: "
 msgstr ""
 
-#: src/readelf.c:5693 src/readelf.c:9102
+#: src/readelf.c:5705 src/readelf.c:9114
 #, c-format
 msgid " CU [%6<PRIx64>] base: "
 msgstr ""
 
-#: src/readelf.c:5699 src/readelf.c:9108
+#: src/readelf.c:5711 src/readelf.c:9120
 #, c-format
 msgid " Not associated with a CU.\n"
 msgstr ""
 
-#: src/readelf.c:5710 src/readelf.c:9119
+#: src/readelf.c:5722 src/readelf.c:9131
 #, c-format
 msgid "too many offset entries for unit length"
 msgstr ""
 
-#: src/readelf.c:5714 src/readelf.c:9123
+#: src/readelf.c:5726 src/readelf.c:9135
 #, fuzzy, c-format
 msgid "  Offsets starting at 0x%<PRIx64>:\n"
 msgstr "  Propietario          Tamaño\n"
 
-#: src/readelf.c:5766
+#: src/readelf.c:5778
 #, fuzzy, c-format
 msgid "invalid range list data"
 msgstr "datos inválidos"
 
-#: src/readelf.c:5951 src/readelf.c:9411
+#: src/readelf.c:5963 src/readelf.c:9423
 #, c-format
 msgid ""
 "   %zu padding bytes\n"
 "\n"
 msgstr ""
 
-#: src/readelf.c:5968
+#: src/readelf.c:5980
 #, c-format
 msgid "cannot get .debug_ranges content: %s"
 msgstr "no se ha podido obtener contenido de .debug_ranges: %s"
 
-#: src/readelf.c:6004 src/readelf.c:9466
+#: src/readelf.c:6016 src/readelf.c:9478
 #, c-format
 msgid ""
 "\n"
 " Unknown CU base: "
 msgstr ""
 
-#: src/readelf.c:6006 src/readelf.c:9468
+#: src/readelf.c:6018 src/readelf.c:9480
 #, c-format
 msgid ""
 "\n"
 " CU [%6<PRIx64>] base: "
 msgstr ""
 
-#: src/readelf.c:6015 src/readelf.c:9494 src/readelf.c:9520
+#: src/readelf.c:6027 src/readelf.c:9506 src/readelf.c:9532
 #, c-format
 msgid " [%6tx]  <INVALID DATA>\n"
 msgstr " [%6tx]  <DATOS INVÁLIDOS>\n"
 
-#: src/readelf.c:6036 src/readelf.c:9600
+#: src/readelf.c:6048 src/readelf.c:9612
 #, fuzzy, c-format
 msgid ""
 " [%6tx] base address\n"
 "          "
 msgstr " [%6tx]   (dirección base) %s\n"
 
-#: src/readelf.c:6044 src/readelf.c:9608
+#: src/readelf.c:6056 src/readelf.c:9620
 #, fuzzy, c-format
 msgid " [%6tx] empty list\n"
 msgstr " [%6tx]  lista vacía\n"
 
-#: src/readelf.c:6299
+#: src/readelf.c:6311
 #, fuzzy
 msgid "         <INVALID DATA>\n"
 msgstr "   <DATOS INVÁLIDOS>\n"
 
-#: src/readelf.c:6552
+#: src/readelf.c:6564
 #, fuzzy, c-format
 msgid "cannot get ELF: %s"
 msgstr "no se puede leer encabezamiento ELF: %s"
 
-#: src/readelf.c:6570
+#: src/readelf.c:6582
 #, c-format
 msgid ""
 "\n"
@@ -5277,7 +5282,7 @@
 "Sección de información de marco de llamada [%2zu] '%s' en compensación "
 "%#<PRIx64>:\n"
 
-#: src/readelf.c:6620
+#: src/readelf.c:6632
 #, c-format
 msgid ""
 "\n"
@@ -5286,65 +5291,65 @@
 "\n"
 " [%6tx] Terminator cero\n"
 
-#: src/readelf.c:6721 src/readelf.c:6875
+#: src/readelf.c:6733 src/readelf.c:6887
 #, c-format
 msgid "invalid augmentation length"
 msgstr "longitud de aumento inválida"
 
-#: src/readelf.c:6736
+#: src/readelf.c:6748
 msgid "FDE address encoding: "
 msgstr "Codificación de dirección FDE:"
 
-#: src/readelf.c:6742
+#: src/readelf.c:6754
 msgid "LSDA pointer encoding: "
 msgstr "Codificación de puntero LSDA:"
 
-#: src/readelf.c:6852
+#: src/readelf.c:6864
 #, c-format
 msgid " (offset: %#<PRIx64>)"
 msgstr " (compensación: %#<PRIx64>)"
 
-#: src/readelf.c:6859
+#: src/readelf.c:6871
 #, c-format
 msgid " (end offset: %#<PRIx64>)"
 msgstr " (fin de compensación: %#<PRIx64>)"
 
-#: src/readelf.c:6896
+#: src/readelf.c:6908
 #, c-format
 msgid "   %-26sLSDA pointer: %#<PRIx64>\n"
 msgstr "Puntero   %-26sLSDA: %#<PRIx64>\n"
 
-#: src/readelf.c:6981
+#: src/readelf.c:6993
 #, fuzzy, c-format
 msgid "DIE [%<PRIx64>] cannot get attribute code: %s"
 msgstr "No se puede obtener código de atributo: %s"
 
-#: src/readelf.c:6991
+#: src/readelf.c:7003
 #, fuzzy, c-format
 msgid "DIE [%<PRIx64>] cannot get attribute form: %s"
 msgstr "No se puede obtener forma de atributo: %s"
 
-#: src/readelf.c:7013
+#: src/readelf.c:7025
 #, fuzzy, c-format
 msgid "DIE [%<PRIx64>] cannot get attribute '%s' (%s) value: %s"
 msgstr "No se puede obtener valor: %s"
 
-#: src/readelf.c:7343
+#: src/readelf.c:7355
 #, fuzzy, c-format
 msgid "invalid file (%<PRId64>): %s"
 msgstr "Archivo inválido"
 
-#: src/readelf.c:7347
+#: src/readelf.c:7359
 #, fuzzy, c-format
 msgid "no srcfiles for CU [%<PRIx64>]"
 msgstr " establecer archivo a %<PRIu64>\n"
 
-#: src/readelf.c:7351
+#: src/readelf.c:7363
 #, fuzzy, c-format
 msgid "couldn't get DWARF CU: %s"
 msgstr "no se puede leer encabezamiento ELF: %s"
 
-#: src/readelf.c:7664
+#: src/readelf.c:7676
 #, c-format
 msgid ""
 "\n"
@@ -5355,12 +5360,12 @@
 "Sección DWARF [%2zu] '%s' en compensación %#<PRIx64>:\n"
 " [Offset]\n"
 
-#: src/readelf.c:7714
+#: src/readelf.c:7726
 #, fuzzy, c-format
 msgid "cannot get next unit: %s"
 msgstr "No se puede obtener próximo DIE: %s"
 
-#: src/readelf.c:7733
+#: src/readelf.c:7745
 #, fuzzy, c-format
 msgid ""
 " Type unit at offset %<PRIu64>:\n"
@@ -5373,7 +5378,7 @@
 "Tamaño de dirección: %<PRIu8>, Tamaño de compensación: %<PRIu8>\n"
 " Tipo de firma: %#<PRIx64>, Tipo de compensación: %#<PRIx64>\n"
 
-#: src/readelf.c:7745
+#: src/readelf.c:7757
 #, c-format
 msgid ""
 " Compilation unit at offset %<PRIu64>:\n"
@@ -5384,39 +5389,39 @@
 " Versión: %<PRIu16>, Compensación de sección de abreviatura: %<PRIu64>,  "
 "Tamaño de dirección: %<PRIu8>, Tamaño de compensación: %<PRIu8>\n"
 
-#: src/readelf.c:7755 src/readelf.c:7918
+#: src/readelf.c:7767 src/readelf.c:7930
 #, c-format
 msgid " Unit type: %s (%<PRIu8>)"
 msgstr ""
 
-#: src/readelf.c:7782
+#: src/readelf.c:7794
 #, c-format
 msgid "unknown version (%d) or unit type (%d)"
 msgstr ""
 
-#: src/readelf.c:7811
+#: src/readelf.c:7823
 #, c-format
 msgid "cannot get DIE offset: %s"
 msgstr "no se puede obtener DIE en compensación: %s"
 
-#: src/readelf.c:7820
+#: src/readelf.c:7832
 #, fuzzy, c-format
 msgid "cannot get tag of DIE at offset [%<PRIx64>] in section '%s': %s"
 msgstr ""
 "no se ha podido obtener etiqueta de DIE en compensación%<PRIu64> en sección "
 "'%s': %s"
 
-#: src/readelf.c:7858
+#: src/readelf.c:7870
 #, c-format
 msgid "cannot get next DIE: %s\n"
 msgstr "No se puede obtener próximo DIE: %s\n"
 
-#: src/readelf.c:7866
+#: src/readelf.c:7878
 #, c-format
 msgid "cannot get next DIE: %s"
 msgstr "No se puede obtener próximo DIE: %s"
 
-#: src/readelf.c:7910
+#: src/readelf.c:7922
 #, fuzzy, c-format
 msgid ""
 " Split compilation unit at offset %<PRIu64>:\n"
@@ -5427,7 +5432,7 @@
 " Versión: %<PRIu16>, Compensación de sección de abreviatura: %<PRIu64>,  "
 "Tamaño de dirección: %<PRIu8>, Tamaño de compensación: %<PRIu8>\n"
 
-#: src/readelf.c:7962
+#: src/readelf.c:7974
 #, fuzzy, c-format
 msgid ""
 "\n"
@@ -5437,18 +5442,18 @@
 "\n"
 "Sección DWARF [%2zu] '%s' en compensación %#<PRIx64>:\n"
 
-#: src/readelf.c:8294
+#: src/readelf.c:8306
 #, fuzzy, c-format
 msgid "unknown form: %s"
 msgstr "Forma %<PRIx64> desconocida"
 
-#: src/readelf.c:8325
+#: src/readelf.c:8337
 #, c-format
 msgid "cannot get line data section data: %s"
 msgstr "No se puede obtener sección de datos de línea: %s"
 
 #. Print what we got so far.
-#: src/readelf.c:8427
+#: src/readelf.c:8439
 #, fuzzy, c-format
 msgid ""
 "\n"
@@ -5479,34 +5484,34 @@
 "\n"
 "Códigos operativos:\n"
 
-#: src/readelf.c:8449
+#: src/readelf.c:8461
 #, fuzzy, c-format
 msgid "cannot handle .debug_line version: %u\n"
 msgstr "no se puede obtener versión de símbolo: %s"
 
-#: src/readelf.c:8457
+#: src/readelf.c:8469
 #, fuzzy, c-format
 msgid "cannot handle address size: %u\n"
 msgstr "no hay valor de dirección"
 
-#: src/readelf.c:8465
+#: src/readelf.c:8477
 #, fuzzy, c-format
 msgid "cannot handle segment selector size: %u\n"
 msgstr "No se puede encontrar la sección: %s"
 
-#: src/readelf.c:8475
+#: src/readelf.c:8487
 #, c-format
 msgid "invalid data at offset %tu in section [%zu] '%s'"
 msgstr "datos inválidos en compensación %tu en sección [%zu] '%s'"
 
-#: src/readelf.c:8490
+#: src/readelf.c:8502
 #, c-format
 msgid "  [%*<PRIuFAST8>]  %hhu argument\n"
 msgid_plural "  [%*<PRIuFAST8>]  %hhu arguments\n"
 msgstr[0] "  [%*<PRIuFAST8>]  argumento %hhu \n"
 msgstr[1] "  [%*<PRIuFAST8>]  argumento %hhu\n"
 
-#: src/readelf.c:8501
+#: src/readelf.c:8513
 msgid ""
 "\n"
 "Directory table:"
@@ -5514,12 +5519,12 @@
 "\n"
 "Tabla de Directorio:"
 
-#: src/readelf.c:8507 src/readelf.c:8584
+#: src/readelf.c:8519 src/readelf.c:8596
 #, fuzzy, c-format
 msgid "      ["
 msgstr "      %s: %s\n"
 
-#: src/readelf.c:8578
+#: src/readelf.c:8590
 #, fuzzy
 msgid ""
 "\n"
@@ -5528,7 +5533,7 @@
 "\n"
 " Tabla de sitio de llamada:"
 
-#: src/readelf.c:8639
+#: src/readelf.c:8651
 #, fuzzy
 msgid " Entry Dir   Time      Size      Name"
 msgstr ""
@@ -5536,7 +5541,7 @@
 "Tabla de nombre de archivo:\n"
 " Directorio de entrada   Tiempo      Tamaño      Nombre"
 
-#: src/readelf.c:8676
+#: src/readelf.c:8688
 msgid ""
 "\n"
 "Line number statements:"
@@ -5544,121 +5549,121 @@
 "\n"
 " Declaraciones de número de Línea:"
 
-#: src/readelf.c:8699
+#: src/readelf.c:8711
 #, fuzzy, c-format
 msgid "invalid maximum operations per instruction is zero"
 msgstr "longitud mínima inválida de tamaño de cadena coincidente"
 
-#: src/readelf.c:8733
+#: src/readelf.c:8745
 #, fuzzy, c-format
 msgid " special opcode %u: address+%u = "
 msgstr " opcode especial %u: dirección+%u = %s, línea%+d = %zu\n"
 
-#: src/readelf.c:8737
+#: src/readelf.c:8749
 #, fuzzy, c-format
 msgid ", op_index = %u, line%+d = %zu\n"
 msgstr ""
 " opcode especial %u: dirección+%u = %s,  op_index = %u, línea%+d = %zu\n"
 
-#: src/readelf.c:8740
+#: src/readelf.c:8752
 #, c-format
 msgid ", line%+d = %zu\n"
 msgstr ""
 
-#: src/readelf.c:8758
+#: src/readelf.c:8770
 #, c-format
 msgid " extended opcode %u: "
 msgstr "  Código operativo extendido %u: "
 
-#: src/readelf.c:8763
+#: src/readelf.c:8775
 #, fuzzy
 msgid " end of sequence"
 msgstr "Fin de secuencia"
 
-#: src/readelf.c:8781
+#: src/readelf.c:8793
 #, fuzzy, c-format
 msgid " set address to "
 msgstr "Establecer dirección a %s\n"
 
-#: src/readelf.c:8809
+#: src/readelf.c:8821
 #, fuzzy, c-format
 msgid " define new file: dir=%u, mtime=%<PRIu64>, length=%<PRIu64>, name=%s\n"
 msgstr ""
 "definir nuevo archivo: dir=%u, mtime=%<PRIu64>, longitud=%<PRIu64>, nombre="
 "%s\n"
 
-#: src/readelf.c:8823
+#: src/readelf.c:8835
 #, c-format
 msgid " set discriminator to %u\n"
 msgstr " establecer discriminador a %u\n"
 
 #. Unknown, ignore it.
-#: src/readelf.c:8828
+#: src/readelf.c:8840
 #, fuzzy
 msgid " unknown opcode"
 msgstr "código operativo desconocido "
 
 #. Takes no argument.
-#: src/readelf.c:8840
+#: src/readelf.c:8852
 msgid " copy"
 msgstr "Copiar"
 
-#: src/readelf.c:8851
+#: src/readelf.c:8863
 #, fuzzy, c-format
 msgid " advance address by %u to "
 msgstr "Dirección de avance por %u a %s\n"
 
-#: src/readelf.c:8855 src/readelf.c:8916
+#: src/readelf.c:8867 src/readelf.c:8928
 #, c-format
 msgid ", op_index to %u"
 msgstr ""
 
-#: src/readelf.c:8867
+#: src/readelf.c:8879
 #, c-format
 msgid " advance line by constant %d to %<PRId64>\n"
 msgstr " línea de avance por la constante %d a %<PRId64>\n"
 
-#: src/readelf.c:8877
+#: src/readelf.c:8889
 #, c-format
 msgid " set file to %<PRIu64>\n"
 msgstr " establecer archivo a %<PRIu64>\n"
 
-#: src/readelf.c:8888
+#: src/readelf.c:8900
 #, c-format
 msgid " set column to %<PRIu64>\n"
 msgstr "  Establecer columna a %<PRIu64>\n"
 
-#: src/readelf.c:8895
+#: src/readelf.c:8907
 #, c-format
 msgid " set '%s' to %<PRIuFAST8>\n"
 msgstr "Establecer '%s' a %<PRIuFAST8>\n"
 
 #. Takes no argument.
-#: src/readelf.c:8901
+#: src/readelf.c:8913
 msgid " set basic block flag"
 msgstr "Establecer bandera de bloque básico"
 
-#: src/readelf.c:8912
+#: src/readelf.c:8924
 #, fuzzy, c-format
 msgid " advance address by constant %u to "
 msgstr "Dirección de avance por constante %u a %s\n"
 
-#: src/readelf.c:8932
+#: src/readelf.c:8944
 #, fuzzy, c-format
 msgid " advance address by fixed value %u to \n"
 msgstr "dirección de avance por valor corregido %u a %s\n"
 
 #. Takes no argument.
-#: src/readelf.c:8942
+#: src/readelf.c:8954
 msgid " set prologue end flag"
 msgstr " Establecer bandera prologue_end"
 
 #. Takes no argument.
-#: src/readelf.c:8947
+#: src/readelf.c:8959
 msgid " set epilogue begin flag"
 msgstr " Establecer bandera epilogue_begin"
 
-#: src/readelf.c:8957
+#: src/readelf.c:8969
 #, c-format
 msgid " set isa to %u\n"
 msgstr " establecer isa para %u\n"
@@ -5666,105 +5671,105 @@
 #. This is a new opcode the generator but not we know about.
 #. Read the parameters associated with it but then discard
 #. everything.  Read all the parameters for this opcode.
-#: src/readelf.c:8966
+#: src/readelf.c:8978
 #, c-format
 msgid " unknown opcode with %<PRIu8> parameter:"
 msgid_plural " unknown opcode with %<PRIu8> parameters:"
 msgstr[0] " opcódigo con parámetro %<PRIu8> desconocido:"
 msgstr[1] " opcódigo con parámetros %<PRIu8> desconocido:"
 
-#: src/readelf.c:9006
+#: src/readelf.c:9018
 #, fuzzy, c-format
 msgid "cannot get .debug_loclists content: %s"
 msgstr "no es posible obtener contenido de .debug_loc: %s"
 
-#: src/readelf.c:9175
+#: src/readelf.c:9187
 #, fuzzy, c-format
 msgid "invalid loclists data"
 msgstr "datos inválidos"
 
-#: src/readelf.c:9428
+#: src/readelf.c:9440
 #, c-format
 msgid "cannot get .debug_loc content: %s"
 msgstr "no es posible obtener contenido de .debug_loc: %s"
 
-#: src/readelf.c:9635 src/readelf.c:10679
+#: src/readelf.c:9647 src/readelf.c:10691
 msgid "   <INVALID DATA>\n"
 msgstr "   <DATOS INVÁLIDOS>\n"
 
-#: src/readelf.c:9690 src/readelf.c:9853
+#: src/readelf.c:9702 src/readelf.c:9865
 #, c-format
 msgid "cannot get macro information section data: %s"
 msgstr "no es posible obtener datos de la sección de macro información: %s"
 
-#: src/readelf.c:9770
+#: src/readelf.c:9782
 #, c-format
 msgid "%*s*** non-terminated string at end of section"
 msgstr "%*s*** cadena no finalizada al final de la sección"
 
-#: src/readelf.c:9793
+#: src/readelf.c:9805
 #, fuzzy, c-format
 msgid "%*s*** missing DW_MACINFO_start_file argument at end of section"
 msgstr "%*s*** cadena no finalizada al final de la sección"
 
-#: src/readelf.c:9894
+#: src/readelf.c:9906
 #, fuzzy, c-format
 msgid " Offset:             0x%<PRIx64>\n"
 msgstr "  Propietario          Tamaño\n"
 
-#: src/readelf.c:9906
+#: src/readelf.c:9918
 #, fuzzy, c-format
 msgid " Version:            %<PRIu16>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:9912 src/readelf.c:10799
+#: src/readelf.c:9924 src/readelf.c:10811
 #, c-format
 msgid "  unknown version, cannot parse section\n"
 msgstr ""
 
-#: src/readelf.c:9919
+#: src/readelf.c:9931
 #, fuzzy, c-format
 msgid " Flag:               0x%<PRIx8>"
 msgstr "  Dirección de punto de entrada:               %#<PRIx64>\n"
 
-#: src/readelf.c:9948
+#: src/readelf.c:9960
 #, fuzzy, c-format
 msgid " Offset length:      %<PRIu8>\n"
 msgstr " (compensación: %#<PRIx64>)"
 
-#: src/readelf.c:9956
+#: src/readelf.c:9968
 #, fuzzy, c-format
 msgid " .debug_line offset: 0x%<PRIx64>\n"
 msgstr " (fin de compensación: %#<PRIx64>)"
 
-#: src/readelf.c:9981
+#: src/readelf.c:9993
 #, fuzzy, c-format
 msgid "  extension opcode table, %<PRIu8> items:\n"
 msgstr " opcódigo con parámetro %<PRIu8> desconocido:"
 
-#: src/readelf.c:9988
+#: src/readelf.c:10000
 #, c-format
 msgid "    [%<PRIx8>]"
 msgstr ""
 
-#: src/readelf.c:10000
+#: src/readelf.c:10012
 #, fuzzy, c-format
 msgid " %<PRIu8> arguments:"
 msgstr "  [%*<PRIuFAST8>]  argumento %hhu \n"
 
-#: src/readelf.c:10015
+#: src/readelf.c:10027
 #, c-format
 msgid " no arguments."
 msgstr ""
 
-#: src/readelf.c:10216
+#: src/readelf.c:10228
 #, c-format
 msgid " [%5d] DIE offset: %6<PRId64>, CU DIE offset: %6<PRId64>, name: %s\n"
 msgstr ""
 " Compensación [%5d] DIE: %6<PRId64>, Compensación CU DIE: %6<PRId64>, "
 "nombre: %s\n"
 
-#: src/readelf.c:10260
+#: src/readelf.c:10272
 #, c-format
 msgid ""
 "\n"
@@ -5775,37 +5780,37 @@
 "Sección DWARF [%2zu] '%s' en compensación %#<PRIx64>:\n"
 " %*s  String\n"
 
-#: src/readelf.c:10275
+#: src/readelf.c:10287
 #, fuzzy, c-format
 msgid " *** error, missing string terminator\n"
 msgstr " *** error en lectura de cadenas: %s\n"
 
-#: src/readelf.c:10304
+#: src/readelf.c:10316
 #, fuzzy, c-format
 msgid "cannot get .debug_str_offsets section data: %s"
 msgstr "no se pueden obtener datos de sección: %s"
 
-#: src/readelf.c:10403
+#: src/readelf.c:10415
 #, fuzzy, c-format
 msgid " Length:        %8<PRIu64>\n"
 msgstr " (compensación: %#<PRIx64>)"
 
-#: src/readelf.c:10405
+#: src/readelf.c:10417
 #, fuzzy, c-format
 msgid " Offset size:   %8<PRIu8>\n"
 msgstr " (compensación: %#<PRIx64>)"
 
-#: src/readelf.c:10419
+#: src/readelf.c:10431
 #, fuzzy, c-format
 msgid " DWARF version: %8<PRIu16>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:10428
+#: src/readelf.c:10440
 #, fuzzy, c-format
 msgid " Padding:       %8<PRIx16>\n"
 msgstr " (compensación: %#<PRIx64>)"
 
-#: src/readelf.c:10482
+#: src/readelf.c:10494
 #, c-format
 msgid ""
 "\n"
@@ -5814,7 +5819,7 @@
 "\n"
 "Sección de tabla de búsqueda de marco de llamada [%2zu] '.eh_frame_hdr':\n"
 
-#: src/readelf.c:10584
+#: src/readelf.c:10596
 #, c-format
 msgid ""
 "\n"
@@ -5823,22 +5828,22 @@
 "\n"
 "Excepción en el manejo de la sección de tabla [%2zu] '.gcc_except_table':\n"
 
-#: src/readelf.c:10607
+#: src/readelf.c:10619
 #, c-format
 msgid " LPStart encoding:    %#x "
 msgstr "Codificación LPStart:    %#x "
 
-#: src/readelf.c:10619
+#: src/readelf.c:10631
 #, c-format
 msgid " TType encoding:      %#x "
 msgstr "Codificación TType:      %#x "
 
-#: src/readelf.c:10634
+#: src/readelf.c:10646
 #, c-format
 msgid " Call site encoding:  %#x "
 msgstr "Codificación de sitio de llamada:  %#x "
 
-#: src/readelf.c:10647
+#: src/readelf.c:10659
 msgid ""
 "\n"
 " Call site table:"
@@ -5846,7 +5851,7 @@
 "\n"
 " Tabla de sitio de llamada:"
 
-#: src/readelf.c:10661
+#: src/readelf.c:10673
 #, c-format
 msgid ""
 " [%4u] Call site start:   %#<PRIx64>\n"
@@ -5859,12 +5864,12 @@
 "        Landing pad:       %#<PRIx64>\n"
 "        Action:            %u\n"
 
-#: src/readelf.c:10734
+#: src/readelf.c:10746
 #, c-format
 msgid "invalid TType encoding"
 msgstr "Codificación TType inválida"
 
-#: src/readelf.c:10761
+#: src/readelf.c:10773
 #, fuzzy, c-format
 msgid ""
 "\n"
@@ -5873,37 +5878,37 @@
 "\n"
 "Sección DWARF [%2zu] '%s' en compensación %#<PRIx64> contiene entrada %zu:\n"
 
-#: src/readelf.c:10790
+#: src/readelf.c:10802
 #, fuzzy, c-format
 msgid " Version:         %<PRId32>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:10808
+#: src/readelf.c:10820
 #, fuzzy, c-format
 msgid " CU offset:       %#<PRIx32>\n"
 msgstr " (compensación: %#<PRIx64>)"
 
-#: src/readelf.c:10815
+#: src/readelf.c:10827
 #, fuzzy, c-format
 msgid " TU offset:       %#<PRIx32>\n"
 msgstr " (compensación: %#<PRIx64>)"
 
-#: src/readelf.c:10822
+#: src/readelf.c:10834
 #, fuzzy, c-format
 msgid " address offset:  %#<PRIx32>\n"
 msgstr " (fin de compensación: %#<PRIx64>)"
 
-#: src/readelf.c:10829
+#: src/readelf.c:10841
 #, fuzzy, c-format
 msgid " symbol offset:   %#<PRIx32>\n"
 msgstr " (compensación: %#<PRIx64>)"
 
-#: src/readelf.c:10836
+#: src/readelf.c:10848
 #, fuzzy, c-format
 msgid " constant offset: %#<PRIx32>\n"
 msgstr " (fin de compensación: %#<PRIx64>)"
 
-#: src/readelf.c:10850
+#: src/readelf.c:10862
 #, fuzzy, c-format
 msgid ""
 "\n"
@@ -5912,7 +5917,7 @@
 "\n"
 "Sección DWARF [%2zu] '%s' en compensación %#<PRIx64> contiene entrada %zu:\n"
 
-#: src/readelf.c:10875
+#: src/readelf.c:10887
 #, fuzzy, c-format
 msgid ""
 "\n"
@@ -5921,7 +5926,7 @@
 "\n"
 "Sección DWARF [%2zu] '%s' en compensación %#<PRIx64> contiene entrada %zu:\n"
 
-#: src/readelf.c:10904
+#: src/readelf.c:10916
 #, fuzzy, c-format
 msgid ""
 "\n"
@@ -5930,7 +5935,7 @@
 "\n"
 "Sección DWARF [%2zu] '%s' en compensación %#<PRIx64> contiene entrada %zu:\n"
 
-#: src/readelf.c:10936
+#: src/readelf.c:10948
 #, fuzzy, c-format
 msgid ""
 "\n"
@@ -5939,18 +5944,18 @@
 "\n"
 "Tabla de símbolos inválida en compensación %#0<PRIx64>\n"
 
-#: src/readelf.c:11074
+#: src/readelf.c:11086
 #, c-format
 msgid "cannot get debug context descriptor: %s"
 msgstr "no se puede depurar descriptor de contexto: %s"
 
-#: src/readelf.c:11437 src/readelf.c:12059 src/readelf.c:12170
-#: src/readelf.c:12228
+#: src/readelf.c:11449 src/readelf.c:12071 src/readelf.c:12182
+#: src/readelf.c:12240
 #, c-format
 msgid "cannot convert core note data: %s"
 msgstr "no es posible convertir datos de la nota principal: %s"
 
-#: src/readelf.c:11800
+#: src/readelf.c:11812
 #, c-format
 msgid ""
 "\n"
@@ -5959,21 +5964,21 @@
 "\n"
 "%*s... <repeats %u more times> ..."
 
-#: src/readelf.c:12307
+#: src/readelf.c:12319
 msgid "  Owner          Data size  Type\n"
 msgstr "  Owner          Data size  Type\n"
 
-#: src/readelf.c:12336
+#: src/readelf.c:12348
 #, c-format
 msgid "  %-13.*s  %9<PRId32>  %s\n"
 msgstr "  %-13.*s  %9<PRId32>  %s\n"
 
-#: src/readelf.c:12388
+#: src/readelf.c:12400
 #, fuzzy, c-format
 msgid "cannot get content of note: %s"
 msgstr "no se puede obtener el contenido de sección de nota: %s"
 
-#: src/readelf.c:12422
+#: src/readelf.c:12434
 #, c-format
 msgid ""
 "\n"
@@ -5982,7 +5987,7 @@
 "\n"
 "Sección de nota [%2zu] '%s' de %<PRIu64> bytes en compensación %#0<PRIx64>:\n"
 
-#: src/readelf.c:12445
+#: src/readelf.c:12457
 #, c-format
 msgid ""
 "\n"
@@ -5991,7 +5996,7 @@
 "\n"
 "Segmento de nota de %<PRIu64> bytes en compensación %#0<PRIx64>:\n"
 
-#: src/readelf.c:12492
+#: src/readelf.c:12504
 #, fuzzy, c-format
 msgid ""
 "\n"
@@ -6000,12 +6005,12 @@
 "\n"
 "Sección [%Zu] '%s' no tiene datos para volcar.\n"
 
-#: src/readelf.c:12519 src/readelf.c:12570
+#: src/readelf.c:12531 src/readelf.c:12582
 #, fuzzy, c-format
 msgid "cannot get data for section [%zu] '%s': %s"
 msgstr "no se pueden obtener datos para sección [%Zu] '%s': %s"
 
-#: src/readelf.c:12524
+#: src/readelf.c:12536
 #, fuzzy, c-format
 msgid ""
 "\n"
@@ -6015,7 +6020,7 @@
 "Volcado Hex de sección [%Zu] '%s', %<PRIu64> bytes en compensación "
 "%#0<PRIx64>:\n"
 
-#: src/readelf.c:12529
+#: src/readelf.c:12541
 #, fuzzy, c-format
 msgid ""
 "\n"
@@ -6026,7 +6031,7 @@
 "Volcado Hex de sección [%Zu] '%s', %<PRIu64> bytes en compensación "
 "%#0<PRIx64>:\n"
 
-#: src/readelf.c:12543
+#: src/readelf.c:12555
 #, fuzzy, c-format
 msgid ""
 "\n"
@@ -6035,7 +6040,7 @@
 "\n"
 "Sección [%Zu] '%s' no tiene datos para volcar.\n"
 
-#: src/readelf.c:12575
+#: src/readelf.c:12587
 #, fuzzy, c-format
 msgid ""
 "\n"
@@ -6045,7 +6050,7 @@
 "Sección de cadena [%Zu] '%s' contiene %<PRIu64> bytes en compensación "
 "%#0<PRIx64>:\n"
 
-#: src/readelf.c:12580
+#: src/readelf.c:12592
 #, fuzzy, c-format
 msgid ""
 "\n"
@@ -6056,7 +6061,7 @@
 "Sección de cadena [%Zu] '%s' contiene %<PRIu64> bytes en compensación "
 "%#0<PRIx64>:\n"
 
-#: src/readelf.c:12629
+#: src/readelf.c:12641
 #, c-format
 msgid ""
 "\n"
@@ -6065,7 +6070,7 @@
 "\n"
 "sección [%lu] no existe"
 
-#: src/readelf.c:12658
+#: src/readelf.c:12671
 #, c-format
 msgid ""
 "\n"
@@ -6074,12 +6079,12 @@
 "\n"
 "sección '%s' no existe"
 
-#: src/readelf.c:12715
+#: src/readelf.c:12728
 #, c-format
 msgid "cannot get symbol index of archive '%s': %s"
 msgstr "no se puede obtener el índice de símbolo de archivo '%s': %s"
 
-#: src/readelf.c:12718
+#: src/readelf.c:12731
 #, c-format
 msgid ""
 "\n"
@@ -6088,7 +6093,7 @@
 "\n"
 "Archivo '%s' no tiene índice de símbolo\n"
 
-#: src/readelf.c:12722
+#: src/readelf.c:12735
 #, fuzzy, c-format
 msgid ""
 "\n"
@@ -6097,12 +6102,12 @@
 "\n"
 "Índice de archivo '%s' tiene %Zu entradas:\n"
 
-#: src/readelf.c:12740
+#: src/readelf.c:12753
 #, fuzzy, c-format
 msgid "cannot extract member at offset %zu in '%s': %s"
 msgstr "no es posible extraer miembro en compensación %Zu en '%s': %s"
 
-#: src/readelf.c:12745
+#: src/readelf.c:12758
 #, c-format
 msgid "Archive member '%s' contains:\n"
 msgstr "Miembro de archivo contiene '%s':\n"
@@ -6699,7 +6704,7 @@
 msgid "cannot get shdrstrndx:%s"
 msgstr "No se puede encontrar la sección: %s"
 
-#: src/unstrip.c:248 src/unstrip.c:2038
+#: src/unstrip.c:248 src/unstrip.c:2081
 #, c-format
 msgid "cannot get ELF header: %s"
 msgstr "no se puede leer encabezamiento ELF: %s"
@@ -6719,12 +6724,12 @@
 msgid "cannot copy ELF header: %s"
 msgstr "no se puede copiar encabezamiento ELF: %s"
 
-#: src/unstrip.c:269 src/unstrip.c:2056 src/unstrip.c:2099
+#: src/unstrip.c:269 src/unstrip.c:2099 src/unstrip.c:2142
 #, fuzzy, c-format
 msgid "cannot get number of program headers: %s"
 msgstr "no se pudo determinar la cantidad de encabezados de programa: %s"
 
-#: src/unstrip.c:274 src/unstrip.c:2060
+#: src/unstrip.c:274 src/unstrip.c:2103
 #, c-format
 msgid "cannot create program headers: %s"
 msgstr "No pueden crear encabezamientos de programa: %s"
@@ -6739,12 +6744,12 @@
 msgid "cannot copy section header: %s"
 msgstr "no se puede copiar encabezamiento de sección: %s"
 
-#: src/unstrip.c:293 src/unstrip.c:1669
+#: src/unstrip.c:293 src/unstrip.c:1703
 #, c-format
 msgid "cannot get section data: %s"
 msgstr "no se pueden obtener datos de sección: %s"
 
-#: src/unstrip.c:295 src/unstrip.c:1671
+#: src/unstrip.c:295 src/unstrip.c:1705
 #, c-format
 msgid "cannot copy section data: %s"
 msgstr "no pueden copiar datos de sección: %s"
@@ -6754,14 +6759,14 @@
 msgid "cannot create directory '%s'"
 msgstr "no se puede crear el directorio '%s'"
 
-#: src/unstrip.c:391 src/unstrip.c:647 src/unstrip.c:681 src/unstrip.c:847
-#: src/unstrip.c:1706
+#: src/unstrip.c:391 src/unstrip.c:651 src/unstrip.c:685 src/unstrip.c:853
+#: src/unstrip.c:1745
 #, c-format
 msgid "cannot get symbol table entry: %s"
 msgstr "no se puede obtener entrada de tabla de símbolos: %s"
 
-#: src/unstrip.c:407 src/unstrip.c:650 src/unstrip.c:671 src/unstrip.c:684
-#: src/unstrip.c:1727 src/unstrip.c:1922 src/unstrip.c:1946
+#: src/unstrip.c:407 src/unstrip.c:654 src/unstrip.c:675 src/unstrip.c:688
+#: src/unstrip.c:1766 src/unstrip.c:1961 src/unstrip.c:1985
 #, c-format
 msgid "cannot update symbol table: %s"
 msgstr "no se puede actualizar tabla de símbolos: %s"
@@ -6771,155 +6776,170 @@
 msgid "cannot update section header: %s"
 msgstr "no se puede actualizar encabezamiento de sección: %s"
 
-#: src/unstrip.c:459 src/unstrip.c:473
+#: src/unstrip.c:463 src/unstrip.c:477
 #, c-format
 msgid "cannot update relocation: %s"
 msgstr "no se puede actualizar reubicación: %s"
 
-#: src/unstrip.c:570
+#: src/unstrip.c:574
 #, c-format
 msgid "cannot get symbol version: %s"
 msgstr "no se puede obtener versión de símbolo: %s"
 
-#: src/unstrip.c:583
+#: src/unstrip.c:587
 #, fuzzy, c-format
 msgid "unexpected section type in [%zu] with sh_link to symtab"
 msgstr "tipo de sección inesperado en [%Zu] con sh_link para symtab"
 
-#: src/unstrip.c:853
+#: src/unstrip.c:842
+#, fuzzy, c-format
+msgid "cannot get symbol section data: %s"
+msgstr "no se pueden obtener datos de sección: %s"
+
+#: src/unstrip.c:844
+#, fuzzy, c-format
+msgid "cannot get string section data: %s"
+msgstr "no se pueden obtener datos de sección: %s"
+
+#: src/unstrip.c:861
 #, fuzzy, c-format
 msgid "invalid string offset in symbol [%zu]"
 msgstr "compensación de cadena inválida en símbolo [%Zu]"
 
-#: src/unstrip.c:1011 src/unstrip.c:1402
+#: src/unstrip.c:1019 src/unstrip.c:1423
 #, fuzzy, c-format
 msgid "cannot read section [%zu] name: %s"
 msgstr "no se puede leer nombre [%Zu]: %s"
 
-#: src/unstrip.c:1026
+#: src/unstrip.c:1034
 #, fuzzy, c-format
 msgid "bad sh_link for group section: %s"
 msgstr ".debug_line section inválida"
 
-#: src/unstrip.c:1032
+#: src/unstrip.c:1040
 #, fuzzy, c-format
 msgid "couldn't get shdr for group section: %s"
 msgstr "No se puede obtener encabezamiento de sección 0th: %s"
 
-#: src/unstrip.c:1037
+#: src/unstrip.c:1045
 #, fuzzy, c-format
 msgid "bad data for group symbol section: %s"
 msgstr "no se puede obtener sección para símbolos\n"
 
-#: src/unstrip.c:1043
+#: src/unstrip.c:1051
 #, fuzzy, c-format
 msgid "couldn't get symbol for group section: %s"
 msgstr "no se puede obtener versión de símbolo: %s"
 
-#: src/unstrip.c:1048
+#: src/unstrip.c:1056
 #, fuzzy, c-format
 msgid "bad symbol name for group section: %s"
 msgstr "No se puede obtener el encabezamiento de sección %zu: %s"
 
-#: src/unstrip.c:1090 src/unstrip.c:1109 src/unstrip.c:1147
+#: src/unstrip.c:1098 src/unstrip.c:1117 src/unstrip.c:1155
 #, c-format
 msgid "cannot read '.gnu.prelink_undo' section: %s"
 msgstr "no se puede leer sección '.gnu.prelink_undo': %s"
 
-#: src/unstrip.c:1127
+#: src/unstrip.c:1135
 #, c-format
 msgid "overflow with shnum = %zu in '%s' section"
 msgstr ""
 
-#: src/unstrip.c:1138
+#: src/unstrip.c:1146
 #, c-format
 msgid "invalid contents in '%s' section"
 msgstr "contenido inválido en sección '%s'"
 
-#: src/unstrip.c:1194 src/unstrip.c:1528
+#: src/unstrip.c:1202 src/unstrip.c:1549
 #, fuzzy, c-format
 msgid "cannot find matching section for [%zu] '%s'"
 msgstr "no se puede hallar sección coincidente para [%Zu] '%s'"
 
-#: src/unstrip.c:1319 src/unstrip.c:1335 src/unstrip.c:1607 src/unstrip.c:1881
+#: src/unstrip.c:1327 src/unstrip.c:1343 src/unstrip.c:1629 src/unstrip.c:1920
 #, c-format
 msgid "cannot add section name to string table: %s"
 msgstr "no se puede añadir nombre de sección a tabla de cadenas: %s"
 
-#: src/unstrip.c:1344
+#: src/unstrip.c:1352
 #, c-format
 msgid "cannot update section header string table data: %s"
 msgstr ""
 "no se pueden actualizar datos de tabla de cadenas de encabezamiento de "
 "sección: %s"
 
-#: src/unstrip.c:1373 src/unstrip.c:1377
+#: src/unstrip.c:1381 src/unstrip.c:1385
 #, c-format
 msgid "cannot get section header string table section index: %s"
 msgstr ""
 "no se puede obtener índice de sección de tabla de cadenas de encabezamiento "
 "de sección: %s"
 
-#: src/unstrip.c:1381 src/unstrip.c:1385 src/unstrip.c:1622
+#: src/unstrip.c:1389 src/unstrip.c:1393 src/unstrip.c:1644
 #, c-format
 msgid "cannot get section count: %s"
 msgstr "No se puede obtener cuenta de sección: %s"
 
-#: src/unstrip.c:1388
+#: src/unstrip.c:1396
 #, c-format
 msgid "more sections in stripped file than debug file -- arguments reversed?"
 msgstr ""
 "más secciones en el archivo despojado que en el archivo de depuración -- "
 "¿argumentos invertidos?"
 
-#: src/unstrip.c:1450 src/unstrip.c:1543
+#: src/unstrip.c:1400
+#, c-format
+msgid "no sections in stripped file"
+msgstr ""
+
+#: src/unstrip.c:1471 src/unstrip.c:1564
 #, c-format
 msgid "cannot read section header string table: %s"
 msgstr "no se puede obtener tabla de cadenas de encabezamiento de sección: %s"
 
-#: src/unstrip.c:1601
+#: src/unstrip.c:1623
 #, c-format
 msgid "cannot add new section: %s"
 msgstr "No se puede añadir nueva sección: %s"
 
-#: src/unstrip.c:1714
+#: src/unstrip.c:1753
 #, fuzzy, c-format
 msgid "symbol [%zu] has invalid section index"
 msgstr "símbolo [%Zu] tiene índice de sección inválido"
 
-#: src/unstrip.c:1746
+#: src/unstrip.c:1785
 #, fuzzy, c-format
 msgid "group has invalid section index [%zd]"
 msgstr "símbolo [%Zu] tiene índice de sección inválido"
 
-#: src/unstrip.c:2017
+#: src/unstrip.c:2060
 #, c-format
 msgid "cannot read section data: %s"
 msgstr "no se puede leer la sección de datos: %s"
 
-#: src/unstrip.c:2046
+#: src/unstrip.c:2089
 #, c-format
 msgid "cannot update ELF header: %s"
 msgstr "No se puede actualizar encabezamiento ELF: %s"
 
-#: src/unstrip.c:2070
+#: src/unstrip.c:2113
 #, c-format
 msgid "cannot update program header: %s"
 msgstr "no se puede actualizar encabezamiento de programa: %s"
 
-#: src/unstrip.c:2075 src/unstrip.c:2157
+#: src/unstrip.c:2118 src/unstrip.c:2200
 #, c-format
 msgid "cannot write output file: %s"
 msgstr "no se puede escribir al archivo de salida: %s"
 
-#: src/unstrip.c:2126
+#: src/unstrip.c:2169
 #, c-format
 msgid "DWARF data not adjusted for prelinking bias; consider prelink -u"
 msgstr ""
 "datos DWARF no se ajustan para polarización de pre-enlace; considere prelink "
 "-u"
 
-#: src/unstrip.c:2129
+#: src/unstrip.c:2172
 #, c-format
 msgid ""
 "DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"
@@ -6927,77 +6947,77 @@
 "Datos DWARF en '%s' no se ajustan a polarización de pre-enlace; considere "
 "prelink -u"
 
-#: src/unstrip.c:2148 src/unstrip.c:2199 src/unstrip.c:2211 src/unstrip.c:2297
+#: src/unstrip.c:2191 src/unstrip.c:2242 src/unstrip.c:2254 src/unstrip.c:2340
 #, c-format
 msgid "cannot create ELF descriptor: %s"
 msgstr "no se puede crear un descriptor ELF: %s"
 
-#: src/unstrip.c:2190
+#: src/unstrip.c:2233
 msgid "WARNING: "
 msgstr ""
 
-#: src/unstrip.c:2192
+#: src/unstrip.c:2235
 msgid ", use --force"
 msgstr ""
 
-#: src/unstrip.c:2215
+#: src/unstrip.c:2258
 msgid "ELF header identification (e_ident) different"
 msgstr ""
 
-#: src/unstrip.c:2218
+#: src/unstrip.c:2261
 msgid "ELF header type (e_type) different"
 msgstr ""
 
-#: src/unstrip.c:2221
+#: src/unstrip.c:2264
 msgid "ELF header machine type (e_machine) different"
 msgstr ""
 
-#: src/unstrip.c:2224
+#: src/unstrip.c:2267
 msgid "stripped program header (e_phnum) smaller than unstripped"
 msgstr ""
 
-#: src/unstrip.c:2254
+#: src/unstrip.c:2297
 #, c-format
 msgid "cannot find stripped file for module '%s': %s"
 msgstr "no se puede hallar archivo obtenido para módulo '%s': %s "
 
-#: src/unstrip.c:2258
+#: src/unstrip.c:2301
 #, c-format
 msgid "cannot open stripped file '%s' for module '%s': %s"
 msgstr "No se puede abrir el archivo '%s' obtenido para módulo '%s': %s"
 
-#: src/unstrip.c:2273
+#: src/unstrip.c:2316
 #, c-format
 msgid "cannot find debug file for module '%s': %s"
 msgstr "no puede hallar archivo de depuración para módulo '%s': %su"
 
-#: src/unstrip.c:2277
+#: src/unstrip.c:2320
 #, c-format
 msgid "cannot open debug file '%s' for module '%s': %s"
 msgstr "No puede abrir archivo de depuración '%s' para módulo '%s': %s"
 
-#: src/unstrip.c:2290
+#: src/unstrip.c:2333
 #, c-format
 msgid "module '%s' file '%s' is not stripped"
 msgstr "No se obtuvo el archivo '%s' de módulo '%s' "
 
-#: src/unstrip.c:2321
+#: src/unstrip.c:2364
 #, c-format
 msgid "cannot cache section addresses for module '%s': %s"
 msgstr ""
 "No puede almacenar en cache direcciones de sección para módulo '%s': %s"
 
-#: src/unstrip.c:2454
+#: src/unstrip.c:2497
 #, c-format
 msgid "no matching modules found"
 msgstr "No se encontraron módulos coincidentes"
 
-#: src/unstrip.c:2463
+#: src/unstrip.c:2506
 #, c-format
 msgid "matched more than one module"
 msgstr "coincidió con más de un módulo"
 
-#: src/unstrip.c:2507
+#: src/unstrip.c:2550
 msgid ""
 "STRIPPED-FILE DEBUG-FILE\n"
 "[MODULE...]"
@@ -7005,7 +7025,7 @@
 "STRIPPED-FILE DEBUG-FILE\n"
 "[MODULE...]"
 
-#: src/unstrip.c:2508
+#: src/unstrip.c:2551
 #, fuzzy
 msgid ""
 "Combine stripped files with separate symbols and debug information.\n"
diff --git a/po/ja.po b/po/ja.po
index c954f3b..cd53f22 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: ja\n"
 "Report-Msgid-Bugs-To: https://sourceware.org/bugzilla/\n"
-"POT-Creation-Date: 2019-08-28 13:23+0200\n"
+"POT-Creation-Date: 2019-11-26 09:48+0100\n"
 "PO-Revision-Date: 2009-09-20 15:32+0900\n"
 "Last-Translator: Hyu_gabaru Ryu_ichi <hyu_gabaru@yahoo.co.jp>\n"
 "Language-Team: Japanese <jp@li.org>\n"
@@ -24,7 +24,7 @@
 "colorize the output.  WHEN defaults to 'always' or can be 'auto' or 'never'"
 msgstr ""
 
-#: lib/color.c:127
+#: lib/color.c:129
 #, c-format
 msgid ""
 "%s: invalid argument '%s' for '--color'\n"
@@ -34,7 +34,7 @@
 "  - 'auto', 'tty', 'if-tty'\n"
 msgstr ""
 
-#: lib/color.c:190 src/objdump.c:726
+#: lib/color.c:194 src/objdump.c:728
 #, fuzzy, c-format
 msgid "cannot allocate memory"
 msgstr "PLT セクションを割り当てられません: %s"
@@ -50,18 +50,18 @@
 "This is free software; see the source for copying conditions.  There is NO\n"
 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
 
-#: lib/xmalloc.c:52 lib/xmalloc.c:65 lib/xmalloc.c:77 src/readelf.c:3437
-#: src/readelf.c:11386 src/unstrip.c:2350 src/unstrip.c:2556
+#: lib/xmalloc.c:52 lib/xmalloc.c:65 lib/xmalloc.c:77 src/readelf.c:3449
+#: src/readelf.c:11398 src/unstrip.c:2393 src/unstrip.c:2599
 #, c-format
 msgid "memory exhausted"
 msgstr "メモリー消費済み"
 
-#: libasm/asm_error.c:65 libdw/dwarf_error.c:57 libdwfl/libdwflP.h:50
+#: libasm/asm_error.c:65 libdw/dwarf_error.c:57 libdwfl/libdwflP.h:51
 #: libelf/elf_error.c:60
 msgid "no error"
 msgstr "エラー無し"
 
-#: libasm/asm_error.c:66 libdw/dwarf_error.c:67 libdwfl/libdwflP.h:52
+#: libasm/asm_error.c:66 libdw/dwarf_error.c:67 libdwfl/libdwflP.h:53
 #: libelf/elf_error.c:91
 msgid "out of memory"
 msgstr "メモリー不足"
@@ -98,7 +98,7 @@
 msgid "no backend support available"
 msgstr "バックエンドサポートが利用できません"
 
-#: libasm/asm_error.c:83 libdw/dwarf_error.c:58 libdwfl/libdwflP.h:51
+#: libasm/asm_error.c:83 libdw/dwarf_error.c:58 libdwfl/libdwflP.h:52
 #: libelf/elf_error.c:63
 msgid "unknown error"
 msgstr "不明なエラー"
@@ -214,7 +214,7 @@
 msgid "invalid directory index"
 msgstr "不当なディレクトリー索引"
 
-#: libdw/dwarf_error.c:87 libdwfl/libdwflP.h:71
+#: libdw/dwarf_error.c:87 libdwfl/libdwflP.h:72
 msgid "address out of range"
 msgstr "アドレスが範囲外です"
 
@@ -245,7 +245,7 @@
 msgid "invalid address range index"
 msgstr "不当なアドレス範囲索引"
 
-#: libdw/dwarf_error.c:94 libdwfl/libdwflP.h:72
+#: libdw/dwarf_error.c:94 libdwfl/libdwflP.h:73
 msgid "no matching address range"
 msgstr "アドレス範囲に対応しません"
 
@@ -293,7 +293,7 @@
 msgid ".debug_addr section missing"
 msgstr ".debug_ranges セクションがありません"
 
-#: libdwfl/argp-std.c:50 src/stack.c:638 src/unstrip.c:2497
+#: libdwfl/argp-std.c:50 src/stack.c:638 src/unstrip.c:2540
 msgid "Input selection options:"
 msgstr "選択オプションを入力してください:"
 
@@ -360,165 +360,165 @@
 msgid "No modules recognized in core file"
 msgstr "コアファイルの中にモジュールを認識できません"
 
-#: libdwfl/libdwflP.h:53
+#: libdwfl/libdwflP.h:54
 msgid "See errno"
 msgstr ""
 
-#: libdwfl/libdwflP.h:54
+#: libdwfl/libdwflP.h:55
 msgid "See elf_errno"
 msgstr ""
 
-#: libdwfl/libdwflP.h:55
+#: libdwfl/libdwflP.h:56
 msgid "See dwarf_errno"
 msgstr ""
 
-#: libdwfl/libdwflP.h:56
+#: libdwfl/libdwflP.h:57
 msgid "See ebl_errno (XXX missing)"
 msgstr ""
 
-#: libdwfl/libdwflP.h:57
+#: libdwfl/libdwflP.h:58
 msgid "gzip decompression failed"
 msgstr ""
 
-#: libdwfl/libdwflP.h:58
+#: libdwfl/libdwflP.h:59
 msgid "bzip2 decompression failed"
 msgstr ""
 
-#: libdwfl/libdwflP.h:59
+#: libdwfl/libdwflP.h:60
 msgid "LZMA decompression failed"
 msgstr ""
 
-#: libdwfl/libdwflP.h:60
+#: libdwfl/libdwflP.h:61
 msgid "no support library found for machine"
 msgstr ""
 
-#: libdwfl/libdwflP.h:61
+#: libdwfl/libdwflP.h:62
 msgid "Callbacks missing for ET_REL file"
 msgstr ""
 
-#: libdwfl/libdwflP.h:62
+#: libdwfl/libdwflP.h:63
 msgid "Unsupported relocation type"
 msgstr ""
 
-#: libdwfl/libdwflP.h:63
+#: libdwfl/libdwflP.h:64
 msgid "r_offset is bogus"
 msgstr ""
 
-#: libdwfl/libdwflP.h:64 libelf/elf_error.c:115 libelf/elf_error.c:175
+#: libdwfl/libdwflP.h:65 libelf/elf_error.c:115 libelf/elf_error.c:175
 msgid "offset out of range"
 msgstr "オフセットが範囲を越えている"
 
-#: libdwfl/libdwflP.h:65
+#: libdwfl/libdwflP.h:66
 #, fuzzy
 msgid "relocation refers to undefined symbol"
 msgstr "定義されたシンボルの印刷サイズ"
 
-#: libdwfl/libdwflP.h:66
+#: libdwfl/libdwflP.h:67
 msgid "Callback returned failure"
 msgstr ""
 
-#: libdwfl/libdwflP.h:67
+#: libdwfl/libdwflP.h:68
 #, fuzzy
 msgid "No DWARF information found"
 msgstr "DWARF 情報がありません"
 
-#: libdwfl/libdwflP.h:68
+#: libdwfl/libdwflP.h:69
 msgid "No symbol table found"
 msgstr ""
 
-#: libdwfl/libdwflP.h:69
+#: libdwfl/libdwflP.h:70
 #, fuzzy
 msgid "No ELF program headers"
 msgstr "プログラムヘッダーを得られません: %s"
 
-#: libdwfl/libdwflP.h:70
+#: libdwfl/libdwflP.h:71
 msgid "address range overlaps an existing module"
 msgstr ""
 
-#: libdwfl/libdwflP.h:73
+#: libdwfl/libdwflP.h:74
 msgid "image truncated"
 msgstr ""
 
-#: libdwfl/libdwflP.h:74
+#: libdwfl/libdwflP.h:75
 #, fuzzy
 msgid "ELF file opened"
 msgstr "ファイルのオープンを追跡します。"
 
-#: libdwfl/libdwflP.h:75
+#: libdwfl/libdwflP.h:76
 #, fuzzy
 msgid "not a valid ELF file"
 msgstr "不当な ELF ファイル"
 
-#: libdwfl/libdwflP.h:76
+#: libdwfl/libdwflP.h:77
 #, fuzzy
 msgid "cannot handle DWARF type description"
 msgstr "Elf 記述子を生成できません: %s"
 
-#: libdwfl/libdwflP.h:77
+#: libdwfl/libdwflP.h:78
 msgid "ELF file does not match build ID"
 msgstr ""
 
-#: libdwfl/libdwflP.h:78
+#: libdwfl/libdwflP.h:79
 #, fuzzy
 msgid "corrupt .gnu.prelink_undo section data"
 msgstr "ラインデータセクションデータを得られません: %s"
 
-#: libdwfl/libdwflP.h:79
+#: libdwfl/libdwflP.h:80
 msgid "Internal error due to ebl"
 msgstr ""
 
-#: libdwfl/libdwflP.h:80
+#: libdwfl/libdwflP.h:81
 msgid "Missing data in core file"
 msgstr ""
 
-#: libdwfl/libdwflP.h:81
+#: libdwfl/libdwflP.h:82
 #, fuzzy
 msgid "Invalid register"
 msgstr "不当なパラメーター"
 
-#: libdwfl/libdwflP.h:82
+#: libdwfl/libdwflP.h:83
 msgid "Error reading process memory"
 msgstr ""
 
-#: libdwfl/libdwflP.h:83
+#: libdwfl/libdwflP.h:84
 msgid "Couldn't find architecture of any ELF"
 msgstr ""
 
-#: libdwfl/libdwflP.h:84
+#: libdwfl/libdwflP.h:85
 msgid "Error parsing /proc filesystem"
 msgstr ""
 
-#: libdwfl/libdwflP.h:85
+#: libdwfl/libdwflP.h:86
 #, fuzzy
 msgid "Invalid DWARF"
 msgstr "不当な DWARF"
 
-#: libdwfl/libdwflP.h:86
+#: libdwfl/libdwflP.h:87
 msgid "Unsupported DWARF"
 msgstr ""
 
-#: libdwfl/libdwflP.h:87
+#: libdwfl/libdwflP.h:88
 msgid "Unable to find more threads"
 msgstr ""
 
-#: libdwfl/libdwflP.h:88
+#: libdwfl/libdwflP.h:89
 msgid "Dwfl already has attached state"
 msgstr ""
 
-#: libdwfl/libdwflP.h:89
+#: libdwfl/libdwflP.h:90
 msgid "Dwfl has no attached state"
 msgstr ""
 
-#: libdwfl/libdwflP.h:90
+#: libdwfl/libdwflP.h:91
 msgid "Unwinding not supported for this architecture"
 msgstr ""
 
-#: libdwfl/libdwflP.h:91
+#: libdwfl/libdwflP.h:92
 #, fuzzy
 msgid "Invalid argument"
 msgstr "不当なパラメーター"
 
-#: libdwfl/libdwflP.h:92
+#: libdwfl/libdwflP.h:93
 #, fuzzy
 msgid "Not an ET_CORE ELF file"
 msgstr "不当な ELF ファイル"
@@ -624,7 +624,7 @@
 msgid "invalid size of destination operand"
 msgstr "宛先演算子の大きさが無効"
 
-#: libelf/elf_error.c:87 src/readelf.c:6154
+#: libelf/elf_error.c:87 src/readelf.c:6166
 #, c-format
 msgid "invalid encoding"
 msgstr "無効なエンコード"
@@ -711,8 +711,8 @@
 msgid "invalid section header"
 msgstr "不当なセクションヘッダー"
 
-#: libelf/elf_error.c:191 src/readelf.c:9902 src/readelf.c:10502
-#: src/readelf.c:10603 src/readelf.c:10785
+#: libelf/elf_error.c:191 src/readelf.c:9914 src/readelf.c:10514
+#: src/readelf.c:10615 src/readelf.c:10797
 #, c-format
 msgid "invalid data"
 msgstr "不当なデータ"
@@ -1374,7 +1374,7 @@
 
 #: src/elfcmp.c:734 src/findtextrel.c:205 src/nm.c:364 src/ranlib.c:141
 #: src/size.c:272 src/strings.c:185 src/strip.c:984 src/strip.c:1021
-#: src/unstrip.c:2146 src/unstrip.c:2175
+#: src/unstrip.c:2189 src/unstrip.c:2218
 #, c-format
 msgid "cannot open '%s'"
 msgstr "'%s' を開けません"
@@ -1468,7 +1468,7 @@
 msgstr "セクション [%2d] '%s': セクションデータを得られません\n"
 
 #. Strings for arguments in help texts.
-#: src/elfcompress.c:1336 src/elflint.c:77 src/readelf.c:153
+#: src/elfcompress.c:1336 src/elflint.c:77 src/readelf.c:158
 msgid "FILE..."
 msgstr "ふぁいる..."
 
@@ -1500,14 +1500,14 @@
 msgid "Pedantic checking of ELF files compliance with gABI/psABI spec."
 msgstr "ELF ファイルが gABI/psABI 仕様へ準拠しているかの厳密なチェック。"
 
-#: src/elflint.c:154 src/readelf.c:360
-#, c-format
-msgid "cannot open input file"
+#: src/elflint.c:154 src/readelf.c:368
+#, fuzzy, c-format
+msgid "cannot open input file '%s'"
 msgstr "入力ファイルを開けません"
 
 #: src/elflint.c:161
-#, c-format
-msgid "cannot generate Elf descriptor: %s\n"
+#, fuzzy, c-format
+msgid "cannot generate Elf descriptor for '%s': %s\n"
 msgstr "Elf 記述子を生成できません: %s\n"
 
 #: src/elflint.c:180
@@ -1519,7 +1519,7 @@
 msgid "No errors"
 msgstr "エラーはありません"
 
-#: src/elflint.c:219 src/readelf.c:563
+#: src/elflint.c:219 src/readelf.c:575
 msgid "Missing file name.\n"
 msgstr "ファイル名がありません。\n"
 
@@ -3553,12 +3553,12 @@
 msgid "cannot create search tree"
 msgstr "検索ツリーを生成できません"
 
-#: src/nm.c:746 src/nm.c:1205 src/objdump.c:777 src/readelf.c:623
-#: src/readelf.c:1435 src/readelf.c:1586 src/readelf.c:1787 src/readelf.c:1993
-#: src/readelf.c:2183 src/readelf.c:2361 src/readelf.c:2437 src/readelf.c:2695
-#: src/readelf.c:2771 src/readelf.c:2858 src/readelf.c:3456 src/readelf.c:3506
-#: src/readelf.c:3569 src/readelf.c:11218 src/readelf.c:12403
-#: src/readelf.c:12614 src/readelf.c:12682 src/size.c:398 src/size.c:470
+#: src/nm.c:746 src/nm.c:1205 src/objdump.c:779 src/readelf.c:635
+#: src/readelf.c:1447 src/readelf.c:1598 src/readelf.c:1799 src/readelf.c:2005
+#: src/readelf.c:2195 src/readelf.c:2373 src/readelf.c:2449 src/readelf.c:2707
+#: src/readelf.c:2783 src/readelf.c:2870 src/readelf.c:3468 src/readelf.c:3518
+#: src/readelf.c:3581 src/readelf.c:11230 src/readelf.c:12415
+#: src/readelf.c:12626 src/readelf.c:12695 src/size.c:398 src/size.c:470
 #: src/strip.c:1038
 #, c-format
 msgid "cannot get section header string table index"
@@ -3604,12 +3604,12 @@
 msgstr "%s: セクションの項目の大きさ `%s' は予期したものとは異なります"
 
 #. XXX Add machine specific object file types.
-#: src/nm.c:1526
+#: src/nm.c:1527
 #, c-format
 msgid "%s%s%s%s: Invalid operation"
 msgstr "%s%s%s%s: 不当な操作"
 
-#: src/nm.c:1583
+#: src/nm.c:1584
 #, c-format
 msgid "%s%s%s: no symbols"
 msgstr "%s%s%s: シンボルがありません"
@@ -3644,7 +3644,7 @@
 msgid "Show information from FILEs (a.out by default)."
 msgstr ""
 
-#: src/objdump.c:218 src/readelf.c:568
+#: src/objdump.c:218 src/readelf.c:580
 msgid "No operation specified.\n"
 msgstr "操作が指定されていません。\n"
 
@@ -3653,11 +3653,11 @@
 msgid "while close `%s'"
 msgstr ""
 
-#: src/objdump.c:363 src/readelf.c:2088 src/readelf.c:2280
+#: src/objdump.c:363 src/readelf.c:2100 src/readelf.c:2292
 msgid "INVALID SYMBOL"
 msgstr "不当なシンボル"
 
-#: src/objdump.c:378 src/readelf.c:2122 src/readelf.c:2316
+#: src/objdump.c:378 src/readelf.c:2134 src/readelf.c:2328
 msgid "INVALID SECTION"
 msgstr "不当なセクション"
 
@@ -3708,90 +3708,95 @@
 msgid "error while freeing sub-ELF descriptor: %s"
 msgstr ""
 
-#: src/readelf.c:94
+#: src/readelf.c:97
 #, fuzzy
 msgid "ELF input selection:"
 msgstr "出力選択:"
 
-#: src/readelf.c:96
+#: src/readelf.c:99
 msgid ""
 "Use the named SECTION (default .gnu_debugdata) as (compressed) ELF input data"
 msgstr ""
 
-#: src/readelf.c:99
+#: src/readelf.c:102
 msgid ""
 "Used with -w to find the skeleton Compile Units in FILE associated with the "
 "Split Compile units in a .dwo input file"
 msgstr ""
 
-#: src/readelf.c:101
+#: src/readelf.c:104
 #, fuzzy
 msgid "ELF output selection:"
 msgstr "出力選択:"
 
-#: src/readelf.c:103
+#: src/readelf.c:106
 msgid "All these plus -p .strtab -p .dynstr -p .comment"
 msgstr ""
 
-#: src/readelf.c:104
+#: src/readelf.c:107
 msgid "Display the dynamic segment"
 msgstr "動的セグメントを表示"
 
-#: src/readelf.c:105
+#: src/readelf.c:108
 msgid "Display the ELF file header"
 msgstr "ELF ファイルヘッダーを表示"
 
-#: src/readelf.c:107
+#: src/readelf.c:110
 msgid "Display histogram of bucket list lengths"
 msgstr "バケットリスト長の柱状図を表示"
 
-#: src/readelf.c:108
+#: src/readelf.c:111
 msgid "Display the program headers"
 msgstr "プログラムヘッダーを表示"
 
-#: src/readelf.c:110
+#: src/readelf.c:113
 msgid "Display relocations"
 msgstr "リロケーションを表示"
 
-#: src/readelf.c:111
+#: src/readelf.c:114
 #, fuzzy
 msgid "Display the section groups"
 msgstr "セクションのヘッダーを表示"
 
-#: src/readelf.c:112
+#: src/readelf.c:115
 #, fuzzy
 msgid "Display the sections' headers"
 msgstr "セクションのヘッダーを表示"
 
-#: src/readelf.c:115
+#: src/readelf.c:118
 #, fuzzy
 msgid "Display the symbol table sections"
 msgstr "シンボルテーブルを表示"
 
-#: src/readelf.c:116
+#: src/readelf.c:120
+#, fuzzy
+msgid "Display (only) the dynamic symbol table"
+msgstr "外部シンボルのみを表示"
+
+#: src/readelf.c:121
 msgid "Display versioning information"
 msgstr "バージョニング情報の表示"
 
-#: src/readelf.c:117
+#: src/readelf.c:122
 #, fuzzy
 msgid "Display the ELF notes"
 msgstr "コアノートを表示"
 
-#: src/readelf.c:119
+#: src/readelf.c:124
 #, fuzzy
 msgid "Display architecture specific information, if any"
 msgstr "(もしあれば)アーキテクチャー固有の情報を表示"
 
-#: src/readelf.c:121
+#: src/readelf.c:126
 msgid "Display sections for exception handling"
 msgstr "例外を取り扱うためのセクションを表示"
 
-#: src/readelf.c:123
+#: src/readelf.c:128
 #, fuzzy
 msgid "Additional output selection:"
 msgstr "出力選択:"
 
-#: src/readelf.c:125
+#: src/readelf.c:130
 #, fuzzy
 msgid ""
 "Display DWARF section content.  SECTION can be one of abbrev, addr, aranges, "
@@ -3801,193 +3806,193 @@
 "DWARF セクションの内容を表示。SECTION は addrevか、aranges、frame、info、"
 "loc、ranges、pubnames、str、macinfo、exception のいずれかです"
 
-#: src/readelf.c:129
+#: src/readelf.c:134
 msgid "Dump the uninterpreted contents of SECTION, by number or name"
 msgstr "数字か名前で解釈できないセクションの内容をダンプする"
 
-#: src/readelf.c:131
+#: src/readelf.c:136
 msgid "Print string contents of sections"
 msgstr "セクションの文字列内容を印刷する"
 
-#: src/readelf.c:134
+#: src/readelf.c:139
 msgid "Display the symbol index of an archive"
 msgstr "アーカイブのシンボル索引を表示"
 
-#: src/readelf.c:136
+#: src/readelf.c:141
 msgid "Output control:"
 msgstr "出力制御:"
 
-#: src/readelf.c:138
+#: src/readelf.c:143
 msgid "Do not find symbol names for addresses in DWARF data"
 msgstr "DWARFデータ中のアドレスのためのシンボル名を探さない"
 
-#: src/readelf.c:140
+#: src/readelf.c:145
 #, fuzzy
 msgid ""
 "Display just offsets instead of resolving values to addresses in DWARF data"
 msgstr "DWARFデータ中のアドレスのためのシンボル名を探さない"
 
-#: src/readelf.c:142
+#: src/readelf.c:147
 msgid "Ignored for compatibility (lines always wide)"
 msgstr ""
 
-#: src/readelf.c:144
+#: src/readelf.c:149
 msgid ""
 "Show compression information for compressed sections (when used with -S); "
 "decompress section before dumping data (when used with -p or -x)"
 msgstr ""
 
 #. Short description of program.
-#: src/readelf.c:149
+#: src/readelf.c:154
 msgid "Print information from ELF file in human-readable form."
 msgstr "ELF ファイルから人間が読める形で情報を印刷する。"
 
 #. Look up once.
-#: src/readelf.c:342
+#: src/readelf.c:350
 msgid "yes"
 msgstr "はい"
 
-#: src/readelf.c:343
+#: src/readelf.c:351
 msgid "no"
 msgstr "いいえ"
 
-#: src/readelf.c:536
+#: src/readelf.c:548
 #, c-format
 msgid "Unknown DWARF debug section `%s'.\n"
 msgstr "不明な DWARF デバッグセクション `%s'.\n"
 
-#: src/readelf.c:607 src/readelf.c:718
+#: src/readelf.c:619 src/readelf.c:730
 #, c-format
 msgid "cannot generate Elf descriptor: %s"
 msgstr "Elf 記述子を生成できません: %s"
 
-#: src/readelf.c:614 src/readelf.c:941 src/strip.c:1133
+#: src/readelf.c:626 src/readelf.c:953 src/strip.c:1133
 #, c-format
 msgid "cannot determine number of sections: %s"
 msgstr "セクション数を決定できません: %s"
 
-#: src/readelf.c:632 src/readelf.c:1251 src/readelf.c:1459
+#: src/readelf.c:644 src/readelf.c:1263 src/readelf.c:1471
 #, c-format
 msgid "cannot get section: %s"
 msgstr "セクションを得られません: %s"
 
-#: src/readelf.c:641 src/readelf.c:1258 src/readelf.c:1467 src/readelf.c:12634
-#: src/unstrip.c:395 src/unstrip.c:426 src/unstrip.c:481 src/unstrip.c:600
-#: src/unstrip.c:621 src/unstrip.c:661 src/unstrip.c:873 src/unstrip.c:1204
-#: src/unstrip.c:1331 src/unstrip.c:1355 src/unstrip.c:1398 src/unstrip.c:1462
-#: src/unstrip.c:1636 src/unstrip.c:1770 src/unstrip.c:1913 src/unstrip.c:2008
+#: src/readelf.c:653 src/readelf.c:1270 src/readelf.c:1479 src/readelf.c:12646
+#: src/unstrip.c:395 src/unstrip.c:426 src/unstrip.c:485 src/unstrip.c:604
+#: src/unstrip.c:625 src/unstrip.c:665 src/unstrip.c:881 src/unstrip.c:1212
+#: src/unstrip.c:1339 src/unstrip.c:1363 src/unstrip.c:1419 src/unstrip.c:1483
+#: src/unstrip.c:1658 src/unstrip.c:1809 src/unstrip.c:1952 src/unstrip.c:2051
 #, c-format
 msgid "cannot get section header: %s"
 msgstr "セクションヘッダーを得られません: %s"
 
-#: src/readelf.c:649
+#: src/readelf.c:661
 #, fuzzy, c-format
 msgid "cannot get section name"
 msgstr "セクションを得られません: %s"
 
-#: src/readelf.c:658 src/readelf.c:6564 src/readelf.c:10490 src/readelf.c:10592
-#: src/readelf.c:10770
+#: src/readelf.c:670 src/readelf.c:6576 src/readelf.c:10502 src/readelf.c:10604
+#: src/readelf.c:10782
 #, c-format
 msgid "cannot get %s content: %s"
 msgstr "%s の内容を得られません: %s"
 
-#: src/readelf.c:674
+#: src/readelf.c:686
 #, fuzzy, c-format
 msgid "cannot create temp file '%s'"
 msgstr "新しいファイル '%s' を生成できません: %s"
 
-#: src/readelf.c:683
+#: src/readelf.c:695
 #, fuzzy, c-format
 msgid "cannot write section data"
 msgstr "セクションデータを割り当てられません: %s"
 
-#: src/readelf.c:689 src/readelf.c:706 src/readelf.c:735
+#: src/readelf.c:701 src/readelf.c:718 src/readelf.c:747
 #, c-format
 msgid "error while closing Elf descriptor: %s"
 msgstr "Elf 記述子を閉じている時にエラー: %s"
 
-#: src/readelf.c:696
+#: src/readelf.c:708
 #, fuzzy, c-format
 msgid "error while rewinding file descriptor"
 msgstr "Elf 記述子を閉じている時にエラー: %s"
 
-#: src/readelf.c:730
+#: src/readelf.c:742
 #, c-format
 msgid "'%s' is not an archive, cannot print archive index"
 msgstr "'%s' はアーカイブではなく、アーカイブ索引を印刷できません"
 
-#: src/readelf.c:834
+#: src/readelf.c:846
 #, c-format
 msgid "cannot stat input file"
 msgstr "入力ファイルを stat できません"
 
-#: src/readelf.c:836
+#: src/readelf.c:848
 #, c-format
 msgid "input file is empty"
 msgstr "入力ファイルが空です"
 
-#: src/readelf.c:838
+#: src/readelf.c:850
 #, c-format
 msgid "failed reading '%s': %s"
 msgstr "'%s' の読込みに失敗: %s"
 
-#: src/readelf.c:867
+#: src/readelf.c:879
 #, fuzzy, c-format
 msgid "No such section '%s' in '%s'"
 msgstr "セクション [%Zu] '%s' からデータが得られません: %s"
 
-#: src/readelf.c:926
+#: src/readelf.c:938
 #, c-format
 msgid "cannot read ELF header: %s"
 msgstr "ELF ヘッダーが読めません: %s"
 
-#: src/readelf.c:934
+#: src/readelf.c:946
 #, c-format
 msgid "cannot create EBL handle"
 msgstr "EBL ヘッダーを生成できません"
 
-#: src/readelf.c:947
+#: src/readelf.c:959
 #, fuzzy, c-format
 msgid "cannot determine number of program headers: %s"
 msgstr "セクション数を決定できません: %s"
 
-#: src/readelf.c:979
+#: src/readelf.c:991
 #, fuzzy, c-format
 msgid "cannot read ELF: %s"
 msgstr "%s を読みません: %s"
 
-#: src/readelf.c:1040
+#: src/readelf.c:1052
 msgid "NONE (None)"
 msgstr "なし (なし)"
 
-#: src/readelf.c:1041
+#: src/readelf.c:1053
 msgid "REL (Relocatable file)"
 msgstr "REL (リロケータブルファイル)"
 
-#: src/readelf.c:1042
+#: src/readelf.c:1054
 msgid "EXEC (Executable file)"
 msgstr "(EXEC (実行ファイル)"
 
-#: src/readelf.c:1043
+#: src/readelf.c:1055
 msgid "DYN (Shared object file)"
 msgstr "DYN (共用オブジェクトファイル)"
 
-#: src/readelf.c:1044
+#: src/readelf.c:1056
 msgid "CORE (Core file)"
 msgstr "CORE (コアファイル)"
 
-#: src/readelf.c:1049
+#: src/readelf.c:1061
 #, c-format
 msgid "OS Specific: (%x)\n"
 msgstr "OS 固有: (%x)\n"
 
 #. && e_type <= ET_HIPROC always true
-#: src/readelf.c:1051
+#: src/readelf.c:1063
 #, c-format
 msgid "Processor Specific: (%x)\n"
 msgstr "プロセッサー固有: (%x)\n"
 
-#: src/readelf.c:1061
+#: src/readelf.c:1073
 msgid ""
 "ELF Header:\n"
 "  Magic:  "
@@ -3995,7 +4000,7 @@
 "ELF ヘッダー:\n"
 " マジック: "
 
-#: src/readelf.c:1065
+#: src/readelf.c:1077
 #, c-format
 msgid ""
 "\n"
@@ -4004,123 +4009,123 @@
 "\n"
 "  クラス:                            %s\n"
 
-#: src/readelf.c:1070
+#: src/readelf.c:1082
 #, c-format
 msgid "  Data:                              %s\n"
 msgstr "  データ:                            %s\n"
 
-#: src/readelf.c:1076
+#: src/readelf.c:1088
 #, c-format
 msgid "  Ident Version:                     %hhd %s\n"
 msgstr "  識別バージョン:                    %hhd %s\n"
 
-#: src/readelf.c:1078 src/readelf.c:1100
+#: src/readelf.c:1090 src/readelf.c:1112
 msgid "(current)"
 msgstr "(現在)"
 
-#: src/readelf.c:1082
+#: src/readelf.c:1094
 #, c-format
 msgid "  OS/ABI:                            %s\n"
 msgstr "  OS/ABI:                            %s\n"
 
-#: src/readelf.c:1085
+#: src/readelf.c:1097
 #, c-format
 msgid "  ABI Version:                       %hhd\n"
 msgstr "  ABI バージョン:                    %hhd\n"
 
-#: src/readelf.c:1088
+#: src/readelf.c:1100
 msgid "  Type:                              "
 msgstr "  タイプ:                            "
 
-#: src/readelf.c:1093
+#: src/readelf.c:1105
 #, c-format
 msgid "  Machine:                           %s\n"
 msgstr "  マシン :                           %s\n"
 
-#: src/readelf.c:1095
+#: src/readelf.c:1107
 #, fuzzy, c-format
 msgid "  Machine:                           <unknown>: 0x%x\n"
 msgstr "  マシン :                           %s\n"
 
-#: src/readelf.c:1098
+#: src/readelf.c:1110
 #, c-format
 msgid "  Version:                           %d %s\n"
 msgstr "  バージョン:                        %d %s\n"
 
-#: src/readelf.c:1102
+#: src/readelf.c:1114
 #, c-format
 msgid "  Entry point address:               %#<PRIx64>\n"
 msgstr "  入口点アドレス     :               %#<PRIx64>\n"
 
-#: src/readelf.c:1105
+#: src/readelf.c:1117
 #, c-format
 msgid "  Start of program headers:          %<PRId64> %s\n"
 msgstr "  プログラムヘッダーの開始:          %<PRId64> %s\n"
 
-#: src/readelf.c:1106 src/readelf.c:1109
+#: src/readelf.c:1118 src/readelf.c:1121
 msgid "(bytes into file)"
 msgstr "(ファイルへのバイト数)"
 
-#: src/readelf.c:1108
+#: src/readelf.c:1120
 #, c-format
 msgid "  Start of section headers:          %<PRId64> %s\n"
 msgstr "  セクションヘッダーの開始:          %<PRId64> %s\n"
 
-#: src/readelf.c:1111
+#: src/readelf.c:1123
 #, c-format
 msgid "  Flags:                             %s\n"
 msgstr "  フラグ:                            %s\n"
 
-#: src/readelf.c:1114
+#: src/readelf.c:1126
 #, c-format
 msgid "  Size of this header:               %<PRId16> %s\n"
 msgstr "  このヘッダーの大きさ:              %<PRId16> %s\n"
 
-#: src/readelf.c:1115 src/readelf.c:1118 src/readelf.c:1135
+#: src/readelf.c:1127 src/readelf.c:1130 src/readelf.c:1147
 msgid "(bytes)"
 msgstr "(バイト)"
 
-#: src/readelf.c:1117
+#: src/readelf.c:1129
 #, c-format
 msgid "  Size of program header entries:    %<PRId16> %s\n"
 msgstr "  プログラムヘッダー項目の大きさ:%<PRId16> %s\n"
 
-#: src/readelf.c:1120
+#: src/readelf.c:1132
 #, fuzzy, c-format
 msgid "  Number of program headers entries: %<PRId16>"
 msgstr "  プログラムヘッダー項目の数 : %<PRId16>\n"
 
-#: src/readelf.c:1127
+#: src/readelf.c:1139
 #, fuzzy, c-format
 msgid " (%<PRIu32> in [0].sh_info)"
 msgstr "([0].sh_link の %<PRIu32>)"
 
-#: src/readelf.c:1130 src/readelf.c:1147 src/readelf.c:1161
+#: src/readelf.c:1142 src/readelf.c:1159 src/readelf.c:1173
 msgid " ([0] not available)"
 msgstr "([0]は使えません)"
 
-#: src/readelf.c:1134
+#: src/readelf.c:1146
 #, c-format
 msgid "  Size of section header entries:    %<PRId16> %s\n"
 msgstr "  セクションヘッダー項目の大きさ:%<PRId16> %s\n"
 
-#: src/readelf.c:1137
+#: src/readelf.c:1149
 #, c-format
 msgid "  Number of section headers entries: %<PRId16>"
 msgstr "  セクションヘッダー項目の数 : %<PRId16>"
 
-#: src/readelf.c:1144
+#: src/readelf.c:1156
 #, c-format
 msgid " (%<PRIu32> in [0].sh_size)"
 msgstr " ([0].sh_size の %<PRIu32>)"
 
 #. We managed to get the zeroth section.
-#: src/readelf.c:1157
+#: src/readelf.c:1169
 #, c-format
 msgid " (%<PRIu32> in [0].sh_link)"
 msgstr "([0].sh_link の %<PRIu32>)"
 
-#: src/readelf.c:1165
+#: src/readelf.c:1177
 #, c-format
 msgid ""
 "  Section header string table index: XINDEX%s\n"
@@ -4129,7 +4134,7 @@
 "  セクションヘッダー文字列テーブル索引: XINDEX%s\n"
 "\n"
 
-#: src/readelf.c:1169
+#: src/readelf.c:1181
 #, c-format
 msgid ""
 "  Section header string table index: %<PRId16>\n"
@@ -4138,12 +4143,12 @@
 "  セクションヘッダー文字列テーブル索引: %<PRId16>\n"
 "\n"
 
-#: src/readelf.c:1216 src/readelf.c:1424
+#: src/readelf.c:1228 src/readelf.c:1436
 #, fuzzy, c-format
 msgid "cannot get number of sections: %s"
 msgstr "セクション数を決定できません: %s"
 
-#: src/readelf.c:1219
+#: src/readelf.c:1231
 #, fuzzy, c-format
 msgid ""
 "There are %zd section headers, starting at offset %#<PRIx64>:\n"
@@ -4152,16 +4157,16 @@
 "オフセット %2$#<PRIx64> から始まる %1$d 個のセクションヘッダーがあります:\n"
 "\n"
 
-#: src/readelf.c:1228
+#: src/readelf.c:1240
 #, fuzzy, c-format
 msgid "cannot get section header string table index: %s"
 msgstr "セクションヘッダー文字列テーブル索引が得られません"
 
-#: src/readelf.c:1231
+#: src/readelf.c:1243
 msgid "Section Headers:"
 msgstr "セクションヘッダー:"
 
-#: src/readelf.c:1234
+#: src/readelf.c:1246
 msgid ""
 "[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk "
 "Inf Al"
@@ -4169,7 +4174,7 @@
 "[番] 名前                 タイプ       アドレス オフセ 大きさ ES フラグLk "
 "Inf Al"
 
-#: src/readelf.c:1236
+#: src/readelf.c:1248
 msgid ""
 "[Nr] Name                 Type         Addr             Off      Size     ES "
 "Flags Lk Inf Al"
@@ -4177,35 +4182,35 @@
 "[番] 名前                 タイプ       アドレス         オフセ   大きさ   ES "
 "フラグLk Inf Al"
 
-#: src/readelf.c:1241
+#: src/readelf.c:1253
 msgid "     [Compression  Size   Al]"
 msgstr ""
 
-#: src/readelf.c:1243
+#: src/readelf.c:1255
 msgid "     [Compression  Size     Al]"
 msgstr ""
 
-#: src/readelf.c:1319
+#: src/readelf.c:1331
 #, fuzzy, c-format
 msgid "bad compression header for section %zd: %s"
 msgstr "セクションヘッダー文字列セクションを生成できません: %s"
 
-#: src/readelf.c:1330
+#: src/readelf.c:1342
 #, fuzzy, c-format
 msgid "bad gnu compressed size for section %zd: %s"
 msgstr "セクションからデータを得られません %d: %s"
 
-#: src/readelf.c:1348
+#: src/readelf.c:1360
 msgid "Program Headers:"
 msgstr "プログラムヘッダー:"
 
-#: src/readelf.c:1350
+#: src/readelf.c:1362
 msgid ""
 "  Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align"
 msgstr ""
 "  タイプ         オフセ   仮アドレス 物アドレス ファイ量 メモ量   Flg 調整 "
 
-#: src/readelf.c:1353
+#: src/readelf.c:1365
 msgid ""
 "  Type           Offset   VirtAddr           PhysAddr           FileSiz  "
 "MemSiz   Flg Align"
@@ -4213,12 +4218,12 @@
 "  タイプ         オフセ   仮想アドレス       物理アドレス      ファイル量メモ"
 "量   Flg 調整 "
 
-#: src/readelf.c:1410
+#: src/readelf.c:1422
 #, c-format
 msgid "\t[Requesting program interpreter: %s]\n"
 msgstr "\t[プログラム割込みを要求: %s]\n"
 
-#: src/readelf.c:1437
+#: src/readelf.c:1449
 msgid ""
 "\n"
 " Section to Segment mapping:\n"
@@ -4228,12 +4233,12 @@
 " セクションからセグメントへのマッビング:\n"
 "  セグメント セクション..."
 
-#: src/readelf.c:1448 src/unstrip.c:2067 src/unstrip.c:2109 src/unstrip.c:2116
+#: src/readelf.c:1460 src/unstrip.c:2110 src/unstrip.c:2152 src/unstrip.c:2159
 #, c-format
 msgid "cannot get program header: %s"
 msgstr "プログラムヘッダーを得られません: %s"
 
-#: src/readelf.c:1594
+#: src/readelf.c:1606
 #, c-format
 msgid ""
 "\n"
@@ -4246,7 +4251,7 @@
 "署名 '%3$s' を持つ COMDAT セクショングループ [%1$2zu] '%2$s' には %4$zu 個の"
 "項目があります:\n"
 
-#: src/readelf.c:1599
+#: src/readelf.c:1611
 #, c-format
 msgid ""
 "\n"
@@ -4259,31 +4264,31 @@
 "署名 '%3$s' を持つセクショングループ [%1$2zu] '%2$s' には %4$zu 個の項目があ"
 "ります:\n"
 
-#: src/readelf.c:1607
+#: src/readelf.c:1619
 msgid "<INVALID SYMBOL>"
 msgstr "<不当なシンボル>"
 
-#: src/readelf.c:1621
+#: src/readelf.c:1633
 msgid "<INVALID SECTION>"
 msgstr "<不当なセクション>"
 
-#: src/readelf.c:1644 src/readelf.c:2371 src/readelf.c:3472 src/readelf.c:12505
-#: src/readelf.c:12512 src/readelf.c:12556 src/readelf.c:12563
+#: src/readelf.c:1656 src/readelf.c:2383 src/readelf.c:3484 src/readelf.c:12517
+#: src/readelf.c:12524 src/readelf.c:12568 src/readelf.c:12575
 msgid "Couldn't uncompress section"
 msgstr ""
 
-#: src/readelf.c:1649 src/readelf.c:2376 src/readelf.c:3477
+#: src/readelf.c:1661 src/readelf.c:2388 src/readelf.c:3489
 #, fuzzy, c-format
 msgid "cannot get section [%zd] header: %s"
 msgstr "セクションヘッダーを得られません: %s"
 
-#: src/readelf.c:1793 src/readelf.c:2443 src/readelf.c:2701 src/readelf.c:2777
-#: src/readelf.c:3081 src/readelf.c:3155 src/readelf.c:5352
+#: src/readelf.c:1805 src/readelf.c:2455 src/readelf.c:2713 src/readelf.c:2789
+#: src/readelf.c:3093 src/readelf.c:3167 src/readelf.c:5364
 #, fuzzy, c-format
 msgid "invalid sh_link value in section %zu"
 msgstr "不当な .debug_line セクション"
 
-#: src/readelf.c:1796
+#: src/readelf.c:1808
 #, c-format
 msgid ""
 "\n"
@@ -4299,36 +4304,36 @@
 " アドレス: %#0*<PRIx64>  オフセット: %#08<PRIx64>  セクションへのリンク: "
 "[%2u] '%s'\n"
 
-#: src/readelf.c:1806
+#: src/readelf.c:1818
 msgid "  Type              Value\n"
 msgstr "  タイプ            値\n"
 
-#: src/readelf.c:1830
+#: src/readelf.c:1842
 #, c-format
 msgid "Shared library: [%s]\n"
 msgstr "共用ライブラリー: [%s]\n"
 
-#: src/readelf.c:1835
+#: src/readelf.c:1847
 #, c-format
 msgid "Library soname: [%s]\n"
 msgstr "ライブラリー so 名: [%s]\n"
 
-#: src/readelf.c:1840
+#: src/readelf.c:1852
 #, c-format
 msgid "Library rpath: [%s]\n"
 msgstr "ライブラリー rパス: [%s]\n"
 
-#: src/readelf.c:1845
+#: src/readelf.c:1857
 #, c-format
 msgid "Library runpath: [%s]\n"
 msgstr "ライブラリー run パス: [%s]\n"
 
-#: src/readelf.c:1865
+#: src/readelf.c:1877
 #, c-format
 msgid "%<PRId64> (bytes)\n"
 msgstr "%<PRId64> (バイト)\n"
 
-#: src/readelf.c:1978 src/readelf.c:2168
+#: src/readelf.c:1990 src/readelf.c:2180
 #, c-format
 msgid ""
 "\n"
@@ -4337,7 +4342,7 @@
 "\n"
 "オフセット %#0<PRIx64> に不当なシンボルテーブル\n"
 
-#: src/readelf.c:1996 src/readelf.c:2186
+#: src/readelf.c:2008 src/readelf.c:2198
 #, c-format
 msgid ""
 "\n"
@@ -4358,7 +4363,7 @@
 #. The .rela.dyn section does not refer to a specific section but
 #. instead of section index zero.  Do not try to print a section
 #. name.
-#: src/readelf.c:2011 src/readelf.c:2201
+#: src/readelf.c:2023 src/readelf.c:2213
 #, c-format
 msgid ""
 "\n"
@@ -4371,29 +4376,29 @@
 "オフセット %3$#0<PRIx64> のリロケーションセクション [%1$2u] '%2$s' には %4$d "
 "個の項目があります:\n"
 
-#: src/readelf.c:2021
+#: src/readelf.c:2033
 msgid "  Offset      Type                 Value       Name\n"
 msgstr "  オフセット  タイプ               値          名前\n"
 
-#: src/readelf.c:2023
+#: src/readelf.c:2035
 msgid "  Offset              Type                 Value               Name\n"
 msgstr "  オフセット          タイプ               値                  名前\n"
 
-#: src/readelf.c:2076 src/readelf.c:2087 src/readelf.c:2100 src/readelf.c:2121
-#: src/readelf.c:2133 src/readelf.c:2267 src/readelf.c:2279 src/readelf.c:2293
-#: src/readelf.c:2315 src/readelf.c:2328
+#: src/readelf.c:2088 src/readelf.c:2099 src/readelf.c:2112 src/readelf.c:2133
+#: src/readelf.c:2145 src/readelf.c:2279 src/readelf.c:2291 src/readelf.c:2305
+#: src/readelf.c:2327 src/readelf.c:2340
 msgid "<INVALID RELOC>"
 msgstr "<不当なRELOC>"
 
-#: src/readelf.c:2211
+#: src/readelf.c:2223
 msgid "  Offset      Type            Value       Addend Name\n"
 msgstr "  オフセット  タイプ          値          付加名\n"
 
-#: src/readelf.c:2213
+#: src/readelf.c:2225
 msgid "  Offset              Type            Value               Addend Name\n"
 msgstr "  オフセット          タイプ          値                  付加名\n"
 
-#: src/readelf.c:2451
+#: src/readelf.c:2463
 #, c-format
 msgid ""
 "\n"
@@ -4405,39 +4410,39 @@
 "\n"
 "シンボルテーブル [%2u] '%s' には %u 個の項目があります:\n"
 
-#: src/readelf.c:2456
+#: src/readelf.c:2468
 #, c-format
 msgid " %lu local symbol  String table: [%2u] '%s'\n"
 msgid_plural " %lu local symbols  String table: [%2u] '%s'\n"
 msgstr[0] " %lu ローカルシンボル文字列テーブル: [%2u] '%s'\n"
 
-#: src/readelf.c:2464
+#: src/readelf.c:2476
 msgid "  Num:    Value   Size Type    Bind   Vis          Ndx Name\n"
 msgstr "  数 :    値      大き タイプ  Bind   Vis          Ndx 名前\n"
 
-#: src/readelf.c:2466
+#: src/readelf.c:2478
 msgid "  Num:            Value   Size Type    Bind   Vis          Ndx Name\n"
 msgstr "  数 :            値      大き タイプ  Bind   Vis          Ndx 名前\n"
 
-#: src/readelf.c:2486
+#: src/readelf.c:2498
 #, c-format
 msgid "%5u: %0*<PRIx64> %6<PRId64> %-7s %-6s %-9s %6s %s"
 msgstr "%5u: %0*<PRIx64> %6<PRId64> %-7s %-6s %-9s %6s %s"
 
-#: src/readelf.c:2574
+#: src/readelf.c:2586
 #, c-format
 msgid "bad dynamic symbol"
 msgstr "不正な動的シンボル"
 
-#: src/readelf.c:2656
+#: src/readelf.c:2668
 msgid "none"
 msgstr "なし"
 
-#: src/readelf.c:2673
+#: src/readelf.c:2685
 msgid "| <unknown>"
 msgstr "| <不明>"
 
-#: src/readelf.c:2704
+#: src/readelf.c:2716
 #, c-format
 msgid ""
 "\n"
@@ -4453,17 +4458,17 @@
 " アドレス: %#0*<PRIx64>  オフセット: %#08<PRIx64>  セクションへのリンク: "
 "[%2u] '%s'\n"
 
-#: src/readelf.c:2725
+#: src/readelf.c:2737
 #, c-format
 msgid "  %#06x: Version: %hu  File: %s  Cnt: %hu\n"
 msgstr "  %#06x: バージョン: %hu  ファイル: %s  数: %hu\n"
 
-#: src/readelf.c:2738
+#: src/readelf.c:2750
 #, c-format
 msgid "  %#06x: Name: %s  Flags: %s  Version: %hu\n"
 msgstr "  %#06x: 名前: %s  フラグ: %s  バージョン: %hu\n"
 
-#: src/readelf.c:2781
+#: src/readelf.c:2793
 #, c-format
 msgid ""
 "\n"
@@ -4479,18 +4484,18 @@
 " アドレス: %#0*<PRIx64>  オフセット: %#08<PRIx64>  セクションへのリンク: "
 "[%2u] '%s'\n"
 
-#: src/readelf.c:2809
+#: src/readelf.c:2821
 #, c-format
 msgid "  %#06x: Version: %hd  Flags: %s  Index: %hd  Cnt: %hd  Name: %s\n"
 msgstr "  %#06x: バージョン: %hd  フラグ: %s  索引: %hd  数: %hd  名前: %s\n"
 
-#: src/readelf.c:2824
+#: src/readelf.c:2836
 #, c-format
 msgid "  %#06x: Parent %d: %s\n"
 msgstr "  %#06x: 親 %d: %s\n"
 
 #. Print the header.
-#: src/readelf.c:3085
+#: src/readelf.c:3097
 #, c-format
 msgid ""
 "\n"
@@ -4506,15 +4511,15 @@
 " アドレス: %#0*<PRIx64>  オフセット: %#08<PRIx64>  セクションへのリンク: "
 "[%2u] '%s'"
 
-#: src/readelf.c:3113
+#: src/readelf.c:3125
 msgid "   0 *local*                     "
 msgstr "   0 *ローカル*                  "
 
-#: src/readelf.c:3118
+#: src/readelf.c:3130
 msgid "   1 *global*                    "
 msgstr "   1 *グローバル*                "
 
-#: src/readelf.c:3160
+#: src/readelf.c:3172
 #, c-format
 msgid ""
 "\n"
@@ -4532,22 +4537,22 @@
 " アドレス: %#0*<PRIx64>  オフセット: %#08<PRIx64>  セクションへのリンク: "
 "[%2u] '%s'\n"
 
-#: src/readelf.c:3182
+#: src/readelf.c:3194
 #, fuzzy, no-c-format
 msgid " Length  Number  % of total  Coverage\n"
 msgstr " 長さ    数      全体の%     範囲    \n"
 
-#: src/readelf.c:3184
+#: src/readelf.c:3196
 #, c-format
 msgid "      0  %6<PRIu32>      %5.1f%%\n"
 msgstr "      0  %6<PRIu32>      %5.1f%%\n"
 
-#: src/readelf.c:3191
+#: src/readelf.c:3203
 #, c-format
 msgid "%7d  %6<PRIu32>      %5.1f%%    %5.1f%%\n"
 msgstr "%7d  %6<PRIu32>      %5.1f%%    %5.1f%%\n"
 
-#: src/readelf.c:3204
+#: src/readelf.c:3216
 #, fuzzy, c-format
 msgid ""
 " Average number of tests:   successful lookup: %f\n"
@@ -4556,37 +4561,37 @@
 " テストの平均数: 検索成功: %f\n"
 "                 検索失敗: %f\n"
 
-#: src/readelf.c:3222 src/readelf.c:3286 src/readelf.c:3352
+#: src/readelf.c:3234 src/readelf.c:3298 src/readelf.c:3364
 #, c-format
 msgid "cannot get data for section %d: %s"
 msgstr "セクションからデータを得られません %d: %s"
 
-#: src/readelf.c:3230
+#: src/readelf.c:3242
 #, fuzzy, c-format
 msgid "invalid data in sysv.hash section %d"
 msgstr "セクション [%zu] '%s' の不当なデータ"
 
-#: src/readelf.c:3259
+#: src/readelf.c:3271
 #, fuzzy, c-format
 msgid "invalid chain in sysv.hash section %d"
 msgstr "セクション [%zu] '%s' の不当なデータ"
 
-#: src/readelf.c:3294
+#: src/readelf.c:3306
 #, fuzzy, c-format
 msgid "invalid data in sysv.hash64 section %d"
 msgstr "セクション [%zu] '%s' の不当なデータ"
 
-#: src/readelf.c:3325
+#: src/readelf.c:3337
 #, fuzzy, c-format
 msgid "invalid chain in sysv.hash64 section %d"
 msgstr "セクション [%zu] '%s' の不当なデータ"
 
-#: src/readelf.c:3361
+#: src/readelf.c:3373
 #, fuzzy, c-format
 msgid "invalid data in gnu.hash section %d"
 msgstr "セクション [%zu] '%s' の不当なデータ"
 
-#: src/readelf.c:3428
+#: src/readelf.c:3440
 #, c-format
 msgid ""
 " Symbol Bias: %u\n"
@@ -4596,7 +4601,7 @@
 " ビットマスクの大きさ: %zu バイト  %<PRIuFAST32>%% ビット設定 第2ハッシュシフ"
 "ト: %u\n"
 
-#: src/readelf.c:3517
+#: src/readelf.c:3529
 #, c-format
 msgid ""
 "\n"
@@ -4609,7 +4614,7 @@
 "オフセット %3$#0<PRIx64> のライブラリー一覧セクション [%1$2zu] '%2$s' には "
 "%4$d 個の項目があります:\n"
 
-#: src/readelf.c:3531
+#: src/readelf.c:3543
 msgid ""
 "       Library                       Time Stamp          Checksum Version "
 "Flags"
@@ -4617,7 +4622,7 @@
 "       ライブラリー                  タイムスタンプ      チェックサム バー"
 "ジョン フラグ"
 
-#: src/readelf.c:3583
+#: src/readelf.c:3595
 #, c-format
 msgid ""
 "\n"
@@ -4628,102 +4633,102 @@
 "オフセット %4$#0<PRIx64> の %3$<PRIu64> バイトのオブジェクト属性セクション "
 "[%1$2zu] '%2$s':\n"
 
-#: src/readelf.c:3600
+#: src/readelf.c:3612
 msgid "  Owner          Size\n"
 msgstr "  所有者         大きさ\n"
 
-#: src/readelf.c:3629
+#: src/readelf.c:3641
 #, c-format
 msgid "  %-13s  %4<PRIu32>\n"
 msgstr "  %-13s  %4<PRIu32>\n"
 
 #. Unknown subsection, print and skip.
-#: src/readelf.c:3668
+#: src/readelf.c:3680
 #, c-format
 msgid "    %-4u %12<PRIu32>\n"
 msgstr "    %-4u %12<PRIu32>\n"
 
 #. Tag_File
-#: src/readelf.c:3673
+#: src/readelf.c:3685
 #, c-format
 msgid "    File: %11<PRIu32>\n"
 msgstr "    ファイル: %11<PRIu32>\n"
 
-#: src/readelf.c:3722
+#: src/readelf.c:3734
 #, c-format
 msgid "      %s: %<PRId64>, %s\n"
 msgstr "      %s: %<PRId64>、%s\n"
 
-#: src/readelf.c:3725
+#: src/readelf.c:3737
 #, c-format
 msgid "      %s: %<PRId64>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:3728
+#: src/readelf.c:3740
 #, c-format
 msgid "      %s: %s\n"
 msgstr "      %s: %s\n"
 
-#: src/readelf.c:3738
+#: src/readelf.c:3750
 #, c-format
 msgid "      %u: %<PRId64>\n"
 msgstr "      %u: %<PRId64>\n"
 
-#: src/readelf.c:3741
+#: src/readelf.c:3753
 #, c-format
 msgid "      %u: %s\n"
 msgstr "      %u: %s\n"
 
-#: src/readelf.c:3811
+#: src/readelf.c:3823
 #, c-format
 msgid "sprintf failure"
 msgstr ""
 
-#: src/readelf.c:4293
+#: src/readelf.c:4305
 msgid "empty block"
 msgstr "空ブロック"
 
-#: src/readelf.c:4296
+#: src/readelf.c:4308
 #, c-format
 msgid "%zu byte block:"
 msgstr "%zu バイトのブロック:"
 
-#: src/readelf.c:4774
+#: src/readelf.c:4786
 #, fuzzy, c-format
 msgid "%*s[%2<PRIuMAX>] %s  <TRUNCATED>\n"
 msgstr "%*s[%4<PRIuMAX>] %s  <TRUNCATED>\n"
 
-#: src/readelf.c:4838
+#: src/readelf.c:4850
 #, c-format
 msgid "%s %#<PRIx64> used with different address sizes"
 msgstr ""
 
-#: src/readelf.c:4845
+#: src/readelf.c:4857
 #, c-format
 msgid "%s %#<PRIx64> used with different offset sizes"
 msgstr ""
 
-#: src/readelf.c:4852
+#: src/readelf.c:4864
 #, c-format
 msgid "%s %#<PRIx64> used with different base addresses"
 msgstr ""
 
-#: src/readelf.c:4859
+#: src/readelf.c:4871
 #, c-format
 msgid "%s %#<PRIx64> used with different attribute %s and %s"
 msgstr ""
 
-#: src/readelf.c:4956
+#: src/readelf.c:4968
 #, c-format
 msgid " [%6tx]  <UNUSED GARBAGE IN REST OF SECTION>\n"
 msgstr ""
 
-#: src/readelf.c:4964
+#: src/readelf.c:4976
 #, c-format
 msgid " [%6tx]  <UNUSED GARBAGE> ... %<PRIu64> bytes ...\n"
 msgstr ""
 
-#: src/readelf.c:5042
+#: src/readelf.c:5054
 #, c-format
 msgid ""
 "\n"
@@ -4734,7 +4739,7 @@
 "オフセット %3$#<PRIx64> の DWARF セクション [%1$2zu] '%2$s':\n"
 " [ コード]\n"
 
-#: src/readelf.c:5050
+#: src/readelf.c:5062
 #, c-format
 msgid ""
 "\n"
@@ -4743,20 +4748,20 @@
 "\n"
 "オフセット %<PRIu64> の略語セクション:\n"
 
-#: src/readelf.c:5063
+#: src/readelf.c:5075
 #, c-format
 msgid " *** error while reading abbreviation: %s\n"
 msgstr " *** 略語を読んでいる間にエラー: %s\n"
 
-#: src/readelf.c:5079
+#: src/readelf.c:5091
 #, c-format
 msgid " [%5u] offset: %<PRId64>, children: %s, tag: %s\n"
 msgstr " [%5u] オフセット: %<PRId64>、子: %s、タグ: %s\n"
 
-#: src/readelf.c:5112 src/readelf.c:5421 src/readelf.c:5588 src/readelf.c:5973
-#: src/readelf.c:6574 src/readelf.c:8311 src/readelf.c:8997 src/readelf.c:9433
-#: src/readelf.c:9678 src/readelf.c:9844 src/readelf.c:10231
-#: src/readelf.c:10291
+#: src/readelf.c:5124 src/readelf.c:5433 src/readelf.c:5600 src/readelf.c:5985
+#: src/readelf.c:6586 src/readelf.c:8323 src/readelf.c:9009 src/readelf.c:9445
+#: src/readelf.c:9690 src/readelf.c:9856 src/readelf.c:10243
+#: src/readelf.c:10303
 #, c-format
 msgid ""
 "\n"
@@ -4765,52 +4770,52 @@
 "\n"
 "オフセット %3$#<PRIx64> の DWARF セクション [%1$2zu] '%2$s':\n"
 
-#: src/readelf.c:5125
+#: src/readelf.c:5137
 #, fuzzy, c-format
 msgid "cannot get .debug_addr section data: %s"
 msgstr "セクションデータを割り当てられません: %s"
 
-#: src/readelf.c:5225 src/readelf.c:5249 src/readelf.c:5633 src/readelf.c:9042
+#: src/readelf.c:5237 src/readelf.c:5261 src/readelf.c:5645 src/readelf.c:9054
 #, fuzzy, c-format
 msgid " Length:         %8<PRIu64>\n"
 msgstr " (オフセット: %#<PRIx64>)"
 
-#: src/readelf.c:5227 src/readelf.c:5264 src/readelf.c:5646 src/readelf.c:9055
+#: src/readelf.c:5239 src/readelf.c:5276 src/readelf.c:5658 src/readelf.c:9067
 #, fuzzy, c-format
 msgid " DWARF version:  %8<PRIu16>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:5228 src/readelf.c:5273 src/readelf.c:5655 src/readelf.c:9064
+#: src/readelf.c:5240 src/readelf.c:5285 src/readelf.c:5667 src/readelf.c:9076
 #, fuzzy, c-format
 msgid " Address size:   %8<PRIu64>\n"
 msgstr " (終了オフセット: %#<PRIx64>)"
 
-#: src/readelf.c:5230 src/readelf.c:5283 src/readelf.c:5665 src/readelf.c:9074
+#: src/readelf.c:5242 src/readelf.c:5295 src/readelf.c:5677 src/readelf.c:9086
 #, fuzzy, c-format
 msgid " Segment size:   %8<PRIu64>\n"
 msgstr " ファイルを %<PRIu64> に設定する\n"
 
-#: src/readelf.c:5268 src/readelf.c:5650 src/readelf.c:9059 src/readelf.c:10423
+#: src/readelf.c:5280 src/readelf.c:5662 src/readelf.c:9071 src/readelf.c:10435
 #, fuzzy, c-format
 msgid "Unknown version"
 msgstr "不明なバージョン"
 
-#: src/readelf.c:5278 src/readelf.c:5491 src/readelf.c:5660 src/readelf.c:9069
+#: src/readelf.c:5290 src/readelf.c:5503 src/readelf.c:5672 src/readelf.c:9081
 #, fuzzy, c-format
 msgid "unsupported address size"
 msgstr "アドレス値ではありません"
 
-#: src/readelf.c:5289 src/readelf.c:5502 src/readelf.c:5670 src/readelf.c:9079
+#: src/readelf.c:5301 src/readelf.c:5514 src/readelf.c:5682 src/readelf.c:9091
 #, c-format
 msgid "unsupported segment size"
 msgstr ""
 
-#: src/readelf.c:5342 src/readelf.c:5416
+#: src/readelf.c:5354 src/readelf.c:5428
 #, c-format
 msgid "cannot get .debug_aranges content: %s"
 msgstr ".debug_aragnes の内容を得られません: %s"
 
-#: src/readelf.c:5357
+#: src/readelf.c:5369
 #, c-format
 msgid ""
 "\n"
@@ -4823,19 +4828,19 @@
 "オフセット %3$#<PRIx64> の DWARF セクション [%1$2zu] '%2$s' には %4$zu 個の項"
 "目があります:\n"
 
-#: src/readelf.c:5388
+#: src/readelf.c:5400
 #, c-format
 msgid " [%*zu] ???\n"
 msgstr " [%*zu] ???\n"
 
-#: src/readelf.c:5390
+#: src/readelf.c:5402
 #, c-format
 msgid ""
 " [%*zu] start: %0#*<PRIx64>, length: %5<PRIu64>, CU DIE offset: %6<PRId64>\n"
 msgstr ""
 " [%*zu] 開始: %0#*<PRIx64>、長さ: %5<PRIu64>、CU DIE オフセット: %6<PRId64>\n"
 
-#: src/readelf.c:5434 src/readelf.c:8338
+#: src/readelf.c:5446 src/readelf.c:8350
 #, fuzzy, c-format
 msgid ""
 "\n"
@@ -4844,154 +4849,154 @@
 "\n"
 "オフセット %Zu のテーブル:\n"
 
-#: src/readelf.c:5438 src/readelf.c:5614 src/readelf.c:6598 src/readelf.c:8349
-#: src/readelf.c:9023
+#: src/readelf.c:5450 src/readelf.c:5626 src/readelf.c:6610 src/readelf.c:8361
+#: src/readelf.c:9035
 #, c-format
 msgid "invalid data in section [%zu] '%s'"
 msgstr "セクション [%zu] '%s' の不当なデータ"
 
-#: src/readelf.c:5454
+#: src/readelf.c:5466
 #, fuzzy, c-format
 msgid ""
 "\n"
 " Length:        %6<PRIu64>\n"
 msgstr " (オフセット: %#<PRIx64>)"
 
-#: src/readelf.c:5466
+#: src/readelf.c:5478
 #, fuzzy, c-format
 msgid " DWARF version: %6<PRIuFAST16>\n"
 msgstr "      %s: %<PRId64>\n"
 
-#: src/readelf.c:5470
+#: src/readelf.c:5482
 #, c-format
 msgid "unsupported aranges version"
 msgstr ""
 
-#: src/readelf.c:5481
+#: src/readelf.c:5493
 #, fuzzy, c-format
 msgid " CU offset:     %6<PRIx64>\n"
 msgstr " (オフセット: %#<PRIx64>)"
 
-#: src/readelf.c:5487
+#: src/readelf.c:5499
 #, fuzzy, c-format
 msgid " Address size:  %6<PRIu64>\n"
 msgstr " (終了オフセット: %#<PRIx64>)"
 
-#: src/readelf.c:5498
+#: src/readelf.c:5510
 #, fuzzy, c-format
 msgid ""
 " Segment size:  %6<PRIu64>\n"
 "\n"
 msgstr " ファイルを %<PRIu64> に設定する\n"
 
-#: src/readelf.c:5553
+#: src/readelf.c:5565
 #, c-format
 msgid "   %zu padding bytes\n"
 msgstr ""
 
-#: src/readelf.c:5597
+#: src/readelf.c:5609
 #, fuzzy, c-format
 msgid "cannot get .debug_rnglists content: %s"
 msgstr ".degub_ranges の内容を得られません: %s"
 
-#: src/readelf.c:5620 src/readelf.c:9029
+#: src/readelf.c:5632 src/readelf.c:9041
 #, fuzzy, c-format
 msgid ""
 "Table at Offset 0x%<PRIx64>:\n"
 "\n"
 msgstr " (終了オフセット: %#<PRIx64>)"
 
-#: src/readelf.c:5675 src/readelf.c:9084
+#: src/readelf.c:5687 src/readelf.c:9096
 #, fuzzy, c-format
 msgid " Offset entries: %8<PRIu64>\n"
 msgstr " (オフセット: %#<PRIx64>)"
 
-#: src/readelf.c:5691 src/readelf.c:9100
+#: src/readelf.c:5703 src/readelf.c:9112
 #, c-format
 msgid " Unknown CU base: "
 msgstr ""
 
-#: src/readelf.c:5693 src/readelf.c:9102
+#: src/readelf.c:5705 src/readelf.c:9114
 #, c-format
 msgid " CU [%6<PRIx64>] base: "
 msgstr ""
 
-#: src/readelf.c:5699 src/readelf.c:9108
+#: src/readelf.c:5711 src/readelf.c:9120
 #, c-format
 msgid " Not associated with a CU.\n"
 msgstr ""
 
-#: src/readelf.c:5710 src/readelf.c:9119
+#: src/readelf.c:5722 src/readelf.c:9131
 #, c-format
 msgid "too many offset entries for unit length"
 msgstr ""
 
-#: src/readelf.c:5714 src/readelf.c:9123
+#: src/readelf.c:5726 src/readelf.c:9135
 #, fuzzy, c-format
 msgid "  Offsets starting at 0x%<PRIx64>:\n"
 msgstr "  所有者         大きさ\n"
 
-#: src/readelf.c:5766
+#: src/readelf.c:5778
 #, fuzzy, c-format
 msgid "invalid range list data"
 msgstr "不当なデータ"
 
-#: src/readelf.c:5951 src/readelf.c:9411
+#: src/readelf.c:5963 src/readelf.c:9423
 #, c-format
 msgid ""
 "   %zu padding bytes\n"
 "\n"
 msgstr ""
 
-#: src/readelf.c:5968
+#: src/readelf.c:5980
 #, c-format
 msgid "cannot get .debug_ranges content: %s"
 msgstr ".degub_ranges の内容を得られません: %s"
 
-#: src/readelf.c:6004 src/readelf.c:9466
+#: src/readelf.c:6016 src/readelf.c:9478
 #, c-format
 msgid ""
 "\n"
 " Unknown CU base: "
 msgstr ""
 
-#: src/readelf.c:6006 src/readelf.c:9468
+#: src/readelf.c:6018 src/readelf.c:9480
 #, c-format
 msgid ""
 "\n"
 " CU [%6<PRIx64>] base: "
 msgstr ""
 
-#: src/readelf.c:6015 src/readelf.c:9494 src/readelf.c:9520
+#: src/readelf.c:6027 src/readelf.c:9506 src/readelf.c:9532
 #, c-format
 msgid " [%6tx]  <INVALID DATA>\n"
 msgstr " [%6tx]  <不当なデータ>\n"
 
-#: src/readelf.c:6036 src/readelf.c:9600
+#: src/readelf.c:6048 src/readelf.c:9612
 #, fuzzy, c-format
 msgid ""
 " [%6tx] base address\n"
 "          "
 msgstr " [%6tx]  ベースアドレス %s\n"
 
-#: src/readelf.c:6044 src/readelf.c:9608
+#: src/readelf.c:6056 src/readelf.c:9620
 #, fuzzy, c-format
 msgid " [%6tx] empty list\n"
 msgstr ""
 "\n"
 " [%6tx] ゼロ終端\n"
 
-#: src/readelf.c:6299
+#: src/readelf.c:6311
 #, fuzzy
 msgid "         <INVALID DATA>\n"
 msgstr " [%6tx]  <不当なデータ>\n"
 
-#: src/readelf.c:6552
+#: src/readelf.c:6564
 #, fuzzy, c-format
 msgid "cannot get ELF: %s"
 msgstr "次の DIE を得られません: %s"
 
-#: src/readelf.c:6570
+#: src/readelf.c:6582
 #, c-format
 msgid ""
 "\n"
@@ -5000,7 +5005,7 @@
 "\n"
 "オフセット %3$#<PRIx64> の フレーム情報呼出しセクション [%1$2zu] '%2$s':\n"
 
-#: src/readelf.c:6620
+#: src/readelf.c:6632
 #, c-format
 msgid ""
 "\n"
@@ -5009,65 +5014,65 @@
 "\n"
 " [%6tx] ゼロ終端\n"
 
-#: src/readelf.c:6721 src/readelf.c:6875
+#: src/readelf.c:6733 src/readelf.c:6887
 #, fuzzy, c-format
 msgid "invalid augmentation length"
 msgstr "不当な拡大エンコード"
 
-#: src/readelf.c:6736
+#: src/readelf.c:6748
 msgid "FDE address encoding: "
 msgstr "FDE アドレスエンコード"
 
-#: src/readelf.c:6742
+#: src/readelf.c:6754
 msgid "LSDA pointer encoding: "
 msgstr "LSDA ポインターエンコード:"
 
-#: src/readelf.c:6852
+#: src/readelf.c:6864
 #, c-format
 msgid " (offset: %#<PRIx64>)"
 msgstr " (オフセット: %#<PRIx64>)"
 
-#: src/readelf.c:6859
+#: src/readelf.c:6871
 #, c-format
 msgid " (end offset: %#<PRIx64>)"
 msgstr " (終了オフセット: %#<PRIx64>)"
 
-#: src/readelf.c:6896
+#: src/readelf.c:6908
 #, c-format
 msgid "   %-26sLSDA pointer: %#<PRIx64>\n"
 msgstr "   %-26sLSDA ポインター: %#<PRIx64>\n"
 
-#: src/readelf.c:6981
+#: src/readelf.c:6993
 #, fuzzy, c-format
 msgid "DIE [%<PRIx64>] cannot get attribute code: %s"
 msgstr "属性コードを得られません: %s"
 
-#: src/readelf.c:6991
+#: src/readelf.c:7003
 #, fuzzy, c-format
 msgid "DIE [%<PRIx64>] cannot get attribute form: %s"
 msgstr "属性様式を得られません: %s"
 
-#: src/readelf.c:7013
+#: src/readelf.c:7025
 #, fuzzy, c-format
 msgid "DIE [%<PRIx64>] cannot get attribute '%s' (%s) value: %s"
 msgstr "属性値を得られません: %s"
 
-#: src/readelf.c:7343
+#: src/readelf.c:7355
 #, fuzzy, c-format
 msgid "invalid file (%<PRId64>): %s"
 msgstr "不当なファイル"