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