From 21528c8512bd07d04e9a721ebb39242a94a585f8 Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Wed, 24 Aug 2022 17:40:43 +0200 Subject: [PATCH 01/25] Use %sysusers_requires_compat to match %sysusers_create_compat Fallout from 8675595d8f6f088b4e96e7aac6354606bdb57b1a --- elfutils.spec | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/elfutils.spec b/elfutils.spec index 11e7613..d5f2419 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -1,6 +1,6 @@ Name: elfutils Version: 0.187 -%global baserelease 7 +%global baserelease 8 Release: %{baserelease}%{?dist} URL: http://elfutils.org/ %global source_url ftp://sourceware.org/pub/elfutils/%{version}/ @@ -232,7 +232,11 @@ BuildRequires: make Requires(post): systemd Requires(preun): systemd Requires(postun): systemd +%if %{with_sysusers} +%{?sysusers_requires_compat} +%else Requires(pre): shadow-utils +%endif # To extract .deb files with a bsdtar (= libarchive) subshell Requires: bsdtar @@ -442,6 +446,9 @@ exit 0 %systemd_postun_with_restart debuginfod.service %changelog +* Wed Aug 24 2022 Debarshi Ray - 0.187-8 +- Use %%sysusers_requires_compat to match %%sysusers_create_compat + * Wed Jul 27 2022 Amit Shah - 0.187-7 - Allow building without default debuginfod URL From 3e1f9c3f60e2ee5204e0b52b5b1b8e2caec3085c Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Wed, 24 Aug 2022 17:46:20 +0200 Subject: [PATCH 02/25] Silence mixed-use-of-spaces-and-tabs --- elfutils.spec | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/elfutils.spec b/elfutils.spec index d5f2419..bd6d2d0 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -56,16 +56,16 @@ BuildRequires: gettext-devel %global _gnu %{nil} %global _program_prefix eu- -%global provide_yama_scope 0 +%global provide_yama_scope 0 %if 0%{?fedora} >= 22 || 0%{?rhel} >= 7 -%global provide_yama_scope 1 +%global provide_yama_scope 1 %endif -%global with_sysusers 0 +%global with_sysusers 0 %if 0%{?fedora} >= 32 || 0%{?rhel} >= 9 -%global with_sysusers 1 +%global with_sysusers 1 %endif %bcond with_debuginfod_url 1 From 17c16efeeb9b8285d9c53e8dd7362adba42a0aeb Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 1 Aug 2022 12:35:18 +0530 Subject: [PATCH 03/25] Use distro-configured debuginfod server Fedora and CentOS configure a debuginfod server by default, whereas RHEL and Amazon Linux do not. The new `dist_debuginfod_url` macro sets the server URL in a central place. Use that value, if defined, to configure with a default server. If unset, do not configure one. This ensures we have a unified spec file for all distro variants, and distro-specific config resides in the macros.dist file. With this change, we do not need the recently-added bcond for with_debuginfo_url, so drop it. Signed-off-by: Amit Shah --- elfutils.spec | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/elfutils.spec b/elfutils.spec index bd6d2d0..9d0a6b3 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -1,6 +1,6 @@ Name: elfutils Version: 0.187 -%global baserelease 8 +%global baserelease 9 Release: %{baserelease}%{?dist} URL: http://elfutils.org/ %global source_url ftp://sourceware.org/pub/elfutils/%{version}/ @@ -68,8 +68,6 @@ BuildRequires: gettext-devel %global with_sysusers 1 %endif -%bcond with_debuginfod_url 1 - # Patches # For s390x... FDO package notes are bogus. @@ -277,8 +275,11 @@ RPM_OPT_FLAGS="${RPM_OPT_FLAGS} -Wformat" trap 'cat config.log' EXIT -%if %{with with_debuginfod_url} -%configure CFLAGS="$RPM_OPT_FLAGS" --enable-debuginfod-urls=https://debuginfod.fedoraproject.org/ +# dist_debuginfod_url is defined in macros.dist. Fedora and CentOS have +# URLs pointing to their respective servers. RHEL and Amazon Linux do +# not configure a default server. +%if "%{?dist_debuginfod_url}" +%configure CFLAGS="$RPM_OPT_FLAGS" --enable-debuginfod-urls=%{dist_debuginfod_url} %else %configure CFLAGS="$RPM_OPT_FLAGS" %endif @@ -405,7 +406,7 @@ fi %{_mandir}/man1/debuginfod-find.1* %{_mandir}/man7/debuginfod*.7* %config(noreplace) %{_sysconfdir}/profile.d/* -%if %{with with_debuginfod_url} +%if "%{?dist_debuginfod_url}" %config(noreplace) %{_sysconfdir}/debuginfod/* %endif @@ -446,6 +447,9 @@ exit 0 %systemd_postun_with_restart debuginfod.service %changelog +* Wed Oct 5 2022 Amit Shah - 0.187-9 +- Auto-configure debuginfod_url based on macros.dist + * Wed Aug 24 2022 Debarshi Ray - 0.187-8 - Use %%sysusers_requires_compat to match %%sysusers_create_compat From 3d4d19222dd89051504cc7b40d5cd727981b2003 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 2 Nov 2022 16:33:41 +0100 Subject: [PATCH 04/25] 0.188-1 - Upgrade to upsteam elfutils 0.188 --- .gitignore | 1 + elfutils-0.187-csh-profile.patch | 28 ----- ...tils-0.187-debuginfod-client-fd-leak.patch | 98 --------------- elfutils-0.187-mhd_epoll.patch | 51 -------- elfutils-0.187-mhd_no_dual_stack.patch | 118 ------------------ elfutils.spec | 22 ++-- sources | 2 +- 7 files changed, 12 insertions(+), 308 deletions(-) delete mode 100644 elfutils-0.187-csh-profile.patch delete mode 100644 elfutils-0.187-debuginfod-client-fd-leak.patch delete mode 100644 elfutils-0.187-mhd_epoll.patch delete mode 100644 elfutils-0.187-mhd_no_dual_stack.patch diff --git a/.gitignore b/.gitignore index f28cb05..d23f6fd 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ /elfutils-0.185.tar.bz2 /elfutils-0.186.tar.bz2 /elfutils-0.187.tar.bz2 +/elfutils-0.188.tar.bz2 diff --git a/elfutils-0.187-csh-profile.patch b/elfutils-0.187-csh-profile.patch deleted file mode 100644 index 6f26815..0000000 --- a/elfutils-0.187-csh-profile.patch +++ /dev/null @@ -1,28 +0,0 @@ -commit f1252e4dbe781f75d806ce0b990779548eeeb7a9 -Author: Mark Wielaard -Date: Tue May 3 17:48:55 2022 +0200 - - config: Move the 2>/dev/null inside the sh -c '' quotes for profile.csh. - - csh/tcsh would warn about "Ambiguous output redirect" if not done inside - the sh -c command. - - Fix-by: наб - - https://bugzilla.redhat.com/show_bug.cgi?id=2080957 - - Signed-off-by: Mark Wielaard - -diff --git a/config/profile.csh.in b/config/profile.csh.in -index 012e243a..74c20c99 100644 ---- a/config/profile.csh.in -+++ b/config/profile.csh.in -@@ -6,7 +6,7 @@ - - if (! $?DEBUGINFOD_URLS) then - set prefix="@prefix@" -- set DEBUGINFOD_URLS=`sh -c 'cat "$0"/*.urls; :' "@sysconfdir@/debuginfod" 2>/dev/null | tr '\n' ' '` -+ set DEBUGINFOD_URLS=`sh -c 'cat "$0"/*.urls 2>/dev/null; :' "@sysconfdir@/debuginfod" | tr '\n' ' '` - if ( "$DEBUGINFOD_URLS" != "" ) then - setenv DEBUGINFOD_URLS "$DEBUGINFOD_URLS" - else diff --git a/elfutils-0.187-debuginfod-client-fd-leak.patch b/elfutils-0.187-debuginfod-client-fd-leak.patch deleted file mode 100644 index 2f6b78b..0000000 --- a/elfutils-0.187-debuginfod-client-fd-leak.patch +++ /dev/null @@ -1,98 +0,0 @@ -commit 59158656f3b0b99d8784ddc82c15778813000edc -Author: Frank Ch. Eigler -Date: Wed May 4 10:26:42 2022 -0400 - - PR29117: fix fd leak in debuginfod client for cache-miss files - - Correct a nasty fd leak and a few less nasty leaks in the debuginfod - client code. The nasty one impacts long-lived apps such as debuginfod - servers. - - Signed-off-by: Mark Wielaard - Signed-off-by: Frank Ch. Eigler - -diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c -index ea6e461a..521972e4 100644 ---- a/debuginfod/debuginfod-client.c -+++ b/debuginfod/debuginfod-client.c -@@ -243,7 +243,13 @@ debuginfod_config_cache(char *config_path, - return -errno; - - if (dprintf(fd, "%ld", cache_config_default_s) < 0) -- return -errno; -+ { -+ int ret = -errno; -+ close (fd); -+ return ret; -+ } -+ -+ close (fd); - } - - long cache_config; -@@ -284,7 +290,13 @@ debuginfod_init_cache (char *cache_path, char *interval_path, char *maxage_path) - return -errno; - - if (dprintf(fd, "%ld", cache_clean_default_interval_s) < 0) -- return -errno; -+ { -+ int ret = -errno; -+ close (fd); -+ return ret; -+ } -+ -+ close (fd); - - /* init max age config file. */ - if (stat(maxage_path, &st) != 0 -@@ -292,8 +304,13 @@ debuginfod_init_cache (char *cache_path, char *interval_path, char *maxage_path) - return -errno; - - if (dprintf(fd, "%ld", cache_default_max_unused_age_s) < 0) -- return -errno; -+ { -+ int ret = -errno; -+ close (fd); -+ return ret; -+ } - -+ close (fd); - return 0; - } - -@@ -812,18 +829,17 @@ debuginfod_query_server (debuginfod_client *c, - has passed since the last attempt. */ - time_t cache_miss; - time_t target_mtime = st.st_mtime; -+ -+ close(fd); /* no need to hold onto the negative-hit file descriptor */ -+ - rc = debuginfod_config_cache(cache_miss_path, - cache_miss_default_s, &st); - if (rc < 0) -- { -- close(fd); -- goto out; -- } -+ goto out; - - cache_miss = (time_t)rc; - if (time(NULL) - target_mtime <= cache_miss) - { -- close(fd); - rc = -ENOENT; - goto out; - } -diff --git a/debuginfod/debuginfod-find.c b/debuginfod/debuginfod-find.c -index 3e8ab203..f60b5463 100644 ---- a/debuginfod/debuginfod-find.c -+++ b/debuginfod/debuginfod-find.c -@@ -231,6 +231,8 @@ main(int argc, char** argv) - fprintf(stderr, "Server query failed: %s\n", strerror(-rc)); - return 1; - } -+ else -+ close (rc); - - printf("%s\n", cache_name); - free (cache_name); diff --git a/elfutils-0.187-mhd_epoll.patch b/elfutils-0.187-mhd_epoll.patch deleted file mode 100644 index fbbbdac..0000000 --- a/elfutils-0.187-mhd_epoll.patch +++ /dev/null @@ -1,51 +0,0 @@ -commit 28f9d86ea89f88b24f1d12c8e9d5ddc3f77da194 -Author: Mark Wielaard -Date: Fri May 6 00:29:28 2022 +0200 - - debuginfod: Use MHD_USE_EPOLL for libmicrohttpd version 0.9.51 or higher - - Also disable MHD_USE_THREAD_PER_CONNECTION when using MHD_USE_EPOLL. - - https://sourceware.org/bugzilla/show_bug.cgi?id=29123 - - Signed-off-by: Mark Wielaard - -diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx -index c02540f1..d4f47bf7 100644 ---- a/debuginfod/debuginfod.cxx -+++ b/debuginfod/debuginfod.cxx -@@ -1,6 +1,6 @@ - /* Debuginfo-over-http server. - Copyright (C) 2019-2021 Red Hat, Inc. -- Copyright (C) 2021 Mark J. Wielaard -+ Copyright (C) 2021, 2022 Mark J. Wielaard - This file is part of elfutils. - - This file is free software; you can redistribute it and/or modify -@@ -3899,7 +3899,14 @@ main (int argc, char *argv[]) - } - } - -- unsigned int mhd_flags = ((connection_pool -+ /* Note that MHD_USE_EPOLL and MHD_USE_THREAD_PER_CONNECTION don't -+ work together. */ -+ unsigned int use_epoll = 0; -+#if MHD_VERSION >= 0x00095100 -+ use_epoll = MHD_USE_EPOLL; -+#endif -+ -+ unsigned int mhd_flags = ((connection_pool || use_epoll - ? 0 : MHD_USE_THREAD_PER_CONNECTION) - #if MHD_VERSION >= 0x00095300 - | MHD_USE_INTERNAL_POLLING_THREAD -@@ -3907,9 +3914,7 @@ main (int argc, char *argv[]) - | MHD_USE_SELECT_INTERNALLY - #endif - | MHD_USE_DUAL_STACK --#ifdef MHD_USE_EPOLL -- | MHD_USE_EPOLL --#endif -+ | use_epoll - #if MHD_VERSION >= 0x00095200 - | MHD_USE_ITC - #endif diff --git a/elfutils-0.187-mhd_no_dual_stack.patch b/elfutils-0.187-mhd_no_dual_stack.patch deleted file mode 100644 index 3f38e36..0000000 --- a/elfutils-0.187-mhd_no_dual_stack.patch +++ /dev/null @@ -1,118 +0,0 @@ -commit ba675ed25a26fd425ffd19b02cf18babf4291b4f -Author: Mark Wielaard -Date: Thu May 5 23:59:57 2022 +0200 - - debuginfod: Try without MHD_USE_DUAL_STACK if MHD_start_daemon fails - - On a systems that have ipv6 disabled debuginfod doesn't start up - anymore because libhttpd MHD_USE_DUAL_STACK only works if it can - open an ipv6 socket. If MHD_start_daemon with MHD_USE_DUAL_STACK - fails try again without that flag set. - - https://sourceware.org/bugzilla/show_bug.cgi?id=29122 - - Signed-off-by: Mark Wielaard - -diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx -index 4aaf41c0..c02540f1 100644 ---- a/debuginfod/debuginfod.cxx -+++ b/debuginfod/debuginfod.cxx -@@ -3899,40 +3899,67 @@ main (int argc, char *argv[]) - } - } - -- // Start httpd server threads. Use a single dual-homed pool. -- MHD_Daemon *d46 = MHD_start_daemon ((connection_pool ? 0 : MHD_USE_THREAD_PER_CONNECTION) -+ unsigned int mhd_flags = ((connection_pool -+ ? 0 : MHD_USE_THREAD_PER_CONNECTION) - #if MHD_VERSION >= 0x00095300 -- | MHD_USE_INTERNAL_POLLING_THREAD -+ | MHD_USE_INTERNAL_POLLING_THREAD - #else -- | MHD_USE_SELECT_INTERNALLY -+ | MHD_USE_SELECT_INTERNALLY - #endif -+ | MHD_USE_DUAL_STACK - #ifdef MHD_USE_EPOLL -- | MHD_USE_EPOLL -+ | MHD_USE_EPOLL - #endif -- | MHD_USE_DUAL_STACK - #if MHD_VERSION >= 0x00095200 -- | MHD_USE_ITC -+ | MHD_USE_ITC - #endif -- | MHD_USE_DEBUG, /* report errors to stderr */ -- http_port, -- NULL, NULL, /* default accept policy */ -- handler_cb, NULL, /* handler callback */ -- MHD_OPTION_EXTERNAL_LOGGER, error_cb, NULL, -- (connection_pool ? MHD_OPTION_THREAD_POOL_SIZE : MHD_OPTION_END), -- (connection_pool ? (int)connection_pool : MHD_OPTION_END), -- MHD_OPTION_END); -+ | MHD_USE_DEBUG); /* report errors to stderr */ - -+ // Start httpd server threads. Use a single dual-homed pool. -+ MHD_Daemon *d46 = MHD_start_daemon (mhd_flags, http_port, -+ NULL, NULL, /* default accept policy */ -+ handler_cb, NULL, /* handler callback */ -+ MHD_OPTION_EXTERNAL_LOGGER, -+ error_cb, NULL, -+ (connection_pool -+ ? MHD_OPTION_THREAD_POOL_SIZE -+ : MHD_OPTION_END), -+ (connection_pool -+ ? (int)connection_pool -+ : MHD_OPTION_END), -+ MHD_OPTION_END); -+ -+ MHD_Daemon *d4 = NULL; - if (d46 == NULL) - { -- sqlite3 *database = db; -- sqlite3 *databaseq = dbq; -- db = dbq = 0; // for signal_handler not to freak -- sqlite3_close (databaseq); -- sqlite3_close (database); -- error (EXIT_FAILURE, 0, "cannot start http server at port %d", http_port); -- } -+ // Cannot use dual_stack, use ipv4 only -+ mhd_flags &= ~(MHD_USE_DUAL_STACK); -+ d4 = MHD_start_daemon (mhd_flags, http_port, -+ NULL, NULL, /* default accept policy */ -+ handler_cb, NULL, /* handler callback */ -+ MHD_OPTION_EXTERNAL_LOGGER, -+ error_cb, NULL, -+ (connection_pool -+ ? MHD_OPTION_THREAD_POOL_SIZE -+ : MHD_OPTION_END), -+ (connection_pool -+ ? (int)connection_pool -+ : MHD_OPTION_END), -+ MHD_OPTION_END); -+ if (d4 == NULL) -+ { -+ sqlite3 *database = db; -+ sqlite3 *databaseq = dbq; -+ db = dbq = 0; // for signal_handler not to freak -+ sqlite3_close (databaseq); -+ sqlite3_close (database); -+ error (EXIT_FAILURE, 0, "cannot start http server at port %d", -+ http_port); -+ } - -- obatched(clog) << "started http server on IPv4 IPv6 " -+ } -+ obatched(clog) << "started http server on" -+ << (d4 != NULL ? " IPv4 " : " IPv4 IPv6 ") - << "port=" << http_port << endl; - - // add maxigroom sql if -G given -@@ -4053,6 +4080,7 @@ main (int argc, char *argv[]) - - /* Stop all the web service threads. */ - if (d46) MHD_stop_daemon (d46); -+ if (d4) MHD_stop_daemon (d4); - - if (! passive_p) - { diff --git a/elfutils.spec b/elfutils.spec index 9d0a6b3..19f9d92 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -1,6 +1,6 @@ Name: elfutils -Version: 0.187 -%global baserelease 9 +Version: 0.188 +%global baserelease 1 Release: %{baserelease}%{?dist} URL: http://elfutils.org/ %global source_url ftp://sourceware.org/pub/elfutils/%{version}/ @@ -48,6 +48,8 @@ BuildRequires: iproute BuildRequires: procps BuildRequires: bsdtar BuildRequires: curl +# For run-debuginfod-response-headers.sh test case +BuildRequires: socat BuildRequires: automake BuildRequires: autoconf @@ -72,14 +74,6 @@ BuildRequires: gettext-devel # For s390x... FDO package notes are bogus. Patch1: elfutils-0.186-fdo-swap.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=2080957 -Patch2: elfutils-0.187-csh-profile.patch -# https://sourceware.org/bugzilla/show_bug.cgi?id=29117 -Patch3: elfutils-0.187-debuginfod-client-fd-leak.patch -# https://sourceware.org/bugzilla/show_bug.cgi?id=29122 -Patch4: elfutils-0.187-mhd_no_dual_stack.patch -# https://sourceware.org/bugzilla/show_bug.cgi?id=29123 -Patch5: elfutils-0.187-mhd_epoll.patch %description Elfutils is a collection of utilities, including stack (to show @@ -420,11 +414,12 @@ fi %{_bindir}/debuginfod %config(noreplace) %{_sysconfdir}/sysconfig/debuginfod %{_unitdir}/debuginfod.service -%{_sysconfdir}/sysconfig/debuginfod %if %{with_sysusers} %{_sysusersdir}/elfutils-debuginfod.conf %endif -%{_mandir}/man8/debuginfod.8* +%{_mandir}/man8/debuginfod*.8* +%{_mandir}/man7/debuginfod*.7* + %dir %attr(0700,debuginfod,debuginfod) %{_localstatedir}/cache/debuginfod %ghost %attr(0600,debuginfod,debuginfod) %{_localstatedir}/cache/debuginfod/debuginfod.sqlite @@ -447,6 +442,9 @@ exit 0 %systemd_postun_with_restart debuginfod.service %changelog +* Wed Nov 2 2022 Mark Wielaard - 0.188-1 +- Upgrade to upsteam elfutils 0.188. + * Wed Oct 5 2022 Amit Shah - 0.187-9 - Auto-configure debuginfod_url based on macros.dist diff --git a/sources b/sources index 808d95e..04cbb1b 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (elfutils-0.187.tar.bz2) = a9b9e32b503b8b50a62d4e4001097ed2721d3475232a6380e6b9853bd1647aec016440c0ca7ceb950daf1144f8db9814ab43cf33cc0ebef7fc91e9e775c9e874 +SHA512 (elfutils-0.188.tar.bz2) = 585551b2d937d19d1becfc2f28935db1dd1a3d25571a62f322b70ac8da98c1a741a55d070327705df6c3e2ee026652e0b9a3c733b050a0b0ec5f2fc75d5b74b5 From 8b711f9c7127b75dcc7fc6ef18a6d6df0331fbc1 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 2 Nov 2022 18:14:57 +0100 Subject: [PATCH 05/25] 0.188-2 - Add elfutils-0.188-static-extract_section.patch --- elfutils-0.188-static-extract_section.patch | 24 +++++++++++++++++++++ elfutils.spec | 5 +++++ 2 files changed, 29 insertions(+) create mode 100644 elfutils-0.188-static-extract_section.patch diff --git a/elfutils-0.188-static-extract_section.patch b/elfutils-0.188-static-extract_section.patch new file mode 100644 index 0000000..6305b3e --- /dev/null +++ b/elfutils-0.188-static-extract_section.patch @@ -0,0 +1,24 @@ +commit 58a7aa900bc2d9822b0d0cb596ba95a21ff0fd2d +Author: Mark Wielaard +Date: Wed Nov 2 17:54:11 2022 +0100 + + debuginfod: Mark extract_section function static + + The extract_section function in debuginfod-client.c is an internal + function and should not be exported. Mark it as static. + + Signed-off-by: Mark Wielaard + +diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c +index 0c4a00cf..f48e32cc 100644 +--- a/debuginfod/debuginfod-client.c ++++ b/debuginfod/debuginfod-client.c +@@ -621,7 +621,7 @@ path_escape (const char *src, char *dest) + section name was not found. -EEXIST indicates that the section was + found but had type SHT_NOBITS. */ + +-int ++static int + extract_section (int fd, const char *section, char *fd_path, char **usr_path) + { + elf_version (EV_CURRENT); diff --git a/elfutils.spec b/elfutils.spec index 19f9d92..ce46a88 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -74,6 +74,8 @@ BuildRequires: gettext-devel # For s390x... FDO package notes are bogus. Patch1: elfutils-0.186-fdo-swap.patch +# Don't export internal function. +Patch2: elfutils-0.188-static-extract_section.patch %description Elfutils is a collection of utilities, including stack (to show @@ -442,6 +444,9 @@ exit 0 %systemd_postun_with_restart debuginfod.service %changelog +* Wed Nov 2 2022 Mark Wielaard - 0.188-2 +- Add elfutils-0.188-static-extract_section.patch. + * Wed Nov 2 2022 Mark Wielaard - 0.188-1 - Upgrade to upsteam elfutils 0.188. From dae35159865c8d1ed670a0b895efdb02b2912f3d Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 2 Nov 2022 18:22:54 +0100 Subject: [PATCH 06/25] 0.188-2 --- elfutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elfutils.spec b/elfutils.spec index ce46a88..733b59e 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -1,6 +1,6 @@ Name: elfutils Version: 0.188 -%global baserelease 1 +%global baserelease 2 Release: %{baserelease}%{?dist} URL: http://elfutils.org/ %global source_url ftp://sourceware.org/pub/elfutils/%{version}/ From 0f93d8ded57ba7d54d7a0541c899ac600e1dee25 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Mon, 7 Nov 2022 17:15:00 +0100 Subject: [PATCH 07/25] 0.188-3 - Add elfutils-0.188-compile-warnings.patch - Add elfutils-0.188-debuginfod-client-lifetime.patch --- elfutils-0.188-compile-warnings.patch | 109 +++++++++++ ...ils-0.188-debuginfod-client-lifetime.patch | 171 ++++++++++++++++++ elfutils.spec | 10 +- 3 files changed, 289 insertions(+), 1 deletion(-) create mode 100644 elfutils-0.188-compile-warnings.patch create mode 100644 elfutils-0.188-debuginfod-client-lifetime.patch diff --git a/elfutils-0.188-compile-warnings.patch b/elfutils-0.188-compile-warnings.patch new file mode 100644 index 0000000..397583f --- /dev/null +++ b/elfutils-0.188-compile-warnings.patch @@ -0,0 +1,109 @@ +commit 75f2de448f311807e2493f2a37a980e2d872b229 +Author: Mark Wielaard +Date: Thu Nov 3 13:38:45 2022 +0100 + + readelf: Check phdr != NULL or shdr != NULL in handle_dynamic. + + The compiler doesn't know that when use_dynamic_segment is true, + then phdr should/will be non-NULL and otherwise shdr is non-NULL. + Add explicit checks to help the compiler out and in case an error + is made calling the handle_dynamic function. + + Signed-off-by: Mark Wielaard + +diff --git a/src/readelf.c b/src/readelf.c +index 0e0b05c4..e721a209 100644 +--- a/src/readelf.c ++++ b/src/readelf.c +@@ -1828,7 +1828,7 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, GElf_Phdr *phdr) + size_t dyn_ents; + + /* Get the data of the section. */ +- if (use_dynamic_segment) ++ if (use_dynamic_segment && phdr != NULL) + data = elf_getdata_rawchunk(ebl->elf, phdr->p_offset, + phdr->p_filesz, ELF_T_DYN); + else +@@ -1840,7 +1840,7 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, GElf_Phdr *phdr) + /* Get the dynamic section entry number */ + dyn_ents = get_dyn_ents (data); + +- if (!use_dynamic_segment) ++ if (!use_dynamic_segment && shdr != NULL) + { + /* Get the section header string table index. */ + if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) +@@ -1862,7 +1862,7 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, GElf_Phdr *phdr) + (int) shdr->sh_link, + elf_strptr (ebl->elf, shstrndx, glink->sh_name)); + } +- else ++ else if (phdr != NULL) + { + printf (ngettext ("\ + \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 "\n", +@@ -1879,7 +1879,7 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, GElf_Phdr *phdr) + /* if --use-dynamic option is enabled, + use the string table to get the related library info. */ + Elf_Data *strtab_data = NULL; +- if (use_dynamic_segment) ++ if (use_dynamic_segment && phdr != NULL) + { + strtab_data = get_dynscn_strtab(ebl->elf, phdr); + if (strtab_data == NULL) +@@ -1903,7 +1903,7 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, GElf_Phdr *phdr) + || dyn->d_tag == DT_RPATH + || dyn->d_tag == DT_RUNPATH) + { +- if (! use_dynamic_segment) ++ if (! use_dynamic_segment && shdr != NULL) + name = elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val); + else if (dyn->d_un.d_val < strtab_data->d_size + && memrchr (strtab_data->d_buf + dyn->d_un.d_val, '\0', + +commit b0a0235771906e3bcd6174c4e3c020b5522b0be5 +Author: Mark Wielaard +Date: Thu Nov 3 13:44:35 2022 +0100 + + libdw: Don't dereference and assign values we are skipping + + We don't use the FDE address encoding byte, so no reason + to read and store it. Just skip past it. + + Signed-off-by: Mark Wielaard + +diff --git a/libdw/dwarf_next_cfi.c b/libdw/dwarf_next_cfi.c +index 23b16885..be08984f 100644 +--- a/libdw/dwarf_next_cfi.c ++++ b/libdw/dwarf_next_cfi.c +@@ -226,7 +226,7 @@ dwarf_next_cfi (const unsigned char e_ident[], + if (sized_augmentation) + { + /* Skip FDE address encoding byte. */ +- encoding = *bytes++; ++ bytes++; + continue; + } + break; + +commit 52a6a3110e019d696284fdd822c2a2f0987dded2 +Author: Mark Wielaard +Date: Thu Nov 3 13:52:32 2022 +0100 + + readelf: Check gelf_getdyn doesn't return NULL + + Signed-off-by: Mark Wielaard + +diff --git a/src/readelf.c b/src/readelf.c +index e721a209..3dafb041 100644 +--- a/src/readelf.c ++++ b/src/readelf.c +@@ -4910,7 +4910,7 @@ get_dynscn_addrs(Elf *elf, GElf_Phdr *phdr, GElf_Addr addrs[i_max]) + GElf_Dyn dyn_mem; + GElf_Dyn *dyn = gelf_getdyn(data, dyn_idx, &dyn_mem); + /* DT_NULL Marks end of dynamic section. */ +- if (dyn->d_tag == DT_NULL) ++ if (dyn == NULL || dyn->d_tag == DT_NULL) + break; + + switch (dyn->d_tag) { diff --git a/elfutils-0.188-debuginfod-client-lifetime.patch b/elfutils-0.188-debuginfod-client-lifetime.patch new file mode 100644 index 0000000..4c8f735 --- /dev/null +++ b/elfutils-0.188-debuginfod-client-lifetime.patch @@ -0,0 +1,171 @@ +commit c424e5f3d24f76e01242d15ba361dc6234706fed +Author: Frank Ch. Eigler +Date: Thu Nov 3 10:07:31 2022 -0400 + + debuginfod.cxx: fix coverity-found use-after-release error + + The debuginfod_client object lifetime needs more careful handling, + made easier with the defer_dtor<> gadget. + + Signed-off-by: Frank Ch. Eigler + +diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx +index f46da6ef..02a11477 100644 +--- a/debuginfod/debuginfod.cxx ++++ b/debuginfod/debuginfod.cxx +@@ -2249,85 +2249,82 @@ handle_buildid (MHD_Connection* conn, + + int fd = -1; + debuginfod_client *client = debuginfod_pool_begin (); +- if (client != NULL) +- { +- debuginfod_set_progressfn (client, & debuginfod_find_progress); ++ if (client == NULL) ++ throw libc_exception(errno, "debuginfod client pool alloc"); ++ defer_dtor client_closer (client, debuginfod_pool_end); ++ ++ debuginfod_set_progressfn (client, & debuginfod_find_progress); + +- if (conn) +- { +- // Transcribe incoming User-Agent: +- string ua = MHD_lookup_connection_value (conn, MHD_HEADER_KIND, "User-Agent") ?: ""; +- string ua_complete = string("User-Agent: ") + ua; +- debuginfod_add_http_header (client, ua_complete.c_str()); +- +- // Compute larger XFF:, for avoiding info loss during +- // federation, and for future cyclicity detection. +- string xff = MHD_lookup_connection_value (conn, MHD_HEADER_KIND, "X-Forwarded-For") ?: ""; +- if (xff != "") +- xff += string(", "); // comma separated list +- +- unsigned int xff_count = 0; +- for (auto&& i : xff){ +- if (i == ',') xff_count++; +- } ++ if (conn) ++ { ++ // Transcribe incoming User-Agent: ++ string ua = MHD_lookup_connection_value (conn, MHD_HEADER_KIND, "User-Agent") ?: ""; ++ string ua_complete = string("User-Agent: ") + ua; ++ debuginfod_add_http_header (client, ua_complete.c_str()); ++ ++ // Compute larger XFF:, for avoiding info loss during ++ // federation, and for future cyclicity detection. ++ string xff = MHD_lookup_connection_value (conn, MHD_HEADER_KIND, "X-Forwarded-For") ?: ""; ++ if (xff != "") ++ xff += string(", "); // comma separated list ++ ++ unsigned int xff_count = 0; ++ for (auto&& i : xff){ ++ if (i == ',') xff_count++; ++ } + +- // if X-Forwarded-For: exceeds N hops, +- // do not delegate a local lookup miss to upstream debuginfods. +- if (xff_count >= forwarded_ttl_limit) +- throw reportable_exception(MHD_HTTP_NOT_FOUND, "not found, --forwared-ttl-limit reached \ ++ // if X-Forwarded-For: exceeds N hops, ++ // do not delegate a local lookup miss to upstream debuginfods. ++ if (xff_count >= forwarded_ttl_limit) ++ throw reportable_exception(MHD_HTTP_NOT_FOUND, "not found, --forwared-ttl-limit reached \ + and will not query the upstream servers"); + +- // Compute the client's numeric IP address only - so can't merge with conninfo() +- const union MHD_ConnectionInfo *u = MHD_get_connection_info (conn, +- MHD_CONNECTION_INFO_CLIENT_ADDRESS); +- struct sockaddr *so = u ? u->client_addr : 0; +- char hostname[256] = ""; // RFC1035 +- if (so && so->sa_family == AF_INET) { +- (void) getnameinfo (so, sizeof (struct sockaddr_in), hostname, sizeof (hostname), NULL, 0, +- NI_NUMERICHOST); +- } else if (so && so->sa_family == AF_INET6) { +- struct sockaddr_in6* addr6 = (struct sockaddr_in6*) so; +- if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) { +- struct sockaddr_in addr4; +- memset (&addr4, 0, sizeof(addr4)); +- addr4.sin_family = AF_INET; +- addr4.sin_port = addr6->sin6_port; +- memcpy (&addr4.sin_addr.s_addr, addr6->sin6_addr.s6_addr+12, sizeof(addr4.sin_addr.s_addr)); +- (void) getnameinfo ((struct sockaddr*) &addr4, sizeof (addr4), +- hostname, sizeof (hostname), NULL, 0, +- NI_NUMERICHOST); +- } else { +- (void) getnameinfo (so, sizeof (struct sockaddr_in6), hostname, sizeof (hostname), NULL, 0, +- NI_NUMERICHOST); +- } +- } +- +- string xff_complete = string("X-Forwarded-For: ")+xff+string(hostname); +- debuginfod_add_http_header (client, xff_complete.c_str()); ++ // Compute the client's numeric IP address only - so can't merge with conninfo() ++ const union MHD_ConnectionInfo *u = MHD_get_connection_info (conn, ++ MHD_CONNECTION_INFO_CLIENT_ADDRESS); ++ struct sockaddr *so = u ? u->client_addr : 0; ++ char hostname[256] = ""; // RFC1035 ++ if (so && so->sa_family == AF_INET) { ++ (void) getnameinfo (so, sizeof (struct sockaddr_in), hostname, sizeof (hostname), NULL, 0, ++ NI_NUMERICHOST); ++ } else if (so && so->sa_family == AF_INET6) { ++ struct sockaddr_in6* addr6 = (struct sockaddr_in6*) so; ++ if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) { ++ struct sockaddr_in addr4; ++ memset (&addr4, 0, sizeof(addr4)); ++ addr4.sin_family = AF_INET; ++ addr4.sin_port = addr6->sin6_port; ++ memcpy (&addr4.sin_addr.s_addr, addr6->sin6_addr.s6_addr+12, sizeof(addr4.sin_addr.s_addr)); ++ (void) getnameinfo ((struct sockaddr*) &addr4, sizeof (addr4), ++ hostname, sizeof (hostname), NULL, 0, ++ NI_NUMERICHOST); ++ } else { ++ (void) getnameinfo (so, sizeof (struct sockaddr_in6), hostname, sizeof (hostname), NULL, 0, ++ NI_NUMERICHOST); + } +- +- 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 if (artifacttype == "section") +- fd = debuginfod_find_section (client, +- (const unsigned char*) buildid.c_str(), +- 0, section.c_str(), NULL); +- ++ } ++ ++ string xff_complete = string("X-Forwarded-For: ")+xff+string(hostname); ++ debuginfod_add_http_header (client, xff_complete.c_str()); + } +- else +- fd = -errno; /* Set by debuginfod_begin. */ +- debuginfod_pool_end (client); +- ++ ++ 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 if (artifacttype == "section") ++ fd = debuginfod_find_section (client, ++ (const unsigned char*) buildid.c_str(), ++ 0, section.c_str(), NULL); ++ + if (fd >= 0) + { + if (conn != 0) diff --git a/elfutils.spec b/elfutils.spec index 733b59e..3d372ad 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -1,6 +1,6 @@ Name: elfutils Version: 0.188 -%global baserelease 2 +%global baserelease 3 Release: %{baserelease}%{?dist} URL: http://elfutils.org/ %global source_url ftp://sourceware.org/pub/elfutils/%{version}/ @@ -76,6 +76,10 @@ BuildRequires: gettext-devel Patch1: elfutils-0.186-fdo-swap.patch # Don't export internal function. Patch2: elfutils-0.188-static-extract_section.patch +# Silence some compiler warnings +Patch3: elfutils-0.188-compile-warnings.patch +# The debuginfod_client object lifetime needs more careful handling +Patch4: elfutils-0.188-debuginfod-client-lifetime.patch %description Elfutils is a collection of utilities, including stack (to show @@ -444,6 +448,10 @@ exit 0 %systemd_postun_with_restart debuginfod.service %changelog +* Mon Nov 7 2022 Mark Wielaard - 0.188-3 +- Add elfutils-0.188-compile-warnings.patch +- Add elfutils-0.188-debuginfod-client-lifetime.patch + * Wed Nov 2 2022 Mark Wielaard - 0.188-2 - Add elfutils-0.188-static-extract_section.patch. From a1e6f5590cfb0425099c7ac3246afd67f62d67c0 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 19 Jan 2023 02:12:19 +0000 Subject: [PATCH 08/25] Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- elfutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/elfutils.spec b/elfutils.spec index 3d372ad..997c470 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -1,6 +1,6 @@ Name: elfutils Version: 0.188 -%global baserelease 3 +%global baserelease 4 Release: %{baserelease}%{?dist} URL: http://elfutils.org/ %global source_url ftp://sourceware.org/pub/elfutils/%{version}/ @@ -448,6 +448,9 @@ exit 0 %systemd_postun_with_restart debuginfod.service %changelog +* Thu Jan 19 2023 Fedora Release Engineering - 0.188-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + * Mon Nov 7 2022 Mark Wielaard - 0.188-3 - Add elfutils-0.188-compile-warnings.patch - Add elfutils-0.188-debuginfod-client-lifetime.patch From c468385a0e2df7a02bdc7d4354403bb79a8458fd Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Fri, 27 Jan 2023 19:09:16 +0100 Subject: [PATCH 09/25] 0.188-5 Add various libcurl fixes for deprecated constants - Add elfutils-0.188-deprecated-CURLINFO.patch, elfutils-0.188-CURL_AT_LEAST_VERSION.patch and elfutils-0.188-CURLOPT_PROTOCOLS_STR.patch --- elfutils-0.188-CURLOPT_PROTOCOLS_STR.patch | 35 ++++++++++++++++ elfutils-0.188-CURL_AT_LEAST_VERSION.patch | 36 ++++++++++++++++ elfutils-0.188-deprecated-CURLINFO.patch | 49 ++++++++++++++++++++++ elfutils.spec | 11 ++++- 4 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 elfutils-0.188-CURLOPT_PROTOCOLS_STR.patch create mode 100644 elfutils-0.188-CURL_AT_LEAST_VERSION.patch create mode 100644 elfutils-0.188-deprecated-CURLINFO.patch diff --git a/elfutils-0.188-CURLOPT_PROTOCOLS_STR.patch b/elfutils-0.188-CURLOPT_PROTOCOLS_STR.patch new file mode 100644 index 0000000..3352c21 --- /dev/null +++ b/elfutils-0.188-CURLOPT_PROTOCOLS_STR.patch @@ -0,0 +1,35 @@ +From 6560fb26a62ef135a804357ef4f15a47de3e49b3 Mon Sep 17 00:00:00 2001 +From: Mark Wielaard +Date: Tue, 10 Jan 2023 23:20:41 +0100 +Subject: [PATCH 8/8] debuginfod-client: Use CURLOPT_PROTOCOLS_STR for libcurl + >= 7.85.0 + +https://sourceware.org/bugzilla/show_bug.cgi?id=29926 + +Signed-off-by: Mark Wielaard +--- + debuginfod/ChangeLog | 5 +++++ + debuginfod/debuginfod-client.c | 5 +++++ + 2 files changed, 10 insertions(+) + +diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c +index a16165bd..1ce45632 100644 +--- a/debuginfod/debuginfod-client.c ++++ b/debuginfod/debuginfod-client.c +@@ -1336,8 +1336,13 @@ debuginfod_query_server (debuginfod_client *c, + + /* Only allow http:// + https:// + file:// so we aren't being + redirected to some unsupported protocol. */ ++#if CURL_AT_LEAST_VERSION(7, 85, 0) ++ curl_easy_setopt_ck(data[i].handle, CURLOPT_PROTOCOLS_STR, ++ "http,https,file"); ++#else + curl_easy_setopt_ck(data[i].handle, CURLOPT_PROTOCOLS, + (CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FILE)); ++#endif + curl_easy_setopt_ck(data[i].handle, CURLOPT_URL, data[i].url); + if (vfd >= 0) + curl_easy_setopt_ck(data[i].handle, CURLOPT_ERRORBUFFER, +-- +2.39.1 + diff --git a/elfutils-0.188-CURL_AT_LEAST_VERSION.patch b/elfutils-0.188-CURL_AT_LEAST_VERSION.patch new file mode 100644 index 0000000..0eca664 --- /dev/null +++ b/elfutils-0.188-CURL_AT_LEAST_VERSION.patch @@ -0,0 +1,36 @@ +From 304741e11018c29e7ff17751e05dcc5c786a3fd9 Mon Sep 17 00:00:00 2001 +From: Mark Wielaard +Date: Wed, 21 Dec 2022 18:21:08 +0100 +Subject: [PATCH 2/8] debuginfod: Define CURL_AT_LEAST_VERSION if necessary + +Older curl.h don't define CURL_AT_LEAST_VERSION, so define it +ourselves because it is nicer than doing hex encoded version +comparisons. + +Signed-off-by: Mark Wielaard +--- + debuginfod/ChangeLog | 4 ++++ + debuginfod/debuginfod-client.c | 7 +++++++ + 2 files changed, 11 insertions(+) + +diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c +index 692aecce..a16165bd 100644 +--- a/debuginfod/debuginfod-client.c ++++ b/debuginfod/debuginfod-client.c +@@ -105,6 +105,13 @@ void debuginfod_end (debuginfod_client *c) { } + #include + #endif + ++/* Older curl.h don't define CURL_AT_LEAST_VERSION. */ ++#ifndef CURL_AT_LEAST_VERSION ++ #define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z)) ++ #define CURL_AT_LEAST_VERSION(x,y,z) \ ++ (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z)) ++#endif ++ + #include + + static pthread_once_t init_control = PTHREAD_ONCE_INIT; +-- +2.39.1 + diff --git a/elfutils-0.188-deprecated-CURLINFO.patch b/elfutils-0.188-deprecated-CURLINFO.patch new file mode 100644 index 0000000..e9bc9a3 --- /dev/null +++ b/elfutils-0.188-deprecated-CURLINFO.patch @@ -0,0 +1,49 @@ +From d2bf497b12fbd49b4996ccf0744303ffd67735b1 Mon Sep 17 00:00:00 2001 +From: Andrew Paprocki +Date: Wed, 21 Dec 2022 11:15:00 -0500 +Subject: [PATCH 1/8] PR29926: debuginfod: Fix usage of deprecated CURLINFO_* + +The `CURLINFO_SIZE_DOWNLOAD_T` and `CURLINFO_CONTENT_LENGTH_DOWNLOAD_T` +identifiers are `enum`s, not pre-processor definitions, so the current +`#ifdef` logic is not selecting the newer API. This results in the +older identifiers being used and they now generate errors when compiled +against Curl 7.87, which has silently deprecated them, causing GCC to +emit `-Werror=deprecated-declarations`. + +Instead, the newer identifiers were added in Curl 7.55, so explicitly +check for `CURL_AT_LEAST_VERSION(7, 55, 0)` instead of the current +logic. This eliminates the error when compiling against Curl 7.87. + +Ref: https://github.com/curl/curl/pull/1511 + +Signed-off-by: Andrew Paprocki +--- + debuginfod/ChangeLog | 4 ++++ + debuginfod/debuginfod-client.c | 4 ++-- + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c +index 8873fcc8..692aecce 100644 +--- a/debuginfod/debuginfod-client.c ++++ b/debuginfod/debuginfod-client.c +@@ -1456,7 +1456,7 @@ debuginfod_query_server (debuginfod_client *c, + deflate-compressing proxies, this number is likely to be + unavailable, so -1 may show. */ + CURLcode curl_res; +-#ifdef CURLINFO_CONTENT_LENGTH_DOWNLOAD_T ++#if CURL_AT_LEAST_VERSION(7, 55, 0) + curl_off_t cl; + curl_res = curl_easy_getinfo(target_handle, + CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, +@@ -1491,7 +1491,7 @@ debuginfod_query_server (debuginfod_client *c, + if (target_handle) /* we've committed to a server; report its download progress */ + { + CURLcode curl_res; +-#ifdef CURLINFO_SIZE_DOWNLOAD_T ++#if CURL_AT_LEAST_VERSION(7, 55, 0) + curl_off_t dl; + curl_res = curl_easy_getinfo(target_handle, + CURLINFO_SIZE_DOWNLOAD_T, +-- +2.39.1 + diff --git a/elfutils.spec b/elfutils.spec index 997c470..849868f 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -1,6 +1,6 @@ Name: elfutils Version: 0.188 -%global baserelease 4 +%global baserelease 5 Release: %{baserelease}%{?dist} URL: http://elfutils.org/ %global source_url ftp://sourceware.org/pub/elfutils/%{version}/ @@ -80,6 +80,10 @@ Patch2: elfutils-0.188-static-extract_section.patch Patch3: elfutils-0.188-compile-warnings.patch # The debuginfod_client object lifetime needs more careful handling Patch4: elfutils-0.188-debuginfod-client-lifetime.patch +# Various libcurl deprecated constants +Patch5: elfutils-0.188-deprecated-CURLINFO.patch +Patch6: elfutils-0.188-CURL_AT_LEAST_VERSION.patch +Patch7: elfutils-0.188-CURLOPT_PROTOCOLS_STR.patch %description Elfutils is a collection of utilities, including stack (to show @@ -448,6 +452,11 @@ exit 0 %systemd_postun_with_restart debuginfod.service %changelog +* Fri Jan 27 2023 Mark Wielaard - 0.188-5 +- Add elfutils-0.188-deprecated-CURLINFO.patch, + elfutils-0.188-CURL_AT_LEAST_VERSION.patch and + elfutils-0.188-CURLOPT_PROTOCOLS_STR.patch + * Thu Jan 19 2023 Fedora Release Engineering - 0.188-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild From ad7295b9972ff5315a064c707ff8ed00213fa7c5 Mon Sep 17 00:00:00 2001 From: Martin Cermak Date: Mon, 13 Feb 2023 12:56:12 +0100 Subject: [PATCH 10/25] CI Tests: Update Regression/GNU-Attribute-notes-not-recognized --- .../Makefile | 2 +- .../main.fmf | 10 +++--- .../runtest.sh | 35 +++++++++++++++---- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/tests/Regression/GNU-Attribute-notes-not-recognized/Makefile b/tests/Regression/GNU-Attribute-notes-not-recognized/Makefile index 03e071d..332e11f 100644 --- a/tests/Regression/GNU-Attribute-notes-not-recognized/Makefile +++ b/tests/Regression/GNU-Attribute-notes-not-recognized/Makefile @@ -54,7 +54,7 @@ $(METADATA): Makefile @echo "TestTime: 48h" >> $(METADATA) @echo "RunFor: elfutils" >> $(METADATA) @echo "Requires: elfutils" >> $(METADATA) - @echo "Requires: bash" >> $(METADATA) + @echo "Requires: bash bash-debuginfo" >> $(METADATA) @echo "Priority: Normal" >> $(METADATA) @echo "License: GPLv2+" >> $(METADATA) @echo "Confidential: no" >> $(METADATA) diff --git a/tests/Regression/GNU-Attribute-notes-not-recognized/main.fmf b/tests/Regression/GNU-Attribute-notes-not-recognized/main.fmf index 896cbd2..eb1809c 100644 --- a/tests/Regression/GNU-Attribute-notes-not-recognized/main.fmf +++ b/tests/Regression/GNU-Attribute-notes-not-recognized/main.fmf @@ -2,15 +2,15 @@ summary: GNU-Attribute-notes-not-recognized description: | Bug summary: elfutils doesn't recognize GNU Attribute notes Bugzilla link: https://bugzilla.redhat.com/show_bug.cgi?id=1650125 -contact: -- Martin Cermak +contact: Martin Cermak component: -- elfutils + - elfutils test: ./runtest.sh framework: beakerlib recommend: -- elfutils -- bash + - elfutils + - bash + - bash-debuginfo duration: 48h extra-summary: /tools/elfutils/Regression/GNU-Attribute-notes-not-recognized extra-task: /tools/elfutils/Regression/GNU-Attribute-notes-not-recognized diff --git a/tests/Regression/GNU-Attribute-notes-not-recognized/runtest.sh b/tests/Regression/GNU-Attribute-notes-not-recognized/runtest.sh index d60f5ac..7b6e187 100755 --- a/tests/Regression/GNU-Attribute-notes-not-recognized/runtest.sh +++ b/tests/Regression/GNU-Attribute-notes-not-recognized/runtest.sh @@ -32,12 +32,35 @@ PACKAGE="elfutils" rlJournalStart rlPhaseStartTest - # Rely on that /bin/bash is annobin-annotated per - # - https://fedoraproject.org/wiki/Toolchain/Watermark - # - https://fedoraproject.org/wiki/Changes/Annobin - # Seems to work fine with bash-4.4.19-6.el8 and elfutils-0.174-5.el8. - set -o pipefail - rlRun "eu-readelf -n /bin/bash | grep -2 '^ GA' | fgrep 'GNU Build Attribute' | tail -50" + # Rely on that /bin/bash is annobin-annotated per + # - https://fedoraproject.org/wiki/Toolchain/Watermark + # - https://fedoraproject.org/wiki/Changes/Annobin + # Seems to work fine with bash-4.4.19-6.el8 and elfutils-0.174-5.el8. + f="/bin/bash" + + # Annobin notes originally used to reside in the binary itself. + # Later on they moved to debuginfo. + # Let's see if we can chase down needed debuginfo somewhere... + + # Attempt getting the needed file using debuginfod + export DEBUGINFOD_URLS=http://debuginfod.usersys.redhat.com:3632/ + rlRun "f=\"$f $(debuginfod-find debuginfo /bin/bash)\"" + + # Attempt getting the needed file by traditional means + rlRun "debuginfo-install -y bash" + rlRun "buildid=$(eu-readelf -n /bin/bash | awk '/Build ID:/ {print $NF}')" + for i in $(rpm -ql bash-debuginfo); do + test -f $i || continue + if eu-readelf -n $i | fgrep $buildid; then + rlRun "f=\"$f $i\"" + fi + done + + set -o pipefail + export f + # Check if eu-readelf can read the notes from at least one of files + # that can possibly contain it... + rlRun "(for i in $f; do eu-readelf -n $i; done ) | grep -2 '^ GA' | fgrep 'GNU Build Attribute' | tail -50" rlPhaseEnd rlJournalPrintText rlJournalEnd From cb758000501eadeefa2de11c216280c8be7e3d17 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Fri, 3 Mar 2023 17:44:51 +0100 Subject: [PATCH 11/25] 0.189-1 - Upgrade to upsteam elfutils 0.189 --- .gitignore | 1 + elfutils-0.188-CURLOPT_PROTOCOLS_STR.patch | 35 ---- elfutils-0.188-CURL_AT_LEAST_VERSION.patch | 36 ---- elfutils-0.188-compile-warnings.patch | 109 ----------- ...ils-0.188-debuginfod-client-lifetime.patch | 171 ------------------ elfutils-0.188-deprecated-CURLINFO.patch | 49 ----- elfutils-0.188-static-extract_section.patch | 24 --- elfutils.spec | 17 +- sources | 2 +- 9 files changed, 7 insertions(+), 437 deletions(-) delete mode 100644 elfutils-0.188-CURLOPT_PROTOCOLS_STR.patch delete mode 100644 elfutils-0.188-CURL_AT_LEAST_VERSION.patch delete mode 100644 elfutils-0.188-compile-warnings.patch delete mode 100644 elfutils-0.188-debuginfod-client-lifetime.patch delete mode 100644 elfutils-0.188-deprecated-CURLINFO.patch delete mode 100644 elfutils-0.188-static-extract_section.patch diff --git a/.gitignore b/.gitignore index d23f6fd..9d73fa8 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,4 @@ /elfutils-0.186.tar.bz2 /elfutils-0.187.tar.bz2 /elfutils-0.188.tar.bz2 +/elfutils-0.189.tar.bz2 diff --git a/elfutils-0.188-CURLOPT_PROTOCOLS_STR.patch b/elfutils-0.188-CURLOPT_PROTOCOLS_STR.patch deleted file mode 100644 index 3352c21..0000000 --- a/elfutils-0.188-CURLOPT_PROTOCOLS_STR.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 6560fb26a62ef135a804357ef4f15a47de3e49b3 Mon Sep 17 00:00:00 2001 -From: Mark Wielaard -Date: Tue, 10 Jan 2023 23:20:41 +0100 -Subject: [PATCH 8/8] debuginfod-client: Use CURLOPT_PROTOCOLS_STR for libcurl - >= 7.85.0 - -https://sourceware.org/bugzilla/show_bug.cgi?id=29926 - -Signed-off-by: Mark Wielaard ---- - debuginfod/ChangeLog | 5 +++++ - debuginfod/debuginfod-client.c | 5 +++++ - 2 files changed, 10 insertions(+) - -diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c -index a16165bd..1ce45632 100644 ---- a/debuginfod/debuginfod-client.c -+++ b/debuginfod/debuginfod-client.c -@@ -1336,8 +1336,13 @@ debuginfod_query_server (debuginfod_client *c, - - /* Only allow http:// + https:// + file:// so we aren't being - redirected to some unsupported protocol. */ -+#if CURL_AT_LEAST_VERSION(7, 85, 0) -+ curl_easy_setopt_ck(data[i].handle, CURLOPT_PROTOCOLS_STR, -+ "http,https,file"); -+#else - curl_easy_setopt_ck(data[i].handle, CURLOPT_PROTOCOLS, - (CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FILE)); -+#endif - curl_easy_setopt_ck(data[i].handle, CURLOPT_URL, data[i].url); - if (vfd >= 0) - curl_easy_setopt_ck(data[i].handle, CURLOPT_ERRORBUFFER, --- -2.39.1 - diff --git a/elfutils-0.188-CURL_AT_LEAST_VERSION.patch b/elfutils-0.188-CURL_AT_LEAST_VERSION.patch deleted file mode 100644 index 0eca664..0000000 --- a/elfutils-0.188-CURL_AT_LEAST_VERSION.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 304741e11018c29e7ff17751e05dcc5c786a3fd9 Mon Sep 17 00:00:00 2001 -From: Mark Wielaard -Date: Wed, 21 Dec 2022 18:21:08 +0100 -Subject: [PATCH 2/8] debuginfod: Define CURL_AT_LEAST_VERSION if necessary - -Older curl.h don't define CURL_AT_LEAST_VERSION, so define it -ourselves because it is nicer than doing hex encoded version -comparisons. - -Signed-off-by: Mark Wielaard ---- - debuginfod/ChangeLog | 4 ++++ - debuginfod/debuginfod-client.c | 7 +++++++ - 2 files changed, 11 insertions(+) - -diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c -index 692aecce..a16165bd 100644 ---- a/debuginfod/debuginfod-client.c -+++ b/debuginfod/debuginfod-client.c -@@ -105,6 +105,13 @@ void debuginfod_end (debuginfod_client *c) { } - #include - #endif - -+/* Older curl.h don't define CURL_AT_LEAST_VERSION. */ -+#ifndef CURL_AT_LEAST_VERSION -+ #define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z)) -+ #define CURL_AT_LEAST_VERSION(x,y,z) \ -+ (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z)) -+#endif -+ - #include - - static pthread_once_t init_control = PTHREAD_ONCE_INIT; --- -2.39.1 - diff --git a/elfutils-0.188-compile-warnings.patch b/elfutils-0.188-compile-warnings.patch deleted file mode 100644 index 397583f..0000000 --- a/elfutils-0.188-compile-warnings.patch +++ /dev/null @@ -1,109 +0,0 @@ -commit 75f2de448f311807e2493f2a37a980e2d872b229 -Author: Mark Wielaard -Date: Thu Nov 3 13:38:45 2022 +0100 - - readelf: Check phdr != NULL or shdr != NULL in handle_dynamic. - - The compiler doesn't know that when use_dynamic_segment is true, - then phdr should/will be non-NULL and otherwise shdr is non-NULL. - Add explicit checks to help the compiler out and in case an error - is made calling the handle_dynamic function. - - Signed-off-by: Mark Wielaard - -diff --git a/src/readelf.c b/src/readelf.c -index 0e0b05c4..e721a209 100644 ---- a/src/readelf.c -+++ b/src/readelf.c -@@ -1828,7 +1828,7 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, GElf_Phdr *phdr) - size_t dyn_ents; - - /* Get the data of the section. */ -- if (use_dynamic_segment) -+ if (use_dynamic_segment && phdr != NULL) - data = elf_getdata_rawchunk(ebl->elf, phdr->p_offset, - phdr->p_filesz, ELF_T_DYN); - else -@@ -1840,7 +1840,7 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, GElf_Phdr *phdr) - /* Get the dynamic section entry number */ - dyn_ents = get_dyn_ents (data); - -- if (!use_dynamic_segment) -+ if (!use_dynamic_segment && shdr != NULL) - { - /* Get the section header string table index. */ - if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) -@@ -1862,7 +1862,7 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, GElf_Phdr *phdr) - (int) shdr->sh_link, - elf_strptr (ebl->elf, shstrndx, glink->sh_name)); - } -- else -+ else if (phdr != NULL) - { - printf (ngettext ("\ - \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 "\n", -@@ -1879,7 +1879,7 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, GElf_Phdr *phdr) - /* if --use-dynamic option is enabled, - use the string table to get the related library info. */ - Elf_Data *strtab_data = NULL; -- if (use_dynamic_segment) -+ if (use_dynamic_segment && phdr != NULL) - { - strtab_data = get_dynscn_strtab(ebl->elf, phdr); - if (strtab_data == NULL) -@@ -1903,7 +1903,7 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, GElf_Phdr *phdr) - || dyn->d_tag == DT_RPATH - || dyn->d_tag == DT_RUNPATH) - { -- if (! use_dynamic_segment) -+ if (! use_dynamic_segment && shdr != NULL) - name = elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val); - else if (dyn->d_un.d_val < strtab_data->d_size - && memrchr (strtab_data->d_buf + dyn->d_un.d_val, '\0', - -commit b0a0235771906e3bcd6174c4e3c020b5522b0be5 -Author: Mark Wielaard -Date: Thu Nov 3 13:44:35 2022 +0100 - - libdw: Don't dereference and assign values we are skipping - - We don't use the FDE address encoding byte, so no reason - to read and store it. Just skip past it. - - Signed-off-by: Mark Wielaard - -diff --git a/libdw/dwarf_next_cfi.c b/libdw/dwarf_next_cfi.c -index 23b16885..be08984f 100644 ---- a/libdw/dwarf_next_cfi.c -+++ b/libdw/dwarf_next_cfi.c -@@ -226,7 +226,7 @@ dwarf_next_cfi (const unsigned char e_ident[], - if (sized_augmentation) - { - /* Skip FDE address encoding byte. */ -- encoding = *bytes++; -+ bytes++; - continue; - } - break; - -commit 52a6a3110e019d696284fdd822c2a2f0987dded2 -Author: Mark Wielaard -Date: Thu Nov 3 13:52:32 2022 +0100 - - readelf: Check gelf_getdyn doesn't return NULL - - Signed-off-by: Mark Wielaard - -diff --git a/src/readelf.c b/src/readelf.c -index e721a209..3dafb041 100644 ---- a/src/readelf.c -+++ b/src/readelf.c -@@ -4910,7 +4910,7 @@ get_dynscn_addrs(Elf *elf, GElf_Phdr *phdr, GElf_Addr addrs[i_max]) - GElf_Dyn dyn_mem; - GElf_Dyn *dyn = gelf_getdyn(data, dyn_idx, &dyn_mem); - /* DT_NULL Marks end of dynamic section. */ -- if (dyn->d_tag == DT_NULL) -+ if (dyn == NULL || dyn->d_tag == DT_NULL) - break; - - switch (dyn->d_tag) { diff --git a/elfutils-0.188-debuginfod-client-lifetime.patch b/elfutils-0.188-debuginfod-client-lifetime.patch deleted file mode 100644 index 4c8f735..0000000 --- a/elfutils-0.188-debuginfod-client-lifetime.patch +++ /dev/null @@ -1,171 +0,0 @@ -commit c424e5f3d24f76e01242d15ba361dc6234706fed -Author: Frank Ch. Eigler -Date: Thu Nov 3 10:07:31 2022 -0400 - - debuginfod.cxx: fix coverity-found use-after-release error - - The debuginfod_client object lifetime needs more careful handling, - made easier with the defer_dtor<> gadget. - - Signed-off-by: Frank Ch. Eigler - -diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx -index f46da6ef..02a11477 100644 ---- a/debuginfod/debuginfod.cxx -+++ b/debuginfod/debuginfod.cxx -@@ -2249,85 +2249,82 @@ handle_buildid (MHD_Connection* conn, - - int fd = -1; - debuginfod_client *client = debuginfod_pool_begin (); -- if (client != NULL) -- { -- debuginfod_set_progressfn (client, & debuginfod_find_progress); -+ if (client == NULL) -+ throw libc_exception(errno, "debuginfod client pool alloc"); -+ defer_dtor client_closer (client, debuginfod_pool_end); -+ -+ debuginfod_set_progressfn (client, & debuginfod_find_progress); - -- if (conn) -- { -- // Transcribe incoming User-Agent: -- string ua = MHD_lookup_connection_value (conn, MHD_HEADER_KIND, "User-Agent") ?: ""; -- string ua_complete = string("User-Agent: ") + ua; -- debuginfod_add_http_header (client, ua_complete.c_str()); -- -- // Compute larger XFF:, for avoiding info loss during -- // federation, and for future cyclicity detection. -- string xff = MHD_lookup_connection_value (conn, MHD_HEADER_KIND, "X-Forwarded-For") ?: ""; -- if (xff != "") -- xff += string(", "); // comma separated list -- -- unsigned int xff_count = 0; -- for (auto&& i : xff){ -- if (i == ',') xff_count++; -- } -+ if (conn) -+ { -+ // Transcribe incoming User-Agent: -+ string ua = MHD_lookup_connection_value (conn, MHD_HEADER_KIND, "User-Agent") ?: ""; -+ string ua_complete = string("User-Agent: ") + ua; -+ debuginfod_add_http_header (client, ua_complete.c_str()); -+ -+ // Compute larger XFF:, for avoiding info loss during -+ // federation, and for future cyclicity detection. -+ string xff = MHD_lookup_connection_value (conn, MHD_HEADER_KIND, "X-Forwarded-For") ?: ""; -+ if (xff != "") -+ xff += string(", "); // comma separated list -+ -+ unsigned int xff_count = 0; -+ for (auto&& i : xff){ -+ if (i == ',') xff_count++; -+ } - -- // if X-Forwarded-For: exceeds N hops, -- // do not delegate a local lookup miss to upstream debuginfods. -- if (xff_count >= forwarded_ttl_limit) -- throw reportable_exception(MHD_HTTP_NOT_FOUND, "not found, --forwared-ttl-limit reached \ -+ // if X-Forwarded-For: exceeds N hops, -+ // do not delegate a local lookup miss to upstream debuginfods. -+ if (xff_count >= forwarded_ttl_limit) -+ throw reportable_exception(MHD_HTTP_NOT_FOUND, "not found, --forwared-ttl-limit reached \ - and will not query the upstream servers"); - -- // Compute the client's numeric IP address only - so can't merge with conninfo() -- const union MHD_ConnectionInfo *u = MHD_get_connection_info (conn, -- MHD_CONNECTION_INFO_CLIENT_ADDRESS); -- struct sockaddr *so = u ? u->client_addr : 0; -- char hostname[256] = ""; // RFC1035 -- if (so && so->sa_family == AF_INET) { -- (void) getnameinfo (so, sizeof (struct sockaddr_in), hostname, sizeof (hostname), NULL, 0, -- NI_NUMERICHOST); -- } else if (so && so->sa_family == AF_INET6) { -- struct sockaddr_in6* addr6 = (struct sockaddr_in6*) so; -- if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) { -- struct sockaddr_in addr4; -- memset (&addr4, 0, sizeof(addr4)); -- addr4.sin_family = AF_INET; -- addr4.sin_port = addr6->sin6_port; -- memcpy (&addr4.sin_addr.s_addr, addr6->sin6_addr.s6_addr+12, sizeof(addr4.sin_addr.s_addr)); -- (void) getnameinfo ((struct sockaddr*) &addr4, sizeof (addr4), -- hostname, sizeof (hostname), NULL, 0, -- NI_NUMERICHOST); -- } else { -- (void) getnameinfo (so, sizeof (struct sockaddr_in6), hostname, sizeof (hostname), NULL, 0, -- NI_NUMERICHOST); -- } -- } -- -- string xff_complete = string("X-Forwarded-For: ")+xff+string(hostname); -- debuginfod_add_http_header (client, xff_complete.c_str()); -+ // Compute the client's numeric IP address only - so can't merge with conninfo() -+ const union MHD_ConnectionInfo *u = MHD_get_connection_info (conn, -+ MHD_CONNECTION_INFO_CLIENT_ADDRESS); -+ struct sockaddr *so = u ? u->client_addr : 0; -+ char hostname[256] = ""; // RFC1035 -+ if (so && so->sa_family == AF_INET) { -+ (void) getnameinfo (so, sizeof (struct sockaddr_in), hostname, sizeof (hostname), NULL, 0, -+ NI_NUMERICHOST); -+ } else if (so && so->sa_family == AF_INET6) { -+ struct sockaddr_in6* addr6 = (struct sockaddr_in6*) so; -+ if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) { -+ struct sockaddr_in addr4; -+ memset (&addr4, 0, sizeof(addr4)); -+ addr4.sin_family = AF_INET; -+ addr4.sin_port = addr6->sin6_port; -+ memcpy (&addr4.sin_addr.s_addr, addr6->sin6_addr.s6_addr+12, sizeof(addr4.sin_addr.s_addr)); -+ (void) getnameinfo ((struct sockaddr*) &addr4, sizeof (addr4), -+ hostname, sizeof (hostname), NULL, 0, -+ NI_NUMERICHOST); -+ } else { -+ (void) getnameinfo (so, sizeof (struct sockaddr_in6), hostname, sizeof (hostname), NULL, 0, -+ NI_NUMERICHOST); - } -- -- 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 if (artifacttype == "section") -- fd = debuginfod_find_section (client, -- (const unsigned char*) buildid.c_str(), -- 0, section.c_str(), NULL); -- -+ } -+ -+ string xff_complete = string("X-Forwarded-For: ")+xff+string(hostname); -+ debuginfod_add_http_header (client, xff_complete.c_str()); - } -- else -- fd = -errno; /* Set by debuginfod_begin. */ -- debuginfod_pool_end (client); -- -+ -+ 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 if (artifacttype == "section") -+ fd = debuginfod_find_section (client, -+ (const unsigned char*) buildid.c_str(), -+ 0, section.c_str(), NULL); -+ - if (fd >= 0) - { - if (conn != 0) diff --git a/elfutils-0.188-deprecated-CURLINFO.patch b/elfutils-0.188-deprecated-CURLINFO.patch deleted file mode 100644 index e9bc9a3..0000000 --- a/elfutils-0.188-deprecated-CURLINFO.patch +++ /dev/null @@ -1,49 +0,0 @@ -From d2bf497b12fbd49b4996ccf0744303ffd67735b1 Mon Sep 17 00:00:00 2001 -From: Andrew Paprocki -Date: Wed, 21 Dec 2022 11:15:00 -0500 -Subject: [PATCH 1/8] PR29926: debuginfod: Fix usage of deprecated CURLINFO_* - -The `CURLINFO_SIZE_DOWNLOAD_T` and `CURLINFO_CONTENT_LENGTH_DOWNLOAD_T` -identifiers are `enum`s, not pre-processor definitions, so the current -`#ifdef` logic is not selecting the newer API. This results in the -older identifiers being used and they now generate errors when compiled -against Curl 7.87, which has silently deprecated them, causing GCC to -emit `-Werror=deprecated-declarations`. - -Instead, the newer identifiers were added in Curl 7.55, so explicitly -check for `CURL_AT_LEAST_VERSION(7, 55, 0)` instead of the current -logic. This eliminates the error when compiling against Curl 7.87. - -Ref: https://github.com/curl/curl/pull/1511 - -Signed-off-by: Andrew Paprocki ---- - debuginfod/ChangeLog | 4 ++++ - debuginfod/debuginfod-client.c | 4 ++-- - 2 files changed, 6 insertions(+), 2 deletions(-) - -diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c -index 8873fcc8..692aecce 100644 ---- a/debuginfod/debuginfod-client.c -+++ b/debuginfod/debuginfod-client.c -@@ -1456,7 +1456,7 @@ debuginfod_query_server (debuginfod_client *c, - deflate-compressing proxies, this number is likely to be - unavailable, so -1 may show. */ - CURLcode curl_res; --#ifdef CURLINFO_CONTENT_LENGTH_DOWNLOAD_T -+#if CURL_AT_LEAST_VERSION(7, 55, 0) - curl_off_t cl; - curl_res = curl_easy_getinfo(target_handle, - CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, -@@ -1491,7 +1491,7 @@ debuginfod_query_server (debuginfod_client *c, - if (target_handle) /* we've committed to a server; report its download progress */ - { - CURLcode curl_res; --#ifdef CURLINFO_SIZE_DOWNLOAD_T -+#if CURL_AT_LEAST_VERSION(7, 55, 0) - curl_off_t dl; - curl_res = curl_easy_getinfo(target_handle, - CURLINFO_SIZE_DOWNLOAD_T, --- -2.39.1 - diff --git a/elfutils-0.188-static-extract_section.patch b/elfutils-0.188-static-extract_section.patch deleted file mode 100644 index 6305b3e..0000000 --- a/elfutils-0.188-static-extract_section.patch +++ /dev/null @@ -1,24 +0,0 @@ -commit 58a7aa900bc2d9822b0d0cb596ba95a21ff0fd2d -Author: Mark Wielaard -Date: Wed Nov 2 17:54:11 2022 +0100 - - debuginfod: Mark extract_section function static - - The extract_section function in debuginfod-client.c is an internal - function and should not be exported. Mark it as static. - - Signed-off-by: Mark Wielaard - -diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c -index 0c4a00cf..f48e32cc 100644 ---- a/debuginfod/debuginfod-client.c -+++ b/debuginfod/debuginfod-client.c -@@ -621,7 +621,7 @@ path_escape (const char *src, char *dest) - section name was not found. -EEXIST indicates that the section was - found but had type SHT_NOBITS. */ - --int -+static int - extract_section (int fd, const char *section, char *fd_path, char **usr_path) - { - elf_version (EV_CURRENT); diff --git a/elfutils.spec b/elfutils.spec index 849868f..8d2b05b 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -1,6 +1,6 @@ Name: elfutils -Version: 0.188 -%global baserelease 5 +Version: 0.189 +%global baserelease 1 Release: %{baserelease}%{?dist} URL: http://elfutils.org/ %global source_url ftp://sourceware.org/pub/elfutils/%{version}/ @@ -74,16 +74,6 @@ BuildRequires: gettext-devel # For s390x... FDO package notes are bogus. Patch1: elfutils-0.186-fdo-swap.patch -# Don't export internal function. -Patch2: elfutils-0.188-static-extract_section.patch -# Silence some compiler warnings -Patch3: elfutils-0.188-compile-warnings.patch -# The debuginfod_client object lifetime needs more careful handling -Patch4: elfutils-0.188-debuginfod-client-lifetime.patch -# Various libcurl deprecated constants -Patch5: elfutils-0.188-deprecated-CURLINFO.patch -Patch6: elfutils-0.188-CURL_AT_LEAST_VERSION.patch -Patch7: elfutils-0.188-CURLOPT_PROTOCOLS_STR.patch %description Elfutils is a collection of utilities, including stack (to show @@ -452,6 +442,9 @@ exit 0 %systemd_postun_with_restart debuginfod.service %changelog +* Fri Mar 3 2023 Mark Wielaard - 0.189-1 +- Upgrade to upsteam elfutils 0.189. + * Fri Jan 27 2023 Mark Wielaard - 0.188-5 - Add elfutils-0.188-deprecated-CURLINFO.patch, elfutils-0.188-CURL_AT_LEAST_VERSION.patch and diff --git a/sources b/sources index 04cbb1b..57e5577 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (elfutils-0.188.tar.bz2) = 585551b2d937d19d1becfc2f28935db1dd1a3d25571a62f322b70ac8da98c1a741a55d070327705df6c3e2ee026652e0b9a3c733b050a0b0ec5f2fc75d5b74b5 +SHA512 (elfutils-0.189.tar.bz2) = 93a877e34db93e5498581d0ab2d702b08c0d87e4cafd9cec9d6636dfa85a168095c305c11583a5b0fb79374dd93bc8d0e9ce6016e6c172764bcea12861605b71 From 66e41cec577e0dc194fcf8f2cc971706954e0dd7 Mon Sep 17 00:00:00 2001 From: Martin Cermak Date: Mon, 6 Mar 2023 10:06:48 +0100 Subject: [PATCH 12/25] CI Tests: Fix the debuginfod URL --- tests/Regression/GNU-Attribute-notes-not-recognized/runtest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Regression/GNU-Attribute-notes-not-recognized/runtest.sh b/tests/Regression/GNU-Attribute-notes-not-recognized/runtest.sh index 7b6e187..aaa6c89 100755 --- a/tests/Regression/GNU-Attribute-notes-not-recognized/runtest.sh +++ b/tests/Regression/GNU-Attribute-notes-not-recognized/runtest.sh @@ -43,7 +43,7 @@ rlJournalStart # Let's see if we can chase down needed debuginfo somewhere... # Attempt getting the needed file using debuginfod - export DEBUGINFOD_URLS=http://debuginfod.usersys.redhat.com:3632/ + export DEBUGINFOD_URLS=https://debuginfod.fedoraproject.org/ rlRun "f=\"$f $(debuginfod-find debuginfo /bin/bash)\"" # Attempt getting the needed file by traditional means From 829b595e08d16f53cf70e56a895983d3f583d56d Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sat, 22 Apr 2023 22:23:26 +0200 Subject: [PATCH 13/25] Add elfutils-0.189-c99-compat.patch --- elfutils-0.189-c99-compat.patch | 31 +++++++++++++++++++++++++++++++ elfutils.spec | 5 +++++ 2 files changed, 36 insertions(+) create mode 100644 elfutils-0.189-c99-compat.patch diff --git a/elfutils-0.189-c99-compat.patch b/elfutils-0.189-c99-compat.patch new file mode 100644 index 0000000..4932c2c --- /dev/null +++ b/elfutils-0.189-c99-compat.patch @@ -0,0 +1,31 @@ +From 6e7ac623674242628c9e54892a532d55d3288bb8 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Sat, 22 Apr 2023 21:37:09 +0200 +Subject: [PATCH] testsuite: Avoid C99 compatibility issues in + run-native-test.sh + +Include for the pause function, and add the return type +of main. Avoids an implicit function declaration and implicit int. + +Signed-off-by: Florian Weimer +--- + tests/run-native-test.sh | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tests/run-native-test.sh b/tests/run-native-test.sh +index d19007f2..042a51c6 100755 +--- a/tests/run-native-test.sh ++++ b/tests/run-native-test.sh +@@ -27,7 +27,8 @@ + # in all builds. + + tempfiles native.c native +-echo 'main () { while (1) pause (); }' > native.c ++printf '#include \nint main (void) { while (1) pause (); }\n' \ ++ > native.c + + native=0 + kill_native() +-- +2.31.1 + diff --git a/elfutils.spec b/elfutils.spec index 8d2b05b..8de0442 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -74,6 +74,8 @@ BuildRequires: gettext-devel # For s390x... FDO package notes are bogus. Patch1: elfutils-0.186-fdo-swap.patch +# testsuite: Avoid C99 compatibility issues in run-native-test.sh +Patch2: elfutils-0.189-c99-compat.patch %description Elfutils is a collection of utilities, including stack (to show @@ -442,6 +444,9 @@ exit 0 %systemd_postun_with_restart debuginfod.service %changelog +* Sat Apr 22 2023 Mark Wielaard +- Add elfutils-0.189-c99-compat.patch + * Fri Mar 3 2023 Mark Wielaard - 0.189-1 - Upgrade to upsteam elfutils 0.189. From 4ae92c9668a4ebe1fd1e8c73243c241a660160aa Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sat, 22 Apr 2023 22:28:38 +0200 Subject: [PATCH 14/25] Add elfutils-0.189-elfcompress.patch --- elfutils-0.189-elfcompress.patch | 95 ++++++++++++++++++++++++++++++++ elfutils.spec | 3 + 2 files changed, 98 insertions(+) create mode 100644 elfutils-0.189-elfcompress.patch diff --git a/elfutils-0.189-elfcompress.patch b/elfutils-0.189-elfcompress.patch new file mode 100644 index 0000000..5f0d681 --- /dev/null +++ b/elfutils-0.189-elfcompress.patch @@ -0,0 +1,95 @@ +From ef9164520c81ea61efe88777a8ad61bf17a54201 Mon Sep 17 00:00:00 2001 +From: Mark Wielaard +Date: Sat, 22 Apr 2023 01:26:17 +0200 +Subject: [PATCH] elfcompress: Don't compress if section already compressed + unless forced + +Before commit a5b07cdf9 "support ZSTD compression algorithm" +elfcompress would not try to compress a section if it already +had the requested compression type (or was already uncompressed) +unless the --force flag was given. An else if construct was changed +to an if in the commit causing elfcompress to warn (in verbose mode) +but then still try to (re)compress the section. + +Add an explicit check so if nothing needs (un)compressing, the file +isn't changed. + +The diff looks large, but git diff -b -w is just: + ++ if (force || type != schtype) ++ { + if (shdr->sh_type != SHT_NOBITS + && (shdr->sh_flags & SHF_ALLOC) == 0) + { +@@ -554,6 +556,7 @@ process_file (const char *fname) + printf ("[%zd] %s ignoring %s section\n", ndx, sname, + (shdr->sh_type == SHT_NOBITS ? "no bits" : "allocated")); + } ++ } + +Signed-off-by: Mark Wielaard +--- + src/elfcompress.c | 43 +++++++++++++++++++++++-------------------- + 1 file changed, 23 insertions(+), 20 deletions(-) + +diff --git a/src/elfcompress.c b/src/elfcompress.c +index 18ade66f..f771b92a 100644 +--- a/src/elfcompress.c ++++ b/src/elfcompress.c +@@ -529,30 +529,33 @@ process_file (const char *fname) + } + } + +- if (shdr->sh_type != SHT_NOBITS +- && (shdr->sh_flags & SHF_ALLOC) == 0) ++ if (force || type != schtype) + { +- set_section (sections, ndx); +- /* Check if we might want to change this section name. */ +- if (! adjust_names +- && ((type != ZLIB_GNU +- && startswith (sname, ".zdebug")) +- || (type == ZLIB_GNU +- && startswith (sname, ".debug")))) +- adjust_names = true; +- +- /* We need a buffer this large if we change the names. */ +- if (adjust_names) ++ if (shdr->sh_type != SHT_NOBITS ++ && (shdr->sh_flags & SHF_ALLOC) == 0) + { +- size_t slen = strlen (sname); +- if (slen > maxnamelen) +- maxnamelen = slen; ++ set_section (sections, ndx); ++ /* Check if we might want to change this section name. */ ++ if (! adjust_names ++ && ((type != ZLIB_GNU ++ && startswith (sname, ".zdebug")) ++ || (type == ZLIB_GNU ++ && startswith (sname, ".debug")))) ++ adjust_names = true; ++ ++ /* We need a buffer this large if we change the names. */ ++ if (adjust_names) ++ { ++ size_t slen = strlen (sname); ++ if (slen > maxnamelen) ++ maxnamelen = slen; ++ } + } ++ else ++ if (verbose >= 0) ++ printf ("[%zd] %s ignoring %s section\n", ndx, sname, ++ (shdr->sh_type == SHT_NOBITS ? "no bits" : "allocated")); + } +- else +- if (verbose >= 0) +- printf ("[%zd] %s ignoring %s section\n", ndx, sname, +- (shdr->sh_type == SHT_NOBITS ? "no bits" : "allocated")); + } + + if (shdr->sh_type == SHT_SYMTAB) +-- +2.31.1 + diff --git a/elfutils.spec b/elfutils.spec index 8de0442..f18aea2 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -76,6 +76,8 @@ BuildRequires: gettext-devel Patch1: elfutils-0.186-fdo-swap.patch # testsuite: Avoid C99 compatibility issues in run-native-test.sh Patch2: elfutils-0.189-c99-compat.patch +# elfcompress: Don't compress if section already compressed unless forced +Patch3: elfutils-0.189-elfcompress.patch %description Elfutils is a collection of utilities, including stack (to show @@ -446,6 +448,7 @@ exit 0 %changelog * Sat Apr 22 2023 Mark Wielaard - Add elfutils-0.189-c99-compat.patch +- Add elfutils-0.189-elfcompress.patch * Fri Mar 3 2023 Mark Wielaard - 0.189-1 - Upgrade to upsteam elfutils 0.189. From 25ede0eead897a8a7c79e6d03d76756baa724827 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sat, 22 Apr 2023 22:29:20 +0200 Subject: [PATCH 15/25] 0.189-2 --- elfutils.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elfutils.spec b/elfutils.spec index f18aea2..86f3b34 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -1,6 +1,6 @@ Name: elfutils Version: 0.189 -%global baserelease 1 +%global baserelease 2 Release: %{baserelease}%{?dist} URL: http://elfutils.org/ %global source_url ftp://sourceware.org/pub/elfutils/%{version}/ @@ -446,7 +446,7 @@ exit 0 %systemd_postun_with_restart debuginfod.service %changelog -* Sat Apr 22 2023 Mark Wielaard +* Sat Apr 22 2023 Mark Wielaard - 0.189-2 - Add elfutils-0.189-c99-compat.patch - Add elfutils-0.189-elfcompress.patch From 7c06a3670c42b5b2ec973902e9645dc45d016abd Mon Sep 17 00:00:00 2001 From: Martin Cermak Date: Tue, 25 Apr 2023 12:40:59 +0200 Subject: [PATCH 16/25] CI Tests: Test cover rhbz2188064 --- .../eu-elfcompress-breaks-hard-links/bubble.c | 36 ++++++++++++ .../eu-elfcompress-breaks-hard-links/main.fmf | 15 +++++ .../runtest.sh | 55 +++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 tests/Regression/eu-elfcompress-breaks-hard-links/bubble.c create mode 100644 tests/Regression/eu-elfcompress-breaks-hard-links/main.fmf create mode 100755 tests/Regression/eu-elfcompress-breaks-hard-links/runtest.sh diff --git a/tests/Regression/eu-elfcompress-breaks-hard-links/bubble.c b/tests/Regression/eu-elfcompress-breaks-hard-links/bubble.c new file mode 100644 index 0000000..9ec3260 --- /dev/null +++ b/tests/Regression/eu-elfcompress-breaks-hard-links/bubble.c @@ -0,0 +1,36 @@ +/* Bubble sort code */ + +#include + +int main() +{ + int array[100], n, c, d, swap; + + printf("Enter number of elements\n"); + scanf("%d", &n); + + printf("Enter %d integers\n", n); + + for (c = 0; c < n; c++) + scanf("%d", &array[c]); + + for (c = 0 ; c < n - 1; c++) + { + for (d = 0 ; d < n - c - 1; d++) + { + if (array[d] > array[d+1]) /* For decreasing order use '<' instead of '>' */ + { + swap = array[d]; + array[d] = array[d+1]; + array[d+1] = swap; + } + } + } + + printf("Sorted list in ascending order:\n"); + + for (c = 0; c < n; c++) + printf("%d\n", array[c]); + + return 0; +} diff --git a/tests/Regression/eu-elfcompress-breaks-hard-links/main.fmf b/tests/Regression/eu-elfcompress-breaks-hard-links/main.fmf new file mode 100644 index 0000000..a34c573 --- /dev/null +++ b/tests/Regression/eu-elfcompress-breaks-hard-links/main.fmf @@ -0,0 +1,15 @@ +summary: eu-elfcompress-breaks-hard-links +description: '' +link: + - relates: https://bugzilla.redhat.com/show_bug.cgi?id=2188064 +contact: Martin Cermak +component: + - elfutils +test: ./runtest.sh +framework: beakerlib +recommend: + - elfutils + - gcc +duration: 1h +extra-summary: /tools/elfutils/Regression/eu-elfcompress-breaks-hard-links +extra-task: /tools/elfutils/Regression/eu-elfcompress-breaks-hard-links diff --git a/tests/Regression/eu-elfcompress-breaks-hard-links/runtest.sh b/tests/Regression/eu-elfcompress-breaks-hard-links/runtest.sh new file mode 100755 index 0000000..7709a74 --- /dev/null +++ b/tests/Regression/eu-elfcompress-breaks-hard-links/runtest.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# runtest.sh of /tools/elfutils/Regression/eu-elfcompress-breaks-hard-links +# Description: eu-elfcompress-breaks-hard-links +# Author: Martin Cermak +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2023 Red Hat, Inc. +# +# 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 2 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/. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Include Beaker environment +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +PACKAGE="elfutils" + +rlJournalStart + rlPhaseStartSetup + rlAssertRpm $PACKAGE + rlRun "TMP=$(mktemp -d)" + rlRun "cp bubble.c $TMP/" + rlRun "pushd $TMP" + rlPhaseEnd + + rlPhaseStartTest + rlRun "gcc -o a.out -g bubble.c" + rlRun "ln a.out a.lnk" + rlRun "eu-elfcompress -q -p -t none a.lnk" + rlRun "i0=$(stat -c '%i' a.out)" + rlRun "i1=$(stat -c '%i' a.lnk)" + rlRun "test $i0 -eq $i1" + rlPhaseEnd + + rlPhaseStartCleanup + rlRun "popd" + rlRun "rm -r $TMP" + rlPhaseEnd +rlJournalPrintText +rlJournalEnd From 771965e4bcd3e0041069c05796a15f78e696b74c Mon Sep 17 00:00:00 2001 From: Martin Cermak Date: Tue, 25 Apr 2023 12:50:10 +0200 Subject: [PATCH 17/25] CI Tests: Simplify test for rhbz2188064 --- .../eu-elfcompress-breaks-hard-links/bubble.c | 32 ------------------- 1 file changed, 32 deletions(-) diff --git a/tests/Regression/eu-elfcompress-breaks-hard-links/bubble.c b/tests/Regression/eu-elfcompress-breaks-hard-links/bubble.c index 9ec3260..f8b643a 100644 --- a/tests/Regression/eu-elfcompress-breaks-hard-links/bubble.c +++ b/tests/Regression/eu-elfcompress-breaks-hard-links/bubble.c @@ -1,36 +1,4 @@ -/* Bubble sort code */ - -#include - int main() { - int array[100], n, c, d, swap; - - printf("Enter number of elements\n"); - scanf("%d", &n); - - printf("Enter %d integers\n", n); - - for (c = 0; c < n; c++) - scanf("%d", &array[c]); - - for (c = 0 ; c < n - 1; c++) - { - for (d = 0 ; d < n - c - 1; d++) - { - if (array[d] > array[d+1]) /* For decreasing order use '<' instead of '>' */ - { - swap = array[d]; - array[d] = array[d+1]; - array[d+1] = swap; - } - } - } - - printf("Sorted list in ascending order:\n"); - - for (c = 0; c < n; c++) - printf("%d\n", array[c]); - return 0; } From 87f9e5c38df3d99ffdaf716450e642a8d0138f20 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Thu, 22 Jun 2023 15:08:31 +0200 Subject: [PATCH 18/25] Add elfutils-0.189-elf_getdata_rawchunk.patch --- elfutils-0.189-elf_getdata_rawchunk.patch | 224 ++++++++++++++++++++++ elfutils.spec | 5 + 2 files changed, 229 insertions(+) create mode 100644 elfutils-0.189-elf_getdata_rawchunk.patch diff --git a/elfutils-0.189-elf_getdata_rawchunk.patch b/elfutils-0.189-elf_getdata_rawchunk.patch new file mode 100644 index 0000000..7ce6695 --- /dev/null +++ b/elfutils-0.189-elf_getdata_rawchunk.patch @@ -0,0 +1,224 @@ +From 3aca5b5f1f1617db2220022d9061dcaf129e54c4 Mon Sep 17 00:00:00 2001 +From: Mark Wielaard +Date: Wed, 21 Jun 2023 18:05:12 +0200 +Subject: [PATCH] libelf: Replace list of elf_getdata_rawchunk results with a + tree + +elf_getdata_rawchunks did a linear search to see if a chunk was +already fetched. Replace this list with a binary search tree to make +lookup faster when a lot of Elf_Data_Chunk were created. + + * libelf/libelfP.h (Elf_Data_Chunk): Remove next field. + (struct Elf): Change the rawchunks type from Elf_Data_Chunk * + to void *. + * elf_getdata_rawchunk.c (chunk_compare): New static function. + (elf_getdata_rawchunk): Use tsearch instead of a manual linked + list. + * elf_end.c (free_chunk): New static function. + (elf_end): Call tdestroy instead of walking linked list. + +Signed-off-by: Mark Wielaard +--- + libelf/elf_end.c | 22 +++++++++------- + libelf/elf_getdata_rawchunk.c | 47 +++++++++++++++++++++++++---------- + libelf/libelfP.h | 13 ++++------ + 3 files changed, 52 insertions(+), 30 deletions(-) + +diff --git a/libelf/elf_end.c b/libelf/elf_end.c +index 5c451f36..3e5d4c86 100644 +--- a/libelf/elf_end.c ++++ b/libelf/elf_end.c +@@ -1,5 +1,6 @@ + /* Free resources associated with Elf descriptor. + Copyright (C) 1998,1999,2000,2001,2002,2004,2005,2007,2015,2016 Red Hat, Inc. ++ Copyright (C) 2023 Mark J. Wielaard + This file is part of elfutils. + Written by Ulrich Drepper , 1998. + +@@ -32,12 +33,22 @@ + #endif + + #include ++#include + #include + #include + + #include "libelfP.h" + + ++static void ++free_chunk (void *n) ++{ ++ Elf_Data_Chunk *rawchunk = (Elf_Data_Chunk *)n; ++ if (rawchunk->dummy_scn.flags & ELF_F_MALLOCED) ++ free (rawchunk->data.d.d_buf); ++ free (rawchunk); ++} ++ + int + elf_end (Elf *elf) + { +@@ -112,20 +123,13 @@ elf_end (Elf *elf) + + case ELF_K_ELF: + { +- Elf_Data_Chunk *rawchunks ++ void *rawchunks + = (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.rawchunks) + == offsetof (struct Elf, state.elf64.rawchunks)) + ? elf->state.elf32.rawchunks + : elf->state.elf64.rawchunks); +- while (rawchunks != NULL) +- { +- Elf_Data_Chunk *next = rawchunks->next; +- if (rawchunks->dummy_scn.flags & ELF_F_MALLOCED) +- free (rawchunks->data.d.d_buf); +- free (rawchunks); +- rawchunks = next; +- } ++ tdestroy (rawchunks, free_chunk); + + Elf_ScnList *list = (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.scns) +diff --git a/libelf/elf_getdata_rawchunk.c b/libelf/elf_getdata_rawchunk.c +index 5a35ccdc..cfd40396 100644 +--- a/libelf/elf_getdata_rawchunk.c ++++ b/libelf/elf_getdata_rawchunk.c +@@ -1,6 +1,6 @@ + /* Return converted data from raw chunk of ELF file. + Copyright (C) 2007, 2014, 2015 Red Hat, Inc. +- Copyright (C) 2022 Mark J. Wielaard ++ Copyright (C) 2022, 2023 Mark J. Wielaard + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify +@@ -33,12 +33,28 @@ + + #include + #include ++#include + #include + #include + + #include "libelfP.h" + #include "common.h" + ++static int ++chunk_compare (const void *a, const void *b) ++{ ++ Elf_Data_Chunk *da = (Elf_Data_Chunk *)a; ++ Elf_Data_Chunk *db = (Elf_Data_Chunk *)b; ++ ++ if (da->offset != db->offset) ++ return da->offset - db->offset; ++ ++ if (da->data.d.d_size != db->data.d.d_size) ++ return da->data.d.d_size - db->data.d.d_size; ++ ++ return da->data.d.d_type - db->data.d.d_type; ++} ++ + Elf_Data * + elf_getdata_rawchunk (Elf *elf, int64_t offset, size_t size, Elf_Type type) + { +@@ -75,19 +91,25 @@ elf_getdata_rawchunk (Elf *elf, int64_t offset, size_t size, Elf_Type type) + rwlock_rdlock (elf->lock); + + /* Maybe we already got this chunk? */ +- Elf_Data_Chunk *rawchunks = elf->state.elf.rawchunks; +- while (rawchunks != NULL) ++ Elf_Data_Chunk key; ++ key.offset = offset; ++ key.data.d.d_size = size; ++ key.data.d.d_type = type; ++ Elf_Data_Chunk **found = tsearch (&key, &elf->state.elf.rawchunks, ++ &chunk_compare); ++ if (found == NULL) ++ goto nomem; ++ ++ /* Existing entry. */ ++ if (*found != &key && *found != NULL) + { +- if ((rawchunks->offset == offset || size == 0) +- && rawchunks->data.d.d_size == size +- && rawchunks->data.d.d_type == type) +- { +- result = &rawchunks->data.d; +- goto out; +- } +- rawchunks = rawchunks->next; ++ result = &(*found)->data.d; ++ goto out; + } + ++ /* New entry. */ ++ *found = NULL; ++ + size_t align = __libelf_type_align (elf->class, type); + if (elf->map_address != NULL) + { +@@ -189,8 +211,7 @@ elf_getdata_rawchunk (Elf *elf, int64_t offset, size_t size, Elf_Type type) + rwlock_unlock (elf->lock); + rwlock_wrlock (elf->lock); + +- chunk->next = elf->state.elf.rawchunks; +- elf->state.elf.rawchunks = chunk; ++ *found = chunk; + result = &chunk->data.d; + + out: +diff --git a/libelf/libelfP.h b/libelf/libelfP.h +index 6624f38a..d3c241e5 100644 +--- a/libelf/libelfP.h ++++ b/libelf/libelfP.h +@@ -1,5 +1,6 @@ + /* Internal interfaces for libelf. + Copyright (C) 1998-2010, 2015, 2016 Red Hat, Inc. ++ Copyright (C) 2023 Mark J. Wielaard + This file is part of elfutils. + Contributed by Ulrich Drepper , 1998. + +@@ -262,11 +263,7 @@ typedef struct Elf_ScnList + typedef struct Elf_Data_Chunk + { + Elf_Data_Scn data; +- union +- { +- Elf_Scn dummy_scn; +- struct Elf_Data_Chunk *next; +- }; ++ Elf_Scn dummy_scn; + int64_t offset; /* The original raw offset in the Elf image. */ + } Elf_Data_Chunk; + +@@ -324,7 +321,7 @@ struct Elf + Elf_ScnList *scns_last; /* Last element in the section list. + If NULL the data has not yet been + read from the file. */ +- Elf_Data_Chunk *rawchunks; /* List of elf_getdata_rawchunk results. */ ++ void *rawchunks; /* Tree of elf_getdata_rawchunk results. */ + unsigned int scnincr; /* Number of sections allocate the last + time. */ + int ehdr_flags; /* Flags (dirty) for ELF header. */ +@@ -343,7 +340,7 @@ struct Elf + Elf_ScnList *scns_last; /* Last element in the section list. + If NULL the data has not yet been + read from the file. */ +- Elf_Data_Chunk *rawchunks; /* List of elf_getdata_rawchunk results. */ ++ void *rawchunks; /* Tree of elf_getdata_rawchunk results. */ + unsigned int scnincr; /* Number of sections allocate the last + time. */ + int ehdr_flags; /* Flags (dirty) for ELF header. */ +@@ -368,7 +365,7 @@ struct Elf + Elf_ScnList *scns_last; /* Last element in the section list. + If NULL the data has not yet been + read from the file. */ +- Elf_Data_Chunk *rawchunks; /* List of elf_getdata_rawchunk results. */ ++ void *rawchunks; /* Tree of elf_getdata_rawchunk results. */ + unsigned int scnincr; /* Number of sections allocate the last + time. */ + int ehdr_flags; /* Flags (dirty) for ELF header. */ +-- +2.40.1 + diff --git a/elfutils.spec b/elfutils.spec index 86f3b34..7955ff1 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -78,6 +78,8 @@ Patch1: elfutils-0.186-fdo-swap.patch Patch2: elfutils-0.189-c99-compat.patch # elfcompress: Don't compress if section already compressed unless forced Patch3: elfutils-0.189-elfcompress.patch +# libelf: Replace list of elf_getdata_rawchunk results with a tree +Patch4: elfutils-0.189-elf_getdata_rawchunk.patch %description Elfutils is a collection of utilities, including stack (to show @@ -446,6 +448,9 @@ exit 0 %systemd_postun_with_restart debuginfod.service %changelog +* Thu Jun 22 2023 Mark Wielaard +- Add elfutils-0.189-elf_getdata_rawchunk.patch + * Sat Apr 22 2023 Mark Wielaard - 0.189-2 - Add elfutils-0.189-c99-compat.patch - Add elfutils-0.189-elfcompress.patch From cb376abe7f3e01ac583fed9852f45bc34fac56dd Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Thu, 22 Jun 2023 15:10:49 +0200 Subject: [PATCH 19/25] 0.189-3 - Add elfutils-0.189-debuginfod_config_cache-double-close.patch --- ...debuginfod_config_cache-double-close.patch | 73 +++++++++++++++++++ elfutils.spec | 7 +- 2 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 elfutils-0.189-debuginfod_config_cache-double-close.patch diff --git a/elfutils-0.189-debuginfod_config_cache-double-close.patch b/elfutils-0.189-debuginfod_config_cache-double-close.patch new file mode 100644 index 0000000..3380b71 --- /dev/null +++ b/elfutils-0.189-debuginfod_config_cache-double-close.patch @@ -0,0 +1,73 @@ +diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c +index ef4d47e3..d92d8d62 100644 +--- a/debuginfod/debuginfod-client.c ++++ b/debuginfod/debuginfod-client.c +@@ -248,7 +248,7 @@ debuginfod_write_callback (char *ptr, size_t size, size_t nmemb, void *data) + + /* handle config file read and write */ + static int +-debuginfod_config_cache(char *config_path, ++debuginfod_config_cache(debuginfod_client *c, char *config_path, + long cache_config_default_s, + struct stat *st) + { +@@ -277,17 +277,27 @@ debuginfod_config_cache(char *config_path, + } + + long cache_config; ++ /* PR29696 - NB: When using fdopen, the file descriptor is NOT ++ dup'ed and will be closed when the stream is closed. Manually ++ closing fd after fclose is called will lead to a race condition ++ where, if reused, the file descriptor will compete for its ++ regular use before being incorrectly closed here. */ + FILE *config_file = fdopen(fd, "r"); + if (config_file) + { + if (fscanf(config_file, "%ld", &cache_config) != 1) +- cache_config = cache_config_default_s; +- fclose(config_file); ++ cache_config = cache_config_default_s; ++ if (0 != fclose (config_file) && c->verbose_fd >= 0) ++ dprintf (c->verbose_fd, "fclose failed with %s (err=%d)\n", ++ strerror (errno), errno); + } + else +- cache_config = cache_config_default_s; +- +- close (fd); ++ { ++ cache_config = cache_config_default_s; ++ if (0 != close (fd) && c->verbose_fd >= 0) ++ dprintf (c->verbose_fd, "close failed with %s (err=%d)\n", ++ strerror (errno), errno); ++ } + return cache_config; + } + +@@ -303,7 +313,7 @@ debuginfod_clean_cache(debuginfod_client *c, + struct stat st; + + /* Create new interval file. */ +- rc = debuginfod_config_cache(interval_path, ++ rc = debuginfod_config_cache(c, interval_path, + cache_clean_default_interval_s, &st); + if (rc < 0) + return rc; +@@ -320,7 +330,7 @@ debuginfod_clean_cache(debuginfod_client *c, + utime (interval_path, NULL); + + /* Read max unused age value from config file. */ +- rc = debuginfod_config_cache(max_unused_path, ++ rc = debuginfod_config_cache(c, max_unused_path, + cache_default_max_unused_age_s, &st); + if (rc < 0) + return rc; +@@ -1110,7 +1135,7 @@ debuginfod_query_server (debuginfod_client *c, + + close(fd); /* no need to hold onto the negative-hit file descriptor */ + +- rc = debuginfod_config_cache(cache_miss_path, ++ rc = debuginfod_config_cache(c, cache_miss_path, + cache_miss_default_s, &st); + if (rc < 0) + goto out; diff --git a/elfutils.spec b/elfutils.spec index 7955ff1..c27e88f 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -1,6 +1,6 @@ Name: elfutils Version: 0.189 -%global baserelease 2 +%global baserelease 3 Release: %{baserelease}%{?dist} URL: http://elfutils.org/ %global source_url ftp://sourceware.org/pub/elfutils/%{version}/ @@ -80,6 +80,8 @@ Patch2: elfutils-0.189-c99-compat.patch Patch3: elfutils-0.189-elfcompress.patch # libelf: Replace list of elf_getdata_rawchunk results with a tree Patch4: elfutils-0.189-elf_getdata_rawchunk.patch +# PR29696: Removed secondary fd close in cache config causing race condition +Patch5: elfutils-0.189-debuginfod_config_cache-double-close.patch %description Elfutils is a collection of utilities, including stack (to show @@ -448,8 +450,9 @@ exit 0 %systemd_postun_with_restart debuginfod.service %changelog -* Thu Jun 22 2023 Mark Wielaard +* Thu Jun 22 2023 Mark Wielaard - 0.189-3 - Add elfutils-0.189-elf_getdata_rawchunk.patch +- Add elfutils-0.189-debuginfod_config_cache-double-close.patch * Sat Apr 22 2023 Mark Wielaard - 0.189-2 - Add elfutils-0.189-c99-compat.patch From 62b5826af2a93fa9108d5c1407e6f24ecaa21860 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 19 Jul 2023 18:20:35 +0000 Subject: [PATCH 20/25] Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- elfutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/elfutils.spec b/elfutils.spec index c27e88f..24dc195 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -1,6 +1,6 @@ Name: elfutils Version: 0.189 -%global baserelease 3 +%global baserelease 4 Release: %{baserelease}%{?dist} URL: http://elfutils.org/ %global source_url ftp://sourceware.org/pub/elfutils/%{version}/ @@ -450,6 +450,9 @@ exit 0 %systemd_postun_with_restart debuginfod.service %changelog +* Wed Jul 19 2023 Fedora Release Engineering - 0.189-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + * Thu Jun 22 2023 Mark Wielaard - 0.189-3 - Add elfutils-0.189-elf_getdata_rawchunk.patch - Add elfutils-0.189-debuginfod_config_cache-double-close.patch From 62589988718e8fac4fb39ec5037f51839f05951b Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Thu, 24 Aug 2023 00:16:51 +0200 Subject: [PATCH 21/25] 0.189-5 - Add elfutils-0.189-relr.patch --- elfutils-0.189-relr.patch | 446 ++++++++++++++++++++++++++++++++++++++ elfutils.spec | 7 +- 2 files changed, 452 insertions(+), 1 deletion(-) create mode 100644 elfutils-0.189-relr.patch diff --git a/elfutils-0.189-relr.patch b/elfutils-0.189-relr.patch new file mode 100644 index 0000000..29a7b73 --- /dev/null +++ b/elfutils-0.189-relr.patch @@ -0,0 +1,446 @@ +commit 6ba977ed6c7ac6e51350f2093ebe0b90ff89f90c +Author: Mark Wielaard +Date: Sun Jul 23 23:14:31 2023 +0200 + + libelf, readelf, elflint: Add RELR support + + Handle RELR as defined here: + https://groups.google.com/g/generic-abi/c/bX460iggiKg/m/YT2RrjpMAwAJ + + Introduce new ELF_T_RELR Elf_Type and handle it for SHT_RELR. Check + various properties in elflint. Print RELR relocations in + readelf. Just the entries with -U. Just the addresses with -N. And + addresses pluse symbol/offsets by default. + + * libebl/eblsectiontypename.c (ebl_section_type_name): Add RELR + to knownstype. + * libelf/elf32_updatenull.c (updatenull_wrlock): Handle + sh_entsize for SHT_RELR. + * libelf/gelf.h (Gelf_Relr): New typedef for Elf64_Relr. + * libelf/gelf_fsize.c (__libelf_type_sizes): Add ELF_T_RELR. + * libelf/gelf_xlate.c (__elf_xfctstom): Likewise. + * libelf/gelf_xlate.h: Add RELR as FUNDAMENTAL. + * libelf/libelf.h (Elf_Type): Add ELF_T_RELR. + * libelf/libelfP.h: Define ELF32_FSZ_RELR and ELF64_FSZ_RELR. + * src/elflint.c (check_reloc_shdr): Check she_entsize for + ELF_T_RELR. + (check_relr): New function. + (check_dynamic): Handle DT_RELR. + (special_sections): Add SHT_RELR. + (check_sections): Call check_relr. + * src/readelf.c (print_relocs): Also accept a Dwfl_Module. + (handle_relocs_relr): New function. + (print_dwarf_addr): Make static and declare early. + (process_elf_file): Pass dwflmod to print_relocs. + (handle_dynamic): Handle DT_RELRSZ and DTRELRENT. + + Signed-off-by: Mark Wielaard + +diff --git a/libebl/eblsectiontypename.c b/libebl/eblsectiontypename.c +index 2008b95a..ade25d4a 100644 +--- a/libebl/eblsectiontypename.c ++++ b/libebl/eblsectiontypename.c +@@ -61,7 +61,8 @@ ebl_section_type_name (Ebl *ebl, int section, char *buf, size_t len) + KNOWNSTYPE (FINI_ARRAY), + KNOWNSTYPE (PREINIT_ARRAY), + KNOWNSTYPE (GROUP), +- KNOWNSTYPE (SYMTAB_SHNDX) ++ KNOWNSTYPE (SYMTAB_SHNDX), ++ KNOWNSTYPE (RELR) + }; + + /* Handle standard names. */ +diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c +index 6c06e5e4..c5d26b00 100644 +--- a/libelf/elf32_updatenull.c ++++ b/libelf/elf32_updatenull.c +@@ -256,6 +256,9 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum) + case SHT_SUNW_syminfo: + sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYMINFO, 1); + break; ++ case SHT_RELR: ++ sh_entsize = elf_typesize (LIBELFBITS, ELF_T_RELR, 1); ++ break; + default: + break; + } +diff --git a/libelf/gelf.h b/libelf/gelf.h +index 7a3c87aa..f032d7e1 100644 +--- a/libelf/gelf.h ++++ b/libelf/gelf.h +@@ -82,6 +82,9 @@ typedef Elf64_Rel GElf_Rel; + /* Relocation table entry with addend (in section of type SHT_RELA). */ + typedef Elf64_Rela GElf_Rela; + ++/* Relative relocation entry (in section of type SHT_RELR). */ ++typedef Elf64_Relr Gelf_Relr; ++ + /* Program segment header. */ + typedef Elf64_Phdr GElf_Phdr; + +diff --git a/libelf/gelf_fsize.c b/libelf/gelf_fsize.c +index 493d7916..63bcbae5 100644 +--- a/libelf/gelf_fsize.c ++++ b/libelf/gelf_fsize.c +@@ -69,7 +69,8 @@ const size_t __libelf_type_sizes[ELFCLASSNUM - 1][ELF_T_NUM] = + [ELF_T_LIB] = sizeof (ElfW2(LIBELFBITS, Ext_Lib)), \ + [ELF_T_AUXV] = sizeof (ElfW2(LIBELFBITS, Ext_auxv_t)), \ + [ELF_T_CHDR] = sizeof (ElfW2(LIBELFBITS, Ext_Chdr)), \ +- [ELF_T_GNUHASH] = ELFW2(LIBELFBITS, FSZ_WORD) ++ [ELF_T_GNUHASH] = ELFW2(LIBELFBITS, FSZ_WORD), \ ++ [ELF_T_RELR] = ELFW2(LIBELFBITS, FSZ_RELR) + TYPE_SIZES (32) + }, + [ELFCLASS64 - 1] = { +diff --git a/libelf/gelf_xlate.c b/libelf/gelf_xlate.c +index d8ad0634..749da1a1 100644 +--- a/libelf/gelf_xlate.c ++++ b/libelf/gelf_xlate.c +@@ -204,7 +204,8 @@ const xfct_t __elf_xfctstom[ELFCLASSNUM - 1][ELF_T_NUM] = + [ELF_T_MOVE] = ElfW2(Bits, cvt_Move), \ + [ELF_T_LIB] = ElfW2(Bits, cvt_Lib), \ + [ELF_T_AUXV] = ElfW2(Bits, cvt_auxv_t), \ +- [ELF_T_CHDR] = ElfW2(Bits, cvt_chdr) ++ [ELF_T_CHDR] = ElfW2(Bits, cvt_chdr), \ ++ [ELF_T_RELR] = ElfW2(Bits, cvt_Relr) + define_xfcts (32), + [ELF_T_GNUHASH] = Elf32_cvt_Word + }, +diff --git a/libelf/gelf_xlate.h b/libelf/gelf_xlate.h +index 3c0e4bf6..d5511c34 100644 +--- a/libelf/gelf_xlate.h ++++ b/libelf/gelf_xlate.h +@@ -36,6 +36,7 @@ FUNDAMENTAL (WORD, Word, LIBELFBITS); + FUNDAMENTAL (SWORD, Sword, LIBELFBITS); + FUNDAMENTAL (XWORD, Xword, LIBELFBITS); + FUNDAMENTAL (SXWORD, Sxword, LIBELFBITS); ++FUNDAMENTAL (RELR, Relr, LIBELFBITS); + + /* The structured types. */ + TYPE (Ehdr, LIBELFBITS) +diff --git a/libelf/libelf.h b/libelf/libelf.h +index 2374a48a..2837db72 100644 +--- a/libelf/libelf.h ++++ b/libelf/libelf.h +@@ -124,6 +124,7 @@ typedef enum + ELF_T_CHDR, /* Compressed, Elf32_Chdr, Elf64_Chdr, ... */ + ELF_T_NHDR8, /* Special GNU Properties note. Same as Nhdr, + except padding. */ ++ ELF_T_RELR, /* Relative relocation entry. */ + /* Keep this the last entry. */ + ELF_T_NUM + } Elf_Type; +diff --git a/libelf/libelfP.h b/libelf/libelfP.h +index d3c241e5..96476064 100644 +--- a/libelf/libelfP.h ++++ b/libelf/libelfP.h +@@ -63,6 +63,7 @@ + #define ELF32_FSZ_SWORD 4 + #define ELF32_FSZ_XWORD 8 + #define ELF32_FSZ_SXWORD 8 ++#define ELF32_FSZ_RELR 4 + + /* Same for 64 bits objects. */ + #define ELF64_FSZ_ADDR 8 +@@ -72,6 +73,7 @@ + #define ELF64_FSZ_SWORD 4 + #define ELF64_FSZ_XWORD 8 + #define ELF64_FSZ_SXWORD 8 ++#define ELF64_FSZ_RELR 8 + + + /* This is an extension of the ELF_F_* enumeration. The values here are +diff --git a/src/elflint.c b/src/elflint.c +index dd42dcb4..864de710 100644 +--- a/src/elflint.c ++++ b/src/elflint.c +@@ -1,5 +1,6 @@ + /* Pedantic checking of ELF files compliance with gABI/psABI spec. + Copyright (C) 2001-2015, 2017, 2018 Red Hat, Inc. ++ Copyright (C) 2023 Mark J. Wielaard + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + +@@ -1291,10 +1292,20 @@ section [%2d] '%s': no relocations for merge-able string sections possible\n"), + + size_t sh_entsize = gelf_fsize (ebl->elf, reltype, 1, EV_CURRENT); + if (shdr->sh_entsize != sh_entsize) +- ERROR (_(reltype == ELF_T_RELA ? "\ +-section [%2d] '%s': section entry size does not match ElfXX_Rela\n" : "\ +-section [%2d] '%s': section entry size does not match ElfXX_Rel\n"), +- idx, section_name (ebl, idx)); ++ { ++ if (reltype == ELF_T_RELA) ++ ERROR ("\ ++section [%2d] '%s': section entry size does not match ElfXX_Rela\n", ++ idx, section_name (ebl, idx)); ++ else if (reltype == ELF_T_REL) ++ ERROR ("\ ++section [%2d] '%s': section entry size does not match ElfXX_Rel\n", ++ idx, section_name (ebl, idx)); ++ else ++ ERROR ("\ ++section [%2d] '%s': section entry size does not match ElfXX_Relr\n", ++ idx, section_name (ebl, idx)); ++ } + + /* In preparation of checking whether relocations are text + relocations or not we need to determine whether the file is +@@ -1590,6 +1601,32 @@ section [%2d] '%s': cannot get relocation %zu: %s\n"), + } + } + ++static void ++check_relr (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) ++{ ++ Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); ++ if (data == NULL) ++ { ++ ERROR (_("section [%2d] '%s': cannot get section data\n"), ++ idx, section_name (ebl, idx)); ++ return; ++ } ++ ++ /* Check the fields of the section header. */ ++ GElf_Shdr destshdr_mem; ++ GElf_Shdr *destshdr = NULL; ++ struct loaded_segment *loaded = NULL; ++ check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_RELR, &destshdr, ++ &destshdr_mem, &loaded); ++ ++ /* Just throw them away. */ ++ while (loaded != NULL) ++ { ++ struct loaded_segment *old = loaded; ++ loaded = loaded->next; ++ free (old); ++ } ++} + + /* Number of dynamic sections. */ + static int ndynamic; +@@ -1780,6 +1817,7 @@ section [%2d] '%s': entry %zu: pointer does not match address of section [%2d] ' + case DT_PLTGOT: + case DT_REL: + case DT_RELA: ++ case DT_RELR: + case DT_SYMBOLIC: + case DT_SYMTAB: + case DT_VERDEF: +@@ -3660,6 +3698,7 @@ static const struct + { ".plt", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more tests + { ".preinit_array", 15, SHT_PREINIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, + { ".rela", 5, SHT_RELA, atleast, 0, SHF_ALLOC | SHF_INFO_LINK }, // XXX more tests ++ { ".relr", 5, SHT_RELR, atleast, 0, SHF_ALLOC }, // XXX more tests + { ".rel", 4, SHT_REL, atleast, 0, SHF_ALLOC | SHF_INFO_LINK }, // XXX more tests + { ".rodata", 8, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS }, + { ".rodata1", 9, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS }, +@@ -4182,6 +4221,10 @@ section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"), + check_rel (ebl, ehdr, shdr, cnt); + break; + ++ case SHT_RELR: ++ check_relr (ebl, ehdr, shdr, cnt); ++ break; ++ + case SHT_DYNAMIC: + check_dynamic (ebl, ehdr, shdr, cnt); + break; +diff --git a/src/readelf.c b/src/readelf.c +index eda0ce09..db31ad09 100644 +--- a/src/readelf.c ++++ b/src/readelf.c +@@ -1,5 +1,6 @@ + /* Print information from ELF file in human-readable form. + Copyright (C) 1999-2018 Red Hat, Inc. ++ Copyright (C) 2023 Mark J. Wielaard + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify +@@ -302,11 +302,13 @@ + static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr); + static void print_scngrp (Ebl *ebl); + static void print_dynamic (Ebl *ebl); +-static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr); ++static void print_relocs (Ebl *ebl, Dwfl_Module *mod, GElf_Ehdr *ehdr); + static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, + GElf_Shdr *shdr); + static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, + GElf_Shdr *shdr); ++static void handle_relocs_relr (Ebl *ebl, Dwfl_Module *mod, Elf_Scn *scn, ++ GElf_Shdr *shdr); + static bool print_symtab (Ebl *ebl, int type); + static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); + static void print_verinfo (Ebl *ebl); +@@ -336,6 +339,8 @@ static void dump_data (Ebl *ebl); + static void dump_strings (Ebl *ebl); + static void print_strings (Ebl *ebl); + static void dump_archive_index (Elf *, const char *); ++static void print_dwarf_addr (Dwfl_Module *dwflmod, int address_size, ++ Dwarf_Addr address, Dwarf_Addr raw); + + enum dyn_idx + { +@@ -1052,7 +1057,7 @@ process_elf_file (Dwfl_Module *dwflmod, int fd) + if (print_dynamic_table) + print_dynamic (ebl); + if (print_relocations) +- print_relocs (pure_ebl, ehdr); ++ print_relocs (pure_ebl, dwflmod, ehdr); + if (print_histogram) + handle_hash (ebl); + if (print_symbol_table || print_dynsym_table) +@@ -1971,9 +1976,11 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, GElf_Phdr *phdr) + case DT_RELASZ: + case DT_STRSZ: + case DT_RELSZ: ++ case DT_RELRSZ: + case DT_RELAENT: + case DT_SYMENT: + case DT_RELENT: ++ case DT_RELRENT: + case DT_PLTPADSZ: + case DT_MOVEENT: + case DT_MOVESZ: +@@ -2049,7 +2056,7 @@ print_dynamic (Ebl *ebl) + + /* Print relocations. */ + static void +-print_relocs (Ebl *ebl, GElf_Ehdr *ehdr) ++print_relocs (Ebl *ebl, Dwfl_Module *mod, GElf_Ehdr *ehdr) + { + /* Find all relocation sections and handle them. */ + Elf_Scn *scn = NULL; +@@ -2066,6 +2073,8 @@ print_relocs (Ebl *ebl, GElf_Ehdr *ehdr) + handle_relocs_rel (ebl, ehdr, scn, shdr); + else if (shdr->sh_type == SHT_RELA) + handle_relocs_rela (ebl, ehdr, scn, shdr); ++ else if (shdr->sh_type == SHT_RELR) ++ handle_relocs_relr (ebl, mod, scn, shdr); + } + } + } +@@ -2454,6 +2463,114 @@ handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr) + } + } + ++/* Handle a relocation section. */ ++static void ++handle_relocs_relr (Ebl *ebl, Dwfl_Module *mod, Elf_Scn *scn, GElf_Shdr *shdr) ++{ ++ int class = gelf_getclass (ebl->elf); ++ size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELR, 1, EV_CURRENT); ++ int nentries = shdr->sh_size / sh_entsize; ++ ++ /* Get the data of the section. */ ++ Elf_Data *data = elf_getdata (scn, NULL); ++ if (data == NULL) ++ return; ++ ++ /* Get the section header string table index. */ ++ size_t shstrndx; ++ if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) ++ error_exit (0, _("cannot get section header string table index")); ++ ++ /* A .relr.dyn section does not refer to a specific section. */ ++ printf (ngettext ("\ ++\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n", ++ "\ ++\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n", ++ nentries), ++ (unsigned int) elf_ndxscn (scn), ++ elf_strptr (ebl->elf, shstrndx, shdr->sh_name), ++ shdr->sh_offset, ++ nentries); ++ ++ if (class == ELFCLASS32) ++ { ++ uint32_t base = 0; ++ for (int cnt = 0; cnt < nentries; ++cnt) ++ { ++ Elf32_Word *words = data->d_buf; ++ Elf32_Word entry = words[cnt]; ++ ++ /* Just the raw entries? */ ++ if (print_unresolved_addresses) ++ printf (" %#010" PRIx32 "%s\n", entry, ++ (entry & 1) == 0 ? " *" : ""); ++ else ++ { ++ /* A real address, also sets base. */ ++ if ((entry & 1) == 0) ++ { ++ printf (" "); ++ print_dwarf_addr (mod, 4, entry, entry); ++ printf (" *\n"); ++ ++ base = entry + 4; ++ } ++ else ++ { ++ /* Untangle address from base and bits. */ ++ uint32_t addr; ++ for (addr = base; (entry >>= 1) != 0; addr += 4) ++ if ((entry & 1) != 0) ++ { ++ printf (" "); ++ print_dwarf_addr (mod, 4, addr, addr); ++ printf ("\n"); ++ } ++ base += 4 * (4 * 8 - 1); ++ } ++ } ++ } ++ } ++ else ++ { ++ uint64_t base = 0; ++ for (int cnt = 0; cnt < nentries; ++cnt) ++ { ++ Elf64_Xword *xwords = data->d_buf; ++ Elf64_Xword entry = xwords[cnt]; ++ ++ /* Just the raw entries? */ ++ if (print_unresolved_addresses) ++ printf (" %#018" PRIx64 "%s\n", entry, ++ (entry & 1) == 0 ? " *" : ""); ++ else ++ { ++ /* A real address, also sets base. */ ++ if ((entry & 1) == 0) ++ { ++ printf (" "); ++ print_dwarf_addr (mod, 8, entry, entry); ++ printf (" *\n"); ++ ++ base = entry + 8; ++ } ++ else ++ { ++ /* Untangle address from base and bits. */ ++ uint64_t addr; ++ for (addr = base; (entry >>= 1) != 0; addr += 8) ++ if ((entry & 1) != 0) ++ { ++ printf (" "); ++ print_dwarf_addr (mod, 8, addr, addr); ++ printf ("\n"); ++ } ++ base += 8 * (8 * 8 - 1); ++ } ++ } ++ } ++ } ++} + + /* Print the program header. Return true if a symtab is printed, + false otherwise. */ +@@ -4107,7 +4224,7 @@ get_debug_elf_data (Dwarf *dbg, Ebl *ebl, int idx, Elf_Scn *scn) + return elf_getdata (scn, NULL); + } + +-void ++static void + print_dwarf_addr (Dwfl_Module *dwflmod, + int address_size, Dwarf_Addr address, Dwarf_Addr raw) + { diff --git a/elfutils.spec b/elfutils.spec index 24dc195..2b4cb14 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -1,6 +1,6 @@ Name: elfutils Version: 0.189 -%global baserelease 4 +%global baserelease 5 Release: %{baserelease}%{?dist} URL: http://elfutils.org/ %global source_url ftp://sourceware.org/pub/elfutils/%{version}/ @@ -82,6 +82,8 @@ Patch3: elfutils-0.189-elfcompress.patch Patch4: elfutils-0.189-elf_getdata_rawchunk.patch # PR29696: Removed secondary fd close in cache config causing race condition Patch5: elfutils-0.189-debuginfod_config_cache-double-close.patch +# Bug 28495 - Add support for SHT_RELR to eu-readelf +Patch6: elfutils-0.189-relr.patch %description Elfutils is a collection of utilities, including stack (to show @@ -450,6 +452,9 @@ exit 0 %systemd_postun_with_restart debuginfod.service %changelog +* Wed Aug 23 2023 Mark Wielaard - 0.189-5 +- Add elfutils-0.189-relr.patch + * Wed Jul 19 2023 Fedora Release Engineering - 0.189-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild From 87c5e66753fb9f61bf424d3306f0414e31647aae Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Fri, 25 Aug 2023 01:15:22 +0200 Subject: [PATCH 22/25] 0.189-6 - Update elfutils-0.189-relr.patch --- elfutils-0.189-relr.patch | 39 +++++++++++++++++++++++++++++++-------- elfutils.spec | 5 ++++- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/elfutils-0.189-relr.patch b/elfutils-0.189-relr.patch index 29a7b73..2814104 100644 --- a/elfutils-0.189-relr.patch +++ b/elfutils-0.189-relr.patch @@ -1,4 +1,4 @@ -commit 6ba977ed6c7ac6e51350f2093ebe0b90ff89f90c +commit e7648c87478ccc337c92841c7785387dd391f954 Author: Mark Wielaard Date: Sun Jul 23 23:14:31 2023 +0200 @@ -10,17 +10,18 @@ Date: Sun Jul 23 23:14:31 2023 +0200 Introduce new ELF_T_RELR Elf_Type and handle it for SHT_RELR. Check various properties in elflint. Print RELR relocations in readelf. Just the entries with -U. Just the addresses with -N. And - addresses pluse symbol/offsets by default. + addresses plus symbol/offsets by default. * libebl/eblsectiontypename.c (ebl_section_type_name): Add RELR to knownstype. * libelf/elf32_updatenull.c (updatenull_wrlock): Handle sh_entsize for SHT_RELR. - * libelf/gelf.h (Gelf_Relr): New typedef for Elf64_Relr. + * libelf/gelf.h (GElf_Relr): New typedef for Elf64_Relr. * libelf/gelf_fsize.c (__libelf_type_sizes): Add ELF_T_RELR. * libelf/gelf_xlate.c (__elf_xfctstom): Likewise. * libelf/gelf_xlate.h: Add RELR as FUNDAMENTAL. - * libelf/libelf.h (Elf_Type): Add ELF_T_RELR. + * libelf/libelf.h (Elf_Type): Add ELF_T_RELR. Add RELR + defines/typedefs if undefined in system elf.h. * libelf/libelfP.h: Define ELF32_FSZ_RELR and ELF64_FSZ_RELR. * src/elflint.c (check_reloc_shdr): Check she_entsize for ELF_T_RELR. @@ -34,6 +35,8 @@ Date: Sun Jul 23 23:14:31 2023 +0200 (process_elf_file): Pass dwflmod to print_relocs. (handle_dynamic): Handle DT_RELRSZ and DTRELRENT. + https://sourceware.org/bugzilla/show_bug.cgi?id=28495 + Signed-off-by: Mark Wielaard diff --git a/libebl/eblsectiontypename.c b/libebl/eblsectiontypename.c @@ -65,7 +68,7 @@ index 6c06e5e4..c5d26b00 100644 break; } diff --git a/libelf/gelf.h b/libelf/gelf.h -index 7a3c87aa..f032d7e1 100644 +index 7a3c87aa..1847021e 100644 --- a/libelf/gelf.h +++ b/libelf/gelf.h @@ -82,6 +82,9 @@ typedef Elf64_Rel GElf_Rel; @@ -73,7 +76,7 @@ index 7a3c87aa..f032d7e1 100644 typedef Elf64_Rela GElf_Rela; +/* Relative relocation entry (in section of type SHT_RELR). */ -+typedef Elf64_Relr Gelf_Relr; ++typedef Elf64_Relr GElf_Relr; + /* Program segment header. */ typedef Elf64_Phdr GElf_Phdr; @@ -119,10 +122,30 @@ index 3c0e4bf6..d5511c34 100644 /* The structured types. */ TYPE (Ehdr, LIBELFBITS) diff --git a/libelf/libelf.h b/libelf/libelf.h -index 2374a48a..2837db72 100644 +index 2374a48a..458a1fad 100644 --- a/libelf/libelf.h +++ b/libelf/libelf.h -@@ -124,6 +124,7 @@ typedef enum +@@ -69,6 +69,19 @@ + #define ELFCOMPRESS_ZSTD 2 /* Zstandard algorithm. */ + #endif + ++#ifndef SHT_RELR ++ /* So RELR defines/typedefs can be used even with an old system elf.h. */ ++ #define SHT_RELR 19 /* RELR relative relocations */ ++ ++ /* RELR relocation table entry */ ++ typedef Elf32_Word Elf32_Relr; ++ typedef Elf64_Xword Elf64_Relr; ++ ++ #define DT_RELRSZ 35 /* Total size of RELR relative relocations */ ++ #define DT_RELR 36 /* Address of RELR relative relocations */ ++ #define DT_RELRENT 37 /* Size of one RELR relative relocaction */ ++#endif ++ + #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) + # define __nonnull_attribute__(...) __attribute__ ((__nonnull__ (__VA_ARGS__))) + # define __deprecated_attribute__ __attribute__ ((__deprecated__)) +@@ -124,6 +137,7 @@ typedef enum ELF_T_CHDR, /* Compressed, Elf32_Chdr, Elf64_Chdr, ... */ ELF_T_NHDR8, /* Special GNU Properties note. Same as Nhdr, except padding. */ diff --git a/elfutils.spec b/elfutils.spec index 2b4cb14..c164f1d 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -1,6 +1,6 @@ Name: elfutils Version: 0.189 -%global baserelease 5 +%global baserelease 6 Release: %{baserelease}%{?dist} URL: http://elfutils.org/ %global source_url ftp://sourceware.org/pub/elfutils/%{version}/ @@ -452,6 +452,9 @@ exit 0 %systemd_postun_with_restart debuginfod.service %changelog +* Thu Aug 24 2023 Mark Wielaard - 0.189-6 +- Update elfutils-0.189-relr.patch + * Wed Aug 23 2023 Mark Wielaard - 0.189-5 - Add elfutils-0.189-relr.patch From d6169014dd19a04b254b15f7dbd4ee269b620c9c Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Fri, 3 Nov 2023 21:11:40 +0100 Subject: [PATCH 23/25] 0.190-1 - Upgrade to upstream elfutils 0.190 - Add eu-srcfiles - Drop upstreamed patches elfutils-0.189-relr.patch elfutils-0.189-debuginfod_config_cache-double-close.patch elfutils-0.189-elf_getdata_rawchunk.patch elfutils-0.189-elfcompress.patch elfutils-0.189-c99-compat.patch - Only package debuginfod-client-config.7 manpage for debuginfod-client --- .gitignore | 1 + elfutils-0.189-c99-compat.patch | 31 -- ...debuginfod_config_cache-double-close.patch | 73 --- elfutils-0.189-elf_getdata_rawchunk.patch | 224 --------- elfutils-0.189-elfcompress.patch | 95 ---- elfutils-0.189-relr.patch | 469 ------------------ elfutils.spec | 27 +- sources | 2 +- 8 files changed, 16 insertions(+), 906 deletions(-) delete mode 100644 elfutils-0.189-c99-compat.patch delete mode 100644 elfutils-0.189-debuginfod_config_cache-double-close.patch delete mode 100644 elfutils-0.189-elf_getdata_rawchunk.patch delete mode 100644 elfutils-0.189-elfcompress.patch delete mode 100644 elfutils-0.189-relr.patch diff --git a/.gitignore b/.gitignore index 9d73fa8..eb85273 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ /elfutils-0.187.tar.bz2 /elfutils-0.188.tar.bz2 /elfutils-0.189.tar.bz2 +/elfutils-0.190.tar.bz2 diff --git a/elfutils-0.189-c99-compat.patch b/elfutils-0.189-c99-compat.patch deleted file mode 100644 index 4932c2c..0000000 --- a/elfutils-0.189-c99-compat.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 6e7ac623674242628c9e54892a532d55d3288bb8 Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Sat, 22 Apr 2023 21:37:09 +0200 -Subject: [PATCH] testsuite: Avoid C99 compatibility issues in - run-native-test.sh - -Include for the pause function, and add the return type -of main. Avoids an implicit function declaration and implicit int. - -Signed-off-by: Florian Weimer ---- - tests/run-native-test.sh | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/tests/run-native-test.sh b/tests/run-native-test.sh -index d19007f2..042a51c6 100755 ---- a/tests/run-native-test.sh -+++ b/tests/run-native-test.sh -@@ -27,7 +27,8 @@ - # in all builds. - - tempfiles native.c native --echo 'main () { while (1) pause (); }' > native.c -+printf '#include \nint main (void) { while (1) pause (); }\n' \ -+ > native.c - - native=0 - kill_native() --- -2.31.1 - diff --git a/elfutils-0.189-debuginfod_config_cache-double-close.patch b/elfutils-0.189-debuginfod_config_cache-double-close.patch deleted file mode 100644 index 3380b71..0000000 --- a/elfutils-0.189-debuginfod_config_cache-double-close.patch +++ /dev/null @@ -1,73 +0,0 @@ -diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c -index ef4d47e3..d92d8d62 100644 ---- a/debuginfod/debuginfod-client.c -+++ b/debuginfod/debuginfod-client.c -@@ -248,7 +248,7 @@ debuginfod_write_callback (char *ptr, size_t size, size_t nmemb, void *data) - - /* handle config file read and write */ - static int --debuginfod_config_cache(char *config_path, -+debuginfod_config_cache(debuginfod_client *c, char *config_path, - long cache_config_default_s, - struct stat *st) - { -@@ -277,17 +277,27 @@ debuginfod_config_cache(char *config_path, - } - - long cache_config; -+ /* PR29696 - NB: When using fdopen, the file descriptor is NOT -+ dup'ed and will be closed when the stream is closed. Manually -+ closing fd after fclose is called will lead to a race condition -+ where, if reused, the file descriptor will compete for its -+ regular use before being incorrectly closed here. */ - FILE *config_file = fdopen(fd, "r"); - if (config_file) - { - if (fscanf(config_file, "%ld", &cache_config) != 1) -- cache_config = cache_config_default_s; -- fclose(config_file); -+ cache_config = cache_config_default_s; -+ if (0 != fclose (config_file) && c->verbose_fd >= 0) -+ dprintf (c->verbose_fd, "fclose failed with %s (err=%d)\n", -+ strerror (errno), errno); - } - else -- cache_config = cache_config_default_s; -- -- close (fd); -+ { -+ cache_config = cache_config_default_s; -+ if (0 != close (fd) && c->verbose_fd >= 0) -+ dprintf (c->verbose_fd, "close failed with %s (err=%d)\n", -+ strerror (errno), errno); -+ } - return cache_config; - } - -@@ -303,7 +313,7 @@ debuginfod_clean_cache(debuginfod_client *c, - struct stat st; - - /* Create new interval file. */ -- rc = debuginfod_config_cache(interval_path, -+ rc = debuginfod_config_cache(c, interval_path, - cache_clean_default_interval_s, &st); - if (rc < 0) - return rc; -@@ -320,7 +330,7 @@ debuginfod_clean_cache(debuginfod_client *c, - utime (interval_path, NULL); - - /* Read max unused age value from config file. */ -- rc = debuginfod_config_cache(max_unused_path, -+ rc = debuginfod_config_cache(c, max_unused_path, - cache_default_max_unused_age_s, &st); - if (rc < 0) - return rc; -@@ -1110,7 +1135,7 @@ debuginfod_query_server (debuginfod_client *c, - - close(fd); /* no need to hold onto the negative-hit file descriptor */ - -- rc = debuginfod_config_cache(cache_miss_path, -+ rc = debuginfod_config_cache(c, cache_miss_path, - cache_miss_default_s, &st); - if (rc < 0) - goto out; diff --git a/elfutils-0.189-elf_getdata_rawchunk.patch b/elfutils-0.189-elf_getdata_rawchunk.patch deleted file mode 100644 index 7ce6695..0000000 --- a/elfutils-0.189-elf_getdata_rawchunk.patch +++ /dev/null @@ -1,224 +0,0 @@ -From 3aca5b5f1f1617db2220022d9061dcaf129e54c4 Mon Sep 17 00:00:00 2001 -From: Mark Wielaard -Date: Wed, 21 Jun 2023 18:05:12 +0200 -Subject: [PATCH] libelf: Replace list of elf_getdata_rawchunk results with a - tree - -elf_getdata_rawchunks did a linear search to see if a chunk was -already fetched. Replace this list with a binary search tree to make -lookup faster when a lot of Elf_Data_Chunk were created. - - * libelf/libelfP.h (Elf_Data_Chunk): Remove next field. - (struct Elf): Change the rawchunks type from Elf_Data_Chunk * - to void *. - * elf_getdata_rawchunk.c (chunk_compare): New static function. - (elf_getdata_rawchunk): Use tsearch instead of a manual linked - list. - * elf_end.c (free_chunk): New static function. - (elf_end): Call tdestroy instead of walking linked list. - -Signed-off-by: Mark Wielaard ---- - libelf/elf_end.c | 22 +++++++++------- - libelf/elf_getdata_rawchunk.c | 47 +++++++++++++++++++++++++---------- - libelf/libelfP.h | 13 ++++------ - 3 files changed, 52 insertions(+), 30 deletions(-) - -diff --git a/libelf/elf_end.c b/libelf/elf_end.c -index 5c451f36..3e5d4c86 100644 ---- a/libelf/elf_end.c -+++ b/libelf/elf_end.c -@@ -1,5 +1,6 @@ - /* Free resources associated with Elf descriptor. - Copyright (C) 1998,1999,2000,2001,2002,2004,2005,2007,2015,2016 Red Hat, Inc. -+ Copyright (C) 2023 Mark J. Wielaard - This file is part of elfutils. - Written by Ulrich Drepper , 1998. - -@@ -32,12 +33,22 @@ - #endif - - #include -+#include - #include - #include - - #include "libelfP.h" - - -+static void -+free_chunk (void *n) -+{ -+ Elf_Data_Chunk *rawchunk = (Elf_Data_Chunk *)n; -+ if (rawchunk->dummy_scn.flags & ELF_F_MALLOCED) -+ free (rawchunk->data.d.d_buf); -+ free (rawchunk); -+} -+ - int - elf_end (Elf *elf) - { -@@ -112,20 +123,13 @@ elf_end (Elf *elf) - - case ELF_K_ELF: - { -- Elf_Data_Chunk *rawchunks -+ void *rawchunks - = (elf->class == ELFCLASS32 - || (offsetof (struct Elf, state.elf32.rawchunks) - == offsetof (struct Elf, state.elf64.rawchunks)) - ? elf->state.elf32.rawchunks - : elf->state.elf64.rawchunks); -- while (rawchunks != NULL) -- { -- Elf_Data_Chunk *next = rawchunks->next; -- if (rawchunks->dummy_scn.flags & ELF_F_MALLOCED) -- free (rawchunks->data.d.d_buf); -- free (rawchunks); -- rawchunks = next; -- } -+ tdestroy (rawchunks, free_chunk); - - Elf_ScnList *list = (elf->class == ELFCLASS32 - || (offsetof (struct Elf, state.elf32.scns) -diff --git a/libelf/elf_getdata_rawchunk.c b/libelf/elf_getdata_rawchunk.c -index 5a35ccdc..cfd40396 100644 ---- a/libelf/elf_getdata_rawchunk.c -+++ b/libelf/elf_getdata_rawchunk.c -@@ -1,6 +1,6 @@ - /* Return converted data from raw chunk of ELF file. - Copyright (C) 2007, 2014, 2015 Red Hat, Inc. -- Copyright (C) 2022 Mark J. Wielaard -+ Copyright (C) 2022, 2023 Mark J. Wielaard - This file is part of elfutils. - - This file is free software; you can redistribute it and/or modify -@@ -33,12 +33,28 @@ - - #include - #include -+#include - #include - #include - - #include "libelfP.h" - #include "common.h" - -+static int -+chunk_compare (const void *a, const void *b) -+{ -+ Elf_Data_Chunk *da = (Elf_Data_Chunk *)a; -+ Elf_Data_Chunk *db = (Elf_Data_Chunk *)b; -+ -+ if (da->offset != db->offset) -+ return da->offset - db->offset; -+ -+ if (da->data.d.d_size != db->data.d.d_size) -+ return da->data.d.d_size - db->data.d.d_size; -+ -+ return da->data.d.d_type - db->data.d.d_type; -+} -+ - Elf_Data * - elf_getdata_rawchunk (Elf *elf, int64_t offset, size_t size, Elf_Type type) - { -@@ -75,19 +91,25 @@ elf_getdata_rawchunk (Elf *elf, int64_t offset, size_t size, Elf_Type type) - rwlock_rdlock (elf->lock); - - /* Maybe we already got this chunk? */ -- Elf_Data_Chunk *rawchunks = elf->state.elf.rawchunks; -- while (rawchunks != NULL) -+ Elf_Data_Chunk key; -+ key.offset = offset; -+ key.data.d.d_size = size; -+ key.data.d.d_type = type; -+ Elf_Data_Chunk **found = tsearch (&key, &elf->state.elf.rawchunks, -+ &chunk_compare); -+ if (found == NULL) -+ goto nomem; -+ -+ /* Existing entry. */ -+ if (*found != &key && *found != NULL) - { -- if ((rawchunks->offset == offset || size == 0) -- && rawchunks->data.d.d_size == size -- && rawchunks->data.d.d_type == type) -- { -- result = &rawchunks->data.d; -- goto out; -- } -- rawchunks = rawchunks->next; -+ result = &(*found)->data.d; -+ goto out; - } - -+ /* New entry. */ -+ *found = NULL; -+ - size_t align = __libelf_type_align (elf->class, type); - if (elf->map_address != NULL) - { -@@ -189,8 +211,7 @@ elf_getdata_rawchunk (Elf *elf, int64_t offset, size_t size, Elf_Type type) - rwlock_unlock (elf->lock); - rwlock_wrlock (elf->lock); - -- chunk->next = elf->state.elf.rawchunks; -- elf->state.elf.rawchunks = chunk; -+ *found = chunk; - result = &chunk->data.d; - - out: -diff --git a/libelf/libelfP.h b/libelf/libelfP.h -index 6624f38a..d3c241e5 100644 ---- a/libelf/libelfP.h -+++ b/libelf/libelfP.h -@@ -1,5 +1,6 @@ - /* Internal interfaces for libelf. - Copyright (C) 1998-2010, 2015, 2016 Red Hat, Inc. -+ Copyright (C) 2023 Mark J. Wielaard - This file is part of elfutils. - Contributed by Ulrich Drepper , 1998. - -@@ -262,11 +263,7 @@ typedef struct Elf_ScnList - typedef struct Elf_Data_Chunk - { - Elf_Data_Scn data; -- union -- { -- Elf_Scn dummy_scn; -- struct Elf_Data_Chunk *next; -- }; -+ Elf_Scn dummy_scn; - int64_t offset; /* The original raw offset in the Elf image. */ - } Elf_Data_Chunk; - -@@ -324,7 +321,7 @@ struct Elf - Elf_ScnList *scns_last; /* Last element in the section list. - If NULL the data has not yet been - read from the file. */ -- Elf_Data_Chunk *rawchunks; /* List of elf_getdata_rawchunk results. */ -+ void *rawchunks; /* Tree of elf_getdata_rawchunk results. */ - unsigned int scnincr; /* Number of sections allocate the last - time. */ - int ehdr_flags; /* Flags (dirty) for ELF header. */ -@@ -343,7 +340,7 @@ struct Elf - Elf_ScnList *scns_last; /* Last element in the section list. - If NULL the data has not yet been - read from the file. */ -- Elf_Data_Chunk *rawchunks; /* List of elf_getdata_rawchunk results. */ -+ void *rawchunks; /* Tree of elf_getdata_rawchunk results. */ - unsigned int scnincr; /* Number of sections allocate the last - time. */ - int ehdr_flags; /* Flags (dirty) for ELF header. */ -@@ -368,7 +365,7 @@ struct Elf - Elf_ScnList *scns_last; /* Last element in the section list. - If NULL the data has not yet been - read from the file. */ -- Elf_Data_Chunk *rawchunks; /* List of elf_getdata_rawchunk results. */ -+ void *rawchunks; /* Tree of elf_getdata_rawchunk results. */ - unsigned int scnincr; /* Number of sections allocate the last - time. */ - int ehdr_flags; /* Flags (dirty) for ELF header. */ --- -2.40.1 - diff --git a/elfutils-0.189-elfcompress.patch b/elfutils-0.189-elfcompress.patch deleted file mode 100644 index 5f0d681..0000000 --- a/elfutils-0.189-elfcompress.patch +++ /dev/null @@ -1,95 +0,0 @@ -From ef9164520c81ea61efe88777a8ad61bf17a54201 Mon Sep 17 00:00:00 2001 -From: Mark Wielaard -Date: Sat, 22 Apr 2023 01:26:17 +0200 -Subject: [PATCH] elfcompress: Don't compress if section already compressed - unless forced - -Before commit a5b07cdf9 "support ZSTD compression algorithm" -elfcompress would not try to compress a section if it already -had the requested compression type (or was already uncompressed) -unless the --force flag was given. An else if construct was changed -to an if in the commit causing elfcompress to warn (in verbose mode) -but then still try to (re)compress the section. - -Add an explicit check so if nothing needs (un)compressing, the file -isn't changed. - -The diff looks large, but git diff -b -w is just: - -+ if (force || type != schtype) -+ { - if (shdr->sh_type != SHT_NOBITS - && (shdr->sh_flags & SHF_ALLOC) == 0) - { -@@ -554,6 +556,7 @@ process_file (const char *fname) - printf ("[%zd] %s ignoring %s section\n", ndx, sname, - (shdr->sh_type == SHT_NOBITS ? "no bits" : "allocated")); - } -+ } - -Signed-off-by: Mark Wielaard ---- - src/elfcompress.c | 43 +++++++++++++++++++++++-------------------- - 1 file changed, 23 insertions(+), 20 deletions(-) - -diff --git a/src/elfcompress.c b/src/elfcompress.c -index 18ade66f..f771b92a 100644 ---- a/src/elfcompress.c -+++ b/src/elfcompress.c -@@ -529,30 +529,33 @@ process_file (const char *fname) - } - } - -- if (shdr->sh_type != SHT_NOBITS -- && (shdr->sh_flags & SHF_ALLOC) == 0) -+ if (force || type != schtype) - { -- set_section (sections, ndx); -- /* Check if we might want to change this section name. */ -- if (! adjust_names -- && ((type != ZLIB_GNU -- && startswith (sname, ".zdebug")) -- || (type == ZLIB_GNU -- && startswith (sname, ".debug")))) -- adjust_names = true; -- -- /* We need a buffer this large if we change the names. */ -- if (adjust_names) -+ if (shdr->sh_type != SHT_NOBITS -+ && (shdr->sh_flags & SHF_ALLOC) == 0) - { -- size_t slen = strlen (sname); -- if (slen > maxnamelen) -- maxnamelen = slen; -+ set_section (sections, ndx); -+ /* Check if we might want to change this section name. */ -+ if (! adjust_names -+ && ((type != ZLIB_GNU -+ && startswith (sname, ".zdebug")) -+ || (type == ZLIB_GNU -+ && startswith (sname, ".debug")))) -+ adjust_names = true; -+ -+ /* We need a buffer this large if we change the names. */ -+ if (adjust_names) -+ { -+ size_t slen = strlen (sname); -+ if (slen > maxnamelen) -+ maxnamelen = slen; -+ } - } -+ else -+ if (verbose >= 0) -+ printf ("[%zd] %s ignoring %s section\n", ndx, sname, -+ (shdr->sh_type == SHT_NOBITS ? "no bits" : "allocated")); - } -- else -- if (verbose >= 0) -- printf ("[%zd] %s ignoring %s section\n", ndx, sname, -- (shdr->sh_type == SHT_NOBITS ? "no bits" : "allocated")); - } - - if (shdr->sh_type == SHT_SYMTAB) --- -2.31.1 - diff --git a/elfutils-0.189-relr.patch b/elfutils-0.189-relr.patch deleted file mode 100644 index 2814104..0000000 --- a/elfutils-0.189-relr.patch +++ /dev/null @@ -1,469 +0,0 @@ -commit e7648c87478ccc337c92841c7785387dd391f954 -Author: Mark Wielaard -Date: Sun Jul 23 23:14:31 2023 +0200 - - libelf, readelf, elflint: Add RELR support - - Handle RELR as defined here: - https://groups.google.com/g/generic-abi/c/bX460iggiKg/m/YT2RrjpMAwAJ - - Introduce new ELF_T_RELR Elf_Type and handle it for SHT_RELR. Check - various properties in elflint. Print RELR relocations in - readelf. Just the entries with -U. Just the addresses with -N. And - addresses plus symbol/offsets by default. - - * libebl/eblsectiontypename.c (ebl_section_type_name): Add RELR - to knownstype. - * libelf/elf32_updatenull.c (updatenull_wrlock): Handle - sh_entsize for SHT_RELR. - * libelf/gelf.h (GElf_Relr): New typedef for Elf64_Relr. - * libelf/gelf_fsize.c (__libelf_type_sizes): Add ELF_T_RELR. - * libelf/gelf_xlate.c (__elf_xfctstom): Likewise. - * libelf/gelf_xlate.h: Add RELR as FUNDAMENTAL. - * libelf/libelf.h (Elf_Type): Add ELF_T_RELR. Add RELR - defines/typedefs if undefined in system elf.h. - * libelf/libelfP.h: Define ELF32_FSZ_RELR and ELF64_FSZ_RELR. - * src/elflint.c (check_reloc_shdr): Check she_entsize for - ELF_T_RELR. - (check_relr): New function. - (check_dynamic): Handle DT_RELR. - (special_sections): Add SHT_RELR. - (check_sections): Call check_relr. - * src/readelf.c (print_relocs): Also accept a Dwfl_Module. - (handle_relocs_relr): New function. - (print_dwarf_addr): Make static and declare early. - (process_elf_file): Pass dwflmod to print_relocs. - (handle_dynamic): Handle DT_RELRSZ and DTRELRENT. - - https://sourceware.org/bugzilla/show_bug.cgi?id=28495 - - Signed-off-by: Mark Wielaard - -diff --git a/libebl/eblsectiontypename.c b/libebl/eblsectiontypename.c -index 2008b95a..ade25d4a 100644 ---- a/libebl/eblsectiontypename.c -+++ b/libebl/eblsectiontypename.c -@@ -61,7 +61,8 @@ ebl_section_type_name (Ebl *ebl, int section, char *buf, size_t len) - KNOWNSTYPE (FINI_ARRAY), - KNOWNSTYPE (PREINIT_ARRAY), - KNOWNSTYPE (GROUP), -- KNOWNSTYPE (SYMTAB_SHNDX) -+ KNOWNSTYPE (SYMTAB_SHNDX), -+ KNOWNSTYPE (RELR) - }; - - /* Handle standard names. */ -diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c -index 6c06e5e4..c5d26b00 100644 ---- a/libelf/elf32_updatenull.c -+++ b/libelf/elf32_updatenull.c -@@ -256,6 +256,9 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum) - case SHT_SUNW_syminfo: - sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYMINFO, 1); - break; -+ case SHT_RELR: -+ sh_entsize = elf_typesize (LIBELFBITS, ELF_T_RELR, 1); -+ break; - default: - break; - } -diff --git a/libelf/gelf.h b/libelf/gelf.h -index 7a3c87aa..1847021e 100644 ---- a/libelf/gelf.h -+++ b/libelf/gelf.h -@@ -82,6 +82,9 @@ typedef Elf64_Rel GElf_Rel; - /* Relocation table entry with addend (in section of type SHT_RELA). */ - typedef Elf64_Rela GElf_Rela; - -+/* Relative relocation entry (in section of type SHT_RELR). */ -+typedef Elf64_Relr GElf_Relr; -+ - /* Program segment header. */ - typedef Elf64_Phdr GElf_Phdr; - -diff --git a/libelf/gelf_fsize.c b/libelf/gelf_fsize.c -index 493d7916..63bcbae5 100644 ---- a/libelf/gelf_fsize.c -+++ b/libelf/gelf_fsize.c -@@ -69,7 +69,8 @@ const size_t __libelf_type_sizes[ELFCLASSNUM - 1][ELF_T_NUM] = - [ELF_T_LIB] = sizeof (ElfW2(LIBELFBITS, Ext_Lib)), \ - [ELF_T_AUXV] = sizeof (ElfW2(LIBELFBITS, Ext_auxv_t)), \ - [ELF_T_CHDR] = sizeof (ElfW2(LIBELFBITS, Ext_Chdr)), \ -- [ELF_T_GNUHASH] = ELFW2(LIBELFBITS, FSZ_WORD) -+ [ELF_T_GNUHASH] = ELFW2(LIBELFBITS, FSZ_WORD), \ -+ [ELF_T_RELR] = ELFW2(LIBELFBITS, FSZ_RELR) - TYPE_SIZES (32) - }, - [ELFCLASS64 - 1] = { -diff --git a/libelf/gelf_xlate.c b/libelf/gelf_xlate.c -index d8ad0634..749da1a1 100644 ---- a/libelf/gelf_xlate.c -+++ b/libelf/gelf_xlate.c -@@ -204,7 +204,8 @@ const xfct_t __elf_xfctstom[ELFCLASSNUM - 1][ELF_T_NUM] = - [ELF_T_MOVE] = ElfW2(Bits, cvt_Move), \ - [ELF_T_LIB] = ElfW2(Bits, cvt_Lib), \ - [ELF_T_AUXV] = ElfW2(Bits, cvt_auxv_t), \ -- [ELF_T_CHDR] = ElfW2(Bits, cvt_chdr) -+ [ELF_T_CHDR] = ElfW2(Bits, cvt_chdr), \ -+ [ELF_T_RELR] = ElfW2(Bits, cvt_Relr) - define_xfcts (32), - [ELF_T_GNUHASH] = Elf32_cvt_Word - }, -diff --git a/libelf/gelf_xlate.h b/libelf/gelf_xlate.h -index 3c0e4bf6..d5511c34 100644 ---- a/libelf/gelf_xlate.h -+++ b/libelf/gelf_xlate.h -@@ -36,6 +36,7 @@ FUNDAMENTAL (WORD, Word, LIBELFBITS); - FUNDAMENTAL (SWORD, Sword, LIBELFBITS); - FUNDAMENTAL (XWORD, Xword, LIBELFBITS); - FUNDAMENTAL (SXWORD, Sxword, LIBELFBITS); -+FUNDAMENTAL (RELR, Relr, LIBELFBITS); - - /* The structured types. */ - TYPE (Ehdr, LIBELFBITS) -diff --git a/libelf/libelf.h b/libelf/libelf.h -index 2374a48a..458a1fad 100644 ---- a/libelf/libelf.h -+++ b/libelf/libelf.h -@@ -69,6 +69,19 @@ - #define ELFCOMPRESS_ZSTD 2 /* Zstandard algorithm. */ - #endif - -+#ifndef SHT_RELR -+ /* So RELR defines/typedefs can be used even with an old system elf.h. */ -+ #define SHT_RELR 19 /* RELR relative relocations */ -+ -+ /* RELR relocation table entry */ -+ typedef Elf32_Word Elf32_Relr; -+ typedef Elf64_Xword Elf64_Relr; -+ -+ #define DT_RELRSZ 35 /* Total size of RELR relative relocations */ -+ #define DT_RELR 36 /* Address of RELR relative relocations */ -+ #define DT_RELRENT 37 /* Size of one RELR relative relocaction */ -+#endif -+ - #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) - # define __nonnull_attribute__(...) __attribute__ ((__nonnull__ (__VA_ARGS__))) - # define __deprecated_attribute__ __attribute__ ((__deprecated__)) -@@ -124,6 +137,7 @@ typedef enum - ELF_T_CHDR, /* Compressed, Elf32_Chdr, Elf64_Chdr, ... */ - ELF_T_NHDR8, /* Special GNU Properties note. Same as Nhdr, - except padding. */ -+ ELF_T_RELR, /* Relative relocation entry. */ - /* Keep this the last entry. */ - ELF_T_NUM - } Elf_Type; -diff --git a/libelf/libelfP.h b/libelf/libelfP.h -index d3c241e5..96476064 100644 ---- a/libelf/libelfP.h -+++ b/libelf/libelfP.h -@@ -63,6 +63,7 @@ - #define ELF32_FSZ_SWORD 4 - #define ELF32_FSZ_XWORD 8 - #define ELF32_FSZ_SXWORD 8 -+#define ELF32_FSZ_RELR 4 - - /* Same for 64 bits objects. */ - #define ELF64_FSZ_ADDR 8 -@@ -72,6 +73,7 @@ - #define ELF64_FSZ_SWORD 4 - #define ELF64_FSZ_XWORD 8 - #define ELF64_FSZ_SXWORD 8 -+#define ELF64_FSZ_RELR 8 - - - /* This is an extension of the ELF_F_* enumeration. The values here are -diff --git a/src/elflint.c b/src/elflint.c -index dd42dcb4..864de710 100644 ---- a/src/elflint.c -+++ b/src/elflint.c -@@ -1,5 +1,6 @@ - /* Pedantic checking of ELF files compliance with gABI/psABI spec. - Copyright (C) 2001-2015, 2017, 2018 Red Hat, Inc. -+ Copyright (C) 2023 Mark J. Wielaard - This file is part of elfutils. - Written by Ulrich Drepper , 2001. - -@@ -1291,10 +1292,20 @@ section [%2d] '%s': no relocations for merge-able string sections possible\n"), - - size_t sh_entsize = gelf_fsize (ebl->elf, reltype, 1, EV_CURRENT); - if (shdr->sh_entsize != sh_entsize) -- ERROR (_(reltype == ELF_T_RELA ? "\ --section [%2d] '%s': section entry size does not match ElfXX_Rela\n" : "\ --section [%2d] '%s': section entry size does not match ElfXX_Rel\n"), -- idx, section_name (ebl, idx)); -+ { -+ if (reltype == ELF_T_RELA) -+ ERROR ("\ -+section [%2d] '%s': section entry size does not match ElfXX_Rela\n", -+ idx, section_name (ebl, idx)); -+ else if (reltype == ELF_T_REL) -+ ERROR ("\ -+section [%2d] '%s': section entry size does not match ElfXX_Rel\n", -+ idx, section_name (ebl, idx)); -+ else -+ ERROR ("\ -+section [%2d] '%s': section entry size does not match ElfXX_Relr\n", -+ idx, section_name (ebl, idx)); -+ } - - /* In preparation of checking whether relocations are text - relocations or not we need to determine whether the file is -@@ -1590,6 +1601,32 @@ section [%2d] '%s': cannot get relocation %zu: %s\n"), - } - } - -+static void -+check_relr (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) -+{ -+ Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); -+ if (data == NULL) -+ { -+ ERROR (_("section [%2d] '%s': cannot get section data\n"), -+ idx, section_name (ebl, idx)); -+ return; -+ } -+ -+ /* Check the fields of the section header. */ -+ GElf_Shdr destshdr_mem; -+ GElf_Shdr *destshdr = NULL; -+ struct loaded_segment *loaded = NULL; -+ check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_RELR, &destshdr, -+ &destshdr_mem, &loaded); -+ -+ /* Just throw them away. */ -+ while (loaded != NULL) -+ { -+ struct loaded_segment *old = loaded; -+ loaded = loaded->next; -+ free (old); -+ } -+} - - /* Number of dynamic sections. */ - static int ndynamic; -@@ -1780,6 +1817,7 @@ section [%2d] '%s': entry %zu: pointer does not match address of section [%2d] ' - case DT_PLTGOT: - case DT_REL: - case DT_RELA: -+ case DT_RELR: - case DT_SYMBOLIC: - case DT_SYMTAB: - case DT_VERDEF: -@@ -3660,6 +3698,7 @@ static const struct - { ".plt", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more tests - { ".preinit_array", 15, SHT_PREINIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, - { ".rela", 5, SHT_RELA, atleast, 0, SHF_ALLOC | SHF_INFO_LINK }, // XXX more tests -+ { ".relr", 5, SHT_RELR, atleast, 0, SHF_ALLOC }, // XXX more tests - { ".rel", 4, SHT_REL, atleast, 0, SHF_ALLOC | SHF_INFO_LINK }, // XXX more tests - { ".rodata", 8, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS }, - { ".rodata1", 9, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS }, -@@ -4182,6 +4221,10 @@ section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"), - check_rel (ebl, ehdr, shdr, cnt); - break; - -+ case SHT_RELR: -+ check_relr (ebl, ehdr, shdr, cnt); -+ break; -+ - case SHT_DYNAMIC: - check_dynamic (ebl, ehdr, shdr, cnt); - break; -diff --git a/src/readelf.c b/src/readelf.c -index eda0ce09..db31ad09 100644 ---- a/src/readelf.c -+++ b/src/readelf.c -@@ -1,5 +1,6 @@ - /* Print information from ELF file in human-readable form. - Copyright (C) 1999-2018 Red Hat, Inc. -+ Copyright (C) 2023 Mark J. Wielaard - This file is part of elfutils. - - This file is free software; you can redistribute it and/or modify -@@ -302,11 +302,13 @@ - static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr); - static void print_scngrp (Ebl *ebl); - static void print_dynamic (Ebl *ebl); --static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr); -+static void print_relocs (Ebl *ebl, Dwfl_Module *mod, GElf_Ehdr *ehdr); - static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, - GElf_Shdr *shdr); - static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, - GElf_Shdr *shdr); -+static void handle_relocs_relr (Ebl *ebl, Dwfl_Module *mod, Elf_Scn *scn, -+ GElf_Shdr *shdr); - static bool print_symtab (Ebl *ebl, int type); - static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); - static void print_verinfo (Ebl *ebl); -@@ -336,6 +339,8 @@ static void dump_data (Ebl *ebl); - static void dump_strings (Ebl *ebl); - static void print_strings (Ebl *ebl); - static void dump_archive_index (Elf *, const char *); -+static void print_dwarf_addr (Dwfl_Module *dwflmod, int address_size, -+ Dwarf_Addr address, Dwarf_Addr raw); - - enum dyn_idx - { -@@ -1052,7 +1057,7 @@ process_elf_file (Dwfl_Module *dwflmod, int fd) - if (print_dynamic_table) - print_dynamic (ebl); - if (print_relocations) -- print_relocs (pure_ebl, ehdr); -+ print_relocs (pure_ebl, dwflmod, ehdr); - if (print_histogram) - handle_hash (ebl); - if (print_symbol_table || print_dynsym_table) -@@ -1971,9 +1976,11 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, GElf_Phdr *phdr) - case DT_RELASZ: - case DT_STRSZ: - case DT_RELSZ: -+ case DT_RELRSZ: - case DT_RELAENT: - case DT_SYMENT: - case DT_RELENT: -+ case DT_RELRENT: - case DT_PLTPADSZ: - case DT_MOVEENT: - case DT_MOVESZ: -@@ -2049,7 +2056,7 @@ print_dynamic (Ebl *ebl) - - /* Print relocations. */ - static void --print_relocs (Ebl *ebl, GElf_Ehdr *ehdr) -+print_relocs (Ebl *ebl, Dwfl_Module *mod, GElf_Ehdr *ehdr) - { - /* Find all relocation sections and handle them. */ - Elf_Scn *scn = NULL; -@@ -2066,6 +2073,8 @@ print_relocs (Ebl *ebl, GElf_Ehdr *ehdr) - handle_relocs_rel (ebl, ehdr, scn, shdr); - else if (shdr->sh_type == SHT_RELA) - handle_relocs_rela (ebl, ehdr, scn, shdr); -+ else if (shdr->sh_type == SHT_RELR) -+ handle_relocs_relr (ebl, mod, scn, shdr); - } - } - } -@@ -2454,6 +2463,114 @@ handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr) - } - } - -+/* Handle a relocation section. */ -+static void -+handle_relocs_relr (Ebl *ebl, Dwfl_Module *mod, Elf_Scn *scn, GElf_Shdr *shdr) -+{ -+ int class = gelf_getclass (ebl->elf); -+ size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELR, 1, EV_CURRENT); -+ int nentries = shdr->sh_size / sh_entsize; -+ -+ /* Get the data of the section. */ -+ Elf_Data *data = elf_getdata (scn, NULL); -+ if (data == NULL) -+ return; -+ -+ /* Get the section header string table index. */ -+ size_t shstrndx; -+ if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) -+ error_exit (0, _("cannot get section header string table index")); -+ -+ /* A .relr.dyn section does not refer to a specific section. */ -+ printf (ngettext ("\ -+\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n", -+ "\ -+\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n", -+ nentries), -+ (unsigned int) elf_ndxscn (scn), -+ elf_strptr (ebl->elf, shstrndx, shdr->sh_name), -+ shdr->sh_offset, -+ nentries); -+ -+ if (class == ELFCLASS32) -+ { -+ uint32_t base = 0; -+ for (int cnt = 0; cnt < nentries; ++cnt) -+ { -+ Elf32_Word *words = data->d_buf; -+ Elf32_Word entry = words[cnt]; -+ -+ /* Just the raw entries? */ -+ if (print_unresolved_addresses) -+ printf (" %#010" PRIx32 "%s\n", entry, -+ (entry & 1) == 0 ? " *" : ""); -+ else -+ { -+ /* A real address, also sets base. */ -+ if ((entry & 1) == 0) -+ { -+ printf (" "); -+ print_dwarf_addr (mod, 4, entry, entry); -+ printf (" *\n"); -+ -+ base = entry + 4; -+ } -+ else -+ { -+ /* Untangle address from base and bits. */ -+ uint32_t addr; -+ for (addr = base; (entry >>= 1) != 0; addr += 4) -+ if ((entry & 1) != 0) -+ { -+ printf (" "); -+ print_dwarf_addr (mod, 4, addr, addr); -+ printf ("\n"); -+ } -+ base += 4 * (4 * 8 - 1); -+ } -+ } -+ } -+ } -+ else -+ { -+ uint64_t base = 0; -+ for (int cnt = 0; cnt < nentries; ++cnt) -+ { -+ Elf64_Xword *xwords = data->d_buf; -+ Elf64_Xword entry = xwords[cnt]; -+ -+ /* Just the raw entries? */ -+ if (print_unresolved_addresses) -+ printf (" %#018" PRIx64 "%s\n", entry, -+ (entry & 1) == 0 ? " *" : ""); -+ else -+ { -+ /* A real address, also sets base. */ -+ if ((entry & 1) == 0) -+ { -+ printf (" "); -+ print_dwarf_addr (mod, 8, entry, entry); -+ printf (" *\n"); -+ -+ base = entry + 8; -+ } -+ else -+ { -+ /* Untangle address from base and bits. */ -+ uint64_t addr; -+ for (addr = base; (entry >>= 1) != 0; addr += 8) -+ if ((entry & 1) != 0) -+ { -+ printf (" "); -+ print_dwarf_addr (mod, 8, addr, addr); -+ printf ("\n"); -+ } -+ base += 8 * (8 * 8 - 1); -+ } -+ } -+ } -+ } -+} - - /* Print the program header. Return true if a symtab is printed, - false otherwise. */ -@@ -4107,7 +4224,7 @@ get_debug_elf_data (Dwarf *dbg, Ebl *ebl, int idx, Elf_Scn *scn) - return elf_getdata (scn, NULL); - } - --void -+static void - print_dwarf_addr (Dwfl_Module *dwflmod, - int address_size, Dwarf_Addr address, Dwarf_Addr raw) - { diff --git a/elfutils.spec b/elfutils.spec index c164f1d..4511694 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -1,6 +1,6 @@ Name: elfutils -Version: 0.189 -%global baserelease 6 +Version: 0.190 +%global baserelease 1 Release: %{baserelease}%{?dist} URL: http://elfutils.org/ %global source_url ftp://sourceware.org/pub/elfutils/%{version}/ @@ -74,16 +74,6 @@ BuildRequires: gettext-devel # For s390x... FDO package notes are bogus. Patch1: elfutils-0.186-fdo-swap.patch -# testsuite: Avoid C99 compatibility issues in run-native-test.sh -Patch2: elfutils-0.189-c99-compat.patch -# elfcompress: Don't compress if section already compressed unless forced -Patch3: elfutils-0.189-elfcompress.patch -# libelf: Replace list of elf_getdata_rawchunk results with a tree -Patch4: elfutils-0.189-elf_getdata_rawchunk.patch -# PR29696: Removed secondary fd close in cache config causing race condition -Patch5: elfutils-0.189-debuginfod_config_cache-double-close.patch -# Bug 28495 - Add support for SHT_RELR to eu-readelf -Patch6: elfutils-0.189-relr.patch %description Elfutils is a collection of utilities, including stack (to show @@ -358,6 +348,7 @@ fi %{_bindir}/eu-ranlib %{_bindir}/eu-readelf %{_bindir}/eu-size +%{_bindir}/eu-srcfiles %{_bindir}/eu-stack %{_bindir}/eu-strings %{_bindir}/eu-strip @@ -428,7 +419,6 @@ fi %{_sysusersdir}/elfutils-debuginfod.conf %endif %{_mandir}/man8/debuginfod*.8* -%{_mandir}/man7/debuginfod*.7* %dir %attr(0700,debuginfod,debuginfod) %{_localstatedir}/cache/debuginfod @@ -452,6 +442,17 @@ exit 0 %systemd_postun_with_restart debuginfod.service %changelog +* Fri Nov 3 2023 Mark Wielaard - 0.190-1 +- Upgrade to upstream elfutils 0.190 +- Add eu-srcfiles +- Drop upstreamed patches + elfutils-0.189-relr.patch + elfutils-0.189-debuginfod_config_cache-double-close.patch + elfutils-0.189-elf_getdata_rawchunk.patch + elfutils-0.189-elfcompress.patch + elfutils-0.189-c99-compat.patch +- Only package debuginfod-client-config.7 manpage for debuginfod-client + * Thu Aug 24 2023 Mark Wielaard - 0.189-6 - Update elfutils-0.189-relr.patch diff --git a/sources b/sources index 57e5577..658148d 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (elfutils-0.189.tar.bz2) = 93a877e34db93e5498581d0ab2d702b08c0d87e4cafd9cec9d6636dfa85a168095c305c11583a5b0fb79374dd93bc8d0e9ce6016e6c172764bcea12861605b71 +SHA512 (elfutils-0.190.tar.bz2) = 9c4f5328097e028286c42f29e39dc3d80914b656cdfbbe05b639e91bc787ae8ae64dd4d69a6e317ce30c01648ded10281b86a51e718295f4c589df1225a48102 From 4bf94eb436332188bd7c35a11ab414aba97697bf Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sat, 4 Nov 2023 01:10:11 +0100 Subject: [PATCH 24/25] 0.190-2 - Update Fedora license tags to spdx license tags --- elfutils.spec | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/elfutils.spec b/elfutils.spec index 4511694..1c8c52f 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -1,10 +1,10 @@ Name: elfutils Version: 0.190 -%global baserelease 1 +%global baserelease 2 Release: %{baserelease}%{?dist} URL: http://elfutils.org/ %global source_url ftp://sourceware.org/pub/elfutils/%{version}/ -License: GPLv3+ and (GPLv2+ or LGPLv3+) and GFDL +License: GPL-3.0-or-later and (GPL-2.0-or-later or LGPL-3.0-or-later) and GFDL-1.3-no-invariants-or-later Source: %{?source_url}%{name}-%{version}.tar.bz2 Source1: elfutils-debuginfod.sysusers Summary: A collection of utilities and DSOs to handle ELF files and DWARF data @@ -85,7 +85,7 @@ elfcompress (to compress or decompress ELF sections). %package libs Summary: Libraries to handle compiled objects -License: GPLv2+ or LGPLv3+ +License: GPL-2.0-or-later or LGPL-3.0-or-later %if 0%{!?_isa:1} Provides: elfutils-libs%{depsuffix} = %{version}-%{release} %endif @@ -108,7 +108,7 @@ libraries. %package devel Summary: Development libraries to handle compiled objects -License: GPLv2+ or LGPLv3+ +License: GPL-2.0-or-later or LGPL-3.0-or-later %if 0%{!?_isa:1} Provides: elfutils-devel%{depsuffix} = %{version}-%{release} %endif @@ -129,7 +129,7 @@ assembler interface. %package libelf Summary: Library to read and write ELF files -License: GPLv2+ or LGPLv3+ +License: GPL-2.0-or-later or LGPL-3.0-or-later %if 0%{!?_isa:1} Provides: elfutils-libelf%{depsuffix} = %{version}-%{release} %endif @@ -143,7 +143,7 @@ elfutils package use it also to generate new ELF files. %package libelf-devel Summary: Development support for libelf -License: GPLv2+ or LGPLv3+ +License: GPL-2.0-or-later or LGPL-3.0-or-later %if 0%{!?_isa:1} Provides: elfutils-libelf-devel%{depsuffix} = %{version}-%{release} %endif @@ -160,7 +160,7 @@ different sections of an ELF file. %if %{provide_yama_scope} %package default-yama-scope Summary: Default yama attach scope sysctl setting -License: GPLv2+ or LGPLv3+ +License: GPL-2.0-or-later or LGPL-3.0-or-later Provides: default-yama-scope BuildArch: noarch # For the sysctl_apply macro we need systemd as build requires. @@ -194,7 +194,7 @@ 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+) +License: GPL-3.0-or-later and (GPL-2.0-or-later or LGPL-3.0-or-later) %if 0%{!?_isa:1} Provides: elfutils-debuginfod-client%{depsuffix} = %{version}-%{release} %endif @@ -204,7 +204,7 @@ Requires: elfutils-libelf%{depsuffix} = %{version}-%{release} %package debuginfod-client-devel Summary: Libraries and headers to build debuginfod client applications -License: GPLv2+ or LGPLv3+ +License: GPL-2.0-or-later or LGPL-3.0-or-later %if 0%{!?_isa:1} Provides: elfutils-debuginfod-client-devel%{depsuffix} = %{version}-%{release} %endif @@ -212,7 +212,7 @@ Requires: elfutils-debuginfod-client%{depsuffix} = %{version}-%{release} %package debuginfod Summary: HTTP ELF/DWARF file server addressed by build-id -License: GPLv3+ +License: GPL-3.0-or-later Requires: elfutils-libs%{depsuffix} = %{version}-%{release} Requires: elfutils-libelf%{depsuffix} = %{version}-%{release} Requires: elfutils-debuginfod-client%{depsuffix} = %{version}-%{release} @@ -442,6 +442,9 @@ exit 0 %systemd_postun_with_restart debuginfod.service %changelog +* Fri Nov 3 2023 Mark Wielaard - 0.190-2 +- Update Fedora license tags to spdx license tags + * Fri Nov 3 2023 Mark Wielaard - 0.190-1 - Upgrade to upstream elfutils 0.190 - Add eu-srcfiles From 67d56959ad806464964319ccd939124357fc95e6 Mon Sep 17 00:00:00 2001 From: Aaron Merey Date: Fri, 24 Nov 2023 14:27:53 -0500 Subject: [PATCH 25/25] 0.190-3 - Add elfutils-0.190-fix-core-noncontig.patch --- elfutils-0.190-fix-core-noncontig.patch | 329 ++++++++++++++++++++++++ elfutils.spec | 10 +- testcore-noncontig.bz2 | Bin 0 -> 54684 bytes 3 files changed, 338 insertions(+), 1 deletion(-) create mode 100644 elfutils-0.190-fix-core-noncontig.patch create mode 100644 testcore-noncontig.bz2 diff --git a/elfutils-0.190-fix-core-noncontig.patch b/elfutils-0.190-fix-core-noncontig.patch new file mode 100644 index 0000000..e8a7f07 --- /dev/null +++ b/elfutils-0.190-fix-core-noncontig.patch @@ -0,0 +1,329 @@ +From 0fba72fed595f77ca19a57553096ce3cc81cf8f3 Mon Sep 17 00:00:00 2001 +From: Aaron Merey +Date: Fri, 24 Nov 2023 14:52:38 -0500 +Subject: [PATCH] libdwfl: Correctly handle corefile non-contiguous segments + +It is possible for segments of different shared libaries to be interleaved +in memory such that the segments of one library are located in between +non-contiguous segments of another library. + +For example, this can be seen with firefox on RHEL 7.9 where multiple +shared libraries could be mapped in between ld-2.17.so segments: + + [...] + 7f0972082000-7f09720a4000 00000000 139264 /usr/lib64/ld-2.17.so + 7f09720a4000-7f09720a5000 00000000 4096 /memfd:mozilla-ipc (deleted) + 7f09720a5000-7f09720a7000 00000000 8192 /memfd:mozilla-ipc (deleted) + 7f09720a7000-7f09720a9000 00000000 8192 /memfd:mozilla-ipc (deleted) + 7f0972134000-7f0972136000 00000000 8192 /usr/lib64/firefox/libmozwayland.so + 7f0972136000-7f0972137000 00002000 4096 /usr/lib64/firefox/libmozwayland.so + 7f0972137000-7f0972138000 00003000 4096 /usr/lib64/firefox/libmozwayland.so + 7f0972138000-7f0972139000 00003000 4096 /usr/lib64/firefox/libmozwayland.so + 7f097213a000-7f0972147000 00000000 53248 /usr/lib64/firefox/libmozsqlite3.so + 7f0972147000-7f097221e000 0000d000 880640 /usr/lib64/firefox/libmozsqlite3.so + 7f097221e000-7f0972248000 000e4000 172032 /usr/lib64/firefox/libmozsqlite3.so + 7f0972248000-7f0972249000 0010e000 4096 /usr/lib64/firefox/libmozsqlite3.so + 7f0972249000-7f097224c000 0010e000 12288 /usr/lib64/firefox/libmozsqlite3.so + 7f097224c000-7f0972250000 00111000 16384 /usr/lib64/firefox/libmozsqlite3.so + 7f0972250000-7f0972253000 00000000 12288 /usr/lib64/firefox/liblgpllibs.so + [...] + 7f09722a3000-7f09722a4000 00021000 4096 /usr/lib64/ld-2.17.so + 7f09722a4000-7f09722a5000 00022000 4096 /usr/lib64/ld-2.17.so + +dwfl_segment_report_module did not account for the possibility of +interleaving non-contiguous segments, resulting in premature closure +of modules as well as failing to report modules. + +Fix this by removing segment skipping in dwfl_segment_report_module. +When dwfl_segment_report_module reported a module, it would return +the index of the segment immediately following the end address of the +current module. Since there's a chance that other modules might fall +within this address range, dwfl_segment_report_module instead returns +the index of the next segment. + +This patch also fixes premature module closure that can occur in +dwfl_segment_report_module when interleaving non-contiguous segments +are found. Previously modules with start and end addresses that overlap +with the current segment would have their build-ids compared with the +current segment's build-id. If there was a mismatch, that module would +be closed. Avoid closing modules in this case when mismatching build-ids +correspond to distinct modules. + +https://sourceware.org/bugzilla/show_bug.cgi?id=30975 + +Signed-off-by: Aaron Merey +--- + libdwfl/dwfl_segment_report_module.c | 37 ++++++++---- + tests/Makefile.am | 8 ++- + tests/dwfl-core-noncontig.c | 82 +++++++++++++++++++++++++++ + tests/run-dwfl-core-noncontig.sh | 63 ++++++++++++++++++++ + 4 files changed, 177 insertions(+), 14 deletions(-) + create mode 100644 tests/dwfl-core-noncontig.c + create mode 100755 tests/run-dwfl-core-noncontig.sh + +diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c +index 3ef62a7d..09ee37b3 100644 +--- a/libdwfl/dwfl_segment_report_module.c ++++ b/libdwfl/dwfl_segment_report_module.c +@@ -737,17 +737,34 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, + && invalid_elf (module->elf, module->disk_file_has_build_id, + &build_id)) + { +- elf_end (module->elf); +- close (module->fd); +- module->elf = NULL; +- module->fd = -1; ++ /* If MODULE's build-id doesn't match the disk file's ++ build-id, close ELF only if MODULE and ELF refer to ++ different builds of files with the same name. This ++ prevents premature closure of the correct ELF in cases ++ where segments of a module are non-contiguous in memory. */ ++ if (name != NULL && module->name[0] != '\0' ++ && strcmp (basename (module->name), basename (name)) == 0) ++ { ++ elf_end (module->elf); ++ close (module->fd); ++ module->elf = NULL; ++ module->fd = -1; ++ } + } +- if (module->elf != NULL) ++ else if (module->elf != NULL) + { +- /* Ignore this found module if it would conflict in address +- space with any already existing module of DWFL. */ ++ /* This module has already been reported. */ + skip_this_module = true; + } ++ else ++ { ++ /* Only report this module if we haven't already done so. */ ++ for (Dwfl_Module *mod = dwfl->modulelist; mod != NULL; ++ mod = mod->next) ++ if (mod->low_addr == module_start ++ && mod->high_addr == module_end) ++ skip_this_module = true; ++ } + } + if (skip_this_module) + goto out; +@@ -781,10 +798,6 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, + } + } + +- /* Our return value now says to skip the segments contained +- within the module. */ +- ndx = addr_segndx (dwfl, segment, module_end, true); +- + /* Examine its .dynamic section to get more interesting details. + If it has DT_SONAME, we'll use that as the module name. + If it has a DT_DEBUG, then it's actually a PIE rather than a DSO. +@@ -929,6 +942,8 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, + ndx = -1; + goto out; + } ++ else ++ ndx++; + + /* We have reported the module. Now let the caller decide whether we + should read the whole thing in right now. */ +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 7fb8efb1..9f8f7698 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -42,7 +42,7 @@ check_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \ + dwfl-bug-addr-overflow arls dwfl-bug-fd-leak \ + dwfl-addr-sect dwfl-bug-report early-offscn \ + dwfl-bug-getmodules dwarf-getmacros dwarf-ranges addrcfi \ +- dwarfcfi \ ++ dwfl-core-noncontig dwarfcfi \ + test-flag-nobits dwarf-getstring rerequest_tag \ + alldts typeiter typeiter2 low_high_pc \ + test-elf_cntl_gelf_getshdr dwflsyms dwfllines \ +@@ -212,7 +212,7 @@ TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \ + $(asm_TESTS) run-disasm-bpf.sh run-low_high_pc-dw-form-indirect.sh \ + run-nvidia-extended-linemap-libdw.sh run-nvidia-extended-linemap-readelf.sh \ + run-readelf-dw-form-indirect.sh run-strip-largealign.sh \ +- run-readelf-Dd.sh ++ run-readelf-Dd.sh run-dwfl-core-noncontig.sh + + if !BIARCH + export ELFUTILS_DISABLE_BIARCH = 1 +@@ -632,7 +632,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \ + run-nvidia-extended-linemap-libdw.sh run-nvidia-extended-linemap-readelf.sh \ + testfile_nvidia_linemap.bz2 \ + testfile-largealign.o.bz2 run-strip-largealign.sh \ +- run-funcretval++11.sh ++ run-funcretval++11.sh \ ++ run-dwfl-core-noncontig.sh testcore-noncontig.bz2 + + + if USE_VALGRIND +@@ -738,6 +739,7 @@ dwfl_bug_fd_leak_LDADD = $(libeu) $(libdw) $(libebl) $(libelf) + dwfl_bug_report_LDADD = $(libdw) $(libebl) $(libelf) + dwfl_bug_getmodules_LDADD = $(libeu) $(libdw) $(libebl) $(libelf) + dwfl_addr_sect_LDADD = $(libeu) $(libdw) $(libebl) $(libelf) $(argp_LDADD) ++dwfl_core_noncontig_LDADD = $(libdw) $(libelf) + dwarf_getmacros_LDADD = $(libdw) + dwarf_ranges_LDADD = $(libdw) + dwarf_getstring_LDADD = $(libdw) +diff --git a/tests/dwfl-core-noncontig.c b/tests/dwfl-core-noncontig.c +new file mode 100644 +index 00000000..04558e28 +--- /dev/null ++++ b/tests/dwfl-core-noncontig.c +@@ -0,0 +1,82 @@ ++/* Test program for dwfl_getmodules bug. ++ Copyright (C) 2008 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 . */ ++ ++#include ++#include ++#include ++#include ++#include ELFUTILS_HEADER(dwfl) ++#include ELFUTILS_HEADER(elf) ++ ++static const Dwfl_Callbacks cb = ++{ ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++}; ++ ++int ++main (int argc, char **argv) ++{ ++ assert (argc == 2); ++ ++ Dwfl *dwfl = dwfl_begin (&cb); ++ ++ int fd = open (argv[1], O_RDONLY); ++ assert (fd != -1); ++ ++ Elf *elf = elf_begin (fd, ELF_C_READ, NULL); ++ (void) dwfl_core_file_report (dwfl, elf, argv[0]); ++ ++ /* testcore-noncontig contains a shared library mapped between ++ non-contiguous segments of another shared library: ++ ++ [...] ++ 7f14e458c000-7f14e45ae000 00000000 139264 /usr/lib64/ld-2.17.so (1) ++ 7f14e4795000-7f14e4798000 00000000 12288 /usr/lib64/firefox/liblgpllibs.so (2) ++ 7f14e4798000-7f14e479d000 00003000 20480 /usr/lib64/firefox/liblgpllibs.so ++ 7f14e479d000-7f14e479f000 00008000 8192 /usr/lib64/firefox/liblgpllibs.so ++ 7f14e479f000-7f14e47a0000 00009000 4096 /usr/lib64/firefox/liblgpllibs.so ++ 7f14e47a0000-7f14e47a1000 0000a000 4096 /usr/lib64/firefox/liblgpllibs.so (3) ++ 7f14e47ad000-7f14e47ae000 00021000 4096 /usr/lib64/ld-2.17.so (4) ++ 7f14e47ae000-7f14e47af000 00022000 4096 /usr/lib64/ld-2.17.so */ ++ ++ /* First segment of the non-contiguous module (1). */ ++ int seg = dwfl_addrsegment (dwfl, 0x7f14e458c000, NULL); ++ assert (seg == 32); ++ ++ /* First segment of the module within the non-contiguous module's address ++ range (2). */ ++ seg = dwfl_addrsegment (dwfl, 0x7f14e4795000, NULL); ++ assert (seg == 33); ++ ++ /* Last segment of the module within the non-contiguous module's ++ address range (3). */ ++ seg = dwfl_addrsegment (dwfl, 0x7f14e47a0000, NULL); ++ assert (seg == 37); ++ ++ /* First segment of non-contiguous module following its address space ++ gap (4). */ ++ seg = dwfl_addrsegment (dwfl, 0x7f14e47ad000, NULL); ++ assert (seg == 40); ++ ++ dwfl_end (dwfl); ++ elf_end (elf); ++ ++ return 0; ++} +diff --git a/tests/run-dwfl-core-noncontig.sh b/tests/run-dwfl-core-noncontig.sh +new file mode 100755 +index 00000000..1245b67f +--- /dev/null ++++ b/tests/run-dwfl-core-noncontig.sh +@@ -0,0 +1,63 @@ ++#! /bin/sh ++# Copyright (C) 2023 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 . ++ ++. $srcdir/test-subr.sh ++ ++# Test whether libdwfl can handle corefiles containing non-contiguous ++# segments where multiple modules are contained within the address ++# space of some other module. ++ ++# testcore-noncontig was generated from the following program with ++# systemd-coredump on RHEL 7.9 Workstation, kernel ++# 3.10.0-1160.105.1.el7.x86_64. liblgpllibs.so was packaged with ++# firefox-115.4.0-1.el7_9.x86_64.rpm. ++ ++# #include ++# #include ++# ++# int main () { ++# dlopen ("/usr/lib64/firefox/liblgpllibs.so", RTLD_GLOBAL | RTLD_NOW); ++# sleep (60); ++# return 0; ++# } ++# ++# gcc -ldl -o test test.c ++ ++tempfiles out ++testfiles testcore-noncontig ++ ++testrun ${abs_builddir}/dwfl-core-noncontig testcore-noncontig ++ ++# Remove parts of the output that could change depending on which ++# libraries are locally installed. ++testrun ${abs_top_builddir}/src/unstrip -n --core testcore-noncontig \ ++ | sed 's/+/ /g' | cut -d " " -f1,3 | sort > out ++ ++testrun_compare cat out <<\EOF ++0x400000 3a1748a544b40a38b3be3d2d13ffa34a2a5a71c0@0x400284 ++0x7f14e357e000 edf51350c7f71496149d064aa8b1441f786df88a@0x7f14e357e1d8 ++0x7f14e3794000 7615604eaf4a068dfae5085444d15c0dee93dfbd@0x7f14e37941d8 ++0x7f14e3a96000 09cfb171310110bc7ea9f4476c9fa044d85baff4@0x7f14e3a96210 ++0x7f14e3d9e000 e10cc8f2b932fc3daeda22f8dac5ebb969524e5b@0x7f14e3d9e248 ++0x7f14e3fba000 fc4fa58e47a5acc137eadb7689bce4357c557a96@0x7f14e3fba280 ++0x7f14e4388000 7f2e9cb0769d7e57bd669b485a74b537b63a57c4@0x7f14e43881d8 ++0x7f14e458c000 62c449974331341bb08dcce3859560a22af1e172@0x7f14e458c1d8 ++0x7f14e4795000 175efdcef445455872a86a6fbee7567ca16a513e@0x7f14e4795248 ++0x7ffcfe59f000 80d79b32785868a2dc10047b39a80d1daec8923d@0x7ffcfe59f328 ++EOF ++ ++exit 0 +-- +2.41.0 + diff --git a/elfutils.spec b/elfutils.spec index 1c8c52f..34ded73 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -1,12 +1,13 @@ Name: elfutils Version: 0.190 -%global baserelease 2 +%global baserelease 3 Release: %{baserelease}%{?dist} URL: http://elfutils.org/ %global source_url ftp://sourceware.org/pub/elfutils/%{version}/ License: GPL-3.0-or-later and (GPL-2.0-or-later or LGPL-3.0-or-later) and GFDL-1.3-no-invariants-or-later Source: %{?source_url}%{name}-%{version}.tar.bz2 Source1: elfutils-debuginfod.sysusers +Source2: testcore-noncontig.bz2 Summary: A collection of utilities and DSOs to handle ELF files and DWARF data # Needed for isa specific Provides and Requires. @@ -74,6 +75,8 @@ BuildRequires: gettext-devel # For s390x... FDO package notes are bogus. Patch1: elfutils-0.186-fdo-swap.patch +# PR30975: Fix handling of corefiles with non-contiguous .so segments. +Patch2: elfutils-0.190-fix-core-noncontig.patch %description Elfutils is a collection of utilities, including stack (to show @@ -258,6 +261,8 @@ autoreconf -f -v -i # are executable. find . -name \*.sh ! -perm -0100 -print | xargs chmod +x +cp %{SOURCE2} tests + %build # Remove -Wall from default flags. The makefiles enable enough warnings # themselves, and they use -Werror. Appending -Wall defeats the cases where @@ -442,6 +447,9 @@ exit 0 %systemd_postun_with_restart debuginfod.service %changelog +* Fri Nov 24 2023 Aaron Merey - 0.190-3 +- Add elfutils-0.190-fix-core-noncontig.patch + * Fri Nov 3 2023 Mark Wielaard - 0.190-2 - Update Fedora license tags to spdx license tags diff --git a/testcore-noncontig.bz2 b/testcore-noncontig.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..514ad010e00499b9a75a98800aa20ec61596d491 GIT binary patch literal 54684 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 @UKR<^xB}Ly6d%v346q%-3;eP-Bq3uzN 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 T*}s3k9B94<(ceDJ6Sest^`bu7 literal 0 HcmV?d00001