1 /* bucomm.c -- Bin Utils COMmon code.
2 Copyright (C) 1991-2023 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 /* Like xmalloc except that ABFD's objalloc memory is returned.
146 Use objalloc_free_block to free this memory and all more recently
147 allocated, or more usually, leave it to bfd_close to free. */
150 bfd_xalloc (bfd
*abfd
, size_t size
)
152 void *ret
= bfd_alloc (abfd
, size
);
158 /* Set the default BFD target based on the configured target. Doing
159 this permits the binutils to be configured for a particular target,
160 and linked against a shared BFD library which was configured for a
164 set_default_bfd_target (void)
166 /* The macro TARGET is defined by Makefile. */
167 const char *target
= TARGET
;
169 if (! bfd_set_default_target (target
))
170 fatal (_("can't set BFD default target to `%s': %s"),
171 target
, bfd_errmsg (bfd_get_error ()));
174 /* After a FALSE return from bfd_check_format_matches with
175 bfd_get_error () == bfd_error_file_ambiguously_recognized, print
176 the possible matching targets and free the list of targets. */
179 list_matching_formats (char **matching
)
182 fprintf (stderr
, _("%s: Matching formats:"), program_name
);
185 fprintf (stderr
, " %s", *p
++);
187 fputc ('\n', stderr
);
190 /* List the supported targets. */
193 list_supported_targets (const char *name
, FILE *f
)
196 const char **targ_names
;
199 fprintf (f
, _("Supported targets:"));
201 fprintf (f
, _("%s: supported targets:"), name
);
203 targ_names
= bfd_target_list ();
204 for (t
= 0; targ_names
[t
] != NULL
; t
++)
205 fprintf (f
, " %s", targ_names
[t
]);
210 /* List the supported architectures. */
213 list_supported_architectures (const char *name
, FILE *f
)
216 const char ** arches
;
219 fprintf (f
, _("Supported architectures:"));
221 fprintf (f
, _("%s: supported architectures:"), name
);
223 for (arch
= arches
= bfd_arch_list (); *arch
; arch
++)
224 fprintf (f
, " %s", *arch
);
230 endian_string (enum bfd_endian endian
)
234 case BFD_ENDIAN_BIG
: return _("big endian");
235 case BFD_ENDIAN_LITTLE
: return _("little endian");
236 default: return _("endianness unknown");
240 /* Data passed to do_display_target and other target iterators. */
242 struct display_target
{
247 /* Number of targets. */
249 /* Size of info in bytes. */
251 /* Per-target info. */
255 /* Non-zero if target/arch combination supported. */
256 unsigned char arch
[bfd_arch_last
- bfd_arch_obscure
- 1];
260 /* List the targets that BFD is configured to support, each followed
261 by its endianness and the architectures it supports. Also build
262 info about target/archs. */
265 do_display_target (const bfd_target
*targ
, void *data
)
267 struct display_target
*param
= (struct display_target
*) data
;
272 amt
= param
->count
* sizeof (*param
->info
);
273 if (param
->alloc
< amt
)
275 size_t size
= ((param
->count
< 64 ? 64 : param
->count
)
276 * sizeof (*param
->info
) * 2);
277 param
->info
= xrealloc (param
->info
, size
);
278 memset ((char *) param
->info
+ param
->alloc
, 0, size
- param
->alloc
);
281 param
->info
[param
->count
- 1].name
= targ
->name
;
283 printf (_("%s\n (header %s, data %s)\n"), targ
->name
,
284 endian_string (targ
->header_byteorder
),
285 endian_string (targ
->byteorder
));
287 abfd
= bfd_openw (param
->filename
, targ
->name
);
290 bfd_nonfatal (param
->filename
);
293 else if (!bfd_set_format (abfd
, bfd_object
))
295 if (bfd_get_error () != bfd_error_invalid_operation
)
297 bfd_nonfatal (targ
->name
);
303 enum bfd_architecture a
;
305 for (a
= bfd_arch_obscure
+ 1; a
< bfd_arch_last
; a
++)
306 if (bfd_set_arch_mach (abfd
, a
, 0))
308 printf (" %s\n", bfd_printable_arch_mach (a
, 0));
309 param
->info
[param
->count
- 1].arch
[a
- bfd_arch_obscure
- 1] = 1;
313 bfd_close_all_done (abfd
);
319 display_target_list (struct display_target
*arg
)
321 arg
->filename
= make_temp_file (NULL
);
327 bfd_iterate_over_targets (do_display_target
, arg
);
329 unlink (arg
->filename
);
330 free (arg
->filename
);
333 /* Calculate how many targets we can print across the page. */
336 do_info_size (int targ
, int width
, const struct display_target
*arg
)
338 while (targ
< arg
->count
)
340 width
-= strlen (arg
->info
[targ
].name
) + 1;
348 /* Print header of target names. */
351 do_info_header (int targ
, int stop_targ
, const struct display_target
*arg
)
353 while (targ
!= stop_targ
)
354 printf ("%s ", arg
->info
[targ
++].name
);
357 /* Print a table row. */
360 do_info_row (int targ
, int stop_targ
, enum bfd_architecture a
,
361 const struct display_target
*arg
)
363 while (targ
!= stop_targ
)
365 if (arg
->info
[targ
].arch
[a
- bfd_arch_obscure
- 1])
366 fputs (arg
->info
[targ
].name
, stdout
);
369 int l
= strlen (arg
->info
[targ
].name
);
374 if (targ
!= stop_targ
)
379 /* Print tables of all the target-architecture combinations that
380 BFD has been configured to support. */
383 display_target_tables (const struct display_target
*arg
)
386 int width
, start_targ
, stop_targ
;
387 enum bfd_architecture arch
;
388 int longest_arch
= 0;
390 for (arch
= bfd_arch_obscure
+ 1; arch
< bfd_arch_last
; arch
++)
392 const char *s
= bfd_printable_arch_mach (arch
, 0);
393 int len
= strlen (s
);
394 if (len
> longest_arch
)
399 columns
= getenv ("COLUMNS");
401 width
= atoi (columns
);
405 for (start_targ
= 0; start_targ
< arg
->count
; start_targ
= stop_targ
)
407 stop_targ
= do_info_size (start_targ
, width
- longest_arch
- 1, arg
);
409 printf ("\n%*s", longest_arch
+ 1, " ");
410 do_info_header (start_targ
, stop_targ
, arg
);
413 for (arch
= bfd_arch_obscure
+ 1; arch
< bfd_arch_last
; arch
++)
415 if (strcmp (bfd_printable_arch_mach (arch
, 0), "UNKNOWN!") != 0)
417 printf ("%*s ", longest_arch
,
418 bfd_printable_arch_mach (arch
, 0));
420 do_info_row (start_targ
, stop_targ
, arch
, arg
);
430 struct display_target arg
;
432 printf (_("BFD header file version %s\n"), BFD_VERSION_STRING
);
434 display_target_list (&arg
);
436 display_target_tables (&arg
);
441 /* Display the archive header for an element as if it were an ls -l listing:
443 Mode User\tGroup\tSize\tDate Name */
446 print_arelt_descr (FILE *file
, bfd
*abfd
, bool verbose
, bool offsets
)
452 if (bfd_stat_arch_elt (abfd
, &buf
) == 0)
456 time_t when
= buf
.st_mtime
;
457 const char *ctime_result
= (const char *) ctime (&when
);
459 /* PR binutils/17605: Check for corrupt time values. */
460 if (ctime_result
== NULL
)
461 sprintf (timebuf
, _("<time data corrupt>"));
463 /* POSIX format: skip weekday and seconds from ctime output. */
464 sprintf (timebuf
, "%.12s %.4s", ctime_result
+ 4, ctime_result
+ 20);
466 mode_string (buf
.st_mode
, modebuf
);
468 /* POSIX 1003.2/D11 says to skip first character (entry type). */
469 fprintf (file
, "%s %ld/%ld %6" PRIu64
" %s ", modebuf
+ 1,
470 (long) buf
.st_uid
, (long) buf
.st_gid
,
471 (uint64_t) buf
.st_size
, timebuf
);
475 fprintf (file
, "%s", bfd_get_filename (abfd
));
479 if (bfd_is_thin_archive (abfd
) && abfd
->proxy_origin
)
480 fprintf (file
, " 0x%lx", (unsigned long) abfd
->proxy_origin
);
481 else if (!bfd_is_thin_archive (abfd
) && abfd
->origin
)
482 fprintf (file
, " 0x%lx", (unsigned long) abfd
->origin
);
485 fprintf (file
, "\n");
488 /* Return a path for a new temporary file in the same directory
492 template_in_dir (const char *path
)
494 #define template "stXXXXXX"
495 const char *slash
= strrchr (path
, '/');
499 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
501 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
502 char *bslash
= strrchr (path
, '\\');
504 if (slash
== NULL
|| (bslash
!= NULL
&& bslash
> slash
))
506 if (slash
== NULL
&& path
[0] != '\0' && path
[1] == ':')
511 if (slash
!= (char *) NULL
)
514 tmpname
= (char *) xmalloc (len
+ sizeof (template) + 2);
515 memcpy (tmpname
, path
, len
);
517 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
518 /* If tmpname is "X:", appending a slash will make it a root
519 directory on drive X, which is NOT the same as the current
520 directory on drive X. */
521 if (len
== 2 && tmpname
[1] == ':')
522 tmpname
[len
++] = '.';
524 tmpname
[len
++] = '/';
528 tmpname
= (char *) xmalloc (sizeof (template));
532 memcpy (tmpname
+ len
, template, sizeof (template));
537 /* Return the name of a created temporary file in the same directory
541 make_tempname (const char *filename
, int *ofd
)
543 char *tmpname
= template_in_dir (filename
);
547 fd
= mkstemp (tmpname
);
549 tmpname
= mktemp (tmpname
);
553 fd
= open (tmpname
, O_RDWR
| O_CREAT
| O_EXCL
, 0600);
558 bfd_set_error (bfd_error_system_call
);
565 /* Return the name of a created temporary directory inside the
566 directory containing FILENAME. */
569 make_tempdir (const char *filename
)
571 char *tmpname
= template_in_dir (filename
);
575 ret
= mkdtemp (tmpname
);
577 ret
= mktemp (tmpname
);
578 #if defined (_WIN32) && !defined (__CYGWIN32__)
579 if (mkdir (tmpname
) != 0)
582 if (mkdir (tmpname
, 0700) != 0)
589 bfd_set_error (bfd_error_system_call
);
594 /* Parse a string into a VMA, with a fatal error if it can't be
598 parse_vma (const char *s
, const char *arg
)
603 ret
= bfd_scan_vma (s
, &end
, 0);
606 fatal (_("%s: bad number: %s"), arg
, s
);
611 /* Returns the size of the named file. If the file does not
612 exist, or if it is not a real file, then a suitable non-fatal
613 error message is printed and (off_t) -1 is returned. */
616 get_file_size (const char * file_name
)
620 if (file_name
== NULL
)
623 if (stat (file_name
, &statbuf
) < 0)
626 non_fatal (_("'%s': No such file"), file_name
);
628 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
629 file_name
, strerror (errno
));
631 else if (S_ISDIR (statbuf
.st_mode
))
632 non_fatal (_("Warning: '%s' is a directory"), file_name
);
633 else if (! S_ISREG (statbuf
.st_mode
))
634 non_fatal (_("Warning: '%s' is not an ordinary file"), file_name
);
635 else if (statbuf
.st_size
< 0)
636 non_fatal (_("Warning: '%s' has negative size, probably it is too large"),
638 #if defined (_WIN32) && !defined (__CYGWIN__)
639 else if (statbuf
.st_size
== 0)
641 /* MS-Windows 'stat' reports the null device as a regular file;
643 int fd
= open (file_name
, O_RDONLY
| O_BINARY
);
647 non_fatal (_("Warning: '%s' is not an ordinary file"),
648 /* libtool wants to see /dev/null in the output. */
649 strcasecmp (file_name
, "nul") ? file_name
: "/dev/null");
654 return statbuf
.st_size
;
659 /* Return the filename in a static buffer. */
662 bfd_get_archive_filename (const bfd
*abfd
)
664 static size_t curr
= 0;
668 assert (abfd
!= NULL
);
670 if (abfd
->my_archive
== NULL
671 || bfd_is_thin_archive (abfd
->my_archive
))
672 return bfd_get_filename (abfd
);
674 needed
= (strlen (bfd_get_filename (abfd
->my_archive
))
675 + strlen (bfd_get_filename (abfd
)) + 3);
680 curr
= needed
+ (needed
>> 1);
681 buf
= (char *) xmalloc (curr
);
683 sprintf (buf
, "%s(%s)", bfd_get_filename (abfd
->my_archive
),
684 bfd_get_filename (abfd
));
688 /* Returns TRUE iff PATHNAME, a filename of an archive member,
689 is valid for writing. For security reasons absolute paths
690 and paths containing /../ are not allowed. See PR 17533. */
693 is_valid_archive_path (char const * pathname
)
695 const char * n
= pathname
;
697 if (IS_ABSOLUTE_PATH (n
))
702 if (*n
== '.' && *++n
== '.' && ( ! *++n
|| IS_DIR_SEPARATOR (*n
)))
705 while (*n
&& ! IS_DIR_SEPARATOR (*n
))
707 while (IS_DIR_SEPARATOR (*n
))