From ef8126868c0b4791a2fcb086d8731a73dda8bf54 Mon Sep 17 00:00:00 2001 From: eabdullin Date: Thu, 28 Mar 2024 10:04:59 +0000 Subject: [PATCH] import CS elfutils-0.190-2.el9 --- .elfutils.metadata | 3 +- .gitignore | 3 +- ...debuginfod_config_cache-double-close.patch | 73 ---- .../elfutils-0.189-elf_getdata_rawchunk.patch | 224 ------------ SOURCES/elfutils-0.189-elfcompress.patch | 95 ----- .../elfutils-0.190-fix-core-noncontig.patch | 329 ++++++++++++++++++ SPECS/elfutils.spec | 30 +- 7 files changed, 353 insertions(+), 404 deletions(-) delete mode 100644 SOURCES/elfutils-0.189-debuginfod_config_cache-double-close.patch delete mode 100644 SOURCES/elfutils-0.189-elf_getdata_rawchunk.patch delete mode 100644 SOURCES/elfutils-0.189-elfcompress.patch create mode 100644 SOURCES/elfutils-0.190-fix-core-noncontig.patch diff --git a/.elfutils.metadata b/.elfutils.metadata index ebfbe78..39deefe 100644 --- a/.elfutils.metadata +++ b/.elfutils.metadata @@ -1 +1,2 @@ -a4b4a20bf3976e71c280b6dfb8443dbdcdd3f2f0 SOURCES/elfutils-0.189.tar.bz2 +b33fdb927bc154f6ca6285194d0e40fb76877dd0 SOURCES/elfutils-0.190.tar.bz2 +f9875667f09b76d7a2c2bf19c9df80a5a95c1824 SOURCES/testcore-noncontig.bz2 diff --git a/.gitignore b/.gitignore index 67c4f0e..e34b6bd 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -SOURCES/elfutils-0.189.tar.bz2 +SOURCES/elfutils-0.190.tar.bz2 +SOURCES/testcore-noncontig.bz2 diff --git a/SOURCES/elfutils-0.189-debuginfod_config_cache-double-close.patch b/SOURCES/elfutils-0.189-debuginfod_config_cache-double-close.patch deleted file mode 100644 index 3380b71..0000000 --- a/SOURCES/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/SOURCES/elfutils-0.189-elf_getdata_rawchunk.patch b/SOURCES/elfutils-0.189-elf_getdata_rawchunk.patch deleted file mode 100644 index 7ce6695..0000000 --- a/SOURCES/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/SOURCES/elfutils-0.189-elfcompress.patch b/SOURCES/elfutils-0.189-elfcompress.patch deleted file mode 100644 index 5f0d681..0000000 --- a/SOURCES/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/SOURCES/elfutils-0.190-fix-core-noncontig.patch b/SOURCES/elfutils-0.190-fix-core-noncontig.patch new file mode 100644 index 0000000..0f99a7c --- /dev/null +++ b/SOURCES/elfutils-0.190-fix-core-noncontig.patch @@ -0,0 +1,329 @@ +From c791d16b7dcf9d985ebe0e852481142753603353 Mon Sep 17 00:00:00 2001 +From: Aaron Merey +Date: Fri, 8 Dec 2023 16:44:35 -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, 176 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 3ef62a7..09ee37b 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 7fb8efb..9f8f769 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 0000000..04558e2 +--- /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 0000000..1245b67 +--- /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.43.0 + diff --git a/SPECS/elfutils.spec b/SPECS/elfutils.spec index 39e7f14..68e0e5c 100644 --- a/SPECS/elfutils.spec +++ b/SPECS/elfutils.spec @@ -1,12 +1,13 @@ Name: elfutils -Version: 0.189 -%global baserelease 3 +Version: 0.190 +%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 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. @@ -72,13 +73,8 @@ BuildRequires: gettext-devel %endif # Patches - -# 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 +# RHEL-18913: Fix handling of corefiles with non-contiguous segments. +Patch1: elfutils-0.190-fix-core-noncontig.patch %description Elfutils is a collection of utilities, including stack (to show @@ -266,6 +262,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 @@ -361,6 +359,7 @@ fi %{_bindir}/eu-ranlib %{_bindir}/eu-readelf %{_bindir}/eu-size +%{_bindir}/eu-srcfiles %{_bindir}/eu-stack %{_bindir}/eu-strings %{_bindir}/eu-strip @@ -431,7 +430,6 @@ fi %{_sysusersdir}/elfutils-debuginfod.conf %endif %{_mandir}/man8/debuginfod*.8* -%{_mandir}/man7/debuginfod*.7* %dir %attr(0700,debuginfod,debuginfod) %{_localstatedir}/cache/debuginfod @@ -455,6 +453,18 @@ exit 0 %systemd_postun_with_restart debuginfod.service %changelog +* Fri Dec 8 2023 Aaron Merey - 0.190-2 +- Add elfutils-0.190-fix-core-noncontig.patch + +* Fri Nov 3 2023 Mark Wielaard - 0.190-1 +- Upgrade to upstream elfutils 0.190 +- Add eu-srcfiles +- Drop upstreamed patches + elfutils-0.189-debuginfod_config_cache-double-close.patch + elfutils-0.189-elf_getdata_rawchunk.patch + elfutils-0.189-elfcompress.patch +- Only package debuginfod-client-config.7 manpage for debuginfod-client + * 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