* readelf.c (dump_type): New type used to classify the kinds of dump requested by the user.
(dump_sects, cmdline_dump_sects): Use the new type. (options): Add --string-dump option. (request_dump): Rename to request_dump_bynumber. Use dump_type. (request_dump_byname): Use dump_type. (parse_args): Parse --string-dump option. (process_section_headers): Fix calls to request_dump. (initialise_dumps_byname): Likewise. (dump_section): Rename to dump_section_as_bytes. (dump_section_as_strings): New function. Display the contents of a section as printable strings. (process_section_contents): String dump the section if requested. (process_object): Use dump_type. (main): Likewise. * Makefile.am: Add dependency for readelf.c on safe-ctype.h. * Makefile.in: Regenerate. * NEWS: Mention the new feature. * doc/binutils.texi: Document the new feature. * testsuite/binutils-all/dumptest.s: New test file. * testsuite/binutils-all/readelf.exp: Add test of readelf's -p switch.
This commit is contained in:
parent
7cd410025f
commit
09c11c861b
@ -1,3 +1,25 @@
|
|||||||
|
2007-08-30 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
* readelf.c (dump_type): New type used to classify the kinds of
|
||||||
|
dump requested by the user.
|
||||||
|
(dump_sects, cmdline_dump_sects): Use the new type.
|
||||||
|
(options): Add --string-dump option.
|
||||||
|
(request_dump): Rename to request_dump_bynumber. Use dump_type.
|
||||||
|
(request_dump_byname): Use dump_type.
|
||||||
|
(parse_args): Parse --string-dump option.
|
||||||
|
(process_section_headers): Fix calls to request_dump.
|
||||||
|
(initialise_dumps_byname): Likewise.
|
||||||
|
(dump_section): Rename to dump_section_as_bytes.
|
||||||
|
(dump_section_as_strings): New function. Display the contents of
|
||||||
|
a section as printable strings.
|
||||||
|
(process_section_contents): String dump the section if requested.
|
||||||
|
(process_object): Use dump_type.
|
||||||
|
(main): Likewise.
|
||||||
|
* Makefile.am: Add dependency for readelf.c on safe-ctype.h.
|
||||||
|
* Makefile.in: Regenerate.
|
||||||
|
* NEWS: Mention the new feature.
|
||||||
|
* doc/binutils.texi: Document the new feature.
|
||||||
|
|
||||||
2007-08-30 Nathan Sidwell <nathan@codesourcery.com>
|
2007-08-30 Nathan Sidwell <nathan@codesourcery.com>
|
||||||
|
|
||||||
* bucomm.c (bfd_nonfatal_message): New.
|
* bucomm.c (bfd_nonfatal_message): New.
|
||||||
|
@ -593,7 +593,7 @@ readelf.o: readelf.c sysdep.h $(INCDIR)/ansidecl.h \
|
|||||||
$(INCDIR)/elf/spu.h $(INCDIR)/elf/v850.h $(INCDIR)/elf/vax.h \
|
$(INCDIR)/elf/spu.h $(INCDIR)/elf/v850.h $(INCDIR)/elf/vax.h \
|
||||||
$(INCDIR)/elf/x86-64.h $(INCDIR)/elf/xstormy16.h $(INCDIR)/elf/xtensa.h \
|
$(INCDIR)/elf/x86-64.h $(INCDIR)/elf/xstormy16.h $(INCDIR)/elf/xtensa.h \
|
||||||
$(INCDIR)/aout/ar.h $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \
|
$(INCDIR)/aout/ar.h $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \
|
||||||
unwind-ia64.h
|
unwind-ia64.h $(INCDIR)/safe-ctype.h
|
||||||
rename.o: rename.c sysdep.h $(INCDIR)/ansidecl.h ../bfd/bfdver.h \
|
rename.o: rename.c sysdep.h $(INCDIR)/ansidecl.h ../bfd/bfdver.h \
|
||||||
config.h $(INCDIR)/fopen-same.h ../bfd/bfd.h $(INCDIR)/ansidecl.h \
|
config.h $(INCDIR)/fopen-same.h ../bfd/bfd.h $(INCDIR)/ansidecl.h \
|
||||||
$(INCDIR)/symcat.h bucomm.h
|
$(INCDIR)/symcat.h bucomm.h
|
||||||
|
@ -532,15 +532,15 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
|
|||||||
@for dep in $?; do \
|
@for dep in $?; do \
|
||||||
case '$(am__configure_deps)' in \
|
case '$(am__configure_deps)' in \
|
||||||
*$$dep*) \
|
*$$dep*) \
|
||||||
echo ' cd $(srcdir) && $(AUTOMAKE) --cygnus '; \
|
echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \
|
||||||
cd $(srcdir) && $(AUTOMAKE) --cygnus \
|
cd $(srcdir) && $(AUTOMAKE) --foreign \
|
||||||
&& exit 0; \
|
&& exit 0; \
|
||||||
exit 1;; \
|
exit 1;; \
|
||||||
esac; \
|
esac; \
|
||||||
done; \
|
done; \
|
||||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile'; \
|
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
|
||||||
cd $(top_srcdir) && \
|
cd $(top_srcdir) && \
|
||||||
$(AUTOMAKE) --cygnus Makefile
|
$(AUTOMAKE) --foreign Makefile
|
||||||
.PRECIOUS: Makefile
|
.PRECIOUS: Makefile
|
||||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||||
@case '$?' in \
|
@case '$?' in \
|
||||||
@ -1343,7 +1343,7 @@ readelf.o: readelf.c sysdep.h $(INCDIR)/ansidecl.h \
|
|||||||
$(INCDIR)/elf/spu.h $(INCDIR)/elf/v850.h $(INCDIR)/elf/vax.h \
|
$(INCDIR)/elf/spu.h $(INCDIR)/elf/v850.h $(INCDIR)/elf/vax.h \
|
||||||
$(INCDIR)/elf/x86-64.h $(INCDIR)/elf/xstormy16.h $(INCDIR)/elf/xtensa.h \
|
$(INCDIR)/elf/x86-64.h $(INCDIR)/elf/xstormy16.h $(INCDIR)/elf/xtensa.h \
|
||||||
$(INCDIR)/aout/ar.h $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \
|
$(INCDIR)/aout/ar.h $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \
|
||||||
unwind-ia64.h
|
unwind-ia64.h $(INCDIR)/safe-ctype.h
|
||||||
rename.o: rename.c sysdep.h $(INCDIR)/ansidecl.h ../bfd/bfdver.h \
|
rename.o: rename.c sysdep.h $(INCDIR)/ansidecl.h ../bfd/bfdver.h \
|
||||||
config.h $(INCDIR)/fopen-same.h ../bfd/bfd.h $(INCDIR)/ansidecl.h \
|
config.h $(INCDIR)/fopen-same.h ../bfd/bfd.h $(INCDIR)/ansidecl.h \
|
||||||
$(INCDIR)/symcat.h bucomm.h
|
$(INCDIR)/symcat.h bucomm.h
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
-*- text -*-
|
-*- text -*-
|
||||||
|
* Added -p switch to readelf to allow string dumps of sections.
|
||||||
|
|
||||||
Changes in 2.18:
|
Changes in 2.18:
|
||||||
* Resolved 37 coding problems in bfd including static array overruns, null
|
* Resolved 37 coding problems in bfd including static array overruns, null
|
||||||
pointer dereferences and use of a malloc buffer after it has been freed, as
|
pointer dereferences and use of a malloc buffer after it has been freed, as
|
||||||
|
@ -282,9 +282,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
|
|||||||
exit 1;; \
|
exit 1;; \
|
||||||
esac; \
|
esac; \
|
||||||
done; \
|
done; \
|
||||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --cygnus doc/Makefile'; \
|
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \
|
||||||
cd $(top_srcdir) && \
|
cd $(top_srcdir) && \
|
||||||
$(AUTOMAKE) --cygnus doc/Makefile
|
$(AUTOMAKE) --foreign doc/Makefile
|
||||||
.PRECIOUS: Makefile
|
.PRECIOUS: Makefile
|
||||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||||
@case '$?' in \
|
@case '$?' in \
|
||||||
|
@ -3601,6 +3601,7 @@ readelf [@option{-a}|@option{--all}]
|
|||||||
[@option{-A}|@option{--arch-specific}]
|
[@option{-A}|@option{--arch-specific}]
|
||||||
[@option{-D}|@option{--use-dynamic}]
|
[@option{-D}|@option{--use-dynamic}]
|
||||||
[@option{-x} <number or name>|@option{--hex-dump=}<number or name>]
|
[@option{-x} <number or name>|@option{--hex-dump=}<number or name>]
|
||||||
|
[@option{-p} <number or name>|@option{--string-dump=}<number or name>]
|
||||||
[@option{-w[liaprmfFsoR]}|
|
[@option{-w[liaprmfFsoR]}|
|
||||||
@option{--debug-dump}[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges]]
|
@option{--debug-dump}[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges]]
|
||||||
[@option{-I}|@option{-histogram}]
|
[@option{-I}|@option{-histogram}]
|
||||||
@ -3726,6 +3727,12 @@ Displays the contents of the indicated section as a hexadecimal dump.
|
|||||||
A number identifies a particular section by index in the section table;
|
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.
|
any other string identifies all sections with that name in the object file.
|
||||||
|
|
||||||
|
@item -p <number or name>
|
||||||
|
@itemx --string-dump=<number or name>
|
||||||
|
Displays the contents of the indicated section as printable strings.
|
||||||
|
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 -w[liaprmfFsoR]
|
@item -w[liaprmfFsoR]
|
||||||
@itemx --debug-dump[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges]
|
@itemx --debug-dump[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges]
|
||||||
Displays the contents of the debug sections in the file, if any are
|
Displays the contents of the debug sections in the file, if any are
|
||||||
|
@ -158,6 +158,7 @@
|
|||||||
|
|
||||||
#include "getopt.h"
|
#include "getopt.h"
|
||||||
#include "libiberty.h"
|
#include "libiberty.h"
|
||||||
|
#include "safe-ctype.h"
|
||||||
|
|
||||||
char *program_name = "readelf";
|
char *program_name = "readelf";
|
||||||
static long archive_file_offset;
|
static long archive_file_offset;
|
||||||
@ -219,33 +220,37 @@ static size_t group_count;
|
|||||||
static struct group *section_groups;
|
static struct group *section_groups;
|
||||||
static struct group **section_headers_groups;
|
static struct group **section_headers_groups;
|
||||||
|
|
||||||
/* A linked list of the section names for which dumps were requested
|
|
||||||
by name. */
|
/* Flag bits indicating particular types of dump. */
|
||||||
|
#define HEX_DUMP (1 << 0) /* The -x command line switch. */
|
||||||
|
#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. */
|
||||||
|
|
||||||
|
typedef unsigned char dump_type;
|
||||||
|
|
||||||
|
/* A linked list of the section names for which dumps were requested. */
|
||||||
struct dump_list_entry
|
struct dump_list_entry
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
int type;
|
dump_type type;
|
||||||
struct dump_list_entry *next;
|
struct dump_list_entry *next;
|
||||||
};
|
};
|
||||||
static struct dump_list_entry *dump_sects_byname;
|
static struct dump_list_entry *dump_sects_byname;
|
||||||
|
|
||||||
/* A dynamic array of flags indicating for which sections a hex dump
|
/* A dynamic array of flags indicating for which sections a dump
|
||||||
has been requested (via the -x switch) and/or a disassembly dump
|
has been requested via command line switches. */
|
||||||
(via the -i switch). */
|
static dump_type * cmdline_dump_sects = NULL;
|
||||||
char *cmdline_dump_sects = NULL;
|
static unsigned int num_cmdline_dump_sects = 0;
|
||||||
unsigned num_cmdline_dump_sects = 0;
|
|
||||||
|
|
||||||
/* A dynamic array of flags indicating for which sections a dump of
|
/* A dynamic array of flags indicating for which sections a dump of
|
||||||
some kind has been requested. It is reset on a per-object file
|
some kind has been requested. It is reset on a per-object file
|
||||||
basis and then initialised from the cmdline_dump_sects array,
|
basis and then initialised from the cmdline_dump_sects array,
|
||||||
the results of interpreting the -w switch, and the
|
the results of interpreting the -w switch, and the
|
||||||
dump_sects_byname list. */
|
dump_sects_byname list. */
|
||||||
char *dump_sects = NULL;
|
static dump_type * dump_sects = NULL;
|
||||||
unsigned int num_dump_sects = 0;
|
static unsigned int num_dump_sects = 0;
|
||||||
|
|
||||||
#define HEX_DUMP (1 << 0)
|
|
||||||
#define DISASS_DUMP (1 << 1)
|
|
||||||
#define DEBUG_DUMP (1 << 2)
|
|
||||||
|
|
||||||
/* How to print a vma value. */
|
/* How to print a vma value. */
|
||||||
typedef enum print_mode
|
typedef enum print_mode
|
||||||
@ -2745,9 +2750,10 @@ static struct option options[] =
|
|||||||
{"arch-specific", no_argument, 0, 'A'},
|
{"arch-specific", no_argument, 0, 'A'},
|
||||||
{"version-info", no_argument, 0, 'V'},
|
{"version-info", no_argument, 0, 'V'},
|
||||||
{"use-dynamic", no_argument, 0, 'D'},
|
{"use-dynamic", no_argument, 0, 'D'},
|
||||||
|
{"unwind", no_argument, 0, 'u'},
|
||||||
{"hex-dump", required_argument, 0, 'x'},
|
{"hex-dump", required_argument, 0, 'x'},
|
||||||
{"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
|
{"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
|
||||||
{"unwind", no_argument, 0, 'u'},
|
{"string-dump", required_argument, 0, 'p'},
|
||||||
#ifdef SUPPORT_DISASSEMBLY
|
#ifdef SUPPORT_DISASSEMBLY
|
||||||
{"instruction-dump", required_argument, 0, 'i'},
|
{"instruction-dump", required_argument, 0, 'i'},
|
||||||
#endif
|
#endif
|
||||||
@ -2782,14 +2788,17 @@ usage (FILE *stream)
|
|||||||
-V --version-info Display the version sections (if present)\n\
|
-V --version-info Display the version sections (if present)\n\
|
||||||
-A --arch-specific Display architecture specific information (if any).\n\
|
-A --arch-specific Display architecture specific information (if any).\n\
|
||||||
-D --use-dynamic Use the dynamic section info when displaying symbols\n\
|
-D --use-dynamic Use the dynamic section info when displaying symbols\n\
|
||||||
-x --hex-dump=<number> Dump the contents of section <number>\n\
|
-x --hex-dump=<number|name>\n\
|
||||||
|
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\
|
||||||
-w[liaprmfFsoR] or\n\
|
-w[liaprmfFsoR] or\n\
|
||||||
--debug-dump[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=str,=loc,=Ranges]\n\
|
--debug-dump[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=str,=loc,=Ranges]\n\
|
||||||
Display the contents of DWARF2 debug sections\n"));
|
Display the contents of DWARF2 debug sections\n"));
|
||||||
#ifdef SUPPORT_DISASSEMBLY
|
#ifdef SUPPORT_DISASSEMBLY
|
||||||
fprintf (stream, _("\
|
fprintf (stream, _("\
|
||||||
-i --instruction-dump=<number>\n\
|
-i --instruction-dump=<number|name>\n\
|
||||||
Disassemble the contents of section <number>\n"));
|
Disassemble the contents of section <number|name>\n"));
|
||||||
#endif
|
#endif
|
||||||
fprintf (stream, _("\
|
fprintf (stream, _("\
|
||||||
-I --histogram Display histogram of bucket list lengths\n\
|
-I --histogram Display histogram of bucket list lengths\n\
|
||||||
@ -2810,20 +2819,20 @@ usage (FILE *stream)
|
|||||||
the first time. */
|
the first time. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
request_dump (unsigned int section, int type)
|
request_dump_bynumber (unsigned int section, dump_type type)
|
||||||
{
|
{
|
||||||
if (section >= num_dump_sects)
|
if (section >= num_dump_sects)
|
||||||
{
|
{
|
||||||
char *new_dump_sects;
|
dump_type *new_dump_sects;
|
||||||
|
|
||||||
new_dump_sects = calloc (section + 1, 1);
|
new_dump_sects = calloc (section + 1, sizeof (* dump_sects));
|
||||||
|
|
||||||
if (new_dump_sects == NULL)
|
if (new_dump_sects == NULL)
|
||||||
error (_("Out of memory allocating dump request table.\n"));
|
error (_("Out of memory allocating dump request table.\n"));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Copy current flag settings. */
|
/* Copy current flag settings. */
|
||||||
memcpy (new_dump_sects, dump_sects, num_dump_sects);
|
memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
|
||||||
|
|
||||||
free (dump_sects);
|
free (dump_sects);
|
||||||
|
|
||||||
@ -2841,7 +2850,7 @@ request_dump (unsigned int section, int type)
|
|||||||
/* Request a dump by section name. */
|
/* Request a dump by section name. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
request_dump_byname (const char *section, int type)
|
request_dump_byname (const char *section, dump_type type)
|
||||||
{
|
{
|
||||||
struct dump_list_entry *new_request;
|
struct dump_list_entry *new_request;
|
||||||
|
|
||||||
@ -2868,7 +2877,7 @@ parse_args (int argc, char **argv)
|
|||||||
usage (stderr);
|
usage (stderr);
|
||||||
|
|
||||||
while ((c = getopt_long
|
while ((c = getopt_long
|
||||||
(argc, argv, "ersuahnldSDAINtgw::x:i:vVWH", options, NULL)) != EOF)
|
(argc, argv, "ersuahnldSDAINtgw::x:i:vVWHp:", options, NULL)) != EOF)
|
||||||
{
|
{
|
||||||
char *cp;
|
char *cp;
|
||||||
int section;
|
int section;
|
||||||
@ -2946,10 +2955,18 @@ parse_args (int argc, char **argv)
|
|||||||
do_dump++;
|
do_dump++;
|
||||||
section = strtoul (optarg, & cp, 0);
|
section = strtoul (optarg, & cp, 0);
|
||||||
if (! *cp && section >= 0)
|
if (! *cp && section >= 0)
|
||||||
request_dump (section, HEX_DUMP);
|
request_dump_bynumber (section, HEX_DUMP);
|
||||||
else
|
else
|
||||||
request_dump_byname (optarg, HEX_DUMP);
|
request_dump_byname (optarg, HEX_DUMP);
|
||||||
break;
|
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);
|
||||||
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
do_dump++;
|
do_dump++;
|
||||||
if (optarg == 0)
|
if (optarg == 0)
|
||||||
@ -3097,11 +3114,9 @@ parse_args (int argc, char **argv)
|
|||||||
do_dump++;
|
do_dump++;
|
||||||
section = strtoul (optarg, & cp, 0);
|
section = strtoul (optarg, & cp, 0);
|
||||||
if (! *cp && section >= 0)
|
if (! *cp && section >= 0)
|
||||||
{
|
request_dump_bynumber (section, DISASS_DUMP);
|
||||||
request_dump (section, DISASS_DUMP);
|
else
|
||||||
break;
|
request_dump_byname (optarg, DISASS_DUMP);
|
||||||
}
|
|
||||||
goto oops;
|
|
||||||
#endif
|
#endif
|
||||||
case 'v':
|
case 'v':
|
||||||
print_version (program_name);
|
print_version (program_name);
|
||||||
@ -3113,9 +3128,6 @@ parse_args (int argc, char **argv)
|
|||||||
do_wide++;
|
do_wide++;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#ifdef SUPPORT_DISASSEMBLY
|
|
||||||
oops:
|
|
||||||
#endif
|
|
||||||
/* xgettext:c-format */
|
/* xgettext:c-format */
|
||||||
error (_("Invalid option '-%c'\n"), c);
|
error (_("Invalid option '-%c'\n"), c);
|
||||||
/* Drop through. */
|
/* Drop through. */
|
||||||
@ -4182,14 +4194,14 @@ process_section_headers (FILE *file)
|
|||||||
|| (do_debug_str && streq (name, "str"))
|
|| (do_debug_str && streq (name, "str"))
|
||||||
|| (do_debug_loc && streq (name, "loc"))
|
|| (do_debug_loc && streq (name, "loc"))
|
||||||
)
|
)
|
||||||
request_dump (i, DEBUG_DUMP);
|
request_dump_bynumber (i, DEBUG_DUMP);
|
||||||
}
|
}
|
||||||
/* linkonce section to be combined with .debug_info at link time. */
|
/* linkonce section to be combined with .debug_info at link time. */
|
||||||
else if ((do_debugging || do_debug_info)
|
else if ((do_debugging || do_debug_info)
|
||||||
&& const_strneq (name, ".gnu.linkonce.wi."))
|
&& const_strneq (name, ".gnu.linkonce.wi."))
|
||||||
request_dump (i, DEBUG_DUMP);
|
request_dump_bynumber (i, DEBUG_DUMP);
|
||||||
else if (do_debug_frames && streq (name, ".eh_frame"))
|
else if (do_debug_frames && streq (name, ".eh_frame"))
|
||||||
request_dump (i, DEBUG_DUMP);
|
request_dump_bynumber (i, DEBUG_DUMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! do_sections)
|
if (! do_sections)
|
||||||
@ -7670,7 +7682,84 @@ disassemble_section (Elf_Internal_Shdr *section, FILE *file)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dump_section (Elf_Internal_Shdr *section, FILE *file)
|
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)
|
||||||
|
|| SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
|
||||||
|
|| SECTION_HEADER (relsec->sh_info) != section
|
||||||
|
|| relsec->sh_size == 0
|
||||||
|
|| SECTION_HEADER_INDEX (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)
|
||||||
|
{
|
||||||
|
printf (" [%6zx] %s\n", data - start, data);
|
||||||
|
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;
|
Elf_Internal_Shdr *relsec;
|
||||||
bfd_size_type bytes;
|
bfd_size_type bytes;
|
||||||
@ -8023,7 +8112,7 @@ initialise_dumps_byname (void)
|
|||||||
for (i = 0, any = 0; i < elf_header.e_shnum; i++)
|
for (i = 0, any = 0; i < elf_header.e_shnum; i++)
|
||||||
if (streq (SECTION_NAME (section_headers + i), cur->name))
|
if (streq (SECTION_NAME (section_headers + i), cur->name))
|
||||||
{
|
{
|
||||||
request_dump (i, cur->type);
|
request_dump_bynumber (i, cur->type);
|
||||||
any = 1;
|
any = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8053,10 +8142,13 @@ process_section_contents (FILE *file)
|
|||||||
disassemble_section (section, file);
|
disassemble_section (section, file);
|
||||||
#endif
|
#endif
|
||||||
if (dump_sects[i] & HEX_DUMP)
|
if (dump_sects[i] & HEX_DUMP)
|
||||||
dump_section (section, file);
|
dump_section_as_bytes (section, file);
|
||||||
|
|
||||||
if (dump_sects[i] & DEBUG_DUMP)
|
if (dump_sects[i] & DEBUG_DUMP)
|
||||||
display_debug_section (section, file);
|
display_debug_section (section, file);
|
||||||
|
|
||||||
|
if (dump_sects[i] & STRING_DUMP)
|
||||||
|
dump_section_as_strings (section, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check to see if the user requested a
|
/* Check to see if the user requested a
|
||||||
@ -9554,16 +9646,17 @@ process_object (char *file_name, FILE *file)
|
|||||||
must make sure that the dump_sets array is zeroed out before each
|
must make sure that the dump_sets array is zeroed out before each
|
||||||
object file is processed. */
|
object file is processed. */
|
||||||
if (num_dump_sects > num_cmdline_dump_sects)
|
if (num_dump_sects > num_cmdline_dump_sects)
|
||||||
memset (dump_sects, 0, num_dump_sects);
|
memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
|
||||||
|
|
||||||
if (num_cmdline_dump_sects > 0)
|
if (num_cmdline_dump_sects > 0)
|
||||||
{
|
{
|
||||||
if (num_dump_sects == 0)
|
if (num_dump_sects == 0)
|
||||||
/* A sneaky way of allocating the dump_sects array. */
|
/* A sneaky way of allocating the dump_sects array. */
|
||||||
request_dump (num_cmdline_dump_sects, 0);
|
request_dump_bynumber (num_cmdline_dump_sects, 0);
|
||||||
|
|
||||||
assert (num_dump_sects >= num_cmdline_dump_sects);
|
assert (num_dump_sects >= num_cmdline_dump_sects);
|
||||||
memcpy (dump_sects, cmdline_dump_sects, num_cmdline_dump_sects);
|
memcpy (dump_sects, cmdline_dump_sects,
|
||||||
|
num_cmdline_dump_sects * sizeof (* dump_sects));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! process_file_header ())
|
if (! process_file_header ())
|
||||||
@ -9938,12 +10031,13 @@ main (int argc, char **argv)
|
|||||||
if (num_dump_sects > 0)
|
if (num_dump_sects > 0)
|
||||||
{
|
{
|
||||||
/* Make a copy of the dump_sects array. */
|
/* Make a copy of the dump_sects array. */
|
||||||
cmdline_dump_sects = malloc (num_dump_sects);
|
cmdline_dump_sects = malloc (num_dump_sects * sizeof (* dump_sects));
|
||||||
if (cmdline_dump_sects == NULL)
|
if (cmdline_dump_sects == NULL)
|
||||||
error (_("Out of memory allocating dump request table.\n"));
|
error (_("Out of memory allocating dump request table.\n"));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy (cmdline_dump_sects, dump_sects, num_dump_sects);
|
memcpy (cmdline_dump_sects, dump_sects,
|
||||||
|
num_dump_sects * sizeof (* dump_sects));
|
||||||
num_cmdline_dump_sects = num_dump_sects;
|
num_cmdline_dump_sects = num_dump_sects;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2007-08-30 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
* binutils-all/dumptest.s: New test file.
|
||||||
|
* binutils-all/readelf.exp: Add test of readelf's -p switch.
|
||||||
|
|
||||||
2007-08-28 Mark Shinwell <shinwell@codesourcery.com>
|
2007-08-28 Mark Shinwell <shinwell@codesourcery.com>
|
||||||
Joseph Myers <joseph@codesourcery.com>
|
Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
|
2
binutils/testsuite/binutils-all/dumptest.s
Normal file
2
binutils/testsuite/binutils-all/dumptest.s
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.data
|
||||||
|
.ascii "test_string"
|
@ -21,6 +21,12 @@
|
|||||||
# Based on scripts written by Ian Lance Taylor <ian@cygnus.com>
|
# Based on scripts written by Ian Lance Taylor <ian@cygnus.com>
|
||||||
# and Ken Raeburn <raeburn@cygnus.com>.
|
# and Ken Raeburn <raeburn@cygnus.com>.
|
||||||
|
|
||||||
|
# Exclude non-ELF targets.
|
||||||
|
if ![is_elf_format] {
|
||||||
|
verbose "$READELF is only intended for ELF targets" 2
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
# First some helpful procedures, then the tests themselves
|
# First some helpful procedures, then the tests themselves
|
||||||
|
|
||||||
# Return the contents of the filename given
|
# Return the contents of the filename given
|
||||||
@ -203,10 +209,58 @@ proc readelf_wi_test {} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Exclude non-ELF targets.
|
# Test readelf's dumping abilities.
|
||||||
if ![is_elf_format] {
|
|
||||||
verbose "$READELF is only intended for ELF targets" 2
|
proc readelf_dump_test {} {
|
||||||
return
|
global READELF
|
||||||
|
global READELFFLAGS
|
||||||
|
global srcdir
|
||||||
|
global subdir
|
||||||
|
|
||||||
|
# Assemble the dump test file.
|
||||||
|
if {![binutils_assemble $srcdir/$subdir/dumptest.s tmpdir/dumptest.o]} then {
|
||||||
|
unresolved "readelf -p: failed to assemble dump test file"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
# Download it.
|
||||||
|
set tempfile [remote_download host tmpdir/dumptest.o]
|
||||||
|
|
||||||
|
# Run "readelf -p.data" on it.
|
||||||
|
set got [remote_exec host "$READELF $READELFFLAGS -p.data $tempfile" "" "/dev/null" "readelf.out"]
|
||||||
|
set got [lindex $got 1]
|
||||||
|
|
||||||
|
# Upload the results.
|
||||||
|
set output [remote_upload host readelf.out]
|
||||||
|
|
||||||
|
# Check for something going wrong.
|
||||||
|
if ![string match "" $got] then {
|
||||||
|
fail "readelf -p: unexpected output"
|
||||||
|
send_log $got
|
||||||
|
send_log "\n"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Search for strings that should be in the output.
|
||||||
|
set sought {
|
||||||
|
".*test_string.*"
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach looked_for $sought {
|
||||||
|
set lines [grep $output $looked_for]
|
||||||
|
if ![llength $lines] then {
|
||||||
|
fail "readelf -p: missing: $looked_for"
|
||||||
|
send_log readelf.out
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file_on_host delete $tempfile
|
||||||
|
file_on_host delete $output
|
||||||
|
|
||||||
|
# All done.
|
||||||
|
pass "readelf -p"
|
||||||
|
|
||||||
|
# XXX FIXME: Add test of readelf -x here
|
||||||
}
|
}
|
||||||
|
|
||||||
if ![is_remote host] {
|
if ![is_remote host] {
|
||||||
@ -220,7 +274,7 @@ send_user "Version [binutil_version $READELF]"
|
|||||||
|
|
||||||
# Assemble the test file.
|
# Assemble the test file.
|
||||||
if {![binutils_assemble $srcdir/$subdir/bintest.s tmpdir/bintest.o]} then {
|
if {![binutils_assemble $srcdir/$subdir/bintest.s tmpdir/bintest.o]} then {
|
||||||
perror "unresolved 1"
|
perror "could not assemble test file"
|
||||||
unresolved "readelf - failed to assemble"
|
unresolved "readelf - failed to assemble"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -241,3 +295,5 @@ readelf_test -s $tempfile readelf.ss {}
|
|||||||
readelf_test -r $tempfile readelf.r {}
|
readelf_test -r $tempfile readelf.r {}
|
||||||
|
|
||||||
readelf_wi_test
|
readelf_wi_test
|
||||||
|
|
||||||
|
readelf_dump_test
|
||||||
|
Loading…
Reference in New Issue
Block a user