xref: /netbsd-src/external/gpl3/binutils.old/dist/binutils/bucomm.c (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 /* bucomm.c -- Bin Utils COMmon code.
2    Copyright (C) 1991-2018 Free Software Foundation, Inc.
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
8    the Free Software Foundation; either version 3 of the License, or
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
18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
19    02110-1301, USA.  */
20 
21 /* We might put this in a library someday so it could be dynamically
22    loaded, but for now it's not necessary.  */
23 
24 #include "sysdep.h"
25 #include "bfd.h"
26 #include "libiberty.h"
27 #include "filenames.h"
28 
29 #include <time.h>		/* ctime, maybe time_t */
30 #include <assert.h>
31 #include "bucomm.h"
32 
33 #ifndef HAVE_TIME_T_IN_TIME_H
34 #ifndef HAVE_TIME_T_IN_TYPES_H
35 typedef long time_t;
36 #endif
37 #endif
38 
39 /* Error reporting.  */
40 
41 char *program_name;
42 
43 void
44 bfd_nonfatal (const char *string)
45 {
46   const char *errmsg;
47 
48   errmsg = bfd_errmsg (bfd_get_error ());
49   fflush (stdout);
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 
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
66    PROGRAM:file[section]: printf-message: bfd-error-message.  */
67 
68 void
69 bfd_nonfatal_message (const char *filename,
70 		      const bfd *abfd,
71 		      const asection *section,
72 		      const char *format, ...)
73 {
74   const char *errmsg;
75   const char *section_name;
76   va_list args;
77 
78   errmsg = bfd_errmsg (bfd_get_error ());
79   fflush (stdout);
80   section_name = NULL;
81   va_start (args, format);
82   fprintf (stderr, "%s", program_name);
83 
84   if (abfd)
85     {
86       if (!filename)
87 	filename = bfd_get_archive_filename (abfd);
88       if (section)
89 	section_name = bfd_get_section_name (abfd, section);
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 
105 void
106 bfd_fatal (const char *string)
107 {
108   bfd_nonfatal (string);
109   xexit (1);
110 }
111 
112 void
113 report (const char * format, va_list args)
114 {
115   fflush (stdout);
116   fprintf (stderr, "%s: ", program_name);
117   vfprintf (stderr, format, args);
118   putc ('\n', stderr);
119 }
120 
121 void
122 fatal (const char *format, ...)
123 {
124   va_list args;
125 
126   va_start (args, format);
127 
128   report (format, args);
129   va_end (args);
130   xexit (1);
131 }
132 
133 void
134 non_fatal (const char *format, ...)
135 {
136   va_list args;
137 
138   va_start (args, format);
139 
140   report (format, args);
141   va_end (args);
142 }
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 
149 void
150 set_default_bfd_target (void)
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 
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.  */
163 
164 void
165 list_matching_formats (char **p)
166 {
167   fflush (stdout);
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 
176 void
177 list_supported_targets (const char *name, FILE *f)
178 {
179   int t;
180   const char **targ_names;
181 
182   if (name == NULL)
183     fprintf (f, _("Supported targets:"));
184   else
185     fprintf (f, _("%s: supported targets:"), name);
186 
187   targ_names = bfd_target_list ();
188   for (t = 0; targ_names[t] != NULL; t++)
189     fprintf (f, " %s", targ_names[t]);
190   fprintf (f, "\n");
191   free (targ_names);
192 }
193 
194 /* List the supported architectures.  */
195 
196 void
197 list_supported_architectures (const char *name, FILE *f)
198 {
199   const char ** arch;
200   const char ** arches;
201 
202   if (name == NULL)
203     fprintf (f, _("Supported architectures:"));
204   else
205     fprintf (f, _("%s: supported architectures:"), name);
206 
207   for (arch = arches = bfd_arch_list (); *arch; arch++)
208     fprintf (f, " %s", *arch);
209   fprintf (f, "\n");
210   free (arches);
211 }
212 
213 static const char *
214 endian_string (enum bfd_endian endian)
215 {
216   switch (endian)
217     {
218     case BFD_ENDIAN_BIG: return _("big endian");
219     case BFD_ENDIAN_LITTLE: return _("little endian");
220     default: return _("endianness unknown");
221     }
222 }
223 
224 /* Data passed to do_display_target and other target iterators.  */
225 
226 struct 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 
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.  */
247 
248 static int
249 do_display_target (const bfd_target *targ, void *data)
250 {
251   struct display_target *param = (struct display_target *) data;
252   bfd *abfd;
253   size_t amt;
254 
255   param->count += 1;
256   amt = param->count * sizeof (*param->info);
257   if (param->alloc < amt)
258     {
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;
266 
267   printf (_("%s\n (header %s, data %s)\n"), targ->name,
268 	  endian_string (targ->header_byteorder),
269 	  endian_string (targ->byteorder));
270 
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)
280 	{
281 	  bfd_nonfatal (targ->name);
282 	  param->error = 1;
283 	}
284     }
285   else
286     {
287       enum bfd_architecture a;
288 
289       for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
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 	  }
295     }
296   if (abfd != NULL)
297     bfd_close_all_done (abfd);
298 
299   return param->error;
300 }
301 
302 static void
303 display_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.  */
318 
319 static int
320 do_info_size (int targ, int width, const struct display_target *arg)
321 {
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.  */
333 
334 static void
335 do_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 
343 static void
344 do_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     }
361 }
362 
363 /* Print tables of all the target-architecture combinations that
364    BFD has been configured to support.  */
365 
366 static void
367 display_target_tables (const struct display_target *arg)
368 {
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++)
375     {
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     }
381 
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');
396 
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 	    }
407 	}
408     }
409 }
410 
411 int
412 display_info (void)
413 {
414   struct display_target arg;
415 
416   printf (_("BFD header file version %s\n"), BFD_VERSION_STRING);
417 
418   display_target_list (&arg);
419   if (!arg.error)
420     display_target_tables (&arg);
421 
422   return arg.error;
423 }
424 
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 
429 void
430 print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose, bfd_boolean offsets)
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;
441 	  const char *ctime_result = (const char *) ctime (&when);
442 	  bfd_size_type size;
443 
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);
450 
451 	  mode_string (buf.st_mode, modebuf);
452 	  modebuf[10] = '\0';
453 	  size = buf.st_size;
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,
457 		   size, timebuf);
458 	}
459     }
460 
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");
472 }
473 
474 /* Return a path for a new temporary file in the same directory
475    as file PATH.  */
476 
477 static char *
478 template_in_dir (const char *path)
479 {
480 #define template "stXXXXXX"
481   const char *slash = strrchr (path, '/');
482   char *tmpname;
483   size_t len;
484 
485 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
486   {
487     /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
488     char *bslash = strrchr (path, '\\');
489 
490     if (slash == NULL || (bslash != NULL && bslash > slash))
491       slash = bslash;
492     if (slash == NULL && path[0] != '\0' && path[1] == ':')
493       slash = path + 1;
494   }
495 #endif
496 
497   if (slash != (char *) NULL)
498     {
499       len = slash - path;
500       tmpname = (char *) xmalloc (len + sizeof (template) + 2);
501       memcpy (tmpname, path, len);
502 
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++] = '.';
509 #endif
510       tmpname[len++] = '/';
511     }
512   else
513     {
514       tmpname = (char *) xmalloc (sizeof (template));
515       len = 0;
516     }
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 
526 char *
527 make_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)
537     return NULL;
538   fd = open (tmpname, O_RDWR | O_CREAT | O_EXCL, 0600);
539 #endif
540   if (fd == -1)
541     {
542       free (tmpname);
543       return NULL;
544     }
545   close (fd);
546   return tmpname;
547 }
548 
549 /* Return the name of a created temporary directory inside the
550    directory containing FILENAME.  */
551 
552 char *
553 make_tempdir (char *filename)
554 {
555   char *tmpname = template_in_dir (filename);
556 
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;
569 #endif
570   return tmpname;
571 #endif
572 }
573 
574 /* Parse a string into a VMA, with a fatal error if it can't be
575    parsed.  */
576 
577 bfd_vma
578 parse_vma (const char *s, const char *arg)
579 {
580   bfd_vma ret;
581   const char *end;
582 
583   ret = bfd_scan_vma (s, &end, 0);
584 
585   if (*end != '\0')
586     fatal (_("%s: bad number: %s"), arg, s);
587 
588   return ret;
589 }
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
593    error message is printed and (off_t) -1 is returned.  */
594 
595 off_t
596 get_file_size (const char * file_name)
597 {
598   struct stat statbuf;
599 
600   if (file_name == NULL)
601     return (off_t) -1;
602 
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));
610     }
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     {
615       if (!S_ISCHR(statbuf.st_mode))
616 	{
617 	  non_fatal (_("Warning: '%s' is not an ordinary file"), file_name);
618 	  return 0;
619 	}
620       return statbuf.st_size ? statbuf.st_size : 1;
621     }
622   else if (statbuf.st_size < 0)
623     non_fatal (_("Warning: '%s' has negative size, probably it is too large"),
624                file_name);
625   else
626     return statbuf.st_size;
627 
628   return (off_t) -1;
629 }
630 
631 /* Return the filename in a static buffer.  */
632 
633 const char *
634 bfd_get_archive_filename (const bfd *abfd)
635 {
636   static size_t curr = 0;
637   static char *buf;
638   size_t needed;
639 
640   assert (abfd != NULL);
641 
642   if (abfd->my_archive == NULL
643       || bfd_is_thin_archive (abfd->my_archive))
644     return bfd_get_filename (abfd);
645 
646   needed = (strlen (bfd_get_filename (abfd->my_archive))
647 	    + strlen (bfd_get_filename (abfd)) + 3);
648   if (needed > curr)
649     {
650       if (curr)
651 	free (buf);
652       curr = needed + (needed >> 1);
653       buf = (char *) xmalloc (curr);
654     }
655   sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive),
656 	   bfd_get_filename (abfd));
657   return buf;
658 }
659 
660 /* Returns TRUE iff PATHNAME, a filename of an archive member,
661    is valid for writing.  For security reasons absolute paths
662    and paths containing /../ are not allowed.  See PR 17533.  */
663 
664 bfd_boolean
665 is_valid_archive_path (char const * pathname)
666 {
667   const char * n = pathname;
668 
669   if (IS_ABSOLUTE_PATH (n))
670     return FALSE;
671 
672   while (*n)
673     {
674       if (*n == '.' && *++n == '.' && ( ! *++n || IS_DIR_SEPARATOR (*n)))
675 	return FALSE;
676 
677       while (*n && ! IS_DIR_SEPARATOR (*n))
678 	n++;
679       while (IS_DIR_SEPARATOR (*n))
680 	n++;
681     }
682 
683   return TRUE;
684 }
685