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