aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binutils/ChangeLog21
-rw-r--r--binutils/NEWS3
-rw-r--r--binutils/doc/binutils.texi11
-rw-r--r--binutils/dwarf.c7
-rw-r--r--binutils/readelf.c684
5 files changed, 393 insertions, 333 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index acce3a8..c748a6a 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,24 @@
+2009-06-23 Nick Clifton <nickc@redhat.com>
+
+ * dwarf.c (display_debug_lines_raw): Include the name of the
+ section in warning message.
+ (struct debug_display): Enable reloc processing for .debug_line
+ and .debug_ranges sections.
+
+ * readelf.c: Add --relocated-dump command line option to dump the
+ relocated contents of a specified section.
+ (request_dump): New function.
+ (parse_args): Use it.
+ (dump_section_as_bytes): Add parameter to indicate whether the
+ contents should be relocated.
+ (target_specific_reloc_handling): Add code for a R_MN10300_16
+ reloc found after a R_MN10300_SYM_DIFF reloc.
+ (debug_apply_relocations): Rename to apply_relocations.
+ (get_section_contents): New function. Replaces common code found
+ in dump_section_as_strings and dump_section_as_bytes.
+ * doc/binutils.texi: Document new command line option.
+ * NEWS: Mention the new feature.
+
2009-06-22 Nick Clifton <nickc@redhat.com>
* readelf.c (target_specific_reloc_handling): New function:
diff --git a/binutils/NEWS b/binutils/NEWS
index 9a33f26..2edef3c 100644
--- a/binutils/NEWS
+++ b/binutils/NEWS
@@ -1,4 +1,7 @@
-*- text -*-
+* Readelf can now display the relocated contents of a section as a sequence
+ of bytes via the --relocated-dump=<name|number> command line option.
+
* The gprof program has been given a new command line option:
--external-symbols-table=<filename> which reads in symbols from a specified
file.
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index d74b12b..2364f9c 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -3844,6 +3844,7 @@ readelf [@option{-a}|@option{--all}]
[@option{-D}|@option{--use-dynamic}]
[@option{-x} <number or name>|@option{--hex-dump=}<number or name>]
[@option{-p} <number or name>|@option{--string-dump=}<number or name>]
+ [@option{-R} <number or name>|@option{--relocated-dump=}<number or name>]
[@option{-c}|@option{--archive-index}]
[@option{-w[lLiaprmfFsoR]}|
@option{--debug-dump}[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges]]
@@ -3966,10 +3967,18 @@ symbols section.
@item -x <number or name>
@itemx --hex-dump=<number or name>
-Displays the contents of the indicated section as a hexadecimal dump.
+Displays the contents of the indicated section as a hexadecimal bytes.
A number identifies a particular section by index in the section table;
any other string identifies all sections with that name in the object file.
+@item -R <number or name>
+@itemx --relocated-dump=<number or name>
+Displays the contents of the indicated section as a hexadecimal
+bytes. A number identifies a particular section by index in the
+section table; any other string identifies all sections with that name
+in the object file. The contents of the section will be relocated
+before they are displayed.
+
@item -p <number or name>
@itemx --string-dump=<number or name>
Displays the contents of the indicated section as printable strings.
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index b524d17..1a01e00 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -2145,7 +2145,8 @@ display_debug_lines_raw (struct dwarf_section *section,
if (info.li_length + initial_length_size > section->size)
{
warn
- (_("The line info appears to be corrupt - the section is too small\n"));
+ (_("The information in section %s appears to be corrupt - the section is too small\n"),
+ section->name);
return 0;
}
@@ -4872,7 +4873,7 @@ struct dwarf_section_display debug_displays[] =
{ { ".debug_info", ".zdebug_info", NULL, NULL, 0, 0 },
display_debug_info, &do_debug_info, 1, 0 },
{ { ".debug_line", ".zdebug_line", NULL, NULL, 0, 0 },
- display_debug_lines, &do_debug_lines, 0, 0 },
+ display_debug_lines, &do_debug_lines, 1, 0 },
{ { ".debug_pubnames", ".zdebug_pubnames", NULL, NULL, 0, 0 },
display_debug_pubnames, &do_debug_pubnames, 0, 0 },
{ { ".eh_frame", "", NULL, NULL, 0, 0 },
@@ -4886,7 +4887,7 @@ struct dwarf_section_display debug_displays[] =
{ { ".debug_pubtypes", ".zdebug_pubtypes", NULL, NULL, 0, 0 },
display_debug_pubnames, &do_debug_pubnames, 0, 0 },
{ { ".debug_ranges", ".zdebug_ranges", NULL, NULL, 0, 0 },
- display_debug_ranges, &do_debug_ranges, 0, 0 },
+ display_debug_ranges, &do_debug_ranges, 1, 0 },
{ { ".debug_static_func", ".zdebug_static_func", NULL, NULL, 0, 0 },
display_debug_not_supported, NULL, 0, 0 },
{ { ".debug_static_vars", ".zdebug_static_vars", NULL, NULL, 0, 0 },
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 87c8119..ce739e6 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -214,6 +214,7 @@ static struct group ** section_headers_groups;
#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
#define STRING_DUMP (1 << 3) /* The -p command line switch. */
+#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
typedef unsigned char dump_type;
@@ -2844,11 +2845,12 @@ static struct option options[] =
{"unwind", no_argument, 0, 'u'},
{"archive-index", no_argument, 0, 'c'},
{"hex-dump", required_argument, 0, 'x'},
- {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
+ {"relocated-dump", required_argument, 0, 'R'},
{"string-dump", required_argument, 0, 'p'},
#ifdef SUPPORT_DISASSEMBLY
{"instruction-dump", required_argument, 0, 'i'},
#endif
+ {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
{"version", no_argument, 0, 'v'},
{"wide", no_argument, 0, 'W'},
@@ -2885,6 +2887,8 @@ usage (FILE * stream)
Dump the contents of section <number|name> as bytes\n\
-p --string-dump=<number|name>\n\
Dump the contents of section <number|name> as strings\n\
+ -R --relocated-dump=<number|name>\n\
+ Dump the contents of section <number|name> as relocated bytes\n\
-w[lLiaprmfFsoR] or\n\
--debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=str,=loc,=Ranges]\n\
Display the contents of DWARF2 debug sections\n"));
@@ -2961,6 +2965,22 @@ request_dump_byname (const char * section, dump_type type)
dump_sects_byname = new_request;
}
+static inline void
+request_dump (dump_type type)
+{
+ int section;
+ char * cp;
+
+ do_dump++;
+ section = strtoul (optarg, & cp, 0);
+
+ if (! *cp && section >= 0)
+ request_dump_bynumber (section, type);
+ else
+ request_dump_byname (optarg, type);
+}
+
+
static void
parse_args (int argc, char ** argv)
{
@@ -2970,11 +2990,8 @@ parse_args (int argc, char ** argv)
usage (stderr);
while ((c = getopt_long
- (argc, argv, "ADHINSVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
+ (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
{
- char * cp;
- int section;
-
switch (c)
{
case 0:
@@ -3048,20 +3065,13 @@ parse_args (int argc, char ** argv)
do_archive_index++;
break;
case 'x':
- do_dump++;
- section = strtoul (optarg, & cp, 0);
- if (! *cp && section >= 0)
- request_dump_bynumber (section, HEX_DUMP);
- else
- request_dump_byname (optarg, HEX_DUMP);
+ request_dump (HEX_DUMP);
break;
case 'p':
- do_dump++;
- section = strtoul (optarg, & cp, 0);
- if (! *cp && section >= 0)
- request_dump_bynumber (section, STRING_DUMP);
- else
- request_dump_byname (optarg, STRING_DUMP);
+ request_dump (STRING_DUMP);
+ break;
+ case 'R':
+ request_dump (RELOC_DUMP);
break;
case 'w':
do_dump++;
@@ -3088,12 +3098,8 @@ parse_args (int argc, char ** argv)
break;
#ifdef SUPPORT_DISASSEMBLY
case 'i':
- do_dump++;
- section = strtoul (optarg, & cp, 0);
- if (! *cp && section >= 0)
- request_dump_bynumber (section, DISASS_DUMP);
- else
- request_dump_byname (optarg, DISASS_DUMP);
+ request_dump (DISASS_DUMP);
+ break;
#endif
case 'v':
print_version (program_name);
@@ -7759,190 +7765,57 @@ process_syminfo (FILE * file ATTRIBUTE_UNUSED)
return 1;
}
-#ifdef SUPPORT_DISASSEMBLY
-static int
-disassemble_section (Elf_Internal_Shdr * section, FILE * file)
-{
- printf (_("\nAssembly dump of section %s\n"),
- SECTION_NAME (section));
-
- /* XXX -- to be done --- XXX */
-
- return 1;
-}
-#endif
-
-static int
-dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
-{
- Elf_Internal_Shdr * relsec;
- bfd_size_type num_bytes;
- bfd_vma addr;
- char * data;
- char * end;
- char * start;
- char * name = SECTION_NAME (section);
- bfd_boolean some_strings_shown;
-
- num_bytes = section->sh_size;
-
- if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
- {
- printf (_("\nSection '%s' has no data to dump.\n"), name);
- return 0;
- }
-
- addr = section->sh_addr;
-
- start = get_data (NULL, file, section->sh_offset, 1, num_bytes,
- _("section data"));
- if (!start)
- return 0;
-
- printf (_("\nString dump of section '%s':\n"), name);
-
- /* 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 = section_headers;
- relsec < section_headers + elf_header.e_shnum;
- ++relsec)
- {
- if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
- || relsec->sh_info >= elf_header.e_shnum
- || section_headers + relsec->sh_info != section
- || relsec->sh_size == 0
- || relsec->sh_link >= elf_header.e_shnum)
- continue;
-
- printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
- break;
- }
-
- data = start;
- end = start + num_bytes;
- some_strings_shown = FALSE;
-
- while (data < end)
- {
- while (!ISPRINT (* data))
- if (++ data >= end)
- break;
-
- if (data < end)
- {
-#ifndef __MSVCRT__
- printf (" [%6tx] %s\n", data - start, data);
-#else
- printf (" [%6Ix] %s\n", (size_t) (data - start), data);
-#endif
- data += strlen (data);
- some_strings_shown = TRUE;
- }
- }
-
- if (! some_strings_shown)
- printf (_(" No strings found in this section."));
-
- free (start);
-
- putchar ('\n');
- return 1;
-}
-
+/* Check to see if the given reloc needs to be handled in a target specific
+ manner. If so then process the reloc and return TRUE otherwise return
+ FALSE. */
-static int
-dump_section_as_bytes (Elf_Internal_Shdr * section, FILE * file)
+static bfd_boolean
+target_specific_reloc_handling (Elf_Internal_Rela * reloc,
+ unsigned char * start,
+ Elf_Internal_Sym * symtab)
{
- Elf_Internal_Shdr * relsec;
- bfd_size_type bytes;
- bfd_vma addr;
- unsigned char * data;
- unsigned char * start;
-
- bytes = section->sh_size;
-
- if (bytes == 0 || section->sh_type == SHT_NOBITS)
- {
- printf (_("\nSection '%s' has no data to dump.\n"),
- SECTION_NAME (section));
- return 0;
- }
- else
- printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
-
- addr = section->sh_addr;
-
- start = get_data (NULL, file, section->sh_offset, 1, bytes,
- _("section data"));
- if (!start)
- return 0;
-
- /* 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 = section_headers;
- relsec < section_headers + elf_header.e_shnum;
- ++relsec)
- {
- if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
- || relsec->sh_info >= elf_header.e_shnum
- || section_headers + relsec->sh_info != section
- || relsec->sh_size == 0
- || relsec->sh_link >= elf_header.e_shnum)
- continue;
-
- printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
- break;
- }
-
- data = start;
+ unsigned int reloc_type = get_reloc_type (reloc->r_info);
- while (bytes)
+ switch (elf_header.e_machine)
{
- int j;
- int k;
- int lbytes;
-
- lbytes = (bytes > 16 ? 16 : bytes);
-
- printf (" 0x%8.8lx ", (unsigned long) addr);
-
- for (j = 0; j < 16; j++)
- {
- if (j < lbytes)
- printf ("%2.2x", data[j]);
- else
- printf (" ");
+ case EM_MN10300:
+ case EM_CYGNUS_MN10300:
+ {
+ static Elf_Internal_Sym * saved_sym = NULL;
- if ((j & 3) == 3)
- printf (" ");
- }
+ switch (reloc_type)
+ {
+ case 34: /* R_MN10300_ALIGN */
+ return TRUE;
+ case 33: /* R_MN10300_SYM_DIFF */
+ saved_sym = symtab + get_reloc_symindex (reloc->r_info);
+ return TRUE;
+ case 1: /* R_MN10300_32 */
+ case 2: /* R_MN10300_16 */
+ if (saved_sym != NULL)
+ {
+ bfd_vma value;
- for (j = 0; j < lbytes; j++)
- {
- k = data[j];
- if (k >= ' ' && k < 0x7f)
- printf ("%c", k);
- else
- printf (".");
- }
+ value = reloc->r_addend
+ + (symtab[get_reloc_symindex (reloc->r_info)].st_value
+ - saved_sym->st_value);
- putchar ('\n');
+ byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
- data += lbytes;
- addr += lbytes;
- bytes -= lbytes;
+ saved_sym = NULL;
+ return TRUE;
+ }
+ break;
+ default:
+ if (saved_sym != NULL)
+ error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
+ break;
+ }
+ break;
+ }
}
- free (start);
-
- putchar ('\n');
- return 1;
+ return FALSE;
}
/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
@@ -8130,8 +8003,8 @@ is_32bit_pcrel_reloc (unsigned int reloc_type)
/* Do not abort or issue an error message here. Not all targets use
pc-relative 32-bit relocs in their DWARF debug information and we
have already tested for target coverage in is_32bit_abs_reloc. A
- more helpful warning message will be generated by
- debug_apply_relocations anyway, so just return. */
+ more helpful warning message will be generated by apply_relocations
+ anyway, so just return. */
return FALSE;
}
}
@@ -8265,133 +8138,15 @@ is_none_reloc (unsigned int reloc_type)
return FALSE;
}
-/* Uncompresses a section that was compressed using zlib, in place.
- This is a copy of bfd_uncompress_section_contents, in bfd/compress.c */
-
-static int
-uncompress_section_contents (unsigned char ** buffer, dwarf_size_type * size)
-{
-#ifndef HAVE_ZLIB_H
- /* These are just to quiet gcc. */
- buffer = 0;
- size = 0;
- return FALSE;
-#else
- dwarf_size_type compressed_size = *size;
- unsigned char * compressed_buffer = *buffer;
- dwarf_size_type uncompressed_size;
- unsigned char * uncompressed_buffer;
- z_stream strm;
- int rc;
- dwarf_size_type header_size = 12;
-
- /* Read the zlib header. In this case, it should be "ZLIB" followed
- by the uncompressed section size, 8 bytes in big-endian order. */
- if (compressed_size < header_size
- || ! streq ((char *) compressed_buffer, "ZLIB"))
- return 0;
-
- uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[11];
-
- /* It is possible the section consists of several compressed
- buffers concatenated together, so we uncompress in a loop. */
- strm.zalloc = NULL;
- strm.zfree = NULL;
- strm.opaque = NULL;
- strm.avail_in = compressed_size - header_size;
- strm.next_in = (Bytef *) compressed_buffer + header_size;
- strm.avail_out = uncompressed_size;
- uncompressed_buffer = xmalloc (uncompressed_size);
-
- rc = inflateInit (& strm);
- while (strm.avail_in > 0)
- {
- if (rc != Z_OK)
- goto fail;
- strm.next_out = ((Bytef *) uncompressed_buffer
- + (uncompressed_size - strm.avail_out));
- rc = inflate (&strm, Z_FINISH);
- if (rc != Z_STREAM_END)
- goto fail;
- rc = inflateReset (& strm);
- }
- rc = inflateEnd (& strm);
- if (rc != Z_OK
- || strm.avail_out != 0)
- goto fail;
-
- free (compressed_buffer);
- *buffer = uncompressed_buffer;
- *size = uncompressed_size;
- return 1;
-
- fail:
- free (uncompressed_buffer);
- return 0;
-#endif /* HAVE_ZLIB_H */
-}
-
-/* Check to see if the given reloc needs to be handled in a target specific
- manner. If so then process the reloc and return TRUE otherwise return
- FALSE. */
-
-static bfd_boolean
-target_specific_reloc_handling (Elf_Internal_Rela * reloc,
- unsigned char * start,
- Elf_Internal_Sym * symtab)
-{
- unsigned int reloc_type = get_reloc_type (reloc->r_info);
-
- switch (elf_header.e_machine)
- {
- case EM_MN10300:
- case EM_CYGNUS_MN10300:
- {
- static Elf_Internal_Sym * saved_sym = NULL;
-
- switch (reloc_type)
- {
- case 34: /* R_MN10300_ALIGN */
- return TRUE;
- case 33: /* R_MN10300_SYM_DIFF */
- saved_sym = symtab + get_reloc_symindex (reloc->r_info);
- return TRUE;
- case 1: /* R_MN10300_32 */
- if (saved_sym != NULL)
- {
- bfd_vma value;
-
- value = reloc->r_addend
- + (symtab[get_reloc_symindex (reloc->r_info)].st_value
- - saved_sym->st_value);
-
- byte_put (start + reloc->r_offset, value, 4);
-
- saved_sym = NULL;
- return TRUE;
- }
- break;
- }
- break;
- }
- }
-
- return FALSE;
-}
-
-/* Apply relocations to a debug section. */
+/* Apply relocations to a section.
+ Note: So far support has been added only for those relocations
+ which can be found in debug sections.
+ FIXME: Add support for more relocations ? */
static void
-debug_apply_relocations (void * file,
- Elf_Internal_Shdr * section,
- unsigned char * start)
+apply_relocations (void * file,
+ Elf_Internal_Shdr * section,
+ unsigned char * start)
{
Elf_Internal_Shdr * relsec;
unsigned char * end = start + section->sh_size;
@@ -8399,7 +8154,7 @@ debug_apply_relocations (void * file,
if (elf_header.e_type != ET_REL)
return;
- /* Find the reloc section associated with the debug section. */
+ /* Find the reloc section associated with the section. */
for (relsec = section_headers;
relsec < section_headers + elf_header.e_shnum;
++relsec)
@@ -8524,6 +8279,274 @@ debug_apply_relocations (void * file,
}
}
+#ifdef SUPPORT_DISASSEMBLY
+static int
+disassemble_section (Elf_Internal_Shdr * section, FILE * file)
+{
+ printf (_("\nAssembly dump of section %s\n"),
+ SECTION_NAME (section));
+
+ /* XXX -- to be done --- XXX */
+
+ return 1;
+}
+#endif
+
+/* Reads in the contents of SECTION from FILE, returning a pointer
+ to a malloc'ed buffer or NULL if something went wrong. */
+
+static char *
+get_section_contents (Elf_Internal_Shdr * section, FILE * file)
+{
+ bfd_size_type num_bytes;
+
+ num_bytes = section->sh_size;
+
+ if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
+ {
+ printf (_("\nSection '%s' has no data to dump.\n"),
+ SECTION_NAME (section));
+ return NULL;
+ }
+
+ return get_data (NULL, file, section->sh_offset, 1, num_bytes,
+ _("section contents"));
+}
+
+
+static void
+dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
+{
+ Elf_Internal_Shdr * relsec;
+ bfd_size_type num_bytes;
+ bfd_vma addr;
+ char * data;
+ char * end;
+ char * start;
+ char * name = SECTION_NAME (section);
+ bfd_boolean some_strings_shown;
+
+ start = get_section_contents (section, file);
+ if (start == NULL)
+ return;
+
+ printf (_("\nString dump of section '%s':\n"), name);
+
+ /* 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 = section_headers;
+ relsec < section_headers + elf_header.e_shnum;
+ ++relsec)
+ {
+ if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
+ || relsec->sh_info >= elf_header.e_shnum
+ || section_headers + relsec->sh_info != section
+ || relsec->sh_size == 0
+ || relsec->sh_link >= elf_header.e_shnum)
+ continue;
+
+ printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
+ break;
+ }
+
+ num_bytes = section->sh_size;
+ addr = section->sh_addr;
+ data = start;
+ end = start + num_bytes;
+ some_strings_shown = FALSE;
+
+ while (data < end)
+ {
+ while (!ISPRINT (* data))
+ if (++ data >= end)
+ break;
+
+ if (data < end)
+ {
+#ifndef __MSVCRT__
+ printf (" [%6tx] %s\n", data - start, data);
+#else
+ printf (" [%6Ix] %s\n", (size_t) (data - start), data);
+#endif
+ data += strlen (data);
+ some_strings_shown = TRUE;
+ }
+ }
+
+ if (! some_strings_shown)
+ printf (_(" No strings found in this section."));
+
+ free (start);
+
+ putchar ('\n');
+}
+
+static void
+dump_section_as_bytes (Elf_Internal_Shdr * section,
+ FILE * file,
+ bfd_boolean relocate)
+{
+ Elf_Internal_Shdr * relsec;
+ bfd_size_type bytes;
+ bfd_vma addr;
+ unsigned char * data;
+ unsigned char * start;
+
+ start = (unsigned char *) get_section_contents (section, file);
+ if (start == NULL)
+ return;
+
+ printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
+
+ if (relocate)
+ {
+ apply_relocations (file, section, start);
+ }
+ 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 = section_headers;
+ relsec < section_headers + elf_header.e_shnum;
+ ++relsec)
+ {
+ if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
+ || relsec->sh_info >= elf_header.e_shnum
+ || section_headers + relsec->sh_info != section
+ || relsec->sh_size == 0
+ || relsec->sh_link >= elf_header.e_shnum)
+ continue;
+
+ printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
+ break;
+ }
+ }
+
+ addr = section->sh_addr;
+ bytes = section->sh_size;
+ data = start;
+
+ while (bytes)
+ {
+ int j;
+ int k;
+ int lbytes;
+
+ lbytes = (bytes > 16 ? 16 : bytes);
+
+ printf (" 0x%8.8lx ", (unsigned long) addr);
+
+ for (j = 0; j < 16; j++)
+ {
+ if (j < lbytes)
+ printf ("%2.2x", data[j]);
+ else
+ printf (" ");
+
+ if ((j & 3) == 3)
+ printf (" ");
+ }
+
+ for (j = 0; j < lbytes; j++)
+ {
+ k = data[j];
+ if (k >= ' ' && k < 0x7f)
+ printf ("%c", k);
+ else
+ printf (".");
+ }
+
+ putchar ('\n');
+
+ data += lbytes;
+ addr += lbytes;
+ bytes -= lbytes;
+ }
+
+ free (start);
+
+ putchar ('\n');
+}
+
+/* Uncompresses a section that was compressed using zlib, in place.
+ This is a copy of bfd_uncompress_section_contents, in bfd/compress.c */
+
+static int
+uncompress_section_contents (unsigned char ** buffer, dwarf_size_type * size)
+{
+#ifndef HAVE_ZLIB_H
+ /* These are just to quiet gcc. */
+ buffer = 0;
+ size = 0;
+ return FALSE;
+#else
+ dwarf_size_type compressed_size = *size;
+ unsigned char * compressed_buffer = *buffer;
+ dwarf_size_type uncompressed_size;
+ unsigned char * uncompressed_buffer;
+ z_stream strm;
+ int rc;
+ dwarf_size_type header_size = 12;
+
+ /* Read the zlib header. In this case, it should be "ZLIB" followed
+ by the uncompressed section size, 8 bytes in big-endian order. */
+ if (compressed_size < header_size
+ || ! streq ((char *) compressed_buffer, "ZLIB"))
+ return 0;
+
+ uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[11];
+
+ /* It is possible the section consists of several compressed
+ buffers concatenated together, so we uncompress in a loop. */
+ strm.zalloc = NULL;
+ strm.zfree = NULL;
+ strm.opaque = NULL;
+ strm.avail_in = compressed_size - header_size;
+ strm.next_in = (Bytef *) compressed_buffer + header_size;
+ strm.avail_out = uncompressed_size;
+ uncompressed_buffer = xmalloc (uncompressed_size);
+
+ rc = inflateInit (& strm);
+ while (strm.avail_in > 0)
+ {
+ if (rc != Z_OK)
+ goto fail;
+ strm.next_out = ((Bytef *) uncompressed_buffer
+ + (uncompressed_size - strm.avail_out));
+ rc = inflate (&strm, Z_FINISH);
+ if (rc != Z_STREAM_END)
+ goto fail;
+ rc = inflateReset (& strm);
+ }
+ rc = inflateEnd (& strm);
+ if (rc != Z_OK
+ || strm.avail_out != 0)
+ goto fail;
+
+ free (compressed_buffer);
+ *buffer = uncompressed_buffer;
+ *size = uncompressed_size;
+ return 1;
+
+ fail:
+ free (uncompressed_buffer);
+ return 0;
+#endif /* HAVE_ZLIB_H */
+}
+
static int
load_specific_debug_section (enum dwarf_section_display_enum debug,
Elf_Internal_Shdr * sec, void * file)
@@ -8551,7 +8574,7 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
return 0;
if (debug_displays [debug].relocate)
- debug_apply_relocations (file, sec, section->start);
+ apply_relocations (file, sec, section->start);
return 1;
}
@@ -8700,13 +8723,16 @@ process_section_contents (FILE * file)
disassemble_section (section, file);
#endif
if (dump_sects[i] & HEX_DUMP)
- dump_section_as_bytes (section, file);
+ dump_section_as_bytes (section, file, FALSE);
- if (dump_sects[i] & DEBUG_DUMP)
- display_debug_section (section, file);
+ if (dump_sects[i] & RELOC_DUMP)
+ dump_section_as_bytes (section, file, TRUE);
if (dump_sects[i] & STRING_DUMP)
dump_section_as_strings (section, file);
+
+ if (dump_sects[i] & DEBUG_DUMP)
+ display_debug_section (section, file);
}
/* Check to see if the user requested a