gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / binutils / bucomm.c
CommitLineData
252b5132 1/* bucomm.c -- Bin Utils COMmon code.
b3adc24a 2 Copyright (C) 1991-2020 Free Software Foundation, Inc.
252b5132
RH
3
4 This file is part of GNU Binutils.
5
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
32866df7 8 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
9 (at your option) any later version.
10
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.
15
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
b43b5d5f
NC
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
19 02110-1301, USA. */
252b5132
RH
20\f
21/* We might put this in a library someday so it could be dynamically
22 loaded, but for now it's not necessary. */
23
3db64b00 24#include "sysdep.h"
252b5132
RH
25#include "bfd.h"
26#include "libiberty.h"
5af11cab 27#include "filenames.h"
252b5132 28
252b5132 29#include <time.h> /* ctime, maybe time_t */
77f762d6 30#include <assert.h>
3db64b00 31#include "bucomm.h"
252b5132
RH
32
33#ifndef HAVE_TIME_T_IN_TIME_H
34#ifndef HAVE_TIME_T_IN_TYPES_H
35typedef long time_t;
36#endif
37#endif
252b5132 38\f
06d86cf7 39/* Error reporting. */
252b5132
RH
40
41char *program_name;
42
43void
2da42df6 44bfd_nonfatal (const char *string)
252b5132 45{
a8c62f1c 46 const char *errmsg;
a68aa5d3 47 enum bfd_error err = bfd_get_error ();
252b5132 48
a68aa5d3
NC
49 if (err == bfd_error_no_error)
50 errmsg = _("cause of error unknown");
51 else
52 errmsg = bfd_errmsg (err);
8e085dd2 53 fflush (stdout);
252b5132
RH
54 if (string)
55 fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg);
56 else
57 fprintf (stderr, "%s: %s\n", program_name, errmsg);
58}
59
2db6cde7
NS
60/* Issue a non fatal error message. FILENAME, or if NULL then BFD,
61 are used to indicate the problematic file. SECTION, if non NULL,
62 is used to provide a section name. If FORMAT is non-null, then it
63 is used to print additional information via vfprintf. Finally the
64 bfd error message is printed. In summary, error messages are of
65 one of the following forms:
66
df56ecde
AM
67 PROGRAM: file: bfd-error-message
68 PROGRAM: file[section]: bfd-error-message
69 PROGRAM: file: printf-message: bfd-error-message
70 PROGRAM: file[section]: printf-message: bfd-error-message. */
2db6cde7
NS
71
72void
73bfd_nonfatal_message (const char *filename,
91d6fa6a
NC
74 const bfd *abfd,
75 const asection *section,
2db6cde7
NS
76 const char *format, ...)
77{
a8c62f1c
AM
78 const char *errmsg;
79 const char *section_name;
2db6cde7 80 va_list args;
a68aa5d3 81 enum bfd_error err = bfd_get_error ();
2db6cde7 82
a68aa5d3
NC
83 if (err == bfd_error_no_error)
84 errmsg = _("cause of error unknown");
85 else
86 errmsg = bfd_errmsg (err);
8e085dd2 87 fflush (stdout);
a8c62f1c 88 section_name = NULL;
2db6cde7
NS
89 va_start (args, format);
90 fprintf (stderr, "%s", program_name);
3aade688 91
91d6fa6a 92 if (abfd)
2db6cde7
NS
93 {
94 if (!filename)
91d6fa6a 95 filename = bfd_get_archive_filename (abfd);
2db6cde7 96 if (section)
fd361982 97 section_name = bfd_section_name (section);
2db6cde7
NS
98 }
99 if (section_name)
df56ecde 100 fprintf (stderr, ": %s[%s]", filename, section_name);
2db6cde7 101 else
df56ecde 102 fprintf (stderr, ": %s", filename);
2db6cde7
NS
103
104 if (format)
105 {
106 fprintf (stderr, ": ");
107 vfprintf (stderr, format, args);
108 }
109 fprintf (stderr, ": %s\n", errmsg);
110 va_end (args);
111}
112
252b5132 113void
2da42df6 114bfd_fatal (const char *string)
252b5132
RH
115{
116 bfd_nonfatal (string);
117 xexit (1);
118}
119
cba12006 120void
2da42df6 121report (const char * format, va_list args)
252b5132 122{
a8c62f1c 123 fflush (stdout);
252b5132
RH
124 fprintf (stderr, "%s: ", program_name);
125 vfprintf (stderr, format, args);
126 putc ('\n', stderr);
127}
128
252b5132 129void
1651e569 130fatal (const char *format, ...)
252b5132 131{
1651e569
TT
132 va_list args;
133
134 va_start (args, format);
252b5132 135
252b5132 136 report (format, args);
1651e569 137 va_end (args);
252b5132
RH
138 xexit (1);
139}
140
141void
1651e569 142non_fatal (const char *format, ...)
252b5132 143{
1651e569
TT
144 va_list args;
145
146 va_start (args, format);
252b5132 147
252b5132 148 report (format, args);
1651e569 149 va_end (args);
252b5132 150}
252b5132
RH
151
152/* Set the default BFD target based on the configured target. Doing
153 this permits the binutils to be configured for a particular target,
154 and linked against a shared BFD library which was configured for a
155 different target. */
156
157void
2da42df6 158set_default_bfd_target (void)
252b5132
RH
159{
160 /* The macro TARGET is defined by Makefile. */
161 const char *target = TARGET;
162
163 if (! bfd_set_default_target (target))
164 fatal (_("can't set BFD default target to `%s': %s"),
165 target, bfd_errmsg (bfd_get_error ()));
166}
167
b34976b6 168/* After a FALSE return from bfd_check_format_matches with
252b5132
RH
169 bfd_get_error () == bfd_error_file_ambiguously_recognized, print
170 the possible matching targets. */
171
172void
2da42df6 173list_matching_formats (char **p)
252b5132 174{
a8c62f1c 175 fflush (stdout);
252b5132
RH
176 fprintf (stderr, _("%s: Matching formats:"), program_name);
177 while (*p)
178 fprintf (stderr, " %s", *p++);
179 fputc ('\n', stderr);
180}
181
182/* List the supported targets. */
183
184void
2da42df6 185list_supported_targets (const char *name, FILE *f)
252b5132 186{
252b5132 187 int t;
a8c62f1c 188 const char **targ_names;
252b5132
RH
189
190 if (name == NULL)
191 fprintf (f, _("Supported targets:"));
192 else
193 fprintf (f, _("%s: supported targets:"), name);
48417c1a 194
a8c62f1c 195 targ_names = bfd_target_list ();
48417c1a
AM
196 for (t = 0; targ_names[t] != NULL; t++)
197 fprintf (f, " %s", targ_names[t]);
252b5132 198 fprintf (f, "\n");
48417c1a 199 free (targ_names);
252b5132 200}
2f83960e
AM
201
202/* List the supported architectures. */
203
204void
2da42df6 205list_supported_architectures (const char *name, FILE *f)
2f83960e 206{
d25576aa
NC
207 const char ** arch;
208 const char ** arches;
2f83960e
AM
209
210 if (name == NULL)
211 fprintf (f, _("Supported architectures:"));
212 else
213 fprintf (f, _("%s: supported architectures:"), name);
214
d25576aa 215 for (arch = arches = bfd_arch_list (); *arch; arch++)
2f83960e
AM
216 fprintf (f, " %s", *arch);
217 fprintf (f, "\n");
d25576aa 218 free (arches);
2f83960e 219}
252b5132 220\f
06d86cf7 221static const char *
2da42df6 222endian_string (enum bfd_endian endian)
06d86cf7
NC
223{
224 switch (endian)
225 {
9cf03b7e
NC
226 case BFD_ENDIAN_BIG: return _("big endian");
227 case BFD_ENDIAN_LITTLE: return _("little endian");
228 default: return _("endianness unknown");
06d86cf7
NC
229 }
230}
231
aac502f7
AM
232/* Data passed to do_display_target and other target iterators. */
233
234struct display_target {
235 /* Temp file. */
236 char *filename;
237 /* Return status. */
238 int error;
239 /* Number of targets. */
240 int count;
241 /* Size of info in bytes. */
242 size_t alloc;
243 /* Per-target info. */
244 struct {
245 /* Target name. */
246 const char *name;
247 /* Non-zero if target/arch combination supported. */
248 unsigned char arch[bfd_arch_last - bfd_arch_obscure - 1];
249 } *info;
250};
251
06d86cf7 252/* List the targets that BFD is configured to support, each followed
aac502f7
AM
253 by its endianness and the architectures it supports. Also build
254 info about target/archs. */
06d86cf7
NC
255
256static int
aac502f7 257do_display_target (const bfd_target *targ, void *data)
06d86cf7 258{
aac502f7
AM
259 struct display_target *param = (struct display_target *) data;
260 bfd *abfd;
261 size_t amt;
06d86cf7 262
aac502f7
AM
263 param->count += 1;
264 amt = param->count * sizeof (*param->info);
265 if (param->alloc < amt)
06d86cf7 266 {
aac502f7
AM
267 size_t size = ((param->count < 64 ? 64 : param->count)
268 * sizeof (*param->info) * 2);
269 param->info = xrealloc (param->info, size);
270 memset ((char *) param->info + param->alloc, 0, size - param->alloc);
271 param->alloc = size;
272 }
273 param->info[param->count - 1].name = targ->name;
06d86cf7 274
aac502f7
AM
275 printf (_("%s\n (header %s, data %s)\n"), targ->name,
276 endian_string (targ->header_byteorder),
277 endian_string (targ->byteorder));
06d86cf7 278
aac502f7
AM
279 abfd = bfd_openw (param->filename, targ->name);
280 if (abfd == NULL)
281 {
282 bfd_nonfatal (param->filename);
283 param->error = 1;
284 }
285 else if (!bfd_set_format (abfd, bfd_object))
286 {
287 if (bfd_get_error () != bfd_error_invalid_operation)
06d86cf7 288 {
aac502f7
AM
289 bfd_nonfatal (targ->name);
290 param->error = 1;
06d86cf7 291 }
aac502f7
AM
292 }
293 else
294 {
295 enum bfd_architecture a;
06d86cf7 296
91610c0c 297 for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
aac502f7
AM
298 if (bfd_set_arch_mach (abfd, a, 0))
299 {
300 printf (" %s\n", bfd_printable_arch_mach (a, 0));
301 param->info[param->count - 1].arch[a - bfd_arch_obscure - 1] = 1;
302 }
06d86cf7 303 }
aac502f7
AM
304 if (abfd != NULL)
305 bfd_close_all_done (abfd);
06d86cf7 306
aac502f7 307 return param->error;
06d86cf7
NC
308}
309
aac502f7
AM
310static void
311display_target_list (struct display_target *arg)
312{
313 arg->filename = make_temp_file (NULL);
314 arg->error = 0;
315 arg->count = 0;
316 arg->alloc = 0;
317 arg->info = NULL;
318
319 bfd_iterate_over_targets (do_display_target, arg);
320
321 unlink (arg->filename);
322 free (arg->filename);
323}
324
325/* Calculate how many targets we can print across the page. */
06d86cf7
NC
326
327static int
aac502f7 328do_info_size (int targ, int width, const struct display_target *arg)
06d86cf7 329{
aac502f7
AM
330 while (targ < arg->count)
331 {
332 width -= strlen (arg->info[targ].name) + 1;
333 if (width < 0)
334 return targ;
335 ++targ;
336 }
337 return targ;
338}
339
340/* Print header of target names. */
06d86cf7 341
aac502f7
AM
342static void
343do_info_header (int targ, int stop_targ, const struct display_target *arg)
344{
345 while (targ != stop_targ)
346 printf ("%s ", arg->info[targ++].name);
347}
348
349/* Print a table row. */
350
351static void
352do_info_row (int targ, int stop_targ, enum bfd_architecture a,
353 const struct display_target *arg)
354{
355 while (targ != stop_targ)
356 {
357 if (arg->info[targ].arch[a - bfd_arch_obscure - 1])
358 fputs (arg->info[targ].name, stdout);
359 else
360 {
361 int l = strlen (arg->info[targ].name);
362 while (l--)
363 putchar ('-');
364 }
365 ++targ;
366 if (targ != stop_targ)
367 putchar (' ');
368 }
06d86cf7
NC
369}
370
371/* Print tables of all the target-architecture combinations that
372 BFD has been configured to support. */
373
aac502f7
AM
374static void
375display_target_tables (const struct display_target *arg)
06d86cf7 376{
aac502f7
AM
377 const char *columns;
378 int width, start_targ, stop_targ;
379 enum bfd_architecture arch;
380 int longest_arch = 0;
381
382 for (arch = bfd_arch_obscure + 1; arch < bfd_arch_last; arch++)
06d86cf7 383 {
aac502f7
AM
384 const char *s = bfd_printable_arch_mach (arch, 0);
385 int len = strlen (s);
386 if (len > longest_arch)
387 longest_arch = len;
388 }
06d86cf7 389
aac502f7
AM
390 width = 0;
391 columns = getenv ("COLUMNS");
392 if (columns != NULL)
393 width = atoi (columns);
394 if (width == 0)
395 width = 80;
396
397 for (start_targ = 0; start_targ < arg->count; start_targ = stop_targ)
398 {
399 stop_targ = do_info_size (start_targ, width - longest_arch - 1, arg);
400
401 printf ("\n%*s", longest_arch + 1, " ");
402 do_info_header (start_targ, stop_targ, arg);
403 putchar ('\n');
06d86cf7 404
aac502f7
AM
405 for (arch = bfd_arch_obscure + 1; arch < bfd_arch_last; arch++)
406 {
407 if (strcmp (bfd_printable_arch_mach (arch, 0), "UNKNOWN!") != 0)
408 {
409 printf ("%*s ", longest_arch,
410 bfd_printable_arch_mach (arch, 0));
411
412 do_info_row (start_targ, stop_targ, arch, arg);
413 putchar ('\n');
414 }
06d86cf7 415 }
06d86cf7 416 }
06d86cf7
NC
417}
418
419int
2da42df6 420display_info (void)
06d86cf7 421{
aac502f7
AM
422 struct display_target arg;
423
06d86cf7 424 printf (_("BFD header file version %s\n"), BFD_VERSION_STRING);
aac502f7
AM
425
426 display_target_list (&arg);
427 if (!arg.error)
428 display_target_tables (&arg);
429
430 return arg.error;
06d86cf7
NC
431}
432\f
252b5132
RH
433/* Display the archive header for an element as if it were an ls -l listing:
434
435 Mode User\tGroup\tSize\tDate Name */
436
437void
1869e86f 438print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose, bfd_boolean offsets)
252b5132
RH
439{
440 struct stat buf;
441
442 if (verbose)
443 {
444 if (bfd_stat_arch_elt (abfd, &buf) == 0)
445 {
446 char modebuf[11];
447 char timebuf[40];
448 time_t when = buf.st_mtime;
b1f88ebe 449 const char *ctime_result = (const char *) ctime (&when);
34debcd1 450 bfd_size_type size;
252b5132 451
0593bd3a
NC
452 /* PR binutils/17605: Check for corrupt time values. */
453 if (ctime_result == NULL)
454 sprintf (timebuf, _("<time data corrupt>"));
455 else
456 /* POSIX format: skip weekday and seconds from ctime output. */
457 sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
252b5132
RH
458
459 mode_string (buf.st_mode, modebuf);
460 modebuf[10] = '\0';
34debcd1 461 size = buf.st_size;
252b5132 462 /* POSIX 1003.2/D11 says to skip first character (entry type). */
34debcd1 463 fprintf (file, "%s %ld/%ld %6" BFD_VMA_FMT "u %s ", modebuf + 1,
252b5132 464 (long) buf.st_uid, (long) buf.st_gid,
34debcd1 465 size, timebuf);
252b5132
RH
466 }
467 }
468
1869e86f
AB
469 fprintf (file, "%s", bfd_get_filename (abfd));
470
471 if (offsets)
472 {
473 if (bfd_is_thin_archive (abfd) && abfd->proxy_origin)
474 fprintf (file, " 0x%lx", (unsigned long) abfd->proxy_origin);
475 else if (!bfd_is_thin_archive (abfd) && abfd->origin)
476 fprintf (file, " 0x%lx", (unsigned long) abfd->origin);
477 }
478
479 fprintf (file, "\n");
252b5132
RH
480}
481
485be063
AM
482/* Return a path for a new temporary file in the same directory
483 as file PATH. */
252b5132 484
485be063
AM
485static char *
486template_in_dir (const char *path)
252b5132 487{
485be063 488#define template "stXXXXXX"
2946671e 489 const char *slash = strrchr (path, '/');
252b5132 490 char *tmpname;
485be063 491 size_t len;
252b5132 492
5af11cab
AM
493#ifdef HAVE_DOS_BASED_FILE_SYSTEM
494 {
495 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
485be063 496 char *bslash = strrchr (path, '\\');
f9c026a8 497
2ab47eed 498 if (slash == NULL || (bslash != NULL && bslash > slash))
5af11cab 499 slash = bslash;
485be063 500 if (slash == NULL && path[0] != '\0' && path[1] == ':')
2946671e 501 slash = path + 1;
5af11cab 502 }
252b5132
RH
503#endif
504
505 if (slash != (char *) NULL)
506 {
485be063 507 len = slash - path;
3f5e193b 508 tmpname = (char *) xmalloc (len + sizeof (template) + 2);
485be063 509 memcpy (tmpname, path, len);
252b5132 510
5af11cab
AM
511#ifdef HAVE_DOS_BASED_FILE_SYSTEM
512 /* If tmpname is "X:", appending a slash will make it a root
513 directory on drive X, which is NOT the same as the current
514 directory on drive X. */
485be063
AM
515 if (len == 2 && tmpname[1] == ':')
516 tmpname[len++] = '.';
5af11cab 517#endif
485be063 518 tmpname[len++] = '/';
252b5132
RH
519 }
520 else
521 {
3f5e193b 522 tmpname = (char *) xmalloc (sizeof (template));
485be063 523 len = 0;
f9c026a8 524 }
485be063
AM
525
526 memcpy (tmpname + len, template, sizeof (template));
527 return tmpname;
528#undef template
529}
530
531/* Return the name of a created temporary file in the same directory
532 as FILENAME. */
533
534char *
1ff5d5c4 535make_tempname (const char *filename)
485be063
AM
536{
537 char *tmpname = template_in_dir (filename);
538 int fd;
539
540#ifdef HAVE_MKSTEMP
541 fd = mkstemp (tmpname);
542#else
543 tmpname = mktemp (tmpname);
544 if (tmpname == NULL)
f9c026a8 545 return NULL;
485be063 546 fd = open (tmpname, O_RDWR | O_CREAT | O_EXCL, 0600);
f9c026a8 547#endif
485be063 548 if (fd == -1)
c48d800e
NC
549 {
550 free (tmpname);
551 return NULL;
552 }
485be063 553 close (fd);
f9c026a8
NC
554 return tmpname;
555}
556
485be063
AM
557/* Return the name of a created temporary directory inside the
558 directory containing FILENAME. */
f9c026a8
NC
559
560char *
1ff5d5c4 561make_tempdir (const char *filename)
f9c026a8 562{
485be063 563 char *tmpname = template_in_dir (filename);
f9c026a8 564
485be063
AM
565#ifdef HAVE_MKDTEMP
566 return mkdtemp (tmpname);
567#else
568 tmpname = mktemp (tmpname);
569 if (tmpname == NULL)
570 return NULL;
571#if defined (_WIN32) && !defined (__CYGWIN32__)
572 if (mkdir (tmpname) != 0)
573 return NULL;
574#else
575 if (mkdir (tmpname, 0700) != 0)
576 return NULL;
f9c026a8 577#endif
252b5132 578 return tmpname;
485be063 579#endif
252b5132
RH
580}
581
582/* Parse a string into a VMA, with a fatal error if it can't be
583 parsed. */
584
585bfd_vma
2da42df6 586parse_vma (const char *s, const char *arg)
252b5132
RH
587{
588 bfd_vma ret;
589 const char *end;
590
591 ret = bfd_scan_vma (s, &end, 0);
f462a9ea 592
252b5132
RH
593 if (*end != '\0')
594 fatal (_("%s: bad number: %s"), arg, s);
595
596 return ret;
597}
f24ddbdd
NC
598
599/* Returns the size of the named file. If the file does not
600 exist, or if it is not a real file, then a suitable non-fatal
a3029abd 601 error message is printed and (off_t) -1 is returned. */
f24ddbdd
NC
602
603off_t
604get_file_size (const char * file_name)
605{
606 struct stat statbuf;
3aade688 607
740a4630
NC
608 if (file_name == NULL)
609 return (off_t) -1;
610
f24ddbdd
NC
611 if (stat (file_name, &statbuf) < 0)
612 {
613 if (errno == ENOENT)
614 non_fatal (_("'%s': No such file"), file_name);
615 else
616 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
617 file_name, strerror (errno));
3aade688 618 }
0602cdad
NC
619 else if (S_ISDIR (statbuf.st_mode))
620 non_fatal (_("Warning: '%s' is a directory"), file_name);
f24ddbdd
NC
621 else if (! S_ISREG (statbuf.st_mode))
622 non_fatal (_("Warning: '%s' is not an ordinary file"), file_name);
9849fbfc
NC
623 else if (statbuf.st_size < 0)
624 non_fatal (_("Warning: '%s' has negative size, probably it is too large"),
625 file_name);
f24ddbdd
NC
626 else
627 return statbuf.st_size;
628
52a476ee 629 return (off_t) -1;
f24ddbdd 630}
77f762d6
L
631
632/* Return the filename in a static buffer. */
633
634const char *
8d8e0703 635bfd_get_archive_filename (const bfd *abfd)
77f762d6
L
636{
637 static size_t curr = 0;
638 static char *buf;
639 size_t needed;
640
641 assert (abfd != NULL);
3aade688 642
b0cffb47
AM
643 if (abfd->my_archive == NULL
644 || bfd_is_thin_archive (abfd->my_archive))
77f762d6
L
645 return bfd_get_filename (abfd);
646
647 needed = (strlen (bfd_get_filename (abfd->my_archive))
648 + strlen (bfd_get_filename (abfd)) + 3);
649 if (needed > curr)
650 {
651 if (curr)
652 free (buf);
653 curr = needed + (needed >> 1);
76e7a751 654 buf = (char *) xmalloc (curr);
77f762d6
L
655 }
656 sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive),
657 bfd_get_filename (abfd));
658 return buf;
659}
dd9b91de
NC
660
661/* Returns TRUE iff PATHNAME, a filename of an archive member,
662 is valid for writing. For security reasons absolute paths
663 and paths containing /../ are not allowed. See PR 17533. */
664
665bfd_boolean
666is_valid_archive_path (char const * pathname)
667{
668 const char * n = pathname;
669
670 if (IS_ABSOLUTE_PATH (n))
671 return FALSE;
672
673 while (*n)
674 {
675 if (*n == '.' && *++n == '.' && ( ! *++n || IS_DIR_SEPARATOR (*n)))
676 return FALSE;
677
678 while (*n && ! IS_DIR_SEPARATOR (*n))
679 n++;
680 while (IS_DIR_SEPARATOR (*n))
681 n++;
682 }
683
684 return TRUE;
685}
This page took 0.846194 seconds and 4 git commands to generate.