diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 7 | ||||
-rw-r--r-- | src/readelf.c | 52 |
2 files changed, 50 insertions, 9 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 4e62c8e9..03a29c64 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2015-10-20 Mark Wielaard <mjw@redhat.com> + + * readelf.c (options): Expand -z help text. + (dump_data_section): Check whether we need and can decompress section + data and call elf_rawzdata if so, + (print_string_section): Likewise. + 2015-10-16 Mark Wielaard <mjw@redhat.com> * readelf.c (argp_option): Describe --decompress,-z. diff --git a/src/readelf.c b/src/readelf.c index 6441c561..2c10a34e 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -113,7 +113,7 @@ static const struct argp_option options[] = { "wide", 'W', NULL, 0, N_("Ignored for compatibility (lines always wide)"), 0 }, { "decompress", 'z', NULL, 0, - N_("Show compression information for compressed sections (when used with -S)."), 0 }, + N_("Show compression information for compressed sections (when used with -S); decompress section before dumping data (when used with -p or -x)"), 0 }, { NULL, 0, NULL, 0, NULL, 0 } }; @@ -9444,16 +9444,33 @@ dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name) elf_ndxscn (scn), name); else { + if (print_decompress) + { + /* We try to decompress the section, but keep the old shdr around + so we can show both the original shdr size and the uncompressed + data size. We don't check for errors, if the section wasn't + compressed before, that is fine too. */ + GElf_Shdr mem; + gelf_zscn_compress (scn, &mem, ELF_ZSCN_T_NONE, 0); + } + Elf_Data *data = elf_rawdata (scn, NULL); if (data == NULL) error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"), elf_ndxscn (scn), name, elf_errmsg (-1)); else { - printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64 - " bytes at offset %#0" PRIx64 ":\n"), - elf_ndxscn (scn), name, - shdr->sh_size, shdr->sh_offset); + if (data->d_size == shdr->sh_size) + printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64 + " bytes at offset %#0" PRIx64 ":\n"), + elf_ndxscn (scn), name, + shdr->sh_size, shdr->sh_offset); + else + printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64 + " bytes (%zd uncompressed) at offset %#0" + PRIx64 ":\n"), + elf_ndxscn (scn), name, + shdr->sh_size, data->d_size, shdr->sh_offset); hex_dump (data->d_buf, data->d_size); } } @@ -9467,16 +9484,33 @@ print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name) elf_ndxscn (scn), name); else { + if (print_decompress) + { + /* We try to decompress the section, but keep the old shdr around + so we can show both the original shdr size and the uncompressed + data size. We don't check for errors, if the section wasn't + compressed before, that is fine too. */ + GElf_Shdr mem; + gelf_zscn_compress (scn, &mem, ELF_ZSCN_T_NONE, 0); + } + Elf_Data *data = elf_rawdata (scn, NULL); if (data == NULL) error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"), elf_ndxscn (scn), name, elf_errmsg (-1)); else { - printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64 - " bytes at offset %#0" PRIx64 ":\n"), - elf_ndxscn (scn), name, - shdr->sh_size, shdr->sh_offset); + if (data->d_size == shdr->sh_size) + printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64 + " bytes at offset %#0" PRIx64 ":\n"), + elf_ndxscn (scn), name, + shdr->sh_size, shdr->sh_offset); + else + printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64 + " bytes (%zd uncompressed) at offset %#0" + PRIx64 ":\n"), + elf_ndxscn (scn), name, + shdr->sh_size, data->d_size, shdr->sh_offset); const char *start = data->d_buf; const char *const limit = start + data->d_size; |