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