From 39b3b73df2e060c32dfc72af30bdfbcd219b2eca Mon Sep 17 00:00:00 2001 From: eabdullin Date: Tue, 14 Nov 2023 19:05:48 +0000 Subject: [PATCH] import UBI elfutils-0.189-3.el8 --- .elfutils.metadata | 2 +- .gitignore | 2 +- SOURCES/elfutils-0.188-compile-warnings.patch | 109 --------- ...ils-0.188-debuginfod-client-lifetime.patch | 171 ------------- ...lfutils-0.188-static-extract_section.patch | 24 -- ...debuginfod_config_cache-double-close.patch | 73 ++++++ .../elfutils-0.189-elf_getdata_rawchunk.patch | 224 ++++++++++++++++++ SOURCES/elfutils-0.189-elfcompress.patch | 95 ++++++++ SPECS/elfutils.spec | 28 ++- 9 files changed, 413 insertions(+), 315 deletions(-) delete mode 100644 SOURCES/elfutils-0.188-compile-warnings.patch delete mode 100644 SOURCES/elfutils-0.188-debuginfod-client-lifetime.patch delete mode 100644 SOURCES/elfutils-0.188-static-extract_section.patch create mode 100644 SOURCES/elfutils-0.189-debuginfod_config_cache-double-close.patch create mode 100644 SOURCES/elfutils-0.189-elf_getdata_rawchunk.patch create mode 100644 SOURCES/elfutils-0.189-elfcompress.patch diff --git a/.elfutils.metadata b/.elfutils.metadata index 8bc5c5d..ebfbe78 100644 --- a/.elfutils.metadata +++ b/.elfutils.metadata @@ -1 +1 @@ -5e23c010b7f9f45140a43e95d8d1f7fb04aa8302 SOURCES/elfutils-0.188.tar.bz2 +a4b4a20bf3976e71c280b6dfb8443dbdcdd3f2f0 SOURCES/elfutils-0.189.tar.bz2 diff --git a/.gitignore b/.gitignore index adbcd0f..67c4f0e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/elfutils-0.188.tar.bz2 +SOURCES/elfutils-0.189.tar.bz2 diff --git a/SOURCES/elfutils-0.188-compile-warnings.patch b/SOURCES/elfutils-0.188-compile-warnings.patch deleted file mode 100644 index 397583f..0000000 --- a/SOURCES/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/SOURCES/elfutils-0.188-debuginfod-client-lifetime.patch b/SOURCES/elfutils-0.188-debuginfod-client-lifetime.patch deleted file mode 100644 index 4c8f735..0000000 --- a/SOURCES/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/SOURCES/elfutils-0.188-static-extract_section.patch b/SOURCES/elfutils-0.188-static-extract_section.patch deleted file mode 100644 index 6305b3e..0000000 --- a/SOURCES/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/SOURCES/elfutils-0.189-debuginfod_config_cache-double-close.patch b/SOURCES/elfutils-0.189-debuginfod_config_cache-double-close.patch new file mode 100644 index 0000000..3380b71 --- /dev/null +++ b/SOURCES/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/SOURCES/elfutils-0.189-elf_getdata_rawchunk.patch b/SOURCES/elfutils-0.189-elf_getdata_rawchunk.patch new file mode 100644 index 0000000..7ce6695 --- /dev/null +++ b/SOURCES/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/SOURCES/elfutils-0.189-elfcompress.patch b/SOURCES/elfutils-0.189-elfcompress.patch new file mode 100644 index 0000000..5f0d681 --- /dev/null +++ b/SOURCES/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/SPECS/elfutils.spec b/SPECS/elfutils.spec index abdf7a7..3f6cd03 100644 --- a/SPECS/elfutils.spec +++ b/SPECS/elfutils.spec @@ -1,5 +1,5 @@ Name: elfutils -Version: 0.188 +Version: 0.189 %global baserelease 3 Release: %{baserelease}%{?dist} URL: http://elfutils.org/ @@ -65,12 +65,12 @@ BuildRequires: gettext-devel # Patches -# Don't export internal function. -Patch1: elfutils-0.188-static-extract_section.patch -# Silence some compiler warnings -Patch2: elfutils-0.188-compile-warnings.patch -# The debuginfod_client object lifetime needs more careful handling -Patch3: elfutils-0.188-debuginfod-client-lifetime.patch +# elfcompress: Don't compress if section already compressed unless forced +Patch1: elfutils-0.189-elfcompress.patch +# libelf: Replace list of elf_getdata_rawchunk results with a tree +Patch2: elfutils-0.189-elf_getdata_rawchunk.patch +# PR29696: Removed secondary fd close in cache config causing race condition +Patch3: elfutils-0.189-debuginfod_config_cache-double-close.patch %description Elfutils is a collection of utilities, including stack (to show @@ -284,9 +284,9 @@ RPM_OPT_FLAGS="${RPM_OPT_FLAGS} -Wformat" trap 'cat config.log' EXIT %if 0%{?centos} >= 8 -%configure CFLAGS="$RPM_OPT_FLAGS -fexceptions" --enable-debuginfod-urls=https://debuginfod.centos.org/ +%configure CFLAGS="$RPM_OPT_FLAGS" --enable-debuginfod-urls=https://debuginfod.centos.org/ %else -%configure CFLAGS="$RPM_OPT_FLAGS -fexceptions" +%configure CFLAGS="$RPM_OPT_FLAGS" %endif trap '' EXIT %make_build @@ -461,6 +461,16 @@ exit 0 %systemd_postun_with_restart debuginfod.service %changelog +* Wed Jun 28 2023 Mark Wielaard - 0.189-3 +- Add elfutils-0.189-elf_getdata_rawchunk.patch +- Add elfutils-0.189-debuginfod_config_cache-double-close.patch + +* Mon Apr 24 2023 Mark Wielaard - 0.189-2 +- Add elfutils-0.189-elfcompress.patch + +* Tue Apr 4 2023 Mark Wielaard - 0.189-1 +- Upgrade to upsteam elfutils 0.189. + * Mon Nov 7 2022 Mark Wielaard - 0.188-3 - Add elfutils-0.188-compile-warnings.patch - Add elfutils-0.188-debuginfod-client-lifetime.patch