1 /* bucomm.c -- Bin Utils COMmon code. 2 Copyright (C) 1991-2016 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 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 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 112 bfd_fatal (const char *string) 113 { 114 bfd_nonfatal (string); 115 xexit (1); 116 } 117 118 void 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 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 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 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 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 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 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 * 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 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 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 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 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 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 /* PR binutils/17605: Check for corrupt time values. */ 433 if (ctime_result == NULL) 434 sprintf (timebuf, _("<time data corrupt>")); 435 else 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 == NULL 609 || bfd_is_thin_archive (abfd->my_archive)) 610 return bfd_get_filename (abfd); 611 612 needed = (strlen (bfd_get_filename (abfd->my_archive)) 613 + strlen (bfd_get_filename (abfd)) + 3); 614 if (needed > curr) 615 { 616 if (curr) 617 free (buf); 618 curr = needed + (needed >> 1); 619 buf = (char *) bfd_malloc (curr); 620 /* If we can't malloc, fail safe by returning just the file name. 621 This function is only used when building error messages. */ 622 if (!buf) 623 { 624 curr = 0; 625 return bfd_get_filename (abfd); 626 } 627 } 628 sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive), 629 bfd_get_filename (abfd)); 630 return buf; 631 } 632 633 /* Returns TRUE iff PATHNAME, a filename of an archive member, 634 is valid for writing. For security reasons absolute paths 635 and paths containing /../ are not allowed. See PR 17533. */ 636 637 bfd_boolean 638 is_valid_archive_path (char const * pathname) 639 { 640 const char * n = pathname; 641 642 if (IS_ABSOLUTE_PATH (n)) 643 return FALSE; 644 645 while (*n) 646 { 647 if (*n == '.' && *++n == '.' && ( ! *++n || IS_DIR_SEPARATOR (*n))) 648 return FALSE; 649 650 while (*n && ! IS_DIR_SEPARATOR (*n)) 651 n++; 652 while (IS_DIR_SEPARATOR (*n)) 653 n++; 654 } 655 656 return TRUE; 657 } 658