1 /* bucomm.c -- Bin Utils COMmon code.
2 Copyright (C) 1991-2022 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"
32 /* Error reporting. */
37 bfd_nonfatal (const char *string
)
40 enum bfd_error err
= bfd_get_error ();
42 if (err
== bfd_error_no_error
)
43 errmsg
= _("cause of error unknown");
45 errmsg
= bfd_errmsg (err
);
48 fprintf (stderr
, "%s: %s: %s\n", program_name
, string
, errmsg
);
50 fprintf (stderr
, "%s: %s\n", program_name
, errmsg
);
53 /* Issue a non fatal error message. FILENAME, or if NULL then BFD,
54 are used to indicate the problematic file. SECTION, if non NULL,
55 is used to provide a section name. If FORMAT is non-null, then it
56 is used to print additional information via vfprintf. Finally the
57 bfd error message is printed. In summary, error messages are of
58 one of the following forms:
60 PROGRAM: file: bfd-error-message
61 PROGRAM: file[section]: bfd-error-message
62 PROGRAM: file: printf-message: bfd-error-message
63 PROGRAM: file[section]: printf-message: bfd-error-message. */
66 bfd_nonfatal_message (const char *filename
,
68 const asection
*section
,
69 const char *format
, ...)
72 const char *section_name
;
73 enum bfd_error err
= bfd_get_error ();
75 if (err
== bfd_error_no_error
)
76 errmsg
= _("cause of error unknown");
78 errmsg
= bfd_errmsg (err
);
81 fprintf (stderr
, "%s", program_name
);
86 filename
= bfd_get_archive_filename (abfd
);
88 section_name
= bfd_section_name (section
);
91 fprintf (stderr
, ": %s[%s]", filename
, section_name
);
93 fprintf (stderr
, ": %s", filename
);
98 va_start (args
, format
);
99 fprintf (stderr
, ": ");
100 vfprintf (stderr
, format
, args
);
103 fprintf (stderr
, ": %s\n", errmsg
);
107 bfd_fatal (const char *string
)
109 bfd_nonfatal (string
);
114 report (const char * format
, va_list args
)
117 fprintf (stderr
, "%s: ", program_name
);
118 vfprintf (stderr
, format
, args
);
123 fatal (const char *format
, ...)
127 va_start (args
, format
);
129 report (format
, args
);
135 non_fatal (const char *format
, ...)
139 va_start (args
, format
);
141 report (format
, args
);
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
151 set_default_bfd_target (void)
153 /* The macro TARGET is defined by Makefile. */
154 const char *target
= TARGET
;
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 ()));
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. */
166 list_matching_formats (char **p
)
169 fprintf (stderr
, _("%s: Matching formats:"), program_name
);
171 fprintf (stderr
, " %s", *p
++);
172 fputc ('\n', stderr
);
175 /* List the supported targets. */
178 list_supported_targets (const char *name
, FILE *f
)
181 const char **targ_names
;
184 fprintf (f
, _("Supported targets:"));
186 fprintf (f
, _("%s: supported targets:"), name
);
188 targ_names
= bfd_target_list ();
189 for (t
= 0; targ_names
[t
] != NULL
; t
++)
190 fprintf (f
, " %s", targ_names
[t
]);
195 /* List the supported architectures. */
198 list_supported_architectures (const char *name
, FILE *f
)
201 const char ** arches
;
204 fprintf (f
, _("Supported architectures:"));
206 fprintf (f
, _("%s: supported architectures:"), name
);
208 for (arch
= arches
= bfd_arch_list (); *arch
; arch
++)
209 fprintf (f
, " %s", *arch
);
215 endian_string (enum bfd_endian endian
)
219 case BFD_ENDIAN_BIG
: return _("big endian");
220 case BFD_ENDIAN_LITTLE
: return _("little endian");
221 default: return _("endianness unknown");
225 /* Data passed to do_display_target and other target iterators. */
227 struct display_target
{
232 /* Number of targets. */
234 /* Size of info in bytes. */
236 /* Per-target info. */
240 /* Non-zero if target/arch combination supported. */
241 unsigned char arch
[bfd_arch_last
- bfd_arch_obscure
- 1];
245 /* List the targets that BFD is configured to support, each followed
246 by its endianness and the architectures it supports. Also build
247 info about target/archs. */
250 do_display_target (const bfd_target
*targ
, void *data
)
252 struct display_target
*param
= (struct display_target
*) data
;
257 amt
= param
->count
* sizeof (*param
->info
);
258 if (param
->alloc
< amt
)
260 size_t size
= ((param
->count
< 64 ? 64 : param
->count
)
261 * sizeof (*param
->info
) * 2);
262 param
->info
= xrealloc (param
->info
, size
);
263 memset ((char *) param
->info
+ param
->alloc
, 0, size
- param
->alloc
);
266 param
->info
[param
->count
- 1].name
= targ
->name
;
268 printf (_("%s\n (header %s, data %s)\n"), targ
->name
,
269 endian_string (targ
->header_byteorder
),
270 endian_string (targ
->byteorder
));
272 abfd
= bfd_openw (param
->filename
, targ
->name
);
275 bfd_nonfatal (param
->filename
);
278 else if (!bfd_set_format (abfd
, bfd_object
))
280 if (bfd_get_error () != bfd_error_invalid_operation
)
282 bfd_nonfatal (targ
->name
);
288 enum bfd_architecture a
;
290 for (a
= bfd_arch_obscure
+ 1; a
< bfd_arch_last
; a
++)
291 if (bfd_set_arch_mach (abfd
, a
, 0))
293 printf (" %s\n", bfd_printable_arch_mach (a
, 0));
294 param
->info
[param
->count
- 1].arch
[a
- bfd_arch_obscure
- 1] = 1;
298 bfd_close_all_done (abfd
);
304 display_target_list (struct display_target
*arg
)
306 arg
->filename
= make_temp_file (NULL
);
312 bfd_iterate_over_targets (do_display_target
, arg
);
314 unlink (arg
->filename
);
315 free (arg
->filename
);
318 /* Calculate how many targets we can print across the page. */
321 do_info_size (int targ
, int width
, const struct display_target
*arg
)
323 while (targ
< arg
->count
)
325 width
-= strlen (arg
->info
[targ
].name
) + 1;
333 /* Print header of target names. */
336 do_info_header (int targ
, int stop_targ
, const struct display_target
*arg
)
338 while (targ
!= stop_targ
)
339 printf ("%s ", arg
->info
[targ
++].name
);
342 /* Print a table row. */
345 do_info_row (int targ
, int stop_targ
, enum bfd_architecture a
,
346 const struct display_target
*arg
)
348 while (targ
!= stop_targ
)
350 if (arg
->info
[targ
].arch
[a
- bfd_arch_obscure
- 1])
351 fputs (arg
->info
[targ
].name
, stdout
);
354 int l
= strlen (arg
->info
[targ
].name
);
359 if (targ
!= stop_targ
)
364 /* Print tables of all the target-architecture combinations that
365 BFD has been configured to support. */
368 display_target_tables (const struct display_target
*arg
)
371 int width
, start_targ
, stop_targ
;
372 enum bfd_architecture arch
;
373 int longest_arch
= 0;
375 for (arch
= bfd_arch_obscure
+ 1; arch
< bfd_arch_last
; arch
++)
377 const char *s
= bfd_printable_arch_mach (arch
, 0);
378 int len
= strlen (s
);
379 if (len
> longest_arch
)
384 columns
= getenv ("COLUMNS");
386 width
= atoi (columns
);
390 for (start_targ
= 0; start_targ
< arg
->count
; start_targ
= stop_targ
)
392 stop_targ
= do_info_size (start_targ
, width
- longest_arch
- 1, arg
);
394 printf ("\n%*s", longest_arch
+ 1, " ");
395 do_info_header (start_targ
, stop_targ
, arg
);
398 for (arch
= bfd_arch_obscure
+ 1; arch
< bfd_arch_last
; arch
++)
400 if (strcmp (bfd_printable_arch_mach (arch
, 0), "UNKNOWN!") != 0)
402 printf ("%*s ", longest_arch
,
403 bfd_printable_arch_mach (arch
, 0));
405 do_info_row (start_targ
, stop_targ
, arch
, arg
);
415 struct display_target arg
;
417 printf (_("BFD header file version %s\n"), BFD_VERSION_STRING
);
419 display_target_list (&arg
);
421 display_target_tables (&arg
);
426 /* Display the archive header for an element as if it were an ls -l listing:
428 Mode User\tGroup\tSize\tDate Name */
431 print_arelt_descr (FILE *file
, bfd
*abfd
, bool verbose
, bool offsets
)
437 if (bfd_stat_arch_elt (abfd
, &buf
) == 0)
441 time_t when
= buf
.st_mtime
;
442 const char *ctime_result
= (const char *) ctime (&when
);
445 /* PR binutils/17605: Check for corrupt time values. */
446 if (ctime_result
== NULL
)
447 sprintf (timebuf
, _("<time data corrupt>"));
449 /* POSIX format: skip weekday and seconds from ctime output. */
450 sprintf (timebuf
, "%.12s %.4s", ctime_result
+ 4, ctime_result
+ 20);
452 mode_string (buf
.st_mode
, modebuf
);
455 /* POSIX 1003.2/D11 says to skip first character (entry type). */
456 fprintf (file
, "%s %ld/%ld %6" BFD_VMA_FMT
"u %s ", modebuf
+ 1,
457 (long) buf
.st_uid
, (long) buf
.st_gid
,
462 fprintf (file
, "%s", bfd_get_filename (abfd
));
466 if (bfd_is_thin_archive (abfd
) && abfd
->proxy_origin
)
467 fprintf (file
, " 0x%lx", (unsigned long) abfd
->proxy_origin
);
468 else if (!bfd_is_thin_archive (abfd
) && abfd
->origin
)
469 fprintf (file
, " 0x%lx", (unsigned long) abfd
->origin
);
472 fprintf (file
, "\n");
475 /* Return a path for a new temporary file in the same directory
479 template_in_dir (const char *path
)
481 #define template "stXXXXXX"
482 const char *slash
= strrchr (path
, '/');
486 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
488 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
489 char *bslash
= strrchr (path
, '\\');
491 if (slash
== NULL
|| (bslash
!= NULL
&& bslash
> slash
))
493 if (slash
== NULL
&& path
[0] != '\0' && path
[1] == ':')
498 if (slash
!= (char *) NULL
)
501 tmpname
= (char *) xmalloc (len
+ sizeof (template) + 2);
502 memcpy (tmpname
, path
, len
);
504 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
505 /* If tmpname is "X:", appending a slash will make it a root
506 directory on drive X, which is NOT the same as the current
507 directory on drive X. */
508 if (len
== 2 && tmpname
[1] == ':')
509 tmpname
[len
++] = '.';
511 tmpname
[len
++] = '/';
515 tmpname
= (char *) xmalloc (sizeof (template));
519 memcpy (tmpname
+ len
, template, sizeof (template));
524 /* Return the name of a created temporary file in the same directory
528 make_tempname (const char *filename
, int *ofd
)
530 char *tmpname
= template_in_dir (filename
);
534 fd
= mkstemp (tmpname
);
536 tmpname
= mktemp (tmpname
);
539 fd
= open (tmpname
, O_RDWR
| O_CREAT
| O_EXCL
, 0600);
550 /* Return the name of a created temporary directory inside the
551 directory containing FILENAME. */
554 make_tempdir (const char *filename
)
556 char *tmpname
= template_in_dir (filename
);
559 return mkdtemp (tmpname
);
561 tmpname
= mktemp (tmpname
);
564 #if defined (_WIN32) && !defined (__CYGWIN32__)
565 if (mkdir (tmpname
) != 0)
568 if (mkdir (tmpname
, 0700) != 0)
575 /* Parse a string into a VMA, with a fatal error if it can't be
579 parse_vma (const char *s
, const char *arg
)
584 ret
= bfd_scan_vma (s
, &end
, 0);
587 fatal (_("%s: bad number: %s"), arg
, s
);
592 /* Returns the size of the named file. If the file does not
593 exist, or if it is not a real file, then a suitable non-fatal
594 error message is printed and (off_t) -1 is returned. */
597 get_file_size (const char * file_name
)
601 if (file_name
== NULL
)
604 if (stat (file_name
, &statbuf
) < 0)
607 non_fatal (_("'%s': No such file"), file_name
);
609 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
610 file_name
, strerror (errno
));
612 else if (S_ISDIR (statbuf
.st_mode
))
613 non_fatal (_("Warning: '%s' is a directory"), file_name
);
614 else if (! S_ISREG (statbuf
.st_mode
))
615 non_fatal (_("Warning: '%s' is not an ordinary file"), file_name
);
616 else if (statbuf
.st_size
< 0)
617 non_fatal (_("Warning: '%s' has negative size, probably it is too large"),
619 #if defined (_WIN32) && !defined (__CYGWIN__)
620 else if (statbuf
.st_size
== 0)
622 /* MS-Windows 'stat' reports the null device as a regular file;
624 int fd
= open (file_name
, O_RDONLY
| O_BINARY
);
628 non_fatal (_("Warning: '%s' is not an ordinary file"),
629 /* libtool wants to see /dev/null in the output. */
630 strcasecmp (file_name
, "nul") ? file_name
: "/dev/null");
635 return statbuf
.st_size
;
640 /* Return the filename in a static buffer. */
643 bfd_get_archive_filename (const bfd
*abfd
)
645 static size_t curr
= 0;
649 assert (abfd
!= NULL
);
651 if (abfd
->my_archive
== NULL
652 || bfd_is_thin_archive (abfd
->my_archive
))
653 return bfd_get_filename (abfd
);
655 needed
= (strlen (bfd_get_filename (abfd
->my_archive
))
656 + strlen (bfd_get_filename (abfd
)) + 3);
661 curr
= needed
+ (needed
>> 1);
662 buf
= (char *) xmalloc (curr
);
664 sprintf (buf
, "%s(%s)", bfd_get_filename (abfd
->my_archive
),
665 bfd_get_filename (abfd
));
669 /* Returns TRUE iff PATHNAME, a filename of an archive member,
670 is valid for writing. For security reasons absolute paths
671 and paths containing /../ are not allowed. See PR 17533. */
674 is_valid_archive_path (char const * pathname
)
676 const char * n
= pathname
;
678 if (IS_ABSOLUTE_PATH (n
))
683 if (*n
== '.' && *++n
== '.' && ( ! *++n
|| IS_DIR_SEPARATOR (*n
)))
686 while (*n
&& ! IS_DIR_SEPARATOR (*n
))
688 while (IS_DIR_SEPARATOR (*n
))