1 /* ar.c - Archive modify and extract.
2 Copyright 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 Bugs: should use getopt the way tar does (complete w/optional -) and
22 should have long options too. GNU ar used to check file against filesystem
23 in quick_update and replace operations (would check mtime). Doesn't warn
24 when name truncated. No way to specify pos_end. Error messages should be
28 #include "libiberty.h"
36 #ifdef HAVE_GOOD_UTIME_H
38 #else /* ! HAVE_GOOD_UTIME_H */
41 #endif /* HAVE_UTIMES */
42 #endif /* ! HAVE_GOOD_UTIME_H */
45 #define EXT_NAME_LEN 3 /* bufflen of addition to name if it's MS-DOS */
47 #define EXT_NAME_LEN 6 /* ditto for *NIX */
52 /* Kludge declaration from BFD! This is ugly! FIXME! XXX */
55 bfd_special_undocumented_glue PARAMS ((bfd * abfd, const char *filename));
57 /* Static declarations */
60 mri_emul PARAMS ((void));
63 normalize PARAMS ((const char *, bfd *));
66 remove_output PARAMS ((void));
69 map_over_members PARAMS ((bfd *, void (*)(bfd *), char **, int));
72 print_contents PARAMS ((bfd * member));
75 delete_members PARAMS ((bfd *, char **files_to_delete));
79 do_quick_append PARAMS ((const char *archive_filename,
80 char **files_to_append));
84 move_members PARAMS ((bfd *, char **files_to_move));
87 replace_members PARAMS ((bfd *, char **files_to_replace, boolean quick));
90 print_descr PARAMS ((bfd * abfd));
93 write_archive PARAMS ((bfd *));
96 ranlib_only PARAMS ((const char *archname));
99 ranlib_touch PARAMS ((const char *archname));
102 usage PARAMS ((int));
104 /** Globals and flags */
108 /* This flag distinguishes between ar and ranlib:
109 1 means this is 'ranlib'; 0 means this is 'ar'.
110 -1 means if we should use argv[0] to decide. */
111 extern int is_ranlib;
113 /* Nonzero means don't warn about creating the archive file if necessary. */
114 int silent_create = 0;
116 /* Nonzero means describe each action performed. */
119 /* Nonzero means preserve dates of members when extracting them. */
120 int preserve_dates = 0;
122 /* Nonzero means don't replace existing members whose dates are more recent
123 than the corresponding files. */
126 /* Controls the writing of an archive symbol table (in BSD: a __.SYMDEF
127 member). -1 means we've been explicitly asked to not write a symbol table;
128 +1 means we've been explictly asked to write it;
130 Traditionally, the default in BSD has been to not write the table.
131 However, for POSIX.2 compliance the default is now to write a symbol table
132 if any of the members are object files. */
135 /* Nonzero means it's the name of an existing member; position new or moved
136 files with respect to this one. */
137 char *posname = NULL;
139 /* Sez how to use `posname': pos_before means position before that member.
140 pos_after means position after that member. pos_end means always at end.
141 pos_default means default appropriately. For the latter two, `posname'
142 should also be zero. */
145 pos_default, pos_before, pos_after, pos_end
146 } postype = pos_default;
149 get_pos_bfd PARAMS ((bfd **, enum pos, const char *));
151 /* Whether to truncate names of files stored in the archive. */
152 static boolean ar_truncate = false;
159 interactive = isatty (fileno (stdin));
163 /* If COUNT is 0, then FUNCTION is called once on each entry. If nonzero,
164 COUNT is the length of the FILES chain; FUNCTION is called on each entry
165 whose name matches one in FILES. */
168 map_over_members (arch, function, files, count)
170 void (*function) PARAMS ((bfd *));
178 for (head = arch->next; head; head = head->next)
185 /* This may appear to be a baroque way of accomplishing what we want.
186 However we have to iterate over the filenames in order to notice where
187 a filename is requested but does not exist in the archive. Ditto
188 mapping over each file each time -- we want to hack multiple
191 for (; count > 0; files++, count--)
193 boolean found = false;
195 for (head = arch->next; head; head = head->next)
198 if (head->filename == NULL)
200 /* Some archive formats don't get the filenames filled in
201 until the elements are opened. */
203 bfd_stat_arch_elt (head, &buf);
205 if ((head->filename != NULL) &&
206 (!strcmp (*files, head->filename)))
213 fprintf (stderr, _("no entry %s in archive\n"), *files);
217 boolean operation_alters_arch = false;
225 s = help ? stdout : stderr;
228 Usage: %s [-]{dmpqrtx}[abcilosSuvV] [member-name] archive-file file...\n\
229 %s -M [<mri-script]\n"),
230 program_name, program_name);
233 Usage: %s [-vV] archive\n"), program_name);
235 list_supported_targets (program_name, stderr);
238 fprintf (s, _("Report bugs to bug-gnu-utils@gnu.org\n"));
240 xexit (help ? 0 : 1);
243 /* Normalize a file name specified on the command line into a file
244 name which we will use in an archive. */
247 normalize (file, abfd)
251 const char *filename;
253 filename = strrchr (file, '/');
254 if (filename != (char *) NULL)
261 && strlen (filename) > abfd->xvec->ar_max_namelen)
266 s = (char *) xmalloc (abfd->xvec->ar_max_namelen + 1);
267 memcpy (s, filename, abfd->xvec->ar_max_namelen);
268 s[abfd->xvec->ar_max_namelen] = '\0';
275 /* Remove any output file. This is only called via xatexit. */
277 static char *output_filename = NULL;
278 static FILE *output_file = NULL;
279 static bfd *output_bfd = NULL;
284 if (output_filename != NULL)
286 if (output_bfd != NULL && output_bfd->iostream != NULL)
287 fclose ((FILE *) (output_bfd->iostream));
288 if (output_file != NULL)
289 fclose (output_file);
290 unlink (output_filename);
294 /* The option parsing should be in its own function.
295 It will be when I have getopt working. */
306 none = 0, delete, replace, print_table,
307 print_files, extract, move, quick_append
311 char *inarch_filename;
314 setlocale (LC_MESSAGES, "");
315 bindtextdomain (PACKAGE, LOCALEDIR);
316 textdomain (PACKAGE);
318 program_name = argv[0];
319 xmalloc_set_program_name (program_name);
325 temp = strrchr (program_name, '/');
330 if (strlen (temp) >= 6
331 && strcmp (temp + strlen (temp) - 6, "ranlib") == 0)
337 if (argc > 1 && argv[1][0] == '-')
339 if (strcmp (argv[1], "--help") == 0)
341 else if (strcmp (argv[1], "--version") == 0)
344 print_version ("ranlib");
346 print_version ("ar");
350 START_PROGRESS (program_name, 0);
353 set_default_bfd_target ();
357 xatexit (remove_output);
361 boolean touch = false;
363 if (argc < 2 || strcmp (argv[1], "--help") == 0)
365 if (strcmp (argv[1], "-V") == 0
366 || strcmp (argv[1], "-v") == 0
367 || strncmp (argv[1], "--v", 3) == 0)
368 print_version ("ranlib");
370 if (strcmp (argv[1], "-t") == 0)
375 while (arg_index < argc)
378 ranlib_only (argv[arg_index]);
380 ranlib_touch (argv[arg_index]);
386 if (argc == 2 && strcmp (argv[1], "-M") == 0)
398 ++arg_ptr; /* compatibility */
400 while ((c = *arg_ptr++) != '\0')
411 if (operation != none)
412 fatal (_("two different operation options specified"));
417 operation_alters_arch = true;
421 operation_alters_arch = true;
424 operation = print_files;
427 operation = quick_append;
428 operation_alters_arch = true;
432 operation_alters_arch = true;
435 operation = print_table;
468 postype = pos_before;
471 postype = pos_before;
480 fprintf (stderr, _("%s: illegal option -- %c\n"), program_name, c);
486 print_version ("ar");
499 /* We can't write an armap when using ar q, so just do ar r
501 if (operation == quick_append && write_armap)
504 if ((operation == none || operation == print_table)
507 ranlib_only (argv[2]);
511 if (operation == none)
512 fatal (_("no operation specified"));
514 if (newer_only && operation != replace)
515 fatal (_("`u' is only meaningful with the `r' option."));
519 if (postype != pos_default)
520 posname = argv[arg_index++];
522 inarch_filename = argv[arg_index++];
524 files = arg_index < argc ? argv + arg_index : NULL;
527 /* We don't use do_quick_append any more. Too many systems
528 expect ar to always rebuild the symbol table even when q is
531 /* We can't do a quick append if we need to construct an
532 extended name table, because do_quick_append won't be able to
533 rebuild the name table. Unfortunately, at this point we
534 don't actually know the maximum name length permitted by this
535 object file format. So, we guess. FIXME. */
536 if (operation == quick_append && ! ar_truncate)
540 for (chk = files; chk != NULL && *chk != '\0'; chk++)
542 if (strlen (normalize (*chk, (bfd *) NULL)) > 14)
550 if (operation == quick_append)
552 /* Note that quick appending to a non-existent archive creates it,
553 even if there are no files to append. */
554 do_quick_append (inarch_filename, files);
559 arch = open_inarch (inarch_filename,
560 files == NULL ? (char *) NULL : files[0]);
565 map_over_members (arch, print_descr, files, argc - 3);
569 map_over_members (arch, print_contents, files, argc - 3);
573 map_over_members (arch, extract_file, files, argc - 3);
578 delete_members (arch, files);
583 move_members (arch, files);
588 if (files != NULL || write_armap > 0)
589 replace_members (arch, files, operation == quick_append);
592 /* Shouldn't happen! */
594 fprintf (stderr, _("%s: internal error -- this option not implemented\n"),
600 END_PROGRESS (program_name);
607 open_inarch (archive_filename, file)
608 const char *archive_filename;
618 bfd_set_error (bfd_error_no_error);
622 if (stat (archive_filename, &sbuf) != 0)
626 /* KLUDGE ALERT! Temporary fix until I figger why
627 * stat() is wrong ... think it's buried in GO32's IDT
631 bfd_fatal (archive_filename);
634 if (!operation_alters_arch)
636 fprintf (stderr, "%s: ", program_name);
637 perror (archive_filename);
642 /* Try to figure out the target to use for the archive from the
643 first object on the list. */
648 obj = bfd_openr (file, NULL);
651 if (bfd_check_format (obj, bfd_object))
652 target = bfd_get_target (obj);
653 (void) bfd_close (obj);
657 /* Create an empty archive. */
658 arch = bfd_openw (archive_filename, target);
660 || ! bfd_set_format (arch, bfd_archive)
661 || ! bfd_close (arch))
662 bfd_fatal (archive_filename);
665 arch = bfd_openr (archive_filename, target);
669 bfd_fatal (archive_filename);
672 if (! bfd_check_format_matches (arch, bfd_archive, &matching))
674 bfd_nonfatal (archive_filename);
675 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
677 list_matching_formats (matching);
683 last_one = &(arch->next);
684 /* Read all the contents right away, regardless. */
685 for (next_one = bfd_openr_next_archived_file (arch, NULL);
687 next_one = bfd_openr_next_archived_file (arch, next_one))
690 *last_one = next_one;
691 last_one = &next_one->next;
693 *last_one = (bfd *) NULL;
694 if (bfd_get_error () != bfd_error_no_more_archived_files)
700 print_contents (abfd)
704 char *cbuf = xmalloc (BUFSIZE);
707 if (bfd_stat_arch_elt (abfd, &buf) != 0)
708 fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
711 printf (_("\n<member %s>\n\n"), bfd_get_filename (abfd));
713 bfd_seek (abfd, 0, SEEK_SET);
716 while (ncopied < size)
720 int tocopy = size - ncopied;
721 if (tocopy > BUFSIZE)
724 nread = bfd_read (cbuf, 1, tocopy, abfd); /* oops -- broke
727 fatal (_("%s is not a valid archive"),
728 bfd_get_filename (bfd_my_archive (abfd)));
729 fwrite (cbuf, 1, nread, stdout);
735 /* Extract a member of the archive into its own file.
737 We defer opening the new file until after we have read a BUFSIZ chunk of the
738 old one, since we know we have just read the archive header for the old
739 one. Since most members are shorter than BUFSIZ, this means we will read
740 the old header, read the old data, write a new inode for the new file, and
741 write the new data, and be done. This 'optimization' is what comes from
742 sitting next to a bare disk and hearing it every time it seeks. -- Gnu
750 char *cbuf = xmalloc (BUFSIZE);
755 if (bfd_stat_arch_elt (abfd, &buf) != 0)
756 fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
760 printf ("x - %s\n", bfd_get_filename (abfd));
762 bfd_seek (abfd, 0, SEEK_SET);
767 /* Seems like an abstraction violation, eh? Well it's OK! */
768 output_filename = bfd_get_filename (abfd);
770 ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
773 perror (bfd_get_filename (abfd));
777 output_file = ostream;
780 while (ncopied < size)
782 tocopy = size - ncopied;
783 if (tocopy > BUFSIZE)
786 nread = bfd_read (cbuf, 1, tocopy, abfd);
788 fatal (_("%s is not a valid archive"),
789 bfd_get_filename (bfd_my_archive (abfd)));
791 /* See comment above; this saves disk arm motion */
794 /* Seems like an abstraction violation, eh? Well it's OK! */
795 output_filename = bfd_get_filename (abfd);
797 ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
800 perror (bfd_get_filename (abfd));
804 output_file = ostream;
806 fwrite (cbuf, 1, nread, ostream);
813 output_filename = NULL;
815 chmod (bfd_get_filename (abfd), buf.st_mode);
819 #ifdef HAVE_GOOD_UTIME_H
821 tb.actime = buf.st_mtime;
822 tb.modtime = buf.st_mtime;
823 utime (bfd_get_filename (abfd), &tb); /* FIXME check result */
824 #else /* ! HAVE_GOOD_UTIME_H */
827 tb[0] = buf.st_mtime;
828 tb[1] = buf.st_mtime;
829 utime (bfd_get_filename (abfd), tb); /* FIXME check result */
830 #else /* HAVE_UTIMES */
831 struct timeval tv[2];
832 tv[0].tv_sec = buf.st_mtime;
834 tv[1].tv_sec = buf.st_mtime;
836 utimes (bfd_get_filename (abfd), tv); /* FIXME check result */
837 #endif /* HAVE_UTIMES */
838 #endif /* ! HAVE_GOOD_UTIME_H */
845 /* We don't use this anymore. Too many systems expect ar to rebuild
846 the symbol table even when q is used. */
848 /* Just do it quickly; don't worry about dups, armap, or anything like that */
851 do_quick_append (archive_filename, files_to_append)
852 const char *archive_filename;
853 char **files_to_append;
856 char *buf = xmalloc (BUFSIZE);
857 long tocopy, thistime;
860 boolean newfile = false;
861 bfd_set_error (bfd_error_no_error);
863 if (stat (archive_filename, &sbuf) != 0)
868 /* KLUDGE ALERT! Temporary fix until I figger why
869 * stat() is wrong ... think it's buried in GO32's IDT
874 bfd_fatal (archive_filename);
880 ofile = fopen (archive_filename, FOPEN_AUB);
883 perror (program_name);
887 temp = bfd_openr (archive_filename, NULL);
890 bfd_fatal (archive_filename);
892 if (newfile == false)
894 if (bfd_check_format (temp, bfd_archive) != true)
895 fatal (_("%s is not an archive"), archive_filename);
899 fwrite (ARMAG, 1, SARMAG, ofile);
901 fprintf (stderr, _("%s: creating %s\n"),
902 program_name, archive_filename);
906 temp->flags |= BFD_TRADITIONAL_FORMAT;
908 /* assume it's an achive, go straight to the end, sans $200 */
911 for (; files_to_append && *files_to_append; ++files_to_append)
913 struct ar_hdr *hdr = bfd_special_undocumented_glue (temp, *files_to_append);
916 bfd_fatal (*files_to_append);
919 BFD_SEND (temp, _bfd_truncate_arname, (temp, *files_to_append, (char *) hdr));
921 ifile = fopen (*files_to_append, FOPEN_RB);
924 bfd_nonfatal (*files_to_append);
927 if (stat (*files_to_append, &sbuf) != 0)
929 bfd_nonfatal (*files_to_append);
932 tocopy = sbuf.st_size;
934 /* XXX should do error-checking! */
935 fwrite (hdr, 1, sizeof (struct ar_hdr), ofile);
940 if (thistime > BUFSIZE)
942 fread (buf, 1, thistime, ifile);
943 fwrite (buf, 1, thistime, ofile);
947 if ((sbuf.st_size % 2) == 1)
948 putc ('\012', ofile);
958 write_archive (iarch)
962 char *old_name, *new_name;
963 bfd *contents_head = iarch->next;
965 old_name = xmalloc (strlen (bfd_get_filename (iarch)) + 1);
966 strcpy (old_name, bfd_get_filename (iarch));
967 new_name = make_tempname (old_name);
969 output_filename = new_name;
971 obfd = bfd_openw (new_name, bfd_get_target (iarch));
974 bfd_fatal (old_name);
978 bfd_set_format (obfd, bfd_archive);
980 /* Request writing the archive symbol table unless we've
981 been explicitly requested not to. */
982 obfd->has_armap = write_armap >= 0;
986 /* This should really use bfd_set_file_flags, but that rejects
988 obfd->flags |= BFD_TRADITIONAL_FORMAT;
991 if (bfd_set_archive_head (obfd, contents_head) != true)
992 bfd_fatal (old_name);
994 if (!bfd_close (obfd))
995 bfd_fatal (old_name);
998 output_filename = NULL;
1000 /* We don't care if this fails; we might be creating the archive. */
1004 if (rename (new_name, old_name) != 0)
1005 bfd_fatal (old_name);
1008 /* Return a pointer to the pointer to the entry which should be rplacd'd
1009 into when altering. DEFAULT_POS should be how to interpret pos_default,
1010 and should be a pos value. */
1013 get_pos_bfd (contents, default_pos, default_posname)
1015 enum pos default_pos;
1016 const char *default_posname;
1018 bfd **after_bfd = contents;
1020 const char *realposname;
1022 if (postype == pos_default)
1024 realpos = default_pos;
1025 realposname = default_posname;
1030 realposname = posname;
1033 if (realpos == pos_end)
1036 after_bfd = &((*after_bfd)->next);
1040 for (; *after_bfd; after_bfd = &(*after_bfd)->next)
1041 if (strcmp ((*after_bfd)->filename, realposname) == 0)
1043 if (realpos == pos_after)
1044 after_bfd = &(*after_bfd)->next;
1052 delete_members (arch, files_to_delete)
1054 char **files_to_delete;
1056 bfd **current_ptr_ptr;
1058 boolean something_changed = false;
1059 for (; *files_to_delete != NULL; ++files_to_delete)
1061 /* In a.out systems, the armap is optional. It's also called
1062 __.SYMDEF. So if the user asked to delete it, we should remember
1063 that fact. This isn't quite right for COFF systems (where
1064 __.SYMDEF might be regular member), but it's very unlikely
1065 to be a problem. FIXME */
1067 if (!strcmp (*files_to_delete, "__.SYMDEF"))
1069 arch->has_armap = false;
1075 current_ptr_ptr = &(arch->next);
1076 while (*current_ptr_ptr)
1078 if (strcmp (*files_to_delete, (*current_ptr_ptr)->filename) == 0)
1081 something_changed = true;
1085 *current_ptr_ptr = ((*current_ptr_ptr)->next);
1090 current_ptr_ptr = &((*current_ptr_ptr)->next);
1094 if (verbose && found == false)
1096 printf (_("No member named `%s'\n"), *files_to_delete);
1102 if (something_changed == true)
1104 write_archive (arch);
1109 /* Reposition existing members within an archive */
1112 move_members (arch, files_to_move)
1114 char **files_to_move;
1116 bfd **after_bfd; /* New entries go after this one */
1117 bfd **current_ptr_ptr; /* cdr pointer into contents */
1119 for (; *files_to_move; ++files_to_move)
1121 current_ptr_ptr = &(arch->next);
1122 while (*current_ptr_ptr)
1124 bfd *current_ptr = *current_ptr_ptr;
1125 if (strcmp (normalize (*files_to_move, arch),
1126 current_ptr->filename) == 0)
1128 /* Move this file to the end of the list - first cut from
1131 *current_ptr_ptr = current_ptr->next;
1133 /* Now glue to end */
1134 after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
1136 *after_bfd = current_ptr;
1137 current_ptr->next = link;
1140 printf ("m - %s\n", *files_to_move);
1145 current_ptr_ptr = &((*current_ptr_ptr)->next);
1147 fprintf (stderr, _("%s: no entry %s in archive %s!\n"),
1148 program_name, *files_to_move, arch->filename);
1153 write_archive (arch);
1156 /* Ought to default to replacing in place, but this is existing practice! */
1159 replace_members (arch, files_to_move, quick)
1161 char **files_to_move;
1164 boolean changed = false;
1165 bfd **after_bfd; /* New entries go after this one */
1170 while (files_to_move && *files_to_move)
1174 current_ptr = &arch->next;
1175 while (*current_ptr)
1177 current = *current_ptr;
1179 /* For compatibility with existing ar programs, we
1180 permit the same file to be added multiple times. */
1181 if (strcmp (normalize (*files_to_move, arch),
1182 normalize (current->filename, arch)) == 0
1183 && current->arelt_data != NULL)
1187 struct stat fsbuf, asbuf;
1189 if (stat (*files_to_move, &fsbuf) != 0)
1191 if (errno != ENOENT)
1192 bfd_fatal (*files_to_move);
1195 if (bfd_stat_arch_elt (current, &asbuf) != 0)
1196 fatal (_("internal stat error on %s"), current->filename);
1198 if (fsbuf.st_mtime <= asbuf.st_mtime)
1202 after_bfd = get_pos_bfd (&arch->next, pos_after,
1206 *after_bfd = bfd_openr (*files_to_move, NULL);
1207 if (*after_bfd == (bfd *) NULL)
1209 bfd_fatal (*files_to_move);
1211 (*after_bfd)->next = temp;
1213 /* snip out this entry from the chain */
1214 *current_ptr = (*current_ptr)->next;
1218 printf ("r - %s\n", *files_to_move);
1225 current_ptr = &(current->next);
1229 /* Add to the end of the archive. */
1231 after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
1233 *after_bfd = bfd_openr (*files_to_move, NULL);
1234 if (*after_bfd == (bfd *) NULL)
1236 bfd_fatal (*files_to_move);
1240 printf ("a - %s\n", *files_to_move);
1243 (*after_bfd)->next = temp;
1253 write_archive (arch);
1257 ranlib_only (archname)
1258 const char *archname;
1263 arch = open_inarch (archname, (char *) NULL);
1266 write_archive (arch);
1269 /* Update the timestamp of the symbol map of an archive. */
1272 ranlib_touch (archname)
1273 const char *archname;
1276 /* I don't think updating works on go32. */
1277 ranlib_only (archname);
1283 f = open (archname, O_RDWR, 0);
1286 bfd_set_error (bfd_error_system_call);
1287 bfd_fatal (archname);
1290 arch = bfd_fdopenr (archname, (const char *) NULL, f);
1292 bfd_fatal (archname);
1293 if (! bfd_check_format_matches (arch, bfd_archive, &matching))
1295 bfd_nonfatal (archname);
1296 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1298 list_matching_formats (matching);
1304 if (! bfd_has_map (arch))
1305 fatal (_("%s: no archive map to update"), archname);
1307 bfd_update_armap_timestamp (arch);
1309 if (! bfd_close (arch))
1310 bfd_fatal (archname);
1314 /* Things which are interesting to map over all or some of the files: */
1320 print_arelt_descr (stdout, abfd, verbose);