diff options
author | Di Chen <dichen@redhat.com> | 2022-03-01 20:44:38 +0800 |
---|---|---|
committer | Mark Wielaard <mark@klomp.org> | 2022-04-19 10:13:11 +0200 |
commit | 5b497d8da4920bf7b63a4aa3752cf580b3ad654c (patch) | |
tree | 974a3f31a9a70946bf9bb4aea89af4ad2b7aa210 | |
parent | 21f089d190ad5f5ebbbbea1a3e1db1acfec1dbe9 (diff) | |
download | elfutils-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>
-rw-r--r-- | src/ChangeLog | 6 | ||||
-rw-r--r-- | src/readelf.c | 31 | ||||
-rw-r--r-- | tests/ChangeLog | 7 | ||||
-rw-r--r-- | tests/alldts.c | 5 | ||||
-rwxr-xr-x | tests/run-alldts.sh | 2 | ||||
-rwxr-xr-x | tests/run-readelf-d.sh | 7 |
6 files changed, 43 insertions, 15 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); diff --git a/tests/ChangeLog b/tests/ChangeLog index e49bff05..c734b260 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,10 @@ +2022-03-01 Di Chen <dichen@redhat.com> + + * alldts.c (dtflags): Put DT_NULL last. + * run-alldts.sh: NULL comes last. + * run-readelf-d.sh: Adjust Dynamic entries, remove DT_NULL + padding. + 2022-04-14 Mark Wielaard <mark@klomp.org> * run-debuginfod-federation-sqlite.sh: Don't try to corrupt diff --git a/tests/alldts.c b/tests/alldts.c index 3e9f9fe6..d0fe4f24 100644 --- a/tests/alldts.c +++ b/tests/alldts.c @@ -44,7 +44,7 @@ main (void) Dwelf_Strent *shstrtabse; const Elf32_Sword dtflags[] = { - DT_NULL, DT_NEEDED, DT_PLTRELSZ, DT_PLTGOT, + DT_NEEDED, DT_PLTRELSZ, DT_PLTGOT, DT_HASH, DT_STRTAB, DT_SYMTAB, DT_RELA, DT_RELASZ, DT_RELAENT, DT_STRSZ, DT_SYMENT, DT_INIT, DT_FINI, DT_SONAME, DT_RPATH, @@ -61,7 +61,8 @@ main (void) DT_GNU_LIBLIST, DT_CONFIG, DT_DEPAUDIT, DT_AUDIT, DT_PLTPAD, DT_MOVETAB, DT_SYMINFO, DT_RELACOUNT, DT_RELCOUNT, DT_FLAGS_1, DT_VERDEF, DT_VERDEFNUM, - DT_VERNEED, DT_VERNEEDNUM, DT_AUXILIARY, DT_FILTER + DT_VERNEED, DT_VERNEEDNUM, DT_AUXILIARY, DT_FILTER, + DT_NULL }; const int ndtflags = sizeof (dtflags) / sizeof (dtflags[0]); diff --git a/tests/run-alldts.sh b/tests/run-alldts.sh index 6a9a9ece..ce3630b0 100755 --- a/tests/run-alldts.sh +++ b/tests/run-alldts.sh @@ -27,7 +27,6 @@ testrun_compare ${abs_top_builddir}/src/readelf -d testfile-alldts <<\EOF Dynamic segment contains 66 entries: Addr: 0x000001a0 Offset: 0x000078 Link to section: [ 0] '' Type Value - NULL NEEDED Shared library: [(null)] PLTRELSZ 3735928559 (bytes) PLTGOT 0xdeadbeef @@ -93,6 +92,7 @@ Dynamic segment contains 66 entries: VERNEEDNUM 3735928559 AUXILIARY 0xdeadbeef FILTER 0xdeadbeef + NULL EOF exit 0 diff --git a/tests/run-readelf-d.sh b/tests/run-readelf-d.sh index d0b6ed24..69b01c49 100755 --- a/tests/run-readelf-d.sh +++ b/tests/run-readelf-d.sh @@ -34,7 +34,7 @@ testfiles testlib_dynseg.so testrun_compare ${abs_top_builddir}/src/readelf -d testlib_dynseg.so <<\EOF -Dynamic segment contains 28 entries: +Dynamic segment contains 23 entries: Addr: 0x00000000000017e0 Offset: 0x0007e0 Link to section: [ 3] '.dynstr' Type Value PLTGOT 0x00000000000019c8 @@ -60,11 +60,6 @@ Dynamic segment contains 28 entries: VERNEED 0x0000000000000498 VERNEEDNUM 2 NULL - NULL - NULL - NULL - NULL - NULL EOF exit 0 |