xref: /openbsd-src/gnu/usr.bin/binutils-2.17/binutils/bucomm.c (revision e2674b3f065fea2bf9414499ea824b5945857fff)
13d8817e4Smiod /* bucomm.c -- Bin Utils COMmon code.
23d8817e4Smiod    Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2003
33d8817e4Smiod    Free Software Foundation, Inc.
43d8817e4Smiod 
53d8817e4Smiod    This file is part of GNU Binutils.
63d8817e4Smiod 
73d8817e4Smiod    This program is free software; you can redistribute it and/or modify
83d8817e4Smiod    it under the terms of the GNU General Public License as published by
93d8817e4Smiod    the Free Software Foundation; either version 2 of the License, or
103d8817e4Smiod    (at your option) any later version.
113d8817e4Smiod 
123d8817e4Smiod    This program is distributed in the hope that it will be useful,
133d8817e4Smiod    but WITHOUT ANY WARRANTY; without even the implied warranty of
143d8817e4Smiod    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
153d8817e4Smiod    GNU General Public License for more details.
163d8817e4Smiod 
173d8817e4Smiod    You should have received a copy of the GNU General Public License
183d8817e4Smiod    along with this program; if not, write to the Free Software
193d8817e4Smiod    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
203d8817e4Smiod    02110-1301, USA.  */
213d8817e4Smiod 
223d8817e4Smiod /* We might put this in a library someday so it could be dynamically
233d8817e4Smiod    loaded, but for now it's not necessary.  */
243d8817e4Smiod 
253d8817e4Smiod #include "bfd.h"
263d8817e4Smiod #include "bfdver.h"
273d8817e4Smiod #include "libiberty.h"
283d8817e4Smiod #include "bucomm.h"
293d8817e4Smiod #include "filenames.h"
303d8817e4Smiod #include "libbfd.h"
313d8817e4Smiod 
323d8817e4Smiod #include <sys/stat.h>
333d8817e4Smiod #include <time.h>		/* ctime, maybe time_t */
343d8817e4Smiod #include <assert.h>
353d8817e4Smiod 
363d8817e4Smiod #ifndef HAVE_TIME_T_IN_TIME_H
373d8817e4Smiod #ifndef HAVE_TIME_T_IN_TYPES_H
383d8817e4Smiod typedef long time_t;
393d8817e4Smiod #endif
403d8817e4Smiod #endif
413d8817e4Smiod 
423d8817e4Smiod static const char * endian_string (enum bfd_endian);
433d8817e4Smiod static int display_target_list (void);
443d8817e4Smiod static int display_info_table (int, int);
453d8817e4Smiod static int display_target_tables (void);
463d8817e4Smiod 
473d8817e4Smiod /* Error reporting.  */
483d8817e4Smiod 
493d8817e4Smiod char *program_name;
503d8817e4Smiod 
513d8817e4Smiod void
bfd_nonfatal(const char * string)523d8817e4Smiod bfd_nonfatal (const char *string)
533d8817e4Smiod {
543d8817e4Smiod   const char *errmsg = bfd_errmsg (bfd_get_error ());
553d8817e4Smiod 
563d8817e4Smiod   if (string)
573d8817e4Smiod     fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg);
583d8817e4Smiod   else
593d8817e4Smiod     fprintf (stderr, "%s: %s\n", program_name, errmsg);
603d8817e4Smiod }
613d8817e4Smiod 
623d8817e4Smiod void
bfd_fatal(const char * string)633d8817e4Smiod bfd_fatal (const char *string)
643d8817e4Smiod {
653d8817e4Smiod   bfd_nonfatal (string);
663d8817e4Smiod   xexit (1);
673d8817e4Smiod }
683d8817e4Smiod 
693d8817e4Smiod void
report(const char * format,va_list args)703d8817e4Smiod report (const char * format, va_list args)
713d8817e4Smiod {
723d8817e4Smiod   fprintf (stderr, "%s: ", program_name);
733d8817e4Smiod   vfprintf (stderr, format, args);
743d8817e4Smiod   putc ('\n', stderr);
753d8817e4Smiod }
763d8817e4Smiod 
773d8817e4Smiod void
fatal(const char * format,...)783d8817e4Smiod fatal VPARAMS ((const char *format, ...))
793d8817e4Smiod {
803d8817e4Smiod   VA_OPEN (args, format);
813d8817e4Smiod   VA_FIXEDARG (args, const char *, format);
823d8817e4Smiod 
833d8817e4Smiod   report (format, args);
843d8817e4Smiod   VA_CLOSE (args);
853d8817e4Smiod   xexit (1);
863d8817e4Smiod }
873d8817e4Smiod 
883d8817e4Smiod void
non_fatal(const char * format,...)893d8817e4Smiod non_fatal VPARAMS ((const char *format, ...))
903d8817e4Smiod {
913d8817e4Smiod   VA_OPEN (args, format);
923d8817e4Smiod   VA_FIXEDARG (args, const char *, format);
933d8817e4Smiod 
943d8817e4Smiod   report (format, args);
953d8817e4Smiod   VA_CLOSE (args);
963d8817e4Smiod }
973d8817e4Smiod 
983d8817e4Smiod /* Set the default BFD target based on the configured target.  Doing
993d8817e4Smiod    this permits the binutils to be configured for a particular target,
1003d8817e4Smiod    and linked against a shared BFD library which was configured for a
1013d8817e4Smiod    different target.  */
1023d8817e4Smiod 
1033d8817e4Smiod void
set_default_bfd_target(void)1043d8817e4Smiod set_default_bfd_target (void)
1053d8817e4Smiod {
1063d8817e4Smiod   /* The macro TARGET is defined by Makefile.  */
1073d8817e4Smiod   const char *target = TARGET;
1083d8817e4Smiod 
1093d8817e4Smiod   if (! bfd_set_default_target (target))
1103d8817e4Smiod     fatal (_("can't set BFD default target to `%s': %s"),
1113d8817e4Smiod 	   target, bfd_errmsg (bfd_get_error ()));
1123d8817e4Smiod }
1133d8817e4Smiod 
1143d8817e4Smiod /* After a FALSE return from bfd_check_format_matches with
1153d8817e4Smiod    bfd_get_error () == bfd_error_file_ambiguously_recognized, print
1163d8817e4Smiod    the possible matching targets.  */
1173d8817e4Smiod 
1183d8817e4Smiod void
list_matching_formats(char ** p)1193d8817e4Smiod list_matching_formats (char **p)
1203d8817e4Smiod {
1213d8817e4Smiod   fprintf (stderr, _("%s: Matching formats:"), program_name);
1223d8817e4Smiod   while (*p)
1233d8817e4Smiod     fprintf (stderr, " %s", *p++);
1243d8817e4Smiod   fputc ('\n', stderr);
1253d8817e4Smiod }
1263d8817e4Smiod 
1273d8817e4Smiod /* List the supported targets.  */
1283d8817e4Smiod 
1293d8817e4Smiod void
list_supported_targets(const char * name,FILE * f)1303d8817e4Smiod list_supported_targets (const char *name, FILE *f)
1313d8817e4Smiod {
1323d8817e4Smiod   int t;
1333d8817e4Smiod   const char **targ_names = bfd_target_list ();
1343d8817e4Smiod 
1353d8817e4Smiod   if (name == NULL)
1363d8817e4Smiod     fprintf (f, _("Supported targets:"));
1373d8817e4Smiod   else
1383d8817e4Smiod     fprintf (f, _("%s: supported targets:"), name);
1393d8817e4Smiod 
1403d8817e4Smiod   for (t = 0; targ_names[t] != NULL; t++)
1413d8817e4Smiod     fprintf (f, " %s", targ_names[t]);
1423d8817e4Smiod   fprintf (f, "\n");
1433d8817e4Smiod   free (targ_names);
1443d8817e4Smiod }
1453d8817e4Smiod 
1463d8817e4Smiod /* List the supported architectures.  */
1473d8817e4Smiod 
1483d8817e4Smiod void
list_supported_architectures(const char * name,FILE * f)1493d8817e4Smiod list_supported_architectures (const char *name, FILE *f)
1503d8817e4Smiod {
1513d8817e4Smiod   const char **arch;
1523d8817e4Smiod 
1533d8817e4Smiod   if (name == NULL)
1543d8817e4Smiod     fprintf (f, _("Supported architectures:"));
1553d8817e4Smiod   else
1563d8817e4Smiod     fprintf (f, _("%s: supported architectures:"), name);
1573d8817e4Smiod 
1583d8817e4Smiod   for (arch = bfd_arch_list (); *arch; arch++)
1593d8817e4Smiod     fprintf (f, " %s", *arch);
1603d8817e4Smiod   fprintf (f, "\n");
1613d8817e4Smiod }
1623d8817e4Smiod 
1633d8817e4Smiod /* The length of the longest architecture name + 1.  */
1643d8817e4Smiod #define LONGEST_ARCH sizeof ("powerpc:common")
1653d8817e4Smiod 
1663d8817e4Smiod static const char *
endian_string(enum bfd_endian endian)1673d8817e4Smiod endian_string (enum bfd_endian endian)
1683d8817e4Smiod {
1693d8817e4Smiod   switch (endian)
1703d8817e4Smiod     {
1713d8817e4Smiod     case BFD_ENDIAN_BIG: return "big endian";
1723d8817e4Smiod     case BFD_ENDIAN_LITTLE: return "little endian";
1733d8817e4Smiod     default: return "endianness unknown";
1743d8817e4Smiod     }
1753d8817e4Smiod }
1763d8817e4Smiod 
1773d8817e4Smiod /* List the targets that BFD is configured to support, each followed
1783d8817e4Smiod    by its endianness and the architectures it supports.  */
1793d8817e4Smiod 
1803d8817e4Smiod static int
display_target_list(void)1813d8817e4Smiod display_target_list (void)
1823d8817e4Smiod {
1833d8817e4Smiod   char *dummy_name;
1843d8817e4Smiod   int t;
1853d8817e4Smiod   int ret = 1;
1863d8817e4Smiod 
1873d8817e4Smiod   dummy_name = make_temp_file (NULL);
1883d8817e4Smiod   for (t = 0; bfd_target_vector[t]; t++)
1893d8817e4Smiod     {
1903d8817e4Smiod       const bfd_target *p = bfd_target_vector[t];
1913d8817e4Smiod       bfd *abfd = bfd_openw (dummy_name, p->name);
1923d8817e4Smiod       enum bfd_architecture a;
1933d8817e4Smiod 
1943d8817e4Smiod       printf ("%s\n (header %s, data %s)\n", p->name,
1953d8817e4Smiod 	      endian_string (p->header_byteorder),
1963d8817e4Smiod 	      endian_string (p->byteorder));
1973d8817e4Smiod 
1983d8817e4Smiod       if (abfd == NULL)
1993d8817e4Smiod 	{
2003d8817e4Smiod           bfd_nonfatal (dummy_name);
2013d8817e4Smiod           ret = 0;
2023d8817e4Smiod 	  continue;
2033d8817e4Smiod 	}
2043d8817e4Smiod 
2053d8817e4Smiod       if (! bfd_set_format (abfd, bfd_object))
2063d8817e4Smiod 	{
2073d8817e4Smiod 	  if (bfd_get_error () != bfd_error_invalid_operation)
2083d8817e4Smiod             {
2093d8817e4Smiod 	      bfd_nonfatal (p->name);
2103d8817e4Smiod               ret = 0;
2113d8817e4Smiod             }
2123d8817e4Smiod 	  bfd_close_all_done (abfd);
2133d8817e4Smiod 	  continue;
2143d8817e4Smiod 	}
2153d8817e4Smiod 
2163d8817e4Smiod       for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
2173d8817e4Smiod 	if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
2183d8817e4Smiod 	  printf ("  %s\n",
2193d8817e4Smiod 		  bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
2203d8817e4Smiod       bfd_close_all_done (abfd);
2213d8817e4Smiod     }
2223d8817e4Smiod   unlink (dummy_name);
2233d8817e4Smiod   free (dummy_name);
2243d8817e4Smiod 
2253d8817e4Smiod   return ret;
2263d8817e4Smiod }
2273d8817e4Smiod 
2283d8817e4Smiod /* Print a table showing which architectures are supported for entries
2293d8817e4Smiod    FIRST through LAST-1 of bfd_target_vector (targets across,
2303d8817e4Smiod    architectures down).  */
2313d8817e4Smiod 
2323d8817e4Smiod static int
display_info_table(int first,int last)2333d8817e4Smiod display_info_table (int first, int last)
2343d8817e4Smiod {
2353d8817e4Smiod   int t;
2363d8817e4Smiod   int ret = 1;
2373d8817e4Smiod   char *dummy_name;
2383d8817e4Smiod   enum bfd_architecture a;
2393d8817e4Smiod 
2403d8817e4Smiod   /* Print heading of target names.  */
2413d8817e4Smiod   printf ("\n%*s", (int) LONGEST_ARCH, " ");
2423d8817e4Smiod   for (t = first; t < last && bfd_target_vector[t]; t++)
2433d8817e4Smiod     printf ("%s ", bfd_target_vector[t]->name);
2443d8817e4Smiod   putchar ('\n');
2453d8817e4Smiod 
2463d8817e4Smiod   dummy_name = make_temp_file (NULL);
2473d8817e4Smiod   for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
2483d8817e4Smiod     if (strcmp (bfd_printable_arch_mach (a, 0), "UNKNOWN!") != 0)
2493d8817e4Smiod       {
2503d8817e4Smiod 	printf ("%*s ", (int) LONGEST_ARCH - 1,
2513d8817e4Smiod 		bfd_printable_arch_mach (a, 0));
2523d8817e4Smiod 	for (t = first; t < last && bfd_target_vector[t]; t++)
2533d8817e4Smiod 	  {
2543d8817e4Smiod 	    const bfd_target *p = bfd_target_vector[t];
2553d8817e4Smiod 	    bfd_boolean ok = TRUE;
2563d8817e4Smiod 	    bfd *abfd = bfd_openw (dummy_name, p->name);
2573d8817e4Smiod 
2583d8817e4Smiod 	    if (abfd == NULL)
2593d8817e4Smiod 	      {
2603d8817e4Smiod 		bfd_nonfatal (p->name);
2613d8817e4Smiod                 ret = 0;
2623d8817e4Smiod 		ok = FALSE;
2633d8817e4Smiod 	      }
2643d8817e4Smiod 
2653d8817e4Smiod 	    if (ok)
2663d8817e4Smiod 	      {
2673d8817e4Smiod 		if (! bfd_set_format (abfd, bfd_object))
2683d8817e4Smiod 		  {
2693d8817e4Smiod 		    if (bfd_get_error () != bfd_error_invalid_operation)
2703d8817e4Smiod                       {
2713d8817e4Smiod 		        bfd_nonfatal (p->name);
2723d8817e4Smiod                         ret = 0;
2733d8817e4Smiod                       }
2743d8817e4Smiod 		    ok = FALSE;
2753d8817e4Smiod 		  }
2763d8817e4Smiod 	      }
2773d8817e4Smiod 
2783d8817e4Smiod 	    if (ok)
2793d8817e4Smiod 	      {
2803d8817e4Smiod 		if (! bfd_set_arch_mach (abfd, a, 0))
2813d8817e4Smiod 		  ok = FALSE;
2823d8817e4Smiod 	      }
2833d8817e4Smiod 
2843d8817e4Smiod 	    if (ok)
2853d8817e4Smiod 	      printf ("%s ", p->name);
2863d8817e4Smiod 	    else
2873d8817e4Smiod 	      {
2883d8817e4Smiod 		int l = strlen (p->name);
2893d8817e4Smiod 		while (l--)
2903d8817e4Smiod 		  putchar ('-');
2913d8817e4Smiod 		putchar (' ');
2923d8817e4Smiod 	      }
2933d8817e4Smiod 	    if (abfd != NULL)
2943d8817e4Smiod 	      bfd_close_all_done (abfd);
2953d8817e4Smiod 	  }
2963d8817e4Smiod 	putchar ('\n');
2973d8817e4Smiod       }
2983d8817e4Smiod   unlink (dummy_name);
2993d8817e4Smiod   free (dummy_name);
3003d8817e4Smiod 
3013d8817e4Smiod   return ret;
3023d8817e4Smiod }
3033d8817e4Smiod 
3043d8817e4Smiod /* Print tables of all the target-architecture combinations that
3053d8817e4Smiod    BFD has been configured to support.  */
3063d8817e4Smiod 
3073d8817e4Smiod static int
display_target_tables(void)3083d8817e4Smiod display_target_tables (void)
3093d8817e4Smiod {
3103d8817e4Smiod   int t;
3113d8817e4Smiod   int columns;
3123d8817e4Smiod   int ret = 1;
3133d8817e4Smiod   char *colum;
3143d8817e4Smiod 
3153d8817e4Smiod   columns = 0;
3163d8817e4Smiod   colum = getenv ("COLUMNS");
3173d8817e4Smiod   if (colum != NULL)
3183d8817e4Smiod     columns = atoi (colum);
3193d8817e4Smiod   if (columns == 0)
3203d8817e4Smiod     columns = 80;
3213d8817e4Smiod 
3223d8817e4Smiod   t = 0;
3233d8817e4Smiod   while (bfd_target_vector[t] != NULL)
3243d8817e4Smiod     {
3253d8817e4Smiod       int oldt = t, wid;
3263d8817e4Smiod 
3273d8817e4Smiod       wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1;
3283d8817e4Smiod       ++t;
3293d8817e4Smiod       while (wid < columns && bfd_target_vector[t] != NULL)
3303d8817e4Smiod 	{
3313d8817e4Smiod 	  int newwid;
3323d8817e4Smiod 
3333d8817e4Smiod 	  newwid = wid + strlen (bfd_target_vector[t]->name) + 1;
3343d8817e4Smiod 	  if (newwid >= columns)
3353d8817e4Smiod 	    break;
3363d8817e4Smiod 	  wid = newwid;
3373d8817e4Smiod 	  ++t;
3383d8817e4Smiod 	}
3393d8817e4Smiod       if (! display_info_table (oldt, t))
3403d8817e4Smiod         ret = 0;
3413d8817e4Smiod     }
3423d8817e4Smiod 
3433d8817e4Smiod   return ret;
3443d8817e4Smiod }
3453d8817e4Smiod 
3463d8817e4Smiod int
display_info(void)3473d8817e4Smiod display_info (void)
3483d8817e4Smiod {
3493d8817e4Smiod   printf (_("BFD header file version %s\n"), BFD_VERSION_STRING);
3503d8817e4Smiod   if (! display_target_list () || ! display_target_tables ())
3513d8817e4Smiod     return 1;
3523d8817e4Smiod   else
3533d8817e4Smiod     return 0;
3543d8817e4Smiod }
3553d8817e4Smiod 
3563d8817e4Smiod /* Display the archive header for an element as if it were an ls -l listing:
3573d8817e4Smiod 
3583d8817e4Smiod    Mode       User\tGroup\tSize\tDate               Name */
3593d8817e4Smiod 
3603d8817e4Smiod void
print_arelt_descr(FILE * file,bfd * abfd,bfd_boolean verbose)3613d8817e4Smiod print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose)
3623d8817e4Smiod {
3633d8817e4Smiod   struct stat buf;
3643d8817e4Smiod 
3653d8817e4Smiod   if (verbose)
3663d8817e4Smiod     {
3673d8817e4Smiod       if (bfd_stat_arch_elt (abfd, &buf) == 0)
3683d8817e4Smiod 	{
3693d8817e4Smiod 	  char modebuf[11];
3703d8817e4Smiod 	  char timebuf[40];
3713d8817e4Smiod 	  time_t when = buf.st_mtime;
3723d8817e4Smiod 	  const char *ctime_result = (const char *) ctime (&when);
3733d8817e4Smiod 
3743d8817e4Smiod 	  /* POSIX format:  skip weekday and seconds from ctime output.  */
3753d8817e4Smiod 	  sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
3763d8817e4Smiod 
3773d8817e4Smiod 	  mode_string (buf.st_mode, modebuf);
3783d8817e4Smiod 	  modebuf[10] = '\0';
3793d8817e4Smiod 	  /* POSIX 1003.2/D11 says to skip first character (entry type).  */
3803d8817e4Smiod 	  fprintf (file, "%s %ld/%ld %6ld %s ", modebuf + 1,
3813d8817e4Smiod 		   (long) buf.st_uid, (long) buf.st_gid,
3823d8817e4Smiod 		   (long) buf.st_size, timebuf);
3833d8817e4Smiod 	}
3843d8817e4Smiod     }
3853d8817e4Smiod 
3863d8817e4Smiod   fprintf (file, "%s\n", bfd_get_filename (abfd));
3873d8817e4Smiod }
3883d8817e4Smiod 
3893d8817e4Smiod /* Return the name of a temporary file in the same directory as FILENAME.  */
3903d8817e4Smiod 
3913d8817e4Smiod char *
make_tempname(char * filename,int isdir)392d2386abeSmiod make_tempname (char *filename, int isdir)
3933d8817e4Smiod {
3943d8817e4Smiod   static char template[] = "stXXXXXX";
3953d8817e4Smiod   char *tmpname;
3963d8817e4Smiod   char *slash = strrchr (filename, '/');
397*e2674b3fSdrahn   char c = '/';
3983d8817e4Smiod 
3993d8817e4Smiod #ifdef HAVE_DOS_BASED_FILE_SYSTEM
4003d8817e4Smiod   {
4013d8817e4Smiod     /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
4023d8817e4Smiod     char *bslash = strrchr (filename, '\\');
4033d8817e4Smiod     if (slash == NULL || (bslash != NULL && bslash > slash))
4043d8817e4Smiod       slash = bslash;
4053d8817e4Smiod     if (slash == NULL && filename[0] != '\0' && filename[1] == ':')
4063d8817e4Smiod       slash = filename + 1;
4073d8817e4Smiod   }
4083d8817e4Smiod #endif
4093d8817e4Smiod 
4103d8817e4Smiod   if (slash != (char *) NULL)
4113d8817e4Smiod     {
4123d8817e4Smiod       c = *slash;
4133d8817e4Smiod       *slash = 0;
4143d8817e4Smiod       tmpname = xmalloc (strlen (filename) + sizeof (template) + 2);
4153d8817e4Smiod       strcpy (tmpname, filename);
4163d8817e4Smiod #ifdef HAVE_DOS_BASED_FILE_SYSTEM
4173d8817e4Smiod       /* If tmpname is "X:", appending a slash will make it a root
4183d8817e4Smiod 	 directory on drive X, which is NOT the same as the current
4193d8817e4Smiod 	 directory on drive X.  */
4203d8817e4Smiod       if (tmpname[1] == ':' && tmpname[2] == '\0')
4213d8817e4Smiod 	strcat (tmpname, ".");
4223d8817e4Smiod #endif
4233d8817e4Smiod       strcat (tmpname, "/");
4243d8817e4Smiod       strcat (tmpname, template);
4253d8817e4Smiod     }
4263d8817e4Smiod   else
4273d8817e4Smiod     {
4283d8817e4Smiod       tmpname = xmalloc (sizeof (template));
4293d8817e4Smiod       strcpy (tmpname, template);
4303d8817e4Smiod     }
431d2386abeSmiod 
432d2386abeSmiod   if (isdir)
433d2386abeSmiod     {
434d2386abeSmiod       if (mkdtemp (tmpname) == (char *) NULL)
435d2386abeSmiod       tmpname = NULL;
436d2386abeSmiod     }
437d2386abeSmiod   else
438d2386abeSmiod     {
439d2386abeSmiod       int fd;
440d2386abeSmiod 
441d2386abeSmiod       fd = mkstemp (tmpname);
442d2386abeSmiod       if (fd == -1)
443d2386abeSmiod       tmpname = NULL;
444d2386abeSmiod       else
445d2386abeSmiod       close (fd);
446d2386abeSmiod     }
447d2386abeSmiod   if (slash != (char *) NULL)
448d2386abeSmiod     *slash = c;
449d2386abeSmiod 
4503d8817e4Smiod   return tmpname;
4513d8817e4Smiod }
4523d8817e4Smiod 
4533d8817e4Smiod /* Parse a string into a VMA, with a fatal error if it can't be
4543d8817e4Smiod    parsed.  */
4553d8817e4Smiod 
4563d8817e4Smiod bfd_vma
parse_vma(const char * s,const char * arg)4573d8817e4Smiod parse_vma (const char *s, const char *arg)
4583d8817e4Smiod {
4593d8817e4Smiod   bfd_vma ret;
4603d8817e4Smiod   const char *end;
4613d8817e4Smiod 
4623d8817e4Smiod   ret = bfd_scan_vma (s, &end, 0);
4633d8817e4Smiod 
4643d8817e4Smiod   if (*end != '\0')
4653d8817e4Smiod     fatal (_("%s: bad number: %s"), arg, s);
4663d8817e4Smiod 
4673d8817e4Smiod   return ret;
4683d8817e4Smiod }
4693d8817e4Smiod 
4703d8817e4Smiod /* Returns the size of the named file.  If the file does not
4713d8817e4Smiod    exist, or if it is not a real file, then a suitable non-fatal
4723d8817e4Smiod    error message is printed and zero is returned.  */
4733d8817e4Smiod 
4743d8817e4Smiod off_t
get_file_size(const char * file_name)4753d8817e4Smiod get_file_size (const char * file_name)
4763d8817e4Smiod {
4773d8817e4Smiod   struct stat statbuf;
4783d8817e4Smiod 
4793d8817e4Smiod   if (stat (file_name, &statbuf) < 0)
4803d8817e4Smiod     {
4813d8817e4Smiod       if (errno == ENOENT)
4823d8817e4Smiod 	non_fatal (_("'%s': No such file"), file_name);
4833d8817e4Smiod       else
4843d8817e4Smiod 	non_fatal (_("Warning: could not locate '%s'.  reason: %s"),
4853d8817e4Smiod 		   file_name, strerror (errno));
4863d8817e4Smiod     }
4873d8817e4Smiod   else if (! S_ISREG (statbuf.st_mode))
4883d8817e4Smiod     non_fatal (_("Warning: '%s' is not an ordinary file"), file_name);
4893d8817e4Smiod   else
4903d8817e4Smiod     return statbuf.st_size;
4913d8817e4Smiod 
4923d8817e4Smiod   return 0;
4933d8817e4Smiod }
4943d8817e4Smiod 
4953d8817e4Smiod /* Return the filename in a static buffer.  */
4963d8817e4Smiod 
4973d8817e4Smiod const char *
bfd_get_archive_filename(bfd * abfd)4983d8817e4Smiod bfd_get_archive_filename (bfd *abfd)
4993d8817e4Smiod {
5003d8817e4Smiod   static size_t curr = 0;
5013d8817e4Smiod   static char *buf;
5023d8817e4Smiod   size_t needed;
5033d8817e4Smiod 
5043d8817e4Smiod   assert (abfd != NULL);
5053d8817e4Smiod 
5063d8817e4Smiod   if (!abfd->my_archive)
5073d8817e4Smiod     return bfd_get_filename (abfd);
5083d8817e4Smiod 
5093d8817e4Smiod   needed = (strlen (bfd_get_filename (abfd->my_archive))
5103d8817e4Smiod 	    + strlen (bfd_get_filename (abfd)) + 3);
5113d8817e4Smiod   if (needed > curr)
5123d8817e4Smiod     {
5133d8817e4Smiod       if (curr)
5143d8817e4Smiod 	free (buf);
5153d8817e4Smiod       curr = needed + (needed >> 1);
5163d8817e4Smiod       buf = bfd_malloc (curr);
5173d8817e4Smiod       /* If we can't malloc, fail safe by returning just the file name.
5183d8817e4Smiod 	 This function is only used when building error messages.  */
5193d8817e4Smiod       if (!buf)
5203d8817e4Smiod 	{
5213d8817e4Smiod 	  curr = 0;
5223d8817e4Smiod 	  return bfd_get_filename (abfd);
5233d8817e4Smiod 	}
5243d8817e4Smiod     }
5253d8817e4Smiod   sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive),
5263d8817e4Smiod 	   bfd_get_filename (abfd));
5273d8817e4Smiod   return buf;
5283d8817e4Smiod }
529