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