[@option{-r}|@option{--reloc}]
[@option{-R}|@option{--dynamic-reloc}]
[@option{-s}|@option{--full-contents}]
+ [@option{-Z}|@option{--decompress}]
[@option{-W[lLiaprmfFsoORtUuTgAck]}|
@option{--dwarf}[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index,=addr,=cu_index,=links]]
[@option{-WK}|@option{--dwarf=follow-links}]
@cindex object file sections
Display the full contents of sections, often used in combination with
@option{-j} to request specific sections. By default all non-empty
-non-bss sections are displayed.
+non-bss sections are displayed. By default any compressed section
+will be displayed in its compressed form. In order to see the
+contents in a decompressed form add the @option{-Z} option to the
+command line.
@item -S
@itemx --source
Normally the disassembly output will skip blocks of zeroes. This
option directs the disassembler to disassemble those blocks, just like
any other data.
+
+@item -Z
+@itemx --decompress
+@cindex sections, full contents
+@cindex object file sections
+@cindex compressed section contents
+The @option{-Z} option is meant to be used in conunction with the
+@option{-s} option. It instructs @command{objdump} to decompress any
+compressed sections before displaying their contents.
@end table
@c man end
static bool extended_color_output = false; /* --visualize-jumps=extended-color. */
static int process_links = false; /* --process-links. */
static int show_all_symbols; /* --show-all-symbols. */
+static bool decompressed_dumps = false; /* -Z, --decompress. */
static enum color_selection
{
fprintf (stream, _("\
-s, --full-contents Display the full contents of all sections requested\n"));
fprintf (stream, _("\
+ -Z, --decompress Decompress section(s) before displaying their contents\n"));
+ fprintf (stream, _("\
-g, --debugging Display debug information in object file\n"));
fprintf (stream, _("\
-e, --debugging-tags Display debug information using ctags style\n"));
#endif
{"debugging", no_argument, NULL, 'g'},
{"debugging-tags", no_argument, NULL, 'e'},
+ {"decompress", no_argument, NULL, 'Z'},
{"demangle", optional_argument, NULL, 'C'},
{"disassemble", optional_argument, NULL, 'd'},
{"disassemble-all", no_argument, NULL, 'D'},
comma = ", ";
}
+ if (bfd_is_section_compressed (abfd, section))
+ printf ("%sCOMPRESSED", comma);
+
printf ("\n");
#undef PF
}
(unsigned long) (section->filepos + start_offset));
printf ("\n");
+ if (bfd_is_section_compressed (abfd, section) && ! decompressed_dumps)
+ printf (_(" NOTE: This section is compressed, but its contents have NOT been expanded for this dump.\n"));
+
if (!bfd_get_full_section_contents (abfd, section, &data))
{
non_fatal (_("Reading section %s failed because: %s"),
display_any_bfd (bfd *file, int level)
{
/* Decompress sections unless dumping the section contents. */
- if (!dump_section_contents)
+ if (!dump_section_contents || decompressed_dumps)
file->flags |= BFD_DECOMPRESS;
/* If the file is an archive, process all of its elements. */
set_default_bfd_target ();
while ((c = getopt_long (argc, argv,
- "CDE:FGHI:LM:P:RSTU:VW::ab:defghij:lm:prstvwxz",
+ "CDE:FGHI:LM:P:RSTU:VW::Zab:defghij:lm:prstvwxz",
long_options, (int *) 0))
!= EOF)
{
case 'm':
machine = optarg;
break;
+ case 'Z':
+ decompressed_dumps = true;
+ break;
case 'M':
{
char *options;
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;
{
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)
;
{
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;
{
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;
Filedata *filedata,
bool relocate)
{
- Elf_Internal_Shdr *relsec;
size_t bytes;
uint64_t section_size;
uint64_t addr;
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;