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