Merge branch 'vendor/BINUTILS220' into bu220
[dragonfly.git] / contrib / binutils-2.20 / 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       int 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   int 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 ((enum bfd_architecture) a, 0),
298                 "UNKNOWN!") != 0)
299       {
300         printf ("%*s ", (int) LONGEST_ARCH - 1,
301                 bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
302         for (t = first; t < last && bfd_target_vector[t]; t++)
303           {
304             const bfd_target *p = bfd_target_vector[t];
305             bfd_boolean ok = TRUE;
306             bfd *abfd = bfd_openw (dummy_name, p->name);
307
308             if (abfd == NULL)
309               {
310                 bfd_nonfatal (p->name);
311                 ret = 0;
312                 ok = FALSE;
313               }
314
315             if (ok)
316               {
317                 if (! bfd_set_format (abfd, bfd_object))
318                   {
319                     if (bfd_get_error () != bfd_error_invalid_operation)
320                       {
321                         bfd_nonfatal (p->name);
322                         ret = 0;
323                       }
324                     ok = FALSE;
325                   }
326               }
327
328             if (ok)
329               {
330                 if (! bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
331                   ok = FALSE;
332               }
333
334             if (ok)
335               printf ("%s ", p->name);
336             else
337               {
338                 int l = strlen (p->name);
339                 while (l--)
340                   putchar ('-');
341                 putchar (' ');
342               }
343             if (abfd != NULL)
344               bfd_close_all_done (abfd);
345           }
346         putchar ('\n');
347       }
348   unlink (dummy_name);
349   free (dummy_name);
350
351   return ret;
352 }
353
354 /* Print tables of all the target-architecture combinations that
355    BFD has been configured to support.  */
356
357 static int
358 display_target_tables (void)
359 {
360   int t;
361   int columns;
362   int ret = 1;
363   char *colum;
364
365   columns = 0;
366   colum = getenv ("COLUMNS");
367   if (colum != NULL)
368     columns = atoi (colum);
369   if (columns == 0)
370     columns = 80;
371
372   t = 0;
373   while (bfd_target_vector[t] != NULL)
374     {
375       int oldt = t, wid;
376
377       wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1;
378       ++t;
379       while (wid < columns && bfd_target_vector[t] != NULL)
380         {
381           int newwid;
382
383           newwid = wid + strlen (bfd_target_vector[t]->name) + 1;
384           if (newwid >= columns)
385             break;
386           wid = newwid;
387           ++t;
388         }
389       if (! display_info_table (oldt, t))
390         ret = 0;
391     }
392
393   return ret;
394 }
395
396 int
397 display_info (void)
398 {
399   printf (_("BFD header file version %s\n"), BFD_VERSION_STRING);
400   if (! display_target_list () || ! display_target_tables ())
401     return 1;
402   else
403     return 0;
404 }
405 \f
406 /* Display the archive header for an element as if it were an ls -l listing:
407
408    Mode       User\tGroup\tSize\tDate               Name */
409
410 void
411 print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose)
412 {
413   struct stat buf;
414
415   if (verbose)
416     {
417       if (bfd_stat_arch_elt (abfd, &buf) == 0)
418         {
419           char modebuf[11];
420           char timebuf[40];
421           time_t when = buf.st_mtime;
422           const char *ctime_result = (const char *) ctime (&when);
423
424           /* POSIX format:  skip weekday and seconds from ctime output.  */
425           sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
426
427           mode_string (buf.st_mode, modebuf);
428           modebuf[10] = '\0';
429           /* POSIX 1003.2/D11 says to skip first character (entry type).  */
430           fprintf (file, "%s %ld/%ld %6ld %s ", modebuf + 1,
431                    (long) buf.st_uid, (long) buf.st_gid,
432                    (long) buf.st_size, timebuf);
433         }
434     }
435
436   fprintf (file, "%s\n", bfd_get_filename (abfd));
437 }
438
439 /* Return a path for a new temporary file in the same directory
440    as file PATH.  */
441
442 static char *
443 template_in_dir (const char *path)
444 {
445 #define template "stXXXXXX"
446   const char *slash = strrchr (path, '/');
447   char *tmpname;
448   size_t len;
449
450 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
451   {
452     /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
453     char *bslash = strrchr (path, '\\');
454
455     if (slash == NULL || (bslash != NULL && bslash > slash))
456       slash = bslash;
457     if (slash == NULL && path[0] != '\0' && path[1] == ':')
458       slash = path + 1;
459   }
460 #endif
461
462   if (slash != (char *) NULL)
463     {
464       len = slash - path;
465       tmpname = (char *) xmalloc (len + sizeof (template) + 2);
466       memcpy (tmpname, path, len);
467
468 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
469       /* If tmpname is "X:", appending a slash will make it a root
470          directory on drive X, which is NOT the same as the current
471          directory on drive X.  */
472       if (len == 2 && tmpname[1] == ':')
473         tmpname[len++] = '.';
474 #endif
475       tmpname[len++] = '/';
476     }
477   else
478     {
479       tmpname = (char *) xmalloc (sizeof (template));
480       len = 0;
481     }
482
483   memcpy (tmpname + len, template, sizeof (template));
484   return tmpname;
485 #undef template
486 }
487
488 /* Return the name of a created temporary file in the same directory
489    as FILENAME.  */
490
491 char *
492 make_tempname (char *filename)
493 {
494   char *tmpname = template_in_dir (filename);
495   int fd;
496
497 #ifdef HAVE_MKSTEMP
498   fd = mkstemp (tmpname);
499 #else
500   tmpname = mktemp (tmpname);
501   if (tmpname == NULL)
502     return NULL;
503   fd = open (tmpname, O_RDWR | O_CREAT | O_EXCL, 0600);
504 #endif
505   if (fd == -1)
506     return NULL;
507   close (fd);
508   return tmpname;
509 }
510
511 /* Return the name of a created temporary directory inside the
512    directory containing FILENAME.  */
513
514 char *
515 make_tempdir (char *filename)
516 {
517   char *tmpname = template_in_dir (filename);
518
519 #ifdef HAVE_MKDTEMP
520   return mkdtemp (tmpname);
521 #else
522   tmpname = mktemp (tmpname);
523   if (tmpname == NULL)
524     return NULL;
525 #if defined (_WIN32) && !defined (__CYGWIN32__)
526   if (mkdir (tmpname) != 0)
527     return NULL;
528 #else
529   if (mkdir (tmpname, 0700) != 0)
530     return NULL;
531 #endif
532   return tmpname;
533 #endif
534 }
535
536 /* Parse a string into a VMA, with a fatal error if it can't be
537    parsed.  */
538
539 bfd_vma
540 parse_vma (const char *s, const char *arg)
541 {
542   bfd_vma ret;
543   const char *end;
544
545   ret = bfd_scan_vma (s, &end, 0);
546
547   if (*end != '\0')
548     fatal (_("%s: bad number: %s"), arg, s);
549
550   return ret;
551 }
552
553 /* Returns the size of the named file.  If the file does not
554    exist, or if it is not a real file, then a suitable non-fatal
555    error message is printed and zero is returned.  */
556
557 off_t
558 get_file_size (const char * file_name)
559 {
560   struct stat statbuf;
561   
562   if (stat (file_name, &statbuf) < 0)
563     {
564       if (errno == ENOENT)
565         non_fatal (_("'%s': No such file"), file_name);
566       else
567         non_fatal (_("Warning: could not locate '%s'.  reason: %s"),
568                    file_name, strerror (errno));
569     }  
570   else if (! S_ISREG (statbuf.st_mode))
571     non_fatal (_("Warning: '%s' is not an ordinary file"), file_name);
572   else
573     return statbuf.st_size;
574
575   return (off_t) -1;
576 }
577
578 /* Return the filename in a static buffer.  */
579
580 const char *
581 bfd_get_archive_filename (const bfd *abfd)
582 {
583   static size_t curr = 0;
584   static char *buf;
585   size_t needed;
586
587   assert (abfd != NULL);
588   
589   if (!abfd->my_archive)
590     return bfd_get_filename (abfd);
591
592   needed = (strlen (bfd_get_filename (abfd->my_archive))
593             + strlen (bfd_get_filename (abfd)) + 3);
594   if (needed > curr)
595     {
596       if (curr)
597         free (buf);
598       curr = needed + (needed >> 1);
599       buf = (char *) bfd_malloc (curr);
600       /* If we can't malloc, fail safe by returning just the file name.
601          This function is only used when building error messages.  */
602       if (!buf)
603         {
604           curr = 0;
605           return bfd_get_filename (abfd);
606         }
607     }
608   sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive),
609            bfd_get_filename (abfd));
610   return buf;
611 }