* 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.
This commit is contained in:
parent
ec3f783efd
commit
cf13d6995d
@ -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:
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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 },
|
||||
|
@ -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)
|
||||
/* 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)
|
||||
{
|
||||
printf (_("\nAssembly dump of section %s\n"),
|
||||
SECTION_NAME (section));
|
||||
unsigned int reloc_type = get_reloc_type (reloc->r_info);
|
||||
|
||||
/* 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)
|
||||
switch (elf_header.e_machine)
|
||||
{
|
||||
printf (_("\nSection '%s' has no data to dump.\n"), name);
|
||||
return 0;
|
||||
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 */
|
||||
case 2: /* R_MN10300_16 */
|
||||
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, reloc_type == 1 ? 4 : 2);
|
||||
|
||||
saved_sym = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (saved_sym != NULL)
|
||||
error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
dump_section_as_bytes (Elf_Internal_Shdr * section, FILE * file)
|
||||
{
|
||||
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;
|
||||
|
||||
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');
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user