- 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
This commit is contained in:
Mark Wielaard 2023-11-03 21:11:40 +01:00
parent 87c5e66753
commit d6169014dd
8 changed files with 16 additions and 906 deletions

1
.gitignore vendored
View File

@ -30,3 +30,4 @@
/elfutils-0.187.tar.bz2
/elfutils-0.188.tar.bz2
/elfutils-0.189.tar.bz2
/elfutils-0.190.tar.bz2

View File

@ -1,31 +0,0 @@
From 6e7ac623674242628c9e54892a532d55d3288bb8 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Sat, 22 Apr 2023 21:37:09 +0200
Subject: [PATCH] testsuite: Avoid C99 compatibility issues in
run-native-test.sh
Include <unistd.h> for the pause function, and add the return type
of main. Avoids an implicit function declaration and implicit int.
Signed-off-by: Florian Weimer <fweimer@redhat.com>
---
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 <unistd.h>\nint main (void) { while (1) pause (); }\n' \
+ > native.c
native=0
kill_native()
--
2.31.1

View File

@ -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;

View File

@ -1,224 +0,0 @@
From 3aca5b5f1f1617db2220022d9061dcaf129e54c4 Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mark@klomp.org>
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 <mark@klomp.org>
---
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 <mark@klomp.org>
This file is part of elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 1998.
@@ -32,12 +33,22 @@
#endif
#include <assert.h>
+#include <search.h>
#include <stddef.h>
#include <stdlib.h>
#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 <mark@klomp.org>
+ Copyright (C) 2022, 2023 Mark J. Wielaard <mark@klomp.org>
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -33,12 +33,28 @@
#include <assert.h>
#include <errno.h>
+#include <search.h>
#include <stdlib.h>
#include <string.h>
#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 <mark@klomp.org>
This file is part of elfutils.
Contributed by Ulrich Drepper <drepper@redhat.com>, 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

View File

@ -1,95 +0,0 @@
From ef9164520c81ea61efe88777a8ad61bf17a54201 Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mark@klomp.org>
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 <mark@klomp.org>
---
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

View File

@ -1,469 +0,0 @@
commit e7648c87478ccc337c92841c7785387dd391f954
Author: Mark Wielaard <mark@klomp.org>
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 <mark@klomp.org>
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 <mark@klomp.org>
This file is part of elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 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 <mark@klomp.org>
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)
{

View File

@ -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 <mjw@fedoraproject.org> - 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 <mjw@fedoraproject.org> - 0.189-6
- Update elfutils-0.189-relr.patch

View File

@ -1 +1 @@
SHA512 (elfutils-0.189.tar.bz2) = 93a877e34db93e5498581d0ab2d702b08c0d87e4cafd9cec9d6636dfa85a168095c305c11583a5b0fb79374dd93bc8d0e9ce6016e6c172764bcea12861605b71
SHA512 (elfutils-0.190.tar.bz2) = 9c4f5328097e028286c42f29e39dc3d80914b656cdfbbe05b639e91bc787ae8ae64dd4d69a6e317ce30c01648ded10281b86a51e718295f4c589df1225a48102