summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDi Chen <dichen@redhat.com>2022-03-01 20:44:38 +0800
committerMark Wielaard <mark@klomp.org>2022-04-19 10:13:11 +0200
commit5b497d8da4920bf7b63a4aa3752cf580b3ad654c (patch)
tree974a3f31a9a70946bf9bb4aea89af4ad2b7aa210 /src
parent21f089d190ad5f5ebbbbea1a3e1db1acfec1dbe9 (diff)
downloadelfutils-5b497d8da4920bf7b63a4aa3752cf580b3ad654c.tar.gz
readelf: Don't consider padding DT_NULL as dynamic section entry
when using `$ eu-readelf -d {FILE}` to get the number of dynamic section entris, it wrongly counts the padding DT_NULLs as dynamic section entries. However, DT_NULL Marks end of dynamic section. They should not be considered as dynamic section entries. https://sourceware.org/bugzilla/show_bug.cgi?id=28928 Signed-off-by: Di Chen <dichen@redhat.com>
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog6
-rw-r--r--src/readelf.c31
2 files changed, 31 insertions, 6 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index c0a3db3f..f563e993 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
+2022-03-01 Di Chen <dichen@redhat.com>
+
+ * readelf.c (get_dyn_ents): New function.
+ (handle_dynamic): Use get_dyn_ents to get the actual number of
+ Dynamic entries in the section.
+
2022-03-27 Mark Wielaard <mark@klomp.org>
* addr2line.c: Replace error (EXIT_FAILURE, ...) with error_exit(...).
diff --git a/src/readelf.c b/src/readelf.c
index 41d64d32..4b275ece 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -1772,6 +1772,24 @@ print_dt_posflag_1 (int class, GElf_Xword d_val)
}
+static size_t
+get_dyn_ents (Elf_Data * dyn_data)
+{
+ GElf_Dyn *dyn;
+ size_t dyn_idx = 0;
+ do
+ {
+ GElf_Dyn dyn_mem;
+ dyn = gelf_getdyn(dyn_data, dyn_idx, &dyn_mem);
+ if (dyn != NULL)
+ ++dyn_idx;
+ }
+ while (dyn != NULL && dyn->d_tag != DT_NULL);
+
+ return dyn_idx;
+}
+
+
static void
handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
{
@@ -1781,19 +1799,20 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
Elf_Data *data;
size_t cnt;
size_t shstrndx;
- size_t sh_entsize;
+ size_t dyn_ents;
/* Get the data of the section. */
data = elf_getdata (scn, NULL);
if (data == NULL)
return;
+ /* Get the dynamic section entry number */
+ dyn_ents = get_dyn_ents (data);
+
/* Get the section header string table index. */
if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
error_exit (0, _("cannot get section header string table index"));
- sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
-
glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
if (glink == NULL)
error_exit (0, _("invalid sh_link value in section %zu"),
@@ -1803,15 +1822,15 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
\nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
"\
\nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
- shdr->sh_size / sh_entsize),
- (unsigned long int) (shdr->sh_size / sh_entsize),
+ dyn_ents),
+ (unsigned long int) dyn_ents,
class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
shdr->sh_offset,
(int) shdr->sh_link,
elf_strptr (ebl->elf, shstrndx, glink->sh_name));
fputs_unlocked (_(" Type Value\n"), stdout);
- for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
+ for (cnt = 0; cnt < dyn_ents; ++cnt)
{
GElf_Dyn dynmem;
GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);