1 /* bucomm.c -- Bin Utils COMmon code.
2 Copyright (C) 1991-2015 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21 /* We might put this in a library someday so it could be dynamically
22 loaded, but for now it's not necessary. */
26 #include "libiberty.h"
27 #include "filenames.h"
30 #include <time.h> /* ctime, maybe time_t */
34 #ifndef HAVE_TIME_T_IN_TIME_H
35 #ifndef HAVE_TIME_T_IN_TYPES_H
40 static const char * endian_string (enum bfd_endian);
41 static int display_target_list (void);
42 static int display_info_table (int, int);
43 static int display_target_tables (void);
45 /* Error reporting. */
50 bfd_nonfatal (const char *string)
54 errmsg = bfd_errmsg (bfd_get_error ());
57 fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg);
59 fprintf (stderr, "%s: %s\n", program_name, errmsg);
62 /* Issue a non fatal error message. FILENAME, or if NULL then BFD,
63 are used to indicate the problematic file. SECTION, if non NULL,
64 is used to provide a section name. If FORMAT is non-null, then it
65 is used to print additional information via vfprintf. Finally the
66 bfd error message is printed. In summary, error messages are of
67 one of the following forms:
69 PROGRAM:file: bfd-error-message
70 PROGRAM:file[section]: bfd-error-message
71 PROGRAM:file: printf-message: bfd-error-message
72 PROGRAM:file[section]: printf-message: bfd-error-message. */
75 bfd_nonfatal_message (const char *filename,
77 const asection *section,
78 const char *format, ...)
81 const char *section_name;
84 errmsg = bfd_errmsg (bfd_get_error ());
87 va_start (args, format);
88 fprintf (stderr, "%s", program_name);
93 filename = bfd_get_archive_filename (abfd);
95 section_name = bfd_get_section_name (abfd, section);
98 fprintf (stderr, ":%s[%s]", filename, section_name);
100 fprintf (stderr, ":%s", filename);
104 fprintf (stderr, ": ");
105 vfprintf (stderr, format, args);
107 fprintf (stderr, ": %s\n", errmsg);
112 bfd_fatal (const char *string)
114 bfd_nonfatal (string);
119 report (const char * format, va_list args)
122 fprintf (stderr, "%s: ", program_name);
123 vfprintf (stderr, format, args);
128 fatal (const char *format, ...)
132 va_start (args, format);
134 report (format, args);
140 non_fatal (const char *format, ...)
144 va_start (args, 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);
432 /* PR binutils/17605: Check for corrupt time values. */
433 if (ctime_result == NULL)
434 sprintf (timebuf, _("<time data corrupt>"));
436 /* POSIX format: skip weekday and seconds from ctime output. */
437 sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
439 mode_string (buf.st_mode, modebuf);
442 /* POSIX 1003.2/D11 says to skip first character (entry type). */
443 fprintf (file, "%s %ld/%ld %6" BFD_VMA_FMT "u %s ", modebuf + 1,
444 (long) buf.st_uid, (long) buf.st_gid,
449 fprintf (file, "%s\n", bfd_get_filename (abfd));
452 /* Return a path for a new temporary file in the same directory
456 template_in_dir (const char *path)
458 #define template "stXXXXXX"
459 const char *slash = strrchr (path, '/');
463 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
465 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
466 char *bslash = strrchr (path, '\\');
468 if (slash == NULL || (bslash != NULL && bslash > slash))
470 if (slash == NULL && path[0] != '\0' && path[1] == ':')
475 if (slash != (char *) NULL)
478 tmpname = (char *) xmalloc (len + sizeof (template) + 2);
479 memcpy (tmpname, path, len);
481 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
482 /* If tmpname is "X:", appending a slash will make it a root
483 directory on drive X, which is NOT the same as the current
484 directory on drive X. */
485 if (len == 2 && tmpname[1] == ':')
486 tmpname[len++] = '.';
488 tmpname[len++] = '/';
492 tmpname = (char *) xmalloc (sizeof (template));
496 memcpy (tmpname + len, template, sizeof (template));
501 /* Return the name of a created temporary file in the same directory
505 make_tempname (char *filename)
507 char *tmpname = template_in_dir (filename);
511 fd = mkstemp (tmpname);
513 tmpname = mktemp (tmpname);
516 fd = open (tmpname, O_RDWR | O_CREAT | O_EXCL, 0600);
527 /* Return the name of a created temporary directory inside the
528 directory containing FILENAME. */
531 make_tempdir (char *filename)
533 char *tmpname = template_in_dir (filename);
536 return mkdtemp (tmpname);
538 tmpname = mktemp (tmpname);
541 #if defined (_WIN32) && !defined (__CYGWIN32__)
542 if (mkdir (tmpname) != 0)
545 if (mkdir (tmpname, 0700) != 0)
552 /* Parse a string into a VMA, with a fatal error if it can't be
556 parse_vma (const char *s, const char *arg)
561 ret = bfd_scan_vma (s, &end, 0);
564 fatal (_("%s: bad number: %s"), arg, s);
569 /* Returns the size of the named file. If the file does not
570 exist, or if it is not a real file, then a suitable non-fatal
571 error message is printed and (off_t) -1 is returned. */
574 get_file_size (const char * file_name)
578 if (stat (file_name, &statbuf) < 0)
581 non_fatal (_("'%s': No such file"), file_name);
583 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
584 file_name, strerror (errno));
586 else if (! S_ISREG (statbuf.st_mode))
587 non_fatal (_("Warning: '%s' is not an ordinary file"), file_name);
588 else if (statbuf.st_size < 0)
589 non_fatal (_("Warning: '%s' has negative size, probably it is too large"),
592 return statbuf.st_size;
597 /* Return the filename in a static buffer. */
600 bfd_get_archive_filename (const bfd *abfd)
602 static size_t curr = 0;
606 assert (abfd != NULL);
608 if (!abfd->my_archive)
609 return bfd_get_filename (abfd);
611 needed = (strlen (bfd_get_filename (abfd->my_archive))
612 + strlen (bfd_get_filename (abfd)) + 3);
617 curr = needed + (needed >> 1);
618 buf = (char *) bfd_malloc (curr);
619 /* If we can't malloc, fail safe by returning just the file name.
620 This function is only used when building error messages. */
624 return bfd_get_filename (abfd);
627 sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive),
628 bfd_get_filename (abfd));
632 /* Returns TRUE iff PATHNAME, a filename of an archive member,
633 is valid for writing. For security reasons absolute paths
634 and paths containing /../ are not allowed. See PR 17533. */
637 is_valid_archive_path (char const * pathname)
639 const char * n = pathname;
641 if (IS_ABSOLUTE_PATH (n))
646 if (*n == '.' && *++n == '.' && ( ! *++n || IS_DIR_SEPARATOR (*n)))
649 while (*n && ! IS_DIR_SEPARATOR (*n))
651 while (IS_DIR_SEPARATOR (*n))