1 /* bucomm.c -- Bin Utils COMmon code.
2 Copyright (C) 1991-2019 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"
29 #include <time.h> /* ctime, maybe time_t */
33 #ifndef HAVE_TIME_T_IN_TIME_H
34 #ifndef HAVE_TIME_T_IN_TYPES_H
39 /* Error reporting. */
44 bfd_nonfatal (const char *string
)
48 errmsg
= bfd_errmsg (bfd_get_error ());
51 fprintf (stderr
, "%s: %s: %s\n", program_name
, string
, errmsg
);
53 fprintf (stderr
, "%s: %s\n", program_name
, errmsg
);
56 /* Issue a non fatal error message. FILENAME, or if NULL then BFD,
57 are used to indicate the problematic file. SECTION, if non NULL,
58 is used to provide a section name. If FORMAT is non-null, then it
59 is used to print additional information via vfprintf. Finally the
60 bfd error message is printed. In summary, error messages are of
61 one of the following forms:
63 PROGRAM:file: bfd-error-message
64 PROGRAM:file[section]: bfd-error-message
65 PROGRAM:file: printf-message: bfd-error-message
66 PROGRAM:file[section]: printf-message: bfd-error-message. */
69 bfd_nonfatal_message (const char *filename
,
71 const asection
*section
,
72 const char *format
, ...)
75 const char *section_name
;
78 errmsg
= bfd_errmsg (bfd_get_error ());
81 va_start (args
, format
);
82 fprintf (stderr
, "%s", program_name
);
87 filename
= bfd_get_archive_filename (abfd
);
89 section_name
= bfd_get_section_name (abfd
, section
);
92 fprintf (stderr
, ":%s[%s]", filename
, section_name
);
94 fprintf (stderr
, ":%s", filename
);
98 fprintf (stderr
, ": ");
99 vfprintf (stderr
, format
, args
);
101 fprintf (stderr
, ": %s\n", errmsg
);
106 bfd_fatal (const char *string
)
108 bfd_nonfatal (string
);
113 report (const char * format
, va_list args
)
116 fprintf (stderr
, "%s: ", program_name
);
117 vfprintf (stderr
, format
, args
);
122 fatal (const char *format
, ...)
126 va_start (args
, format
);
128 report (format
, args
);
134 non_fatal (const char *format
, ...)
138 va_start (args
, format
);
140 report (format
, args
);
144 /* Set the default BFD target based on the configured target. Doing
145 this permits the binutils to be configured for a particular target,
146 and linked against a shared BFD library which was configured for a
150 set_default_bfd_target (void)
152 /* The macro TARGET is defined by Makefile. */
153 const char *target
= TARGET
;
155 if (! bfd_set_default_target (target
))
156 fatal (_("can't set BFD default target to `%s': %s"),
157 target
, bfd_errmsg (bfd_get_error ()));
160 /* After a FALSE return from bfd_check_format_matches with
161 bfd_get_error () == bfd_error_file_ambiguously_recognized, print
162 the possible matching targets. */
165 list_matching_formats (char **p
)
168 fprintf (stderr
, _("%s: Matching formats:"), program_name
);
170 fprintf (stderr
, " %s", *p
++);
171 fputc ('\n', stderr
);
174 /* List the supported targets. */
177 list_supported_targets (const char *name
, FILE *f
)
180 const char **targ_names
;
183 fprintf (f
, _("Supported targets:"));
185 fprintf (f
, _("%s: supported targets:"), name
);
187 targ_names
= bfd_target_list ();
188 for (t
= 0; targ_names
[t
] != NULL
; t
++)
189 fprintf (f
, " %s", targ_names
[t
]);
194 /* List the supported architectures. */
197 list_supported_architectures (const char *name
, FILE *f
)
200 const char ** arches
;
203 fprintf (f
, _("Supported architectures:"));
205 fprintf (f
, _("%s: supported architectures:"), name
);
207 for (arch
= arches
= bfd_arch_list (); *arch
; arch
++)
208 fprintf (f
, " %s", *arch
);
214 endian_string (enum bfd_endian endian
)
218 case BFD_ENDIAN_BIG
: return _("big endian");
219 case BFD_ENDIAN_LITTLE
: return _("little endian");
220 default: return _("endianness unknown");
224 /* Data passed to do_display_target and other target iterators. */
226 struct display_target
{
231 /* Number of targets. */
233 /* Size of info in bytes. */
235 /* Per-target info. */
239 /* Non-zero if target/arch combination supported. */
240 unsigned char arch
[bfd_arch_last
- bfd_arch_obscure
- 1];
244 /* List the targets that BFD is configured to support, each followed
245 by its endianness and the architectures it supports. Also build
246 info about target/archs. */
249 do_display_target (const bfd_target
*targ
, void *data
)
251 struct display_target
*param
= (struct display_target
*) data
;
256 amt
= param
->count
* sizeof (*param
->info
);
257 if (param
->alloc
< amt
)
259 size_t size
= ((param
->count
< 64 ? 64 : param
->count
)
260 * sizeof (*param
->info
) * 2);
261 param
->info
= xrealloc (param
->info
, size
);
262 memset ((char *) param
->info
+ param
->alloc
, 0, size
- param
->alloc
);
265 param
->info
[param
->count
- 1].name
= targ
->name
;
267 printf (_("%s\n (header %s, data %s)\n"), targ
->name
,
268 endian_string (targ
->header_byteorder
),
269 endian_string (targ
->byteorder
));
271 abfd
= bfd_openw (param
->filename
, targ
->name
);
274 bfd_nonfatal (param
->filename
);
277 else if (!bfd_set_format (abfd
, bfd_object
))
279 if (bfd_get_error () != bfd_error_invalid_operation
)
281 bfd_nonfatal (targ
->name
);
287 enum bfd_architecture a
;
289 for (a
= bfd_arch_obscure
+ 1; a
< bfd_arch_last
; a
++)
290 if (bfd_set_arch_mach (abfd
, a
, 0))
292 printf (" %s\n", bfd_printable_arch_mach (a
, 0));
293 param
->info
[param
->count
- 1].arch
[a
- bfd_arch_obscure
- 1] = 1;
297 bfd_close_all_done (abfd
);
303 display_target_list (struct display_target
*arg
)
305 arg
->filename
= make_temp_file (NULL
);
311 bfd_iterate_over_targets (do_display_target
, arg
);
313 unlink (arg
->filename
);
314 free (arg
->filename
);
317 /* Calculate how many targets we can print across the page. */
320 do_info_size (int targ
, int width
, const struct display_target
*arg
)
322 while (targ
< arg
->count
)
324 width
-= strlen (arg
->info
[targ
].name
) + 1;
332 /* Print header of target names. */
335 do_info_header (int targ
, int stop_targ
, const struct display_target
*arg
)
337 while (targ
!= stop_targ
)
338 printf ("%s ", arg
->info
[targ
++].name
);
341 /* Print a table row. */
344 do_info_row (int targ
, int stop_targ
, enum bfd_architecture a
,
345 const struct display_target
*arg
)
347 while (targ
!= stop_targ
)
349 if (arg
->info
[targ
].arch
[a
- bfd_arch_obscure
- 1])
350 fputs (arg
->info
[targ
].name
, stdout
);
353 int l
= strlen (arg
->info
[targ
].name
);
358 if (targ
!= stop_targ
)
363 /* Print tables of all the target-architecture combinations that
364 BFD has been configured to support. */
367 display_target_tables (const struct display_target
*arg
)
370 int width
, start_targ
, stop_targ
;
371 enum bfd_architecture arch
;
372 int longest_arch
= 0;
374 for (arch
= bfd_arch_obscure
+ 1; arch
< bfd_arch_last
; arch
++)
376 const char *s
= bfd_printable_arch_mach (arch
, 0);
377 int len
= strlen (s
);
378 if (len
> longest_arch
)
383 columns
= getenv ("COLUMNS");
385 width
= atoi (columns
);
389 for (start_targ
= 0; start_targ
< arg
->count
; start_targ
= stop_targ
)
391 stop_targ
= do_info_size (start_targ
, width
- longest_arch
- 1, arg
);
393 printf ("\n%*s", longest_arch
+ 1, " ");
394 do_info_header (start_targ
, stop_targ
, arg
);
397 for (arch
= bfd_arch_obscure
+ 1; arch
< bfd_arch_last
; arch
++)
399 if (strcmp (bfd_printable_arch_mach (arch
, 0), "UNKNOWN!") != 0)
401 printf ("%*s ", longest_arch
,
402 bfd_printable_arch_mach (arch
, 0));
404 do_info_row (start_targ
, stop_targ
, arch
, arg
);
414 struct display_target arg
;
416 printf (_("BFD header file version %s\n"), BFD_VERSION_STRING
);
418 display_target_list (&arg
);
420 display_target_tables (&arg
);
425 /* Display the archive header for an element as if it were an ls -l listing:
427 Mode User\tGroup\tSize\tDate Name */
430 print_arelt_descr (FILE *file
, bfd
*abfd
, bfd_boolean verbose
, bfd_boolean offsets
)
436 if (bfd_stat_arch_elt (abfd
, &buf
) == 0)
440 time_t when
= buf
.st_mtime
;
441 const char *ctime_result
= (const char *) ctime (&when
);
444 /* PR binutils/17605: Check for corrupt time values. */
445 if (ctime_result
== NULL
)
446 sprintf (timebuf
, _("<time data corrupt>"));
448 /* POSIX format: skip weekday and seconds from ctime output. */
449 sprintf (timebuf
, "%.12s %.4s", ctime_result
+ 4, ctime_result
+ 20);
451 mode_string (buf
.st_mode
, modebuf
);
454 /* POSIX 1003.2/D11 says to skip first character (entry type). */
455 fprintf (file
, "%s %ld/%ld %6" BFD_VMA_FMT
"u %s ", modebuf
+ 1,
456 (long) buf
.st_uid
, (long) buf
.st_gid
,
461 fprintf (file
, "%s", bfd_get_filename (abfd
));
465 if (bfd_is_thin_archive (abfd
) && abfd
->proxy_origin
)
466 fprintf (file
, " 0x%lx", (unsigned long) abfd
->proxy_origin
);
467 else if (!bfd_is_thin_archive (abfd
) && abfd
->origin
)
468 fprintf (file
, " 0x%lx", (unsigned long) abfd
->origin
);
471 fprintf (file
, "\n");
474 /* Return a path for a new temporary file in the same directory
478 template_in_dir (const char *path
)
480 #define template "stXXXXXX"
481 const char *slash
= strrchr (path
, '/');
485 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
487 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
488 char *bslash
= strrchr (path
, '\\');
490 if (slash
== NULL
|| (bslash
!= NULL
&& bslash
> slash
))
492 if (slash
== NULL
&& path
[0] != '\0' && path
[1] == ':')
497 if (slash
!= (char *) NULL
)
500 tmpname
= (char *) xmalloc (len
+ sizeof (template) + 2);
501 memcpy (tmpname
, path
, len
);
503 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
504 /* If tmpname is "X:", appending a slash will make it a root
505 directory on drive X, which is NOT the same as the current
506 directory on drive X. */
507 if (len
== 2 && tmpname
[1] == ':')
508 tmpname
[len
++] = '.';
510 tmpname
[len
++] = '/';
514 tmpname
= (char *) xmalloc (sizeof (template));
518 memcpy (tmpname
+ len
, template, sizeof (template));
523 /* Return the name of a created temporary file in the same directory
527 make_tempname (char *filename
)
529 char *tmpname
= template_in_dir (filename
);
533 fd
= mkstemp (tmpname
);
535 tmpname
= mktemp (tmpname
);
538 fd
= open (tmpname
, O_RDWR
| O_CREAT
| O_EXCL
, 0600);
549 /* Return the name of a created temporary directory inside the
550 directory containing FILENAME. */
553 make_tempdir (char *filename
)
555 char *tmpname
= template_in_dir (filename
);
558 return mkdtemp (tmpname
);
560 tmpname
= mktemp (tmpname
);
563 #if defined (_WIN32) && !defined (__CYGWIN32__)
564 if (mkdir (tmpname
) != 0)
567 if (mkdir (tmpname
, 0700) != 0)
574 /* Parse a string into a VMA, with a fatal error if it can't be
578 parse_vma (const char *s
, const char *arg
)
583 ret
= bfd_scan_vma (s
, &end
, 0);
586 fatal (_("%s: bad number: %s"), arg
, s
);
591 /* Returns the size of the named file. If the file does not
592 exist, or if it is not a real file, then a suitable non-fatal
593 error message is printed and (off_t) -1 is returned. */
596 get_file_size (const char * file_name
)
600 if (file_name
== NULL
)
603 if (stat (file_name
, &statbuf
) < 0)
606 non_fatal (_("'%s': No such file"), file_name
);
608 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
609 file_name
, strerror (errno
));
611 else if (S_ISDIR (statbuf
.st_mode
))
612 non_fatal (_("Warning: '%s' is a directory"), file_name
);
613 else if (! S_ISREG (statbuf
.st_mode
))
614 non_fatal (_("Warning: '%s' is not an ordinary file"), file_name
);
615 else if (statbuf
.st_size
< 0)
616 non_fatal (_("Warning: '%s' has negative size, probably it is too large"),
619 return statbuf
.st_size
;
624 /* Return the filename in a static buffer. */
627 bfd_get_archive_filename (const bfd
*abfd
)
629 static size_t curr
= 0;
633 assert (abfd
!= NULL
);
635 if (abfd
->my_archive
== NULL
636 || bfd_is_thin_archive (abfd
->my_archive
))
637 return bfd_get_filename (abfd
);
639 needed
= (strlen (bfd_get_filename (abfd
->my_archive
))
640 + strlen (bfd_get_filename (abfd
)) + 3);
645 curr
= needed
+ (needed
>> 1);
646 buf
= (char *) xmalloc (curr
);
648 sprintf (buf
, "%s(%s)", bfd_get_filename (abfd
->my_archive
),
649 bfd_get_filename (abfd
));
653 /* Returns TRUE iff PATHNAME, a filename of an archive member,
654 is valid for writing. For security reasons absolute paths
655 and paths containing /../ are not allowed. See PR 17533. */
658 is_valid_archive_path (char const * pathname
)
660 const char * n
= pathname
;
662 if (IS_ABSOLUTE_PATH (n
))
667 if (*n
== '.' && *++n
== '.' && ( ! *++n
|| IS_DIR_SEPARATOR (*n
)))
670 while (*n
&& ! IS_DIR_SEPARATOR (*n
))
672 while (IS_DIR_SEPARATOR (*n
))