aboutsummaryrefslogtreecommitdiff
path: root/binutils/readelf.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2023-11-14 10:57:58 +0000
committerNick Clifton <nickc@redhat.com>2023-11-14 10:57:58 +0000
commitfab62191f84583780c2c6d024d0e583400881770 (patch)
tree8d3f4bec0f333cfab0808a08f8e435cdc2bc9171 /binutils/readelf.c
parent319b460545dc79280e2904dcc280057cf71fb753 (diff)
downloadgdb-fab62191f84583780c2c6d024d0e583400881770.zip
gdb-fab62191f84583780c2c6d024d0e583400881770.tar.gz
gdb-fab62191f84583780c2c6d024d0e583400881770.tar.bz2
Improve objdump's handling of compressed sections.
PR 31062 * objdump.c (decompressed_dumps): New local variable. (usage): Mention the -z/--decompress option. (long_options): Add --decompress. (dump_section_header): Add "COMPRESSED" to the Flags field of any compressed section. (dump_section): Warn users when dumping a compressed section. (display_any_bfd): Decompress the section if decompressed_dumps is true. (main): Handle the -z/--decompress option. * NEWS: Mention the new feature. * doc/binutils.texi: Document the new feature. * testsuite/binutils-all/objdump.s: Update expected output. * testsuite/binutils-all/objdump.exp: Add test of -Z -s. * testsuite/binutils-all/objdump.Zs: New file. * readelf.c (maybe_expand_or_relocate_section): New function. Contains common code found in dump functions. Adds a note message if a compressed section is not being decompressed. (dump_section_as_strings): Use new function. (dump_section_as_bytes): Likewise.
Diffstat (limited to 'binutils/readelf.c')
-rw-r--r--binutils/readelf.c230
1 files changed, 84 insertions, 146 deletions
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 661ef0a..775106f 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -15961,35 +15961,18 @@ uncompress_section_contents (bool is_zstd,
return false;
}
-static bool
-dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
+static uint64_t
+maybe_expand_or_relocate_section (Elf_Internal_Shdr * section,
+ Filedata * filedata,
+ unsigned char ** start_ptr,
+ bool relocate)
{
- Elf_Internal_Shdr *relsec;
- uint64_t num_bytes;
- unsigned char *data;
- unsigned char *end;
- unsigned char *real_start;
- unsigned char *start;
- bool some_strings_shown;
-
- real_start = start = (unsigned char *) get_section_contents (section, filedata);
- if (start == NULL)
- /* PR 21820: Do not fail if the section was empty. */
- return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
-
- num_bytes = section->sh_size;
-
- if (filedata->is_separate)
- printf (_("\nString dump of section '%s' in linked file %s:\n"),
- printable_section_name (filedata, section),
- filedata->file_name);
- else
- printf (_("\nString dump of section '%s':\n"),
- printable_section_name (filedata, section));
-
+ uint64_t section_size = section->sh_size;
+ unsigned char * start = * start_ptr;
+
if (decompress_dumps)
{
- uint64_t new_size = num_bytes;
+ uint64_t new_size = section_size;
uint64_t uncompressed_size = 0;
bool is_zstd = false;
@@ -15997,12 +15980,12 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
{
Elf_Internal_Chdr chdr;
unsigned int compression_header_size
- = get_compression_header (& chdr, (unsigned char *) start,
- num_bytes);
+ = get_compression_header (& chdr, start, section_size);
+
if (compression_header_size == 0)
/* An error message will have already been generated
by get_compression_header. */
- goto error_out;
+ return (uint64_t) -1;
if (chdr.ch_type == ch_compress_zlib)
;
@@ -16014,8 +15997,9 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
{
warn (_("section '%s' has unsupported compress type: %d\n"),
printable_section_name (filedata, section), chdr.ch_type);
- goto error_out;
+ return (uint64_t) -1;
}
+
uncompressed_size = chdr.ch_size;
start += compression_header_size;
new_size -= compression_header_size;
@@ -16041,38 +16025,86 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
{
if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
&new_size, filedata->file_size))
- num_bytes = new_size;
+ section_size = new_size;
else
{
error (_("Unable to decompress section %s\n"),
printable_section_name (filedata, section));
- goto error_out;
+ return (uint64_t) -1;
}
}
else
- start = real_start;
+ start = * start_ptr;
+ }
+ else if (((section->sh_flags & SHF_COMPRESSED) != 0)
+ || (section_size > 12 && streq ((char *) start, "ZLIB")))
+ {
+ printf (_(" NOTE: This section is compressed, but its contents have NOT been expanded for this dump.\n"));
}
- /* If the section being dumped has relocations against it the user might
- be expecting these relocations to have been applied. Check for this
- case and issue a warning message in order to avoid confusion.
- FIXME: Maybe we ought to have an option that dumps a section with
- relocs applied ? */
- for (relsec = filedata->section_headers;
- relsec < filedata->section_headers + filedata->file_header.e_shnum;
- ++relsec)
+ if (relocate)
{
- if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
- || relsec->sh_info >= filedata->file_header.e_shnum
- || filedata->section_headers + relsec->sh_info != section
- || relsec->sh_size == 0
- || relsec->sh_link >= filedata->file_header.e_shnum)
- continue;
+ if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
+ return (uint64_t) -1;
+ }
+ else
+ {
+ Elf_Internal_Shdr *relsec;
- printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
- break;
+ /* If the section being dumped has relocations against it the user might
+ be expecting these relocations to have been applied. Check for this
+ case and issue a warning message in order to avoid confusion.
+ FIXME: Maybe we ought to have an option that dumps a section with
+ relocs applied ? */
+ for (relsec = filedata->section_headers;
+ relsec < filedata->section_headers + filedata->file_header.e_shnum;
+ ++relsec)
+ {
+ if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
+ || relsec->sh_info >= filedata->file_header.e_shnum
+ || filedata->section_headers + relsec->sh_info != section
+ || relsec->sh_size == 0
+ || relsec->sh_link >= filedata->file_header.e_shnum)
+ continue;
+
+ printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
+ break;
+ }
}
+ * start_ptr = start;
+ return section_size;
+}
+
+static bool
+dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
+{
+ uint64_t num_bytes;
+ unsigned char *data;
+ unsigned char *end;
+ unsigned char *real_start;
+ unsigned char *start;
+ bool some_strings_shown;
+
+ real_start = start = (unsigned char *) get_section_contents (section, filedata);
+ if (start == NULL)
+ /* PR 21820: Do not fail if the section was empty. */
+ return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
+
+ num_bytes = section->sh_size;
+
+ if (filedata->is_separate)
+ printf (_("\nString dump of section '%s' in linked file %s:\n"),
+ printable_section_name (filedata, section),
+ filedata->file_name);
+ else
+ printf (_("\nString dump of section '%s':\n"),
+ printable_section_name (filedata, section));
+
+ num_bytes = maybe_expand_or_relocate_section (section, filedata, & start, false);
+ if (num_bytes == (uint64_t) -1)
+ goto error_out;
+
data = start;
end = start + num_bytes;
some_strings_shown = false;
@@ -16187,7 +16219,6 @@ dump_section_as_bytes (Elf_Internal_Shdr *section,
Filedata *filedata,
bool relocate)
{
- Elf_Internal_Shdr *relsec;
size_t bytes;
uint64_t section_size;
uint64_t addr;
@@ -16210,102 +16241,9 @@ dump_section_as_bytes (Elf_Internal_Shdr *section,
printf (_("\nHex dump of section '%s':\n"),
printable_section_name (filedata, section));
- if (decompress_dumps)
- {
- uint64_t new_size = section_size;
- uint64_t uncompressed_size = 0;
- bool is_zstd = false;
-
- if ((section->sh_flags & SHF_COMPRESSED) != 0)
- {
- Elf_Internal_Chdr chdr;
- unsigned int compression_header_size
- = get_compression_header (& chdr, start, section_size);
-
- if (compression_header_size == 0)
- /* An error message will have already been generated
- by get_compression_header. */
- goto error_out;
-
- if (chdr.ch_type == ch_compress_zlib)
- ;
-#ifdef HAVE_ZSTD
- else if (chdr.ch_type == ch_compress_zstd)
- is_zstd = true;
-#endif
- else
- {
- warn (_("section '%s' has unsupported compress type: %d\n"),
- printable_section_name (filedata, section), chdr.ch_type);
- goto error_out;
- }
- uncompressed_size = chdr.ch_size;
- start += compression_header_size;
- new_size -= compression_header_size;
- }
- else if (new_size > 12 && streq ((char *) start, "ZLIB"))
- {
- /* Read the zlib header. In this case, it should be "ZLIB"
- followed by the uncompressed section size, 8 bytes in
- big-endian order. */
- uncompressed_size = start[4]; uncompressed_size <<= 8;
- uncompressed_size += start[5]; uncompressed_size <<= 8;
- uncompressed_size += start[6]; uncompressed_size <<= 8;
- uncompressed_size += start[7]; uncompressed_size <<= 8;
- uncompressed_size += start[8]; uncompressed_size <<= 8;
- uncompressed_size += start[9]; uncompressed_size <<= 8;
- uncompressed_size += start[10]; uncompressed_size <<= 8;
- uncompressed_size += start[11];
- start += 12;
- new_size -= 12;
- }
-
- if (uncompressed_size)
- {
- if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
- &new_size, filedata->file_size))
- {
- section_size = new_size;
- }
- else
- {
- error (_("Unable to decompress section %s\n"),
- printable_section_name (filedata, section));
- /* FIXME: Print the section anyway ? */
- goto error_out;
- }
- }
- else
- start = real_start;
- }
-
- if (relocate)
- {
- if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
- goto error_out;
- }
- else
- {
- /* If the section being dumped has relocations against it the user might
- be expecting these relocations to have been applied. Check for this
- case and issue a warning message in order to avoid confusion.
- FIXME: Maybe we ought to have an option that dumps a section with
- relocs applied ? */
- for (relsec = filedata->section_headers;
- relsec < filedata->section_headers + filedata->file_header.e_shnum;
- ++relsec)
- {
- if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
- || relsec->sh_info >= filedata->file_header.e_shnum
- || filedata->section_headers + relsec->sh_info != section
- || relsec->sh_size == 0
- || relsec->sh_link >= filedata->file_header.e_shnum)
- continue;
-
- printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
- break;
- }
- }
+ section_size = maybe_expand_or_relocate_section (section, filedata, & start, relocate);
+ if (section_size == (uint64_t) -1)
+ goto error_out;
addr = section->sh_addr;
bytes = section_size;