Initial import of Binutils 2.24 on vendor branch
[dragonfly.git] / contrib / binutils-2.24 / binutils / bucomm.c
1 /* bucomm.c -- Bin Utils COMmon code.
2    Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002,
3    2003, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4    Free Software Foundation, Inc.
5
6    This file is part of GNU Binutils.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21    02110-1301, USA.  */
22 \f
23 /* We might put this in a library someday so it could be dynamically
24    loaded, but for now it's not necessary.  */
25
26 #include "sysdep.h"
27 #include "bfd.h"
28 #include "libiberty.h"
29 #include "filenames.h"
30 #include "libbfd.h"
31
32 #include <time.h>               /* ctime, maybe time_t */
33 #include <assert.h>
34 #include "bucomm.h"
35
36 #ifndef HAVE_TIME_T_IN_TIME_H
37 #ifndef HAVE_TIME_T_IN_TYPES_H
38 typedef long time_t;
39 #endif
40 #endif
41
42 static const char * endian_string (enum bfd_endian);
43 static int display_target_list (void);
44 static int display_info_table (int, int);
45 static int display_target_tables (void);
46 \f
47 /* Error reporting.  */
48
49 char *program_name;
50
51 void
52 bfd_nonfatal (const char *string)
53 {
54   const char *errmsg;
55
56   errmsg = bfd_errmsg (bfd_get_error ());
57   fflush (stdout);
58   if (string)
59     fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg);
60   else
61     fprintf (stderr, "%s: %s\n", program_name, errmsg);
62 }
63
64 /* Issue a non fatal error message.  FILENAME, or if NULL then BFD,
65    are used to indicate the problematic file.  SECTION, if non NULL,
66    is used to provide a section name.  If FORMAT is non-null, then it
67    is used to print additional information via vfprintf.  Finally the
68    bfd error message is printed.  In summary, error messages are of
69    one of the following forms:
70
71    PROGRAM:file: bfd-error-message
72    PROGRAM:file[section]: bfd-error-message
73    PROGRAM:file: printf-message: bfd-error-message
74    PROGRAM:file[section]: printf-message: bfd-error-message.  */
75
76 void
77 bfd_nonfatal_message (const char *filename,
78                       const bfd *abfd,
79                       const asection *section,
80                       const char *format, ...)
81 {
82   const char *errmsg;
83   const char *section_name;
84   va_list args;
85
86   errmsg = bfd_errmsg (bfd_get_error ());
87   fflush (stdout);
88   section_name = NULL;
89   va_start (args, format);
90   fprintf (stderr, "%s", program_name);
91   
92   if (abfd)
93     {
94       if (!filename)
95         filename = bfd_get_archive_filename (abfd);
96       if (section)
97         section_name = bfd_get_section_name (abfd, section);
98     }
99   if (section_name)
100     fprintf (stderr, ":%s[%s]", filename, section_name);
101   else
102     fprintf (stderr, ":%s", filename);
103
104   if (format)
105     {
106       fprintf (stderr, ": ");
107       vfprintf (stderr, format, args);
108     }
109   fprintf (stderr, ": %s\n", errmsg);
110   va_end (args);
111 }
112
113 void
114 bfd_fatal (const char *string)
115 {
116   bfd_nonfatal (string);
117   xexit (1);
118 }
119
120 void
121 report (const char * format, va_list args)
122 {
123   fflush (stdout);
124   fprintf (stderr, "%s: ", program_name);
125   vfprintf (stderr, format, args);
126   putc ('\n', stderr);
127 }
128
129 void
130 fatal VPARAMS ((const char *format, ...))
131 {
132   VA_OPEN (args, format);
133   VA_FIXEDARG (args, const char *, format);
134
135   report (format, args);
136   VA_CLOSE (args);
137   xexit (1);
138 }
139
140 void
141 non_fatal VPARAMS ((const char *format, ...))
142 {
143   VA_OPEN (args, format);
144   VA_FIXEDARG (args, const char *, format);
145
146   report (format, args);
147   VA_CLOSE (args);
148 }
149
150 /* Set the default BFD target based on the configured target.  Doing
151    this permits the binutils to be configured for a particular target,
152    and linked against a shared BFD library which was configured for a
153    different target.  */
154
155 void
156 set_default_bfd_target (void)
157 {
158   /* The macro TARGET is defined by Makefile.  */
159   const char *target = TARGET;
160
161   if (! bfd_set_default_target (target))
162     fatal (_("can't set BFD default target to `%s': %s"),
163            target, bfd_errmsg (bfd_get_error ()));
164 }
165
166 /* After a FALSE return from bfd_check_format_matches with
167    bfd_get_error () == bfd_error_file_ambiguously_recognized, print
168    the possible matching targets.  */
169
170 void
171 list_matching_formats (char **p)
172 {
173   fflush (stdout);
174   fprintf (stderr, _("%s: Matching formats:"), program_name);
175   while (*p)
176     fprintf (stderr, " %s", *p++);
177   fputc ('\n', stderr);
178 }
179
180 /* List the supported targets.  */
181
182 void
183 list_supported_targets (const char *name, FILE *f)
184 {
185   int t;
186   const char **targ_names;
187
188   if (name == NULL)
189     fprintf (f, _("Supported targets:"));
190   else
191     fprintf (f, _("%s: supported targets:"), name);
192
193   targ_names = bfd_target_list ();
194   for (t = 0; targ_names[t] != NULL; t++)
195     fprintf (f, " %s", targ_names[t]);
196   fprintf (f, "\n");
197   free (targ_names);
198 }
199
200 /* List the supported architectures.  */
201
202 void
203 list_supported_architectures (const char *name, FILE *f)
204 {
205   const char ** arch;
206   const char ** arches;
207
208   if (name == NULL)
209     fprintf (f, _("Supported architectures:"));
210   else
211     fprintf (f, _("%s: supported architectures:"), name);
212
213   for (arch = arches = bfd_arch_list (); *arch; arch++)
214     fprintf (f, " %s", *arch);
215   fprintf (f, "\n");
216   free (arches);
217 }
218 \f
219 /* The length of the longest architecture name + 1.  */
220 #define LONGEST_ARCH sizeof ("powerpc:common")
221
222 static const char *
223 endian_string (enum bfd_endian endian)
224 {
225   switch (endian)
226     {
227     case BFD_ENDIAN_BIG: return _("big endian");
228     case BFD_ENDIAN_LITTLE: return _("little endian");
229     default: return _("endianness unknown");
230     }
231 }
232
233 /* List the targets that BFD is configured to support, each followed
234    by its endianness and the architectures it supports.  */
235
236 static int
237 display_target_list (void)
238 {
239   char *dummy_name;
240   int t;
241   int ret = 1;
242
243   dummy_name = make_temp_file (NULL);
244   for (t = 0; bfd_target_vector[t]; t++)
245     {
246       const bfd_target *p = bfd_target_vector[t];
247       bfd *abfd = bfd_openw (dummy_name, p->name);
248       int a;
249
250       printf (_("%s\n (header %s, data %s)\n"), p->name,
251               endian_string (p->header_byteorder),
252               endian_string (p->byteorder));
253
254       if (abfd == NULL)
255         {
256           bfd_nonfatal (dummy_name);
257           ret = 0;
258           continue;
259         }
260
261       if (! bfd_set_format (abfd, bfd_object))
262         {
263           if (bfd_get_error () != bfd_error_invalid_operation)
264             {
265               bfd_nonfatal (p->name);
266               ret = 0;
267             }
268           bfd_close_all_done (abfd);
269           continue;
270         }
271
272       for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
273         if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
274           printf ("  %s\n",
275                   bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
276       bfd_close_all_done (abfd);
277     }
278   unlink (dummy_name);
279   free (dummy_name);
280
281   return ret;
282 }
283
284 /* Print a table showing which architectures are supported for entries
285    FIRST through LAST-1 of bfd_target_vector (targets across,
286    architectures down).  */
287
288 static int
289 display_info_table (int first, int last)
290 {
291   int t;
292   int ret = 1;
293   char *dummy_name;
294   int a;
295
296   /* Print heading of target names.  */
297   printf ("\n%*s", (int) LONGEST_ARCH, " ");
298   for (t = first; t < last && bfd_target_vector[t]; t++)
299     printf ("%s ", bfd_target_vector[t]->name);
300   putchar ('\n');
301
302   dummy_name = make_temp_file (NULL);
303   for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
304     if (strcmp (bfd_printable_arch_mach ((enum bfd_architecture) a, 0),
305                 "UNKNOWN!") != 0)
306       {
307         printf ("%*s ", (int) LONGEST_ARCH - 1,
308                 bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
309         for (t = first; t < last && bfd_target_vector[t]; t++)
310           {
311             const bfd_target *p = bfd_target_vector[t];
312             bfd_boolean ok = TRUE;
313             bfd *abfd = bfd_openw (dummy_name, p->name);
314
315             if (abfd == NULL)
316               {
317                 bfd_nonfatal (p->name);
318                 ret = 0;
319                 ok = FALSE;
320               }
321
322             if (ok)
323               {
324                 if (! bfd_set_format (abfd, bfd_object))
325                   {
326                     if (bfd_get_error () != bfd_error_invalid_operation)
327                       {
328                         bfd_nonfatal (p->name);
329                         ret = 0;
330                       }
331                     ok = FALSE;
332                   }
333               }
334
335             if (ok)
336               {
337                 if (! bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
338                   ok = FALSE;
339               }
340
341             if (ok)
342               printf ("%s ", p->name);
343             else
344               {
345                 int l = strlen (p->name);
346                 while (l--)
347                   putchar ('-');
348                 putchar (' ');
349               }
350             if (abfd != NULL)
351               bfd_close_all_done (abfd);
352           }
353         putchar ('\n');
354       }
355   unlink (dummy_name);
356   free (dummy_name);
357
358   return ret;
359 }
360
361 /* Print tables of all the target-architecture combinations that
362    BFD has been configured to support.  */
363
364 static int
365 display_target_tables (void)
366 {
367   int t;
368   int columns;
369   int ret = 1;
370   char *colum;
371
372   columns = 0;
373   colum = getenv ("COLUMNS");
374   if (colum != NULL)
375     columns = atoi (colum);
376   if (columns == 0)
377     columns = 80;
378
379   t = 0;
380   while (bfd_target_vector[t] != NULL)
381     {
382       int oldt = t, wid;
383
384       wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1;
385       ++t;
386       while (wid < columns && bfd_target_vector[t] != NULL)
387         {
388           int newwid;
389
390           newwid = wid + strlen (bfd_target_vector[t]->name) + 1;
391           if (newwid >= columns)
392             break;
393           wid = newwid;
394           ++t;
395         }
396       if (! display_info_table (oldt, t))
397         ret = 0;
398     }
399
400   return ret;
401 }
402
403 int
404 display_info (void)
405 {
406   printf (_("BFD header file version %s\n"), BFD_VERSION_STRING);
407   if (! display_target_list () || ! display_target_tables ())
408     return 1;
409   else
410     return 0;
411 }
412 \f
413 /* Display the archive header for an element as if it were an ls -l listing:
414
415    Mode       User\tGroup\tSize\tDate               Name */
416
417 void
418 print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose)
419 {
420   struct stat buf;
421
422   if (verbose)
423     {
424       if (bfd_stat_arch_elt (abfd, &buf) == 0)
425         {
426           char modebuf[11];
427           char timebuf[40];
428           time_t when = buf.st_mtime;
429           const char *ctime_result = (const char *) ctime (&when);
430           bfd_size_type size;
431
432           /* POSIX format:  skip weekday and seconds from ctime output.  */
433           sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
434
435           mode_string (buf.st_mode, modebuf);
436           modebuf[10] = '\0';
437           size = buf.st_size;
438           /* POSIX 1003.2/D11 says to skip first character (entry type).  */
439           fprintf (file, "%s %ld/%ld %6" BFD_VMA_FMT "u %s ", modebuf + 1,
440                    (long) buf.st_uid, (long) buf.st_gid,
441                    size, timebuf);
442         }
443     }
444
445   fprintf (file, "%s\n", bfd_get_filename (abfd));
446 }
447
448 /* Return a path for a new temporary file in the same directory
449    as file PATH.  */
450
451 static char *
452 template_in_dir (const char *path)
453 {
454 #define template "stXXXXXX"
455   const char *slash = strrchr (path, '/');
456   char *tmpname;
457   size_t len;
458
459 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
460   {
461     /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
462     char *bslash = strrchr (path, '\\');
463
464     if (slash == NULL || (bslash != NULL && bslash > slash))
465       slash = bslash;
466     if (slash == NULL && path[0] != '\0' && path[1] == ':')
467       slash = path + 1;
468   }
469 #endif
470
471   if (slash != (char *) NULL)
472     {
473       len = slash - path;
474       tmpname = (char *) xmalloc (len + sizeof (template) + 2);
475       memcpy (tmpname, path, len);
476
477 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
478       /* If tmpname is "X:", appending a slash will make it a root
479          directory on drive X, which is NOT the same as the current
480          directory on drive X.  */
481       if (len == 2 && tmpname[1] == ':')
482         tmpname[len++] = '.';
483 #endif
484       tmpname[len++] = '/';
485     }
486   else
487     {
488       tmpname = (char *) xmalloc (sizeof (template));
489       len = 0;
490     }
491
492   memcpy (tmpname + len, template, sizeof (template));
493   return tmpname;
494 #undef template
495 }
496
497 /* Return the name of a created temporary file in the same directory
498    as FILENAME.  */
499
500 char *
501 make_tempname (char *filename)
502 {
503   char *tmpname = template_in_dir (filename);
504   int fd;
505
506 #ifdef HAVE_MKSTEMP
507   fd = mkstemp (tmpname);
508 #else
509   tmpname = mktemp (tmpname);
510   if (tmpname == NULL)
511     return NULL;
512   fd = open (tmpname, O_RDWR | O_CREAT | O_EXCL, 0600);
513 #endif
514   if (fd == -1)
515     {
516       free (tmpname);
517       return NULL;
518     }
519   close (fd);
520   return tmpname;
521 }
522
523 /* Return the name of a created temporary directory inside the
524    directory containing FILENAME.  */
525
526 char *
527 make_tempdir (char *filename)
528 {
529   char *tmpname = template_in_dir (filename);
530
531 #ifdef HAVE_MKDTEMP
532   return mkdtemp (tmpname);
533 #else
534   tmpname = mktemp (tmpname);
535   if (tmpname == NULL)
536     return NULL;
537 #if defined (_WIN32) && !defined (__CYGWIN32__)
538   if (mkdir (tmpname) != 0)
539     return NULL;
540 #else
541   if (mkdir (tmpname, 0700) != 0)
542     return NULL;
543 #endif
544   return tmpname;
545 #endif
546 }
547
548 /* Parse a string into a VMA, with a fatal error if it can't be
549    parsed.  */
550
551 bfd_vma
552 parse_vma (const char *s, const char *arg)
553 {
554   bfd_vma ret;
555   const char *end;
556
557   ret = bfd_scan_vma (s, &end, 0);
558
559   if (*end != '\0')
560     fatal (_("%s: bad number: %s"), arg, s);
561
562   return ret;
563 }
564
565 /* Returns the size of the named file.  If the file does not
566    exist, or if it is not a real file, then a suitable non-fatal
567    error message is printed and (off_t) -1 is returned.  */
568
569 off_t
570 get_file_size (const char * file_name)
571 {
572   struct stat statbuf;
573   
574   if (stat (file_name, &statbuf) < 0)
575     {
576       if (errno == ENOENT)
577         non_fatal (_("'%s': No such file"), file_name);
578       else
579         non_fatal (_("Warning: could not locate '%s'.  reason: %s"),
580                    file_name, strerror (errno));
581     }  
582   else if (! S_ISREG (statbuf.st_mode))
583     non_fatal (_("Warning: '%s' is not an ordinary file"), file_name);
584   else if (statbuf.st_size < 0)
585     non_fatal (_("Warning: '%s' has negative size, probably it is too large"),
586                file_name);
587   else
588     return statbuf.st_size;
589
590   return (off_t) -1;
591 }
592
593 /* Return the filename in a static buffer.  */
594
595 const char *
596 bfd_get_archive_filename (const bfd *abfd)
597 {
598   static size_t curr = 0;
599   static char *buf;
600   size_t needed;
601
602   assert (abfd != NULL);
603   
604   if (!abfd->my_archive)
605     return bfd_get_filename (abfd);
606
607   needed = (strlen (bfd_get_filename (abfd->my_archive))
608             + strlen (bfd_get_filename (abfd)) + 3);
609   if (needed > curr)
610     {
611       if (curr)
612         free (buf);
613       curr = needed + (needed >> 1);
614       buf = (char *) bfd_malloc (curr);
615       /* If we can't malloc, fail safe by returning just the file name.
616          This function is only used when building error messages.  */
617       if (!buf)
618         {
619           curr = 0;
620           return bfd_get_filename (abfd);
621         }
622     }
623   sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive),
624            bfd_get_filename (abfd));
625   return buf;
626 }