Add option to ar's 't' command to display the offset of elements within the archive.
authorAnt Bikeneev <ant.bikineev@gmail.com>
Wed, 30 May 2018 16:06:26 +0000 (17:06 +0100)
committerNick Clifton <nickc@redhat.com>
Wed, 30 May 2018 16:08:03 +0000 (17:08 +0100)
PR 23107
* ar.c (display_offsets): New variable.
(usage): Add description of 'O' operator.
(decode_option): Handle 'O' operator.
(print_descr): Pass display_offsets to print_arelt_descr.
* arsup.c: Update call to printy_arelt_descr.
* objdump.c: Likewise.
* bucomm.c (print_arelt_descr): If offsets parameter is true then
display offset of archive element within the archive.
* bucomm.h: Update prototype for print_arelt_descr.
* doc/binutils.texi: Update description of ar command.
* NEWS: Mention the new feature.
* testsuite/binutils-all/ar.exp: Add text of new feature.

binutils/ChangeLog
binutils/NEWS
binutils/ar.c
binutils/arsup.c
binutils/bucomm.c
binutils/bucomm.h
binutils/doc/binutils.texi
binutils/objdump.c
binutils/testsuite/binutils-all/ar.exp

index 185dffd..8e1172a 100644 (file)
@@ -1,3 +1,19 @@
+2018-05-30  Ant Bikeneev  <ant.bikineev@gmail.com>
+
+       PR 23107
+       * ar.c (display_offsets): New variable.
+       (usage): Add description of 'O' operator.
+       (decode_option): Handle 'O' operator.
+       (print_descr): Pass display_offsets to print_arelt_descr.
+       * arsup.c: Update call to printy_arelt_descr.
+       * objdump.c: Likewise.
+       * bucomm.c (print_arelt_descr): If offsets parameter is true then
+       display offset of archive element within the archive.
+       * bucomm.h: Update prototype for print_arelt_descr.
+       * doc/binutils.texi: Update description of ar command.
+       * NEWS: Mention the new feature.
+       * testsuite/binutils-all/ar.exp: Add text of new feature.
+
 2018-05-28  Alan Modra  <amodra@gmail.com>
 
        PR 23235
index d90d889..5a35f61 100644 (file)
@@ -10,6 +10,8 @@
 * The AArch64 port now emits warnings when a combination of an instruction and
   a named register could be invalid.
 
+* Added O modifier to ar to display member offsets inside an archive
+
 Changes in 2.30:
 
 * Add --debug-dump=links option to readelf and --dwarf=links option to objdump
index 66a81e7..28a6789 100644 (file)
@@ -75,6 +75,9 @@ int silent_create = 0;
 /* Nonzero means describe each action performed.  */
 int verbose = 0;
 
+/* Nonzero means display offsets of files in the archive.  */
+int display_offsets = 0;
+
 /* Nonzero means preserve dates of members when extracting them.  */
 int preserve_dates = 0;
 
@@ -268,13 +271,13 @@ usage (int help)
 #if BFD_SUPPORTS_PLUGINS
   /* xgettext:c-format */
   const char *command_line
-    = _("Usage: %s [emulation options] [-]{dmpqrstx}[abcDfilMNoPsSTuvV]"
+    = _("Usage: %s [emulation options] [-]{dmpqrstx}[abcDfilMNoOPsSTuvV]"
        " [--plugin <name>] [member-name] [count] archive-file file...\n");
 
 #else
   /* xgettext:c-format */
   const char *command_line
-    = _("Usage: %s [emulation options] [-]{dmpqrstx}[abcDfilMNoPsSTuvV]"
+    = _("Usage: %s [emulation options] [-]{dmpqrstx}[abcDfilMNoOPsSTuvV]"
        " [member-name] [count] archive-file file...\n");
 #endif
   s = help ? stdout : stderr;
@@ -290,7 +293,7 @@ usage (int help)
   fprintf (s, _("  q[f]         - quick append file(s) to the archive\n"));
   fprintf (s, _("  r[ab][f][u]  - replace existing or insert new file(s) into the archive\n"));
   fprintf (s, _("  s            - act as ranlib\n"));
-  fprintf (s, _("  t            - display contents of archive\n"));
+  fprintf (s, _("  t[O][v]      - display contents of the archive\n"));
   fprintf (s, _("  x[o]         - extract file(s) from the archive\n"));
   fprintf (s, _(" command specific modifiers:\n"));
   fprintf (s, _("  [a]          - put file(s) after [member-name]\n"));
@@ -313,6 +316,7 @@ usage (int help)
   fprintf (s, _("  [f]          - truncate inserted file names\n"));
   fprintf (s, _("  [P]          - use full path names when matching\n"));
   fprintf (s, _("  [o]          - preserve original dates\n"));
+  fprintf (s, _("  [O]          - display offsets of files in the archive\n"));
   fprintf (s, _("  [u]          - only replace files that are newer than current archive contents\n"));
   fprintf (s, _(" generic modifiers:\n"));
   fprintf (s, _("  [c]          - do not warn if the library had to be created\n"));
@@ -473,7 +477,7 @@ decode_options (int argc, char **argv)
       argv = new_argv;
     }
 
-  while ((c = getopt_long (argc, argv, "hdmpqrtxlcoVsSuvabiMNfPTDU",
+  while ((c = getopt_long (argc, argv, "hdmpqrtxlcoOVsSuvabiMNfPTDU",
                           long_options, NULL)) != EOF)
     {
       switch (c)
@@ -528,6 +532,9 @@ decode_options (int argc, char **argv)
         case 'o':
           preserve_dates = 1;
           break;
+        case 'O':
+          display_offsets = 1;
+          break;
         case 'V':
           show_version = TRUE;
           break;
@@ -1503,5 +1510,5 @@ ranlib_touch (const char *archname)
 static void
 print_descr (bfd *abfd)
 {
-  print_arelt_descr (stdout, abfd, verbose);
+  print_arelt_descr (stdout, abfd, verbose, display_offsets);
 }
index ee2bb9b..dffce0b 100644 (file)
@@ -96,7 +96,7 @@ map_over_list (bfd *arch, void (*function) (bfd *, bfd *), struct list *list)
 static void
 ar_directory_doer (bfd *abfd, bfd *ignore ATTRIBUTE_UNUSED)
 {
-  print_arelt_descr(outfile, abfd, verbose);
+  print_arelt_descr(outfile, abfd, verbose, FALSE);
 }
 
 void
index d3a8d2d..8269c8d 100644 (file)
@@ -427,7 +427,7 @@ display_info (void)
    Mode       User\tGroup\tSize\tDate               Name */
 
 void
-print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose)
+print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose, bfd_boolean offsets)
 {
   struct stat buf;
 
@@ -458,7 +458,17 @@ print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose)
        }
     }
 
-  fprintf (file, "%s\n", bfd_get_filename (abfd));
+  fprintf (file, "%s", bfd_get_filename (abfd));
+
+  if (offsets)
+    {
+      if (bfd_is_thin_archive (abfd) && abfd->proxy_origin)
+        fprintf (file, " 0x%lx", (unsigned long) abfd->proxy_origin);
+      else if (!bfd_is_thin_archive (abfd) && abfd->origin)
+        fprintf (file, " 0x%lx", (unsigned long) abfd->origin);
+    }
+
+  fprintf (file, "\n");
 }
 
 /* Return a path for a new temporary file in the same directory
index cb97957..c49cc7e 100644 (file)
@@ -49,7 +49,7 @@ void list_supported_architectures (const char *, FILE *);
 
 int display_info (void);
 
-void print_arelt_descr (FILE *, bfd *, bfd_boolean);
+void print_arelt_descr (FILE *, bfd *, bfd_boolean, bfd_boolean);
 
 char *make_tempname (char *);
 char *make_tempdir (char *);
index e4d32b6..863ef31 100644 (file)
@@ -361,9 +361,10 @@ modifier.  In either case it does the same thing.
 @cindex contents of archive
 Display a @emph{table} listing the contents of @var{archive}, or those
 of the files listed in @var{member}@dots{} that are present in the
-archive.  Normally only the member name is shown; if you also want to
-see the modes (permissions), timestamp, owner, group, and size, you can
-request that by also specifying the @samp{v} modifier.
+archive.  Normally only the member name is shown, but if the modifier
+@samp{O} is specified, then the corresponding offset of the member is also
+displayed.  Finally, in order to see the modes (permissions), timestamp,
+owner, group, and size the @samp{v} modifier should be included.
 
 If you do not specify a @var{member}, all files in the archive
 are listed.
@@ -456,6 +457,11 @@ Preserve the @emph{original} dates of members when extracting them.  If
 you do not specify this modifier, files extracted from the archive
 are stamped with the time of extraction.
 
+@item O
+@cindex offsets of files
+Display member offsets inside the archive. Use together with the @samp{t}
+option.
+
 @item P
 Use the full path name when matching names in the archive.  @sc{gnu}
 @command{ar} can not create an archive with a full path name (such archives
index aab2063..f468fcd 100644 (file)
@@ -3582,7 +3582,7 @@ dump_bfd (bfd *abfd)
     printf (_("\n%s:     file format %s\n"), bfd_get_filename (abfd),
            abfd->xvec->name);
   if (dump_ar_hdrs)
-    print_arelt_descr (stdout, abfd, TRUE);
+    print_arelt_descr (stdout, abfd, TRUE, FALSE);
   if (dump_file_header)
     dump_bfd_header (abfd);
   if (dump_private_headers)
index f7c37b4..7abde85 100644 (file)
@@ -4,12 +4,12 @@
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation; either version 3 of the License, or
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
@@ -113,7 +113,7 @@ proc long_filenames { bfdtests } {
        fail $testname
        return
     }
-    
+
     if [is_remote host] {
        remote_file host delete $file1
        remote_file host delete $file2
@@ -435,6 +435,12 @@ proc deterministic_archive { } {
        return
     }
 
+    set got [binutils_run $AR "tvO $archive"]
+    if ![string match "rw-r--r-- 0/0 *bintest.o 0x*" $got] {
+       fail $testname
+       return
+    }
+
     pass $testname
 }
 
@@ -571,7 +577,7 @@ proc empty_archive { } {
 
     # FIXME: There ought to be a way to dynamically create an empty file.
     set empty $srcdir/$subdir/empty
-    
+
     if [is_remote host] {
        set archive artest.a
        set objfile [remote_download host $empty]