]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
* readelf.c (dump_type): New type used to classify the kinds of dump requested by...
authorNick Clifton <nickc@redhat.com>
Thu, 30 Aug 2007 13:47:35 +0000 (13:47 +0000)
committerNick Clifton <nickc@redhat.com>
Thu, 30 Aug 2007 13:47:35 +0000 (13:47 +0000)
  (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.

binutils/ChangeLog
binutils/Makefile.am
binutils/Makefile.in
binutils/NEWS
binutils/doc/Makefile.in
binutils/doc/binutils.texi
binutils/readelf.c
binutils/testsuite/ChangeLog
binutils/testsuite/binutils-all/dumptest.s [new file with mode: 0644]
binutils/testsuite/binutils-all/readelf.exp

index 430b9545d103f87277c91548467f050bcb3ab2e4..0f6b0756883f3e8a997eb20238e4299812a3b5be 100644 (file)
@@ -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>
 
        * bucomm.c (bfd_nonfatal_message): New.
index 047622cb5e77e3741586186abf1a8160afd99637..9590b18d4cd52a205d509fe54dec37eb1ab2c53a 100644 (file)
@@ -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/x86-64.h $(INCDIR)/elf/xstormy16.h $(INCDIR)/elf/xtensa.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 \
   config.h $(INCDIR)/fopen-same.h ../bfd/bfd.h $(INCDIR)/ansidecl.h \
   $(INCDIR)/symcat.h bucomm.h
index eead9efcc484ea05cfa9c0595bd2cca8a06f6d0c..e0fc8f3179424cb2cd5243c93472c6e19cc0ff50 100644 (file)
@@ -532,15 +532,15 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__confi
        @for dep in $?; do \
          case '$(am__configure_deps)' in \
            *$$dep*) \
-             echo ' cd $(srcdir) && $(AUTOMAKE) --cygnus '; \
-             cd $(srcdir) && $(AUTOMAKE) --cygnus  \
+             echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \
+             cd $(srcdir) && $(AUTOMAKE) --foreign  \
                && exit 0; \
              exit 1;; \
          esac; \
        done; \
-       echo ' cd $(top_srcdir) && $(AUTOMAKE) --cygnus  Makefile'; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  Makefile'; \
        cd $(top_srcdir) && \
-         $(AUTOMAKE) --cygnus  Makefile
+         $(AUTOMAKE) --foreign  Makefile
 .PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
        @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/x86-64.h $(INCDIR)/elf/xstormy16.h $(INCDIR)/elf/xtensa.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 \
   config.h $(INCDIR)/fopen-same.h ../bfd/bfd.h $(INCDIR)/ansidecl.h \
   $(INCDIR)/symcat.h bucomm.h
index 20070d794c7d136e8a4369dc562579d99de29c2f..0009c6f9e0db7579f0739771520bf5606eead6c6 100644 (file)
@@ -1,4 +1,6 @@
 -*- text -*-
+* Added -p switch to readelf to allow string dumps of sections.
+
 Changes in 2.18:
 * 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
index d258024e5746d7fcdf9de708d5ec6661c6bbfe5a..8136d2a999e836b17f3636894b6e56d437d3ccb7 100644 (file)
@@ -282,9 +282,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__confi
              exit 1;; \
          esac; \
        done; \
-       echo ' cd $(top_srcdir) && $(AUTOMAKE) --cygnus  doc/Makefile'; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  doc/Makefile'; \
        cd $(top_srcdir) && \
-         $(AUTOMAKE) --cygnus  doc/Makefile
+         $(AUTOMAKE) --foreign  doc/Makefile
 .PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
        @case '$?' in \
index 52787f772d3ebda74cc79780bd4fc11b29c4e61e..a2768bf7e3a0935c53c13ec2446f41c34d33d18d 100644 (file)
@@ -3601,6 +3601,7 @@ readelf [@option{-a}|@option{--all}]
         [@option{-A}|@option{--arch-specific}]
         [@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{-w[liaprmfFsoR]}|
          @option{--debug-dump}[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges]]
         [@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;
 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]
 @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
index 9fc8e0cf0513c477385261c73ca90f2620577222..e166dca7c427513dc39e2e2b6ef091d85e39ca88 100644 (file)
 
 #include "getopt.h"
 #include "libiberty.h"
+#include "safe-ctype.h"
 
 char *program_name = "readelf";
 static long archive_file_offset;
@@ -219,33 +220,37 @@ static size_t group_count;
 static struct group *section_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
 {
   char *name;
-  int type;
+  dump_type type;
   struct dump_list_entry *next;
 };
 static struct dump_list_entry *dump_sects_byname;
 
-/* A dynamic array of flags indicating for which sections a hex dump
-   has been requested (via the -x switch) and/or a disassembly dump
-   (via the -i switch).  */
-char *cmdline_dump_sects = NULL;
-unsigned num_cmdline_dump_sects = 0;
+/* A dynamic array of flags indicating for which sections a dump
+   has been requested via command line switches.  */
+static dump_type *   cmdline_dump_sects = NULL;
+static unsigned int  num_cmdline_dump_sects = 0;
 
 /* 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
    basis and then initialised from the cmdline_dump_sects array,
    the results of interpreting the -w switch, and the
    dump_sects_byname list.  */
-char *dump_sects = NULL;
-unsigned int num_dump_sects = 0;
+static dump_type *   dump_sects = NULL;
+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.  */
 typedef enum print_mode
@@ -2745,9 +2750,10 @@ static struct option options[] =
   {"arch-specific",    no_argument, 0, 'A'},
   {"version-info",     no_argument, 0, 'V'},
   {"use-dynamic",      no_argument, 0, 'D'},
+  {"unwind",          no_argument, 0, 'u'},
   {"hex-dump",        required_argument, 0, 'x'},
   {"debug-dump",       optional_argument, 0, OPTION_DEBUG_DUMP},
-  {"unwind",          no_argument, 0, 'u'},
+  {"string-dump",      required_argument, 0, 'p'},
 #ifdef SUPPORT_DISASSEMBLY
   {"instruction-dump", required_argument, 0, 'i'},
 #endif
@@ -2782,14 +2788,17 @@ usage (FILE *stream)
   -V --version-info      Display the version sections (if present)\n\
   -A --arch-specific     Display architecture specific information (if any).\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\
   --debug-dump[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=str,=loc,=Ranges]\n\
                          Display the contents of DWARF2 debug sections\n"));
 #ifdef SUPPORT_DISASSEMBLY
   fprintf (stream, _("\
-  -i --instruction-dump=<number>\n\
-                         Disassemble the contents of section <number>\n"));
+  -i --instruction-dump=<number|name>\n\
+                         Disassemble the contents of section <number|name>\n"));
 #endif
   fprintf (stream, _("\
   -I --histogram         Display histogram of bucket list lengths\n\
@@ -2810,20 +2819,20 @@ usage (FILE *stream)
    the first time.  */
 
 static void
-request_dump (unsigned int section, int type)
+request_dump_bynumber (unsigned int section, dump_type type)
 {
   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)
        error (_("Out of memory allocating dump request table.\n"));
       else
        {
          /* 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);
 
@@ -2841,7 +2850,7 @@ request_dump (unsigned int section, int type)
 /* Request a dump by section name.  */
 
 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;
 
@@ -2868,7 +2877,7 @@ parse_args (int argc, char **argv)
     usage (stderr);
 
   while ((c = getopt_long
-         (argc, argv, "ersuahnldSDAINtgw::x:i:vVWH", options, NULL)) != EOF)
+         (argc, argv, "ersuahnldSDAINtgw::x:i:vVWHp:", options, NULL)) != EOF)
     {
       char *cp;
       int section;
@@ -2946,10 +2955,18 @@ parse_args (int argc, char **argv)
          do_dump++;
          section = strtoul (optarg, & cp, 0);
          if (! *cp && section >= 0)
-           request_dump (section, HEX_DUMP);
+           request_dump_bynumber (section, HEX_DUMP);
          else
            request_dump_byname (optarg, 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);
+         break;
        case 'w':
          do_dump++;
          if (optarg == 0)
@@ -3097,11 +3114,9 @@ parse_args (int argc, char **argv)
          do_dump++;
          section = strtoul (optarg, & cp, 0);
          if (! *cp && section >= 0)
-           {
-             request_dump (section, DISASS_DUMP);
-             break;
-           }
-         goto oops;
+           request_dump_bynumber (section, DISASS_DUMP);
+         else
+           request_dump_byname (optarg, DISASS_DUMP);
 #endif
        case 'v':
          print_version (program_name);
@@ -3113,9 +3128,6 @@ parse_args (int argc, char **argv)
          do_wide++;
          break;
        default:
-#ifdef SUPPORT_DISASSEMBLY
-       oops:
-#endif
          /* xgettext:c-format */
          error (_("Invalid option '-%c'\n"), c);
          /* Drop through.  */
@@ -4182,14 +4194,14 @@ process_section_headers (FILE *file)
              || (do_debug_str      && streq (name, "str"))
              || (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.  */
       else if ((do_debugging || do_debug_info)
               && 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"))
-       request_dump (i, DEBUG_DUMP);
+       request_dump_bynumber (i, DEBUG_DUMP);
     }
 
   if (! do_sections)
@@ -7670,7 +7682,84 @@ disassemble_section (Elf_Internal_Shdr *section, FILE *file)
 #endif
 
 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;
   bfd_size_type bytes;
@@ -8023,7 +8112,7 @@ initialise_dumps_byname (void)
       for (i = 0, any = 0; i < elf_header.e_shnum; i++)
        if (streq (SECTION_NAME (section_headers + i), cur->name))
          {
-           request_dump (i, cur->type);
+           request_dump_bynumber (i, cur->type);
            any = 1;
          }
 
@@ -8053,10 +8142,13 @@ process_section_contents (FILE *file)
        disassemble_section (section, file);
 #endif
       if (dump_sects[i] & HEX_DUMP)
-       dump_section (section, file);
+       dump_section_as_bytes (section, file);
 
       if (dump_sects[i] & DEBUG_DUMP)
        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
@@ -9554,16 +9646,17 @@ process_object (char *file_name, FILE *file)
      must make sure that the dump_sets array is zeroed out before each
      object file is processed.  */
   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_dump_sects == 0)
        /* 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);
-      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 ())
@@ -9938,12 +10031,13 @@ main (int argc, char **argv)
   if (num_dump_sects > 0)
     {
       /* 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)
        error (_("Out of memory allocating dump request table.\n"));
       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;
        }
     }
index c1fcd3ca1173b08b9a69821355c4c2fec047cc6c..82292aa46beb9b5ad859fb8f1458723b8df0545e 100644 (file)
@@ -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>
             Joseph Myers  <joseph@codesourcery.com>
 
diff --git a/binutils/testsuite/binutils-all/dumptest.s b/binutils/testsuite/binutils-all/dumptest.s
new file mode 100644 (file)
index 0000000..6335d22
--- /dev/null
@@ -0,0 +1,2 @@
+       .data
+       .ascii "test_string"
index d8ba1c0d4068d15e3b2df9721df8561c618bcf68..52be1ee58e49303f99380c32128a56558fe0062e 100644 (file)
 # Based on scripts written by Ian Lance Taylor <ian@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
 
 # Return the contents of the filename given
@@ -203,10 +209,58 @@ proc readelf_wi_test {} {
 }
 
 
-# Exclude non-ELF targets.
-if ![is_elf_format] {
-    verbose "$READELF is only intended for ELF targets" 2
-    return
+# Test readelf's dumping abilities.
+
+proc readelf_dump_test {} {
+    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] {
@@ -220,7 +274,7 @@ send_user "Version [binutil_version $READELF]"
 
 # Assemble the test file.
 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"
     return
 }
@@ -241,3 +295,5 @@ readelf_test -s $tempfile readelf.ss {}
 readelf_test -r $tempfile readelf.r  {}
 
 readelf_wi_test
+
+readelf_dump_test