xref: /openbsd/gnu/usr.bin/binutils/binutils/bucomm.c (revision 007c2a45)
12159047fSniklas /* bucomm.c -- Bin Utils COMmon code.
2c074d1c9Sdrahn    Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2003
3b305b0f1Sespie    Free Software Foundation, Inc.
42159047fSniklas 
52159047fSniklas    This file is part of GNU Binutils.
62159047fSniklas 
72159047fSniklas    This program is free software; you can redistribute it and/or modify
82159047fSniklas    it under the terms of the GNU General Public License as published by
92159047fSniklas    the Free Software Foundation; either version 2 of the License, or
102159047fSniklas    (at your option) any later version.
112159047fSniklas 
122159047fSniklas    This program is distributed in the hope that it will be useful,
132159047fSniklas    but WITHOUT ANY WARRANTY; without even the implied warranty of
142159047fSniklas    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
152159047fSniklas    GNU General Public License for more details.
162159047fSniklas 
172159047fSniklas    You should have received a copy of the GNU General Public License
182159047fSniklas    along with this program; if not, write to the Free Software
19b305b0f1Sespie    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20b305b0f1Sespie    02111-1307, USA.  */
212159047fSniklas 
222159047fSniklas /* We might put this in a library someday so it could be dynamically
232159047fSniklas    loaded, but for now it's not necessary.  */
242159047fSniklas 
252159047fSniklas #include "bfd.h"
26c074d1c9Sdrahn #include "bfdver.h"
272159047fSniklas #include "libiberty.h"
282159047fSniklas #include "bucomm.h"
29b305b0f1Sespie #include "filenames.h"
30c074d1c9Sdrahn #include "libbfd.h"
312159047fSniklas 
322159047fSniklas #include <sys/stat.h>
332159047fSniklas #include <time.h>		/* ctime, maybe time_t */
342159047fSniklas 
352159047fSniklas #ifndef HAVE_TIME_T_IN_TIME_H
362159047fSniklas #ifndef HAVE_TIME_T_IN_TYPES_H
372159047fSniklas typedef long time_t;
382159047fSniklas #endif
392159047fSniklas #endif
40c074d1c9Sdrahn 
41*007c2a45Smiod static const char * endian_string (enum bfd_endian);
42*007c2a45Smiod static int display_target_list (void);
43*007c2a45Smiod static int display_info_table (int, int);
44*007c2a45Smiod static int display_target_tables (void);
452159047fSniklas 
46c074d1c9Sdrahn /* Error reporting.  */
472159047fSniklas 
482159047fSniklas char *program_name;
492159047fSniklas 
502159047fSniklas void
bfd_nonfatal(const char * string)51*007c2a45Smiod bfd_nonfatal (const char *string)
522159047fSniklas {
53c074d1c9Sdrahn   const char *errmsg = bfd_errmsg (bfd_get_error ());
542159047fSniklas 
552159047fSniklas   if (string)
562159047fSniklas     fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg);
572159047fSniklas   else
582159047fSniklas     fprintf (stderr, "%s: %s\n", program_name, errmsg);
592159047fSniklas }
602159047fSniklas 
612159047fSniklas void
bfd_fatal(const char * string)62*007c2a45Smiod bfd_fatal (const char *string)
632159047fSniklas {
642159047fSniklas   bfd_nonfatal (string);
652159047fSniklas   xexit (1);
662159047fSniklas }
672159047fSniklas 
68b305b0f1Sespie void
report(const char * format,va_list args)69*007c2a45Smiod report (const char * format, va_list args)
70b305b0f1Sespie {
71b305b0f1Sespie   fprintf (stderr, "%s: ", program_name);
72b305b0f1Sespie   vfprintf (stderr, format, args);
73b305b0f1Sespie   putc ('\n', stderr);
74b305b0f1Sespie }
75b305b0f1Sespie 
762159047fSniklas void
fatal(const char * format,...)77c074d1c9Sdrahn fatal VPARAMS ((const char *format, ...))
782159047fSniklas {
79c074d1c9Sdrahn   VA_OPEN (args, format);
80c074d1c9Sdrahn   VA_FIXEDARG (args, const char *, format);
812159047fSniklas 
82b305b0f1Sespie   report (format, args);
83c074d1c9Sdrahn   VA_CLOSE (args);
842159047fSniklas   xexit (1);
852159047fSniklas }
86b305b0f1Sespie 
87b305b0f1Sespie void
non_fatal(const char * format,...)88c074d1c9Sdrahn non_fatal VPARAMS ((const char *format, ...))
89b305b0f1Sespie {
90c074d1c9Sdrahn   VA_OPEN (args, format);
91c074d1c9Sdrahn   VA_FIXEDARG (args, const char *, format);
92b305b0f1Sespie 
93b305b0f1Sespie   report (format, args);
94c074d1c9Sdrahn   VA_CLOSE (args);
95b305b0f1Sespie }
962159047fSniklas 
97b305b0f1Sespie /* Set the default BFD target based on the configured target.  Doing
98b305b0f1Sespie    this permits the binutils to be configured for a particular target,
99b305b0f1Sespie    and linked against a shared BFD library which was configured for a
100b305b0f1Sespie    different target.  */
101b305b0f1Sespie 
102b305b0f1Sespie void
set_default_bfd_target(void)103*007c2a45Smiod set_default_bfd_target (void)
104b305b0f1Sespie {
105b305b0f1Sespie   /* The macro TARGET is defined by Makefile.  */
106b305b0f1Sespie   const char *target = TARGET;
107b305b0f1Sespie 
108b305b0f1Sespie   if (! bfd_set_default_target (target))
109b305b0f1Sespie     fatal (_("can't set BFD default target to `%s': %s"),
110b305b0f1Sespie 	   target, bfd_errmsg (bfd_get_error ()));
111b305b0f1Sespie }
112b305b0f1Sespie 
113c074d1c9Sdrahn /* After a FALSE return from bfd_check_format_matches with
114b305b0f1Sespie    bfd_get_error () == bfd_error_file_ambiguously_recognized, print
115b305b0f1Sespie    the possible matching targets.  */
1162159047fSniklas 
1172159047fSniklas void
list_matching_formats(char ** p)118*007c2a45Smiod list_matching_formats (char **p)
1192159047fSniklas {
120b305b0f1Sespie   fprintf (stderr, _("%s: Matching formats:"), program_name);
1212159047fSniklas   while (*p)
1222159047fSniklas     fprintf (stderr, " %s", *p++);
123b305b0f1Sespie   fputc ('\n', stderr);
1242159047fSniklas }
1252159047fSniklas 
1262159047fSniklas /* List the supported targets.  */
1272159047fSniklas 
1282159047fSniklas void
list_supported_targets(const char * name,FILE * f)129*007c2a45Smiod list_supported_targets (const char *name, FILE *f)
1302159047fSniklas {
1312159047fSniklas   int t;
132c074d1c9Sdrahn   const char **targ_names = bfd_target_list ();
1332159047fSniklas 
1342159047fSniklas   if (name == NULL)
135b305b0f1Sespie     fprintf (f, _("Supported targets:"));
1362159047fSniklas   else
137b305b0f1Sespie     fprintf (f, _("%s: supported targets:"), name);
138c074d1c9Sdrahn 
139c074d1c9Sdrahn   for (t = 0; targ_names[t] != NULL; t++)
140c074d1c9Sdrahn     fprintf (f, " %s", targ_names[t]);
1412159047fSniklas   fprintf (f, "\n");
142c074d1c9Sdrahn   free (targ_names);
143c074d1c9Sdrahn }
144c074d1c9Sdrahn 
145c074d1c9Sdrahn /* List the supported architectures.  */
146c074d1c9Sdrahn 
147c074d1c9Sdrahn void
list_supported_architectures(const char * name,FILE * f)148*007c2a45Smiod list_supported_architectures (const char *name, FILE *f)
149c074d1c9Sdrahn {
150c074d1c9Sdrahn   const char **arch;
151c074d1c9Sdrahn 
152c074d1c9Sdrahn   if (name == NULL)
153c074d1c9Sdrahn     fprintf (f, _("Supported architectures:"));
154c074d1c9Sdrahn   else
155c074d1c9Sdrahn     fprintf (f, _("%s: supported architectures:"), name);
156c074d1c9Sdrahn 
157c074d1c9Sdrahn   for (arch = bfd_arch_list (); *arch; arch++)
158c074d1c9Sdrahn     fprintf (f, " %s", *arch);
159c074d1c9Sdrahn   fprintf (f, "\n");
160c074d1c9Sdrahn }
161c074d1c9Sdrahn 
162c074d1c9Sdrahn /* The length of the longest architecture name + 1.  */
163c074d1c9Sdrahn #define LONGEST_ARCH sizeof ("powerpc:common")
164c074d1c9Sdrahn 
165c074d1c9Sdrahn static const char *
endian_string(enum bfd_endian endian)166*007c2a45Smiod endian_string (enum bfd_endian endian)
167c074d1c9Sdrahn {
168c074d1c9Sdrahn   switch (endian)
169c074d1c9Sdrahn     {
170c074d1c9Sdrahn     case BFD_ENDIAN_BIG: return "big endian";
171c074d1c9Sdrahn     case BFD_ENDIAN_LITTLE: return "little endian";
172c074d1c9Sdrahn     default: return "endianness unknown";
173c074d1c9Sdrahn     }
174c074d1c9Sdrahn }
175c074d1c9Sdrahn 
176c074d1c9Sdrahn /* List the targets that BFD is configured to support, each followed
177c074d1c9Sdrahn    by its endianness and the architectures it supports.  */
178c074d1c9Sdrahn 
179c074d1c9Sdrahn static int
display_target_list(void)180*007c2a45Smiod display_target_list (void)
181c074d1c9Sdrahn {
182c074d1c9Sdrahn   char *dummy_name;
183c074d1c9Sdrahn   int t;
184c074d1c9Sdrahn   int ret = 1;
185c074d1c9Sdrahn 
186c074d1c9Sdrahn   dummy_name = make_temp_file (NULL);
187c074d1c9Sdrahn   for (t = 0; bfd_target_vector[t]; t++)
188c074d1c9Sdrahn     {
189c074d1c9Sdrahn       const bfd_target *p = bfd_target_vector[t];
190c074d1c9Sdrahn       bfd *abfd = bfd_openw (dummy_name, p->name);
191c074d1c9Sdrahn       int a;
192c074d1c9Sdrahn 
193c074d1c9Sdrahn       printf ("%s\n (header %s, data %s)\n", p->name,
194c074d1c9Sdrahn 	      endian_string (p->header_byteorder),
195c074d1c9Sdrahn 	      endian_string (p->byteorder));
196c074d1c9Sdrahn 
197c074d1c9Sdrahn       if (abfd == NULL)
198c074d1c9Sdrahn 	{
199c074d1c9Sdrahn           bfd_nonfatal (dummy_name);
200c074d1c9Sdrahn           ret = 0;
201c074d1c9Sdrahn 	  continue;
202c074d1c9Sdrahn 	}
203c074d1c9Sdrahn 
204c074d1c9Sdrahn       if (! bfd_set_format (abfd, bfd_object))
205c074d1c9Sdrahn 	{
206c074d1c9Sdrahn 	  if (bfd_get_error () != bfd_error_invalid_operation)
207c074d1c9Sdrahn             {
208c074d1c9Sdrahn 	      bfd_nonfatal (p->name);
209c074d1c9Sdrahn               ret = 0;
210c074d1c9Sdrahn             }
211c074d1c9Sdrahn 	  bfd_close_all_done (abfd);
212c074d1c9Sdrahn 	  continue;
213c074d1c9Sdrahn 	}
214c074d1c9Sdrahn 
215c074d1c9Sdrahn       for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++)
216c074d1c9Sdrahn 	if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
217c074d1c9Sdrahn 	  printf ("  %s\n",
218c074d1c9Sdrahn 		  bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
219c074d1c9Sdrahn       bfd_close_all_done (abfd);
220c074d1c9Sdrahn     }
221c074d1c9Sdrahn   unlink (dummy_name);
222c074d1c9Sdrahn   free (dummy_name);
223c074d1c9Sdrahn 
224c074d1c9Sdrahn   return ret;
225c074d1c9Sdrahn }
226c074d1c9Sdrahn 
227c074d1c9Sdrahn /* Print a table showing which architectures are supported for entries
228c074d1c9Sdrahn    FIRST through LAST-1 of bfd_target_vector (targets across,
229c074d1c9Sdrahn    architectures down).  */
230c074d1c9Sdrahn 
231c074d1c9Sdrahn static int
display_info_table(int first,int last)232*007c2a45Smiod display_info_table (int first, int last)
233c074d1c9Sdrahn {
234c074d1c9Sdrahn   int t;
235c074d1c9Sdrahn   int a;
236c074d1c9Sdrahn   int ret = 1;
237c074d1c9Sdrahn   char *dummy_name;
238c074d1c9Sdrahn 
239c074d1c9Sdrahn   /* Print heading of target names.  */
240c074d1c9Sdrahn   printf ("\n%*s", (int) LONGEST_ARCH, " ");
241c074d1c9Sdrahn   for (t = first; t < last && bfd_target_vector[t]; t++)
242c074d1c9Sdrahn     printf ("%s ", bfd_target_vector[t]->name);
243c074d1c9Sdrahn   putchar ('\n');
244c074d1c9Sdrahn 
245c074d1c9Sdrahn   dummy_name = make_temp_file (NULL);
246c074d1c9Sdrahn   for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++)
247c074d1c9Sdrahn     if (strcmp (bfd_printable_arch_mach (a, 0), "UNKNOWN!") != 0)
248c074d1c9Sdrahn       {
249c074d1c9Sdrahn 	printf ("%*s ", (int) LONGEST_ARCH - 1,
250c074d1c9Sdrahn 		bfd_printable_arch_mach (a, 0));
251c074d1c9Sdrahn 	for (t = first; t < last && bfd_target_vector[t]; t++)
252c074d1c9Sdrahn 	  {
253c074d1c9Sdrahn 	    const bfd_target *p = bfd_target_vector[t];
254c074d1c9Sdrahn 	    bfd_boolean ok = TRUE;
255c074d1c9Sdrahn 	    bfd *abfd = bfd_openw (dummy_name, p->name);
256c074d1c9Sdrahn 
257c074d1c9Sdrahn 	    if (abfd == NULL)
258c074d1c9Sdrahn 	      {
259c074d1c9Sdrahn 		bfd_nonfatal (p->name);
260c074d1c9Sdrahn                 ret = 0;
261c074d1c9Sdrahn 		ok = FALSE;
262c074d1c9Sdrahn 	      }
263c074d1c9Sdrahn 
264c074d1c9Sdrahn 	    if (ok)
265c074d1c9Sdrahn 	      {
266c074d1c9Sdrahn 		if (! bfd_set_format (abfd, bfd_object))
267c074d1c9Sdrahn 		  {
268c074d1c9Sdrahn 		    if (bfd_get_error () != bfd_error_invalid_operation)
269c074d1c9Sdrahn                       {
270c074d1c9Sdrahn 		        bfd_nonfatal (p->name);
271c074d1c9Sdrahn                         ret = 0;
272c074d1c9Sdrahn                       }
273c074d1c9Sdrahn 		    ok = FALSE;
274c074d1c9Sdrahn 		  }
275c074d1c9Sdrahn 	      }
276c074d1c9Sdrahn 
277c074d1c9Sdrahn 	    if (ok)
278c074d1c9Sdrahn 	      {
279c074d1c9Sdrahn 		if (! bfd_set_arch_mach (abfd, a, 0))
280c074d1c9Sdrahn 		  ok = FALSE;
281c074d1c9Sdrahn 	      }
282c074d1c9Sdrahn 
283c074d1c9Sdrahn 	    if (ok)
284c074d1c9Sdrahn 	      printf ("%s ", p->name);
285c074d1c9Sdrahn 	    else
286c074d1c9Sdrahn 	      {
287c074d1c9Sdrahn 		int l = strlen (p->name);
288c074d1c9Sdrahn 		while (l--)
289c074d1c9Sdrahn 		  putchar ('-');
290c074d1c9Sdrahn 		putchar (' ');
291c074d1c9Sdrahn 	      }
292c074d1c9Sdrahn 	    if (abfd != NULL)
293c074d1c9Sdrahn 	      bfd_close_all_done (abfd);
294c074d1c9Sdrahn 	  }
295c074d1c9Sdrahn 	putchar ('\n');
296c074d1c9Sdrahn       }
297c074d1c9Sdrahn   unlink (dummy_name);
298c074d1c9Sdrahn   free (dummy_name);
299c074d1c9Sdrahn 
300c074d1c9Sdrahn   return ret;
301c074d1c9Sdrahn }
302c074d1c9Sdrahn 
303c074d1c9Sdrahn /* Print tables of all the target-architecture combinations that
304c074d1c9Sdrahn    BFD has been configured to support.  */
305c074d1c9Sdrahn 
306c074d1c9Sdrahn static int
display_target_tables(void)307*007c2a45Smiod display_target_tables (void)
308c074d1c9Sdrahn {
309c074d1c9Sdrahn   int t;
310c074d1c9Sdrahn   int columns;
311c074d1c9Sdrahn   int ret = 1;
312c074d1c9Sdrahn   char *colum;
313c074d1c9Sdrahn 
314c074d1c9Sdrahn   columns = 0;
315c074d1c9Sdrahn   colum = getenv ("COLUMNS");
316c074d1c9Sdrahn   if (colum != NULL)
317c074d1c9Sdrahn     columns = atoi (colum);
318c074d1c9Sdrahn   if (columns == 0)
319c074d1c9Sdrahn     columns = 80;
320c074d1c9Sdrahn 
321c074d1c9Sdrahn   t = 0;
322c074d1c9Sdrahn   while (bfd_target_vector[t] != NULL)
323c074d1c9Sdrahn     {
324c074d1c9Sdrahn       int oldt = t, wid;
325c074d1c9Sdrahn 
326c074d1c9Sdrahn       wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1;
327c074d1c9Sdrahn       ++t;
328c074d1c9Sdrahn       while (wid < columns && bfd_target_vector[t] != NULL)
329c074d1c9Sdrahn 	{
330c074d1c9Sdrahn 	  int newwid;
331c074d1c9Sdrahn 
332c074d1c9Sdrahn 	  newwid = wid + strlen (bfd_target_vector[t]->name) + 1;
333c074d1c9Sdrahn 	  if (newwid >= columns)
334c074d1c9Sdrahn 	    break;
335c074d1c9Sdrahn 	  wid = newwid;
336c074d1c9Sdrahn 	  ++t;
337c074d1c9Sdrahn 	}
338c074d1c9Sdrahn       if (! display_info_table (oldt, t))
339c074d1c9Sdrahn         ret = 0;
340c074d1c9Sdrahn     }
341c074d1c9Sdrahn 
342c074d1c9Sdrahn   return ret;
343c074d1c9Sdrahn }
344c074d1c9Sdrahn 
345c074d1c9Sdrahn int
display_info(void)346*007c2a45Smiod display_info (void)
347c074d1c9Sdrahn {
348c074d1c9Sdrahn   printf (_("BFD header file version %s\n"), BFD_VERSION_STRING);
349c074d1c9Sdrahn   if (! display_target_list () || ! display_target_tables ())
350c074d1c9Sdrahn     return 1;
351c074d1c9Sdrahn   else
352c074d1c9Sdrahn     return 0;
3532159047fSniklas }
3542159047fSniklas 
3552159047fSniklas /* Display the archive header for an element as if it were an ls -l listing:
3562159047fSniklas 
3572159047fSniklas    Mode       User\tGroup\tSize\tDate               Name */
3582159047fSniklas 
3592159047fSniklas void
print_arelt_descr(FILE * file,bfd * abfd,bfd_boolean verbose)360*007c2a45Smiod print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose)
3612159047fSniklas {
3622159047fSniklas   struct stat buf;
3632159047fSniklas 
3642159047fSniklas   if (verbose)
3652159047fSniklas     {
3662159047fSniklas       if (bfd_stat_arch_elt (abfd, &buf) == 0)
3672159047fSniklas 	{
3682159047fSniklas 	  char modebuf[11];
3692159047fSniklas 	  char timebuf[40];
3702159047fSniklas 	  time_t when = buf.st_mtime;
371c074d1c9Sdrahn 	  const char *ctime_result = (const char *) ctime (&when);
3722159047fSniklas 
3732159047fSniklas 	  /* POSIX format:  skip weekday and seconds from ctime output.  */
3742159047fSniklas 	  sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
3752159047fSniklas 
3762159047fSniklas 	  mode_string (buf.st_mode, modebuf);
3772159047fSniklas 	  modebuf[10] = '\0';
3782159047fSniklas 	  /* POSIX 1003.2/D11 says to skip first character (entry type).  */
3792159047fSniklas 	  fprintf (file, "%s %ld/%ld %6ld %s ", modebuf + 1,
3802159047fSniklas 		   (long) buf.st_uid, (long) buf.st_gid,
3812159047fSniklas 		   (long) buf.st_size, timebuf);
3822159047fSniklas 	}
3832159047fSniklas     }
3842159047fSniklas 
3852159047fSniklas   fprintf (file, "%s\n", bfd_get_filename (abfd));
3862159047fSniklas }
3872159047fSniklas 
388b305b0f1Sespie /* Return the name of a temporary file in the same directory as FILENAME.  */
3892159047fSniklas 
3902159047fSniklas char *
make_tempname(char * filename,int isdir)391*007c2a45Smiod make_tempname (char *filename, int isdir)
3922159047fSniklas {
393b305b0f1Sespie   static char template[] = "stXXXXXX";
3942159047fSniklas   char *tmpname;
3952159047fSniklas   char *slash = strrchr (filename, '/');
3969a986918Sespie   char c;
3972159047fSniklas 
398b305b0f1Sespie #ifdef HAVE_DOS_BASED_FILE_SYSTEM
399b305b0f1Sespie   {
400b305b0f1Sespie     /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
401b305b0f1Sespie     char *bslash = strrchr (filename, '\\');
402b55d4692Sfgsch     if (slash == NULL || (bslash != NULL && bslash > slash))
403b305b0f1Sespie       slash = bslash;
404b305b0f1Sespie     if (slash == NULL && filename[0] != '\0' && filename[1] == ':')
405b305b0f1Sespie       slash = filename + 1;
406b305b0f1Sespie   }
407b305b0f1Sespie #endif
408b305b0f1Sespie 
4092159047fSniklas   if (slash != (char *) NULL)
4102159047fSniklas     {
411b305b0f1Sespie       c = *slash;
4122159047fSniklas       *slash = 0;
413b305b0f1Sespie       tmpname = xmalloc (strlen (filename) + sizeof (template) + 2);
4142159047fSniklas       strcpy (tmpname, filename);
415b305b0f1Sespie #ifdef HAVE_DOS_BASED_FILE_SYSTEM
416b305b0f1Sespie       /* If tmpname is "X:", appending a slash will make it a root
417b305b0f1Sespie 	 directory on drive X, which is NOT the same as the current
418b305b0f1Sespie 	 directory on drive X.  */
419b305b0f1Sespie       if (tmpname[1] == ':' && tmpname[2] == '\0')
420b305b0f1Sespie 	strcat (tmpname, ".");
421b305b0f1Sespie #endif
4222159047fSniklas       strcat (tmpname, "/");
4232159047fSniklas       strcat (tmpname, template);
4242159047fSniklas     }
4252159047fSniklas   else
4262159047fSniklas     {
4272159047fSniklas       tmpname = xmalloc (sizeof (template));
4282159047fSniklas       strcpy (tmpname, template);
4292159047fSniklas     }
4309a986918Sespie 
4319a986918Sespie   if (isdir)
4329a986918Sespie     {
4333d4065ffSespie       if (mkdtemp (tmpname) == (char *) NULL)
4349a986918Sespie       tmpname = NULL;
4359a986918Sespie     }
4369a986918Sespie   else
4379a986918Sespie     {
4389a986918Sespie       int fd;
4399a986918Sespie 
4409a986918Sespie       fd = mkstemp (tmpname);
4419a986918Sespie       if (fd == -1)
4429a986918Sespie       tmpname = NULL;
4439a986918Sespie       else
4449a986918Sespie       close (fd);
4459a986918Sespie     }
4469a986918Sespie   if (slash != (char *) NULL)
4479a986918Sespie     *slash = c;
4489a986918Sespie 
4492159047fSniklas   return tmpname;
4502159047fSniklas }
4512159047fSniklas 
4522159047fSniklas /* Parse a string into a VMA, with a fatal error if it can't be
4532159047fSniklas    parsed.  */
4542159047fSniklas 
4552159047fSniklas bfd_vma
parse_vma(const char * s,const char * arg)456*007c2a45Smiod parse_vma (const char *s, const char *arg)
4572159047fSniklas {
4582159047fSniklas   bfd_vma ret;
4592159047fSniklas   const char *end;
4602159047fSniklas 
4612159047fSniklas   ret = bfd_scan_vma (s, &end, 0);
462b305b0f1Sespie 
4632159047fSniklas   if (*end != '\0')
464b305b0f1Sespie     fatal (_("%s: bad number: %s"), arg, s);
465b305b0f1Sespie 
4662159047fSniklas   return ret;
4672159047fSniklas }
468*007c2a45Smiod 
469*007c2a45Smiod /* Returns the size of the named file.  If the file does not
470*007c2a45Smiod    exist, or if it is not a real file, then a suitable non-fatal
471*007c2a45Smiod    error message is printed and zero is returned.  */
472*007c2a45Smiod 
473*007c2a45Smiod off_t
get_file_size(const char * file_name)474*007c2a45Smiod get_file_size (const char * file_name)
475*007c2a45Smiod {
476*007c2a45Smiod   struct stat statbuf;
477*007c2a45Smiod 
478*007c2a45Smiod   if (stat (file_name, &statbuf) < 0)
479*007c2a45Smiod     {
480*007c2a45Smiod       if (errno == ENOENT)
481*007c2a45Smiod 	non_fatal (_("'%s': No such file"), file_name);
482*007c2a45Smiod       else
483*007c2a45Smiod 	non_fatal (_("Warning: could not locate '%s'.  reason: %s"),
484*007c2a45Smiod 		   file_name, strerror (errno));
485*007c2a45Smiod     }
486*007c2a45Smiod   else if (! S_ISREG (statbuf.st_mode))
487*007c2a45Smiod     non_fatal (_("Warning: '%s' is not an ordinary file"), file_name);
488*007c2a45Smiod   else
489*007c2a45Smiod     return statbuf.st_size;
490*007c2a45Smiod 
491*007c2a45Smiod   return 0;
492*007c2a45Smiod }
493