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.
6 This file is part of GNU Binutils.
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.
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.
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
23 /* We might put this in a library someday so it could be dynamically
24 loaded, but for now it's not necessary. */
28 #include "libiberty.h"
29 #include "filenames.h"
32 #include <time.h> /* ctime, maybe time_t */
36 #ifndef HAVE_TIME_T_IN_TIME_H
37 #ifndef HAVE_TIME_T_IN_TYPES_H
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);
47 /* Error reporting. */
52 bfd_nonfatal (const char *string)
56 errmsg = bfd_errmsg (bfd_get_error ());
59 fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg);
61 fprintf (stderr, "%s: %s\n", program_name, errmsg);
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:
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. */
77 bfd_nonfatal_message (const char *filename,
79 const asection *section,
80 const char *format, ...)
83 const char *section_name;
86 errmsg = bfd_errmsg (bfd_get_error ());
89 va_start (args, format);
90 fprintf (stderr, "%s", program_name);
95 filename = bfd_get_archive_filename (abfd);
97 section_name = bfd_get_section_name (abfd, section);
100 fprintf (stderr, ":%s[%s]", filename, section_name);
102 fprintf (stderr, ":%s", filename);
106 fprintf (stderr, ": ");
107 vfprintf (stderr, format, args);
109 fprintf (stderr, ": %s\n", errmsg);
114 bfd_fatal (const char *string)
116 bfd_nonfatal (string);
121 report (const char * format, va_list args)
124 fprintf (stderr, "%s: ", program_name);
125 vfprintf (stderr, format, args);
130 fatal VPARAMS ((const char *format, ...))
132 VA_OPEN (args, format);
133 VA_FIXEDARG (args, const char *, format);
135 report (format, args);
141 non_fatal VPARAMS ((const char *format, ...))
143 VA_OPEN (args, format);
144 VA_FIXEDARG (args, const char *, format);
146 report (format, args);
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
156 set_default_bfd_target (void)
158 /* The macro TARGET is defined by Makefile. */
159 const char *target = TARGET;
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 ()));
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. */
171 list_matching_formats (char **p)
174 fprintf (stderr, _("%s: Matching formats:"), program_name);
176 fprintf (stderr, " %s", *p++);
177 fputc ('\n', stderr);
180 /* List the supported targets. */
183 list_supported_targets (const char *name, FILE *f)
186 const char **targ_names;
189 fprintf (f, _("Supported targets:"));
191 fprintf (f, _("%s: supported targets:"), name);
193 targ_names = bfd_target_list ();
194 for (t = 0; targ_names[t] != NULL; t++)
195 fprintf (f, " %s", targ_names[t]);
200 /* List the supported architectures. */
203 list_supported_architectures (const char *name, FILE *f)
206 const char ** arches;
209 fprintf (f, _("Supported architectures:"));
211 fprintf (f, _("%s: supported architectures:"), name);
213 for (arch = arches = bfd_arch_list (); *arch; arch++)
214 fprintf (f, " %s", *arch);
219 /* The length of the longest architecture name + 1. */
220 #define LONGEST_ARCH sizeof ("powerpc:common")
223 endian_string (enum bfd_endian endian)
227 case BFD_ENDIAN_BIG: return _("big endian");
228 case BFD_ENDIAN_LITTLE: return _("little endian");
229 default: return _("endianness unknown");
233 /* List the targets that BFD is configured to support, each followed
234 by its endianness and the architectures it supports. */
237 display_target_list (void)
243 dummy_name = make_temp_file (NULL);
244 for (t = 0; bfd_target_vector[t]; t++)
246 const bfd_target *p = bfd_target_vector[t];
247 bfd *abfd = bfd_openw (dummy_name, p->name);
250 printf (_("%s\n (header %s, data %s)\n"), p->name,
251 endian_string (p->header_byteorder),
252 endian_string (p->byteorder));
256 bfd_nonfatal (dummy_name);
261 if (! bfd_set_format (abfd, bfd_object))
263 if (bfd_get_error () != bfd_error_invalid_operation)
265 bfd_nonfatal (p->name);
268 bfd_close_all_done (abfd);
272 for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
273 if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
275 bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
276 bfd_close_all_done (abfd);
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). */
289 display_info_table (int first, int last)
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);
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),
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++)
311 const bfd_target *p = bfd_target_vector[t];
312 bfd_boolean ok = TRUE;
313 bfd *abfd = bfd_openw (dummy_name, p->name);
317 bfd_nonfatal (p->name);
324 if (! bfd_set_format (abfd, bfd_object))
326 if (bfd_get_error () != bfd_error_invalid_operation)
328 bfd_nonfatal (p->name);
337 if (! bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
342 printf ("%s ", p->name);
345 int l = strlen (p->name);
351 bfd_close_all_done (abfd);
361 /* Print tables of all the target-architecture combinations that
362 BFD has been configured to support. */
365 display_target_tables (void)
373 colum = getenv ("COLUMNS");
375 columns = atoi (colum);
380 while (bfd_target_vector[t] != NULL)
384 wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1;
386 while (wid < columns && bfd_target_vector[t] != NULL)
390 newwid = wid + strlen (bfd_target_vector[t]->name) + 1;
391 if (newwid >= columns)
396 if (! display_info_table (oldt, t))
406 printf (_("BFD header file version %s\n"), BFD_VERSION_STRING);
407 if (! display_target_list () || ! display_target_tables ())
413 /* Display the archive header for an element as if it were an ls -l listing:
415 Mode User\tGroup\tSize\tDate Name */
418 print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose)
424 if (bfd_stat_arch_elt (abfd, &buf) == 0)
428 time_t when = buf.st_mtime;
429 const char *ctime_result = (const char *) ctime (&when);
431 /* POSIX format: skip weekday and seconds from ctime output. */
432 sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
434 mode_string (buf.st_mode, modebuf);
436 /* POSIX 1003.2/D11 says to skip first character (entry type). */
437 fprintf (file, "%s %ld/%ld %6ld %s ", modebuf + 1,
438 (long) buf.st_uid, (long) buf.st_gid,
439 (long) buf.st_size, timebuf);
443 fprintf (file, "%s\n", bfd_get_filename (abfd));
446 /* Return a path for a new temporary file in the same directory
450 template_in_dir (const char *path)
452 #define template "stXXXXXX"
453 const char *slash = strrchr (path, '/');
457 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
459 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
460 char *bslash = strrchr (path, '\\');
462 if (slash == NULL || (bslash != NULL && bslash > slash))
464 if (slash == NULL && path[0] != '\0' && path[1] == ':')
469 if (slash != (char *) NULL)
472 tmpname = (char *) xmalloc (len + sizeof (template) + 2);
473 memcpy (tmpname, path, len);
475 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
476 /* If tmpname is "X:", appending a slash will make it a root
477 directory on drive X, which is NOT the same as the current
478 directory on drive X. */
479 if (len == 2 && tmpname[1] == ':')
480 tmpname[len++] = '.';
482 tmpname[len++] = '/';
486 tmpname = (char *) xmalloc (sizeof (template));
490 memcpy (tmpname + len, template, sizeof (template));
495 /* Return the name of a created temporary file in the same directory
499 make_tempname (char *filename)
501 char *tmpname = template_in_dir (filename);
505 fd = mkstemp (tmpname);
507 tmpname = mktemp (tmpname);
510 fd = open (tmpname, O_RDWR | O_CREAT | O_EXCL, 0600);
521 /* Return the name of a created temporary directory inside the
522 directory containing FILENAME. */
525 make_tempdir (char *filename)
527 char *tmpname = template_in_dir (filename);
530 return mkdtemp (tmpname);
532 tmpname = mktemp (tmpname);
535 #if defined (_WIN32) && !defined (__CYGWIN32__)
536 if (mkdir (tmpname) != 0)
539 if (mkdir (tmpname, 0700) != 0)
546 /* Parse a string into a VMA, with a fatal error if it can't be
550 parse_vma (const char *s, const char *arg)
555 ret = bfd_scan_vma (s, &end, 0);
558 fatal (_("%s: bad number: %s"), arg, s);
563 /* Returns the size of the named file. If the file does not
564 exist, or if it is not a real file, then a suitable non-fatal
565 error message is printed and (off_t) -1 is returned. */
568 get_file_size (const char * file_name)
572 if (stat (file_name, &statbuf) < 0)
575 non_fatal (_("'%s': No such file"), file_name);
577 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
578 file_name, strerror (errno));
580 else if (! S_ISREG (statbuf.st_mode))
581 non_fatal (_("Warning: '%s' is not an ordinary file"), file_name);
582 else if (statbuf.st_size < 0)
583 non_fatal (_("Warning: '%s' has negative size, probably it is too large"),
586 return statbuf.st_size;
591 /* Return the filename in a static buffer. */
594 bfd_get_archive_filename (const bfd *abfd)
596 static size_t curr = 0;
600 assert (abfd != NULL);
602 if (!abfd->my_archive)
603 return bfd_get_filename (abfd);
605 needed = (strlen (bfd_get_filename (abfd->my_archive))
606 + strlen (bfd_get_filename (abfd)) + 3);
611 curr = needed + (needed >> 1);
612 buf = (char *) bfd_malloc (curr);
613 /* If we can't malloc, fail safe by returning just the file name.
614 This function is only used when building error messages. */
618 return bfd_get_filename (abfd);
621 sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive),
622 bfd_get_filename (abfd));