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.
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"
33 #include <time.h> /* ctime, maybe time_t */
37 #ifndef HAVE_TIME_T_IN_TIME_H
38 #ifndef HAVE_TIME_T_IN_TYPES_H
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);
48 /* Error reporting. */
53 bfd_nonfatal (const char *string)
57 errmsg = bfd_errmsg (bfd_get_error ());
60 fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg);
62 fprintf (stderr, "%s: %s\n", program_name, errmsg);
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:
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. */
78 bfd_nonfatal_message (const char *filename,
80 const asection *section,
81 const char *format, ...)
84 const char *section_name;
87 errmsg = bfd_errmsg (bfd_get_error ());
90 va_start (args, format);
91 fprintf (stderr, "%s", program_name);
96 filename = bfd_get_archive_filename (abfd);
98 section_name = bfd_get_section_name (abfd, section);
101 fprintf (stderr, ":%s[%s]", filename, section_name);
103 fprintf (stderr, ":%s", filename);
107 fprintf (stderr, ": ");
108 vfprintf (stderr, format, args);
110 fprintf (stderr, ": %s\n", errmsg);
115 bfd_fatal (const char *string)
117 bfd_nonfatal (string);
122 report (const char * format, va_list args)
125 fprintf (stderr, "%s: ", program_name);
126 vfprintf (stderr, format, args);
131 fatal VPARAMS ((const char *format, ...))
133 VA_OPEN (args, format);
134 VA_FIXEDARG (args, const char *, format);
136 report (format, args);
142 non_fatal VPARAMS ((const char *format, ...))
144 VA_OPEN (args, format);
145 VA_FIXEDARG (args, const char *, format);
147 report (format, args);
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
157 set_default_bfd_target (void)
159 /* The macro TARGET is defined by Makefile. */
160 const char *target = TARGET;
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 ()));
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. */
172 list_matching_formats (char **p)
175 fprintf (stderr, _("%s: Matching formats:"), program_name);
177 fprintf (stderr, " %s", *p++);
178 fputc ('\n', stderr);
181 /* List the supported targets. */
184 list_supported_targets (const char *name, FILE *f)
187 const char **targ_names;
190 fprintf (f, _("Supported targets:"));
192 fprintf (f, _("%s: supported targets:"), name);
194 targ_names = bfd_target_list ();
195 for (t = 0; targ_names[t] != NULL; t++)
196 fprintf (f, " %s", targ_names[t]);
201 /* List the supported architectures. */
204 list_supported_architectures (const char *name, FILE *f)
207 const char ** arches;
210 fprintf (f, _("Supported architectures:"));
212 fprintf (f, _("%s: supported architectures:"), name);
214 for (arch = arches = bfd_arch_list (); *arch; arch++)
215 fprintf (f, " %s", *arch);
220 /* The length of the longest architecture name + 1. */
221 #define LONGEST_ARCH sizeof ("powerpc:common")
224 endian_string (enum bfd_endian endian)
228 case BFD_ENDIAN_BIG: return "big endian";
229 case BFD_ENDIAN_LITTLE: return "little endian";
230 default: return "endianness unknown";
234 /* List the targets that BFD is configured to support, each followed
235 by its endianness and the architectures it supports. */
238 display_target_list (void)
244 dummy_name = make_temp_file (NULL);
245 for (t = 0; bfd_target_vector[t]; t++)
247 const bfd_target *p = bfd_target_vector[t];
248 bfd *abfd = bfd_openw (dummy_name, p->name);
251 printf ("%s\n (header %s, data %s)\n", p->name,
252 endian_string (p->header_byteorder),
253 endian_string (p->byteorder));
257 bfd_nonfatal (dummy_name);
262 if (! bfd_set_format (abfd, bfd_object))
264 if (bfd_get_error () != bfd_error_invalid_operation)
266 bfd_nonfatal (p->name);
269 bfd_close_all_done (abfd);
273 for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
274 if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
276 bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
277 bfd_close_all_done (abfd);
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). */
290 display_info_table (int first, int last)
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);
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),
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++)
312 const bfd_target *p = bfd_target_vector[t];
313 bfd_boolean ok = TRUE;
314 bfd *abfd = bfd_openw (dummy_name, p->name);
318 bfd_nonfatal (p->name);
325 if (! bfd_set_format (abfd, bfd_object))
327 if (bfd_get_error () != bfd_error_invalid_operation)
329 bfd_nonfatal (p->name);
338 if (! bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
343 printf ("%s ", p->name);
346 int l = strlen (p->name);
352 bfd_close_all_done (abfd);
362 /* Print tables of all the target-architecture combinations that
363 BFD has been configured to support. */
366 display_target_tables (void)
374 colum = getenv ("COLUMNS");
376 columns = atoi (colum);
381 while (bfd_target_vector[t] != NULL)
385 wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1;
387 while (wid < columns && bfd_target_vector[t] != NULL)
391 newwid = wid + strlen (bfd_target_vector[t]->name) + 1;
392 if (newwid >= columns)
397 if (! display_info_table (oldt, t))
407 printf (_("BFD header file version %s\n"), BFD_VERSION_STRING);
408 if (! display_target_list () || ! display_target_tables ())
414 /* Display the archive header for an element as if it were an ls -l listing:
416 Mode User\tGroup\tSize\tDate Name */
419 print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose)
425 if (bfd_stat_arch_elt (abfd, &buf) == 0)
429 time_t when = buf.st_mtime;
430 const char *ctime_result = (const char *) ctime (&when);
432 /* POSIX format: skip weekday and seconds from ctime output. */
433 sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
435 mode_string (buf.st_mode, modebuf);
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);
444 fprintf (file, "%s\n", bfd_get_filename (abfd));
447 /* Return a path for a new temporary file in the same directory
451 template_in_dir (const char *path)
453 #define template "stXXXXXX"
454 const char *slash = strrchr (path, '/');
458 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
460 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
461 char *bslash = strrchr (path, '\\');
463 if (slash == NULL || (bslash != NULL && bslash > slash))
465 if (slash == NULL && path[0] != '\0' && path[1] == ':')
470 if (slash != (char *) NULL)
473 tmpname = (char *) xmalloc (len + sizeof (template) + 2);
474 memcpy (tmpname, path, len);
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++] = '.';
483 tmpname[len++] = '/';
487 tmpname = (char *) xmalloc (sizeof (template));
491 memcpy (tmpname + len, template, sizeof (template));
496 /* Return the name of a created temporary file in the same directory
500 make_tempname (char *filename)
502 char *tmpname = template_in_dir (filename);
506 fd = mkstemp (tmpname);
508 tmpname = mktemp (tmpname);
511 fd = open (tmpname, O_RDWR | O_CREAT | O_EXCL, 0600);
522 /* Return the name of a created temporary directory inside the
523 directory containing FILENAME. */
526 make_tempdir (char *filename)
528 char *tmpname = template_in_dir (filename);
531 return mkdtemp (tmpname);
533 tmpname = mktemp (tmpname);
536 #if defined (_WIN32) && !defined (__CYGWIN32__)
537 if (mkdir (tmpname) != 0)
540 if (mkdir (tmpname, 0700) != 0)
547 /* Parse a string into a VMA, with a fatal error if it can't be
551 parse_vma (const char *s, const char *arg)
556 ret = bfd_scan_vma (s, &end, 0);
559 fatal (_("%s: bad number: %s"), arg, s);
564 /* Returns the size of the named file. If the file does not
565 exist, or if it is not a real file, then a suitable non-fatal
566 error message is printed and (off_t) -1 is returned. */
569 get_file_size (const char * file_name)
573 if (stat (file_name, &statbuf) < 0)
576 non_fatal (_("'%s': No such file"), file_name);
578 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
579 file_name, strerror (errno));
581 else if (! S_ISREG (statbuf.st_mode))
582 non_fatal (_("Warning: '%s' is not an ordinary file"), file_name);
583 else if (statbuf.st_size < 0)
584 non_fatal (_("Warning: '%s' has negative size, probably it is too large"),
587 return statbuf.st_size;
592 /* Return the filename in a static buffer. */
595 bfd_get_archive_filename (const bfd *abfd)
597 static size_t curr = 0;
601 assert (abfd != NULL);
603 if (!abfd->my_archive)
604 return bfd_get_filename (abfd);
606 needed = (strlen (bfd_get_filename (abfd->my_archive))
607 + strlen (bfd_get_filename (abfd)) + 3);
612 curr = needed + (needed >> 1);
613 buf = (char *) bfd_malloc (curr);
614 /* If we can't malloc, fail safe by returning just the file name.
615 This function is only used when building error messages. */
619 return bfd_get_filename (abfd);
622 sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive),
623 bfd_get_filename (abfd));