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 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 /* PR binutils/17605: Check for corrupt time values. */ 437 if (ctime_result == NULL) 438 sprintf (timebuf, _("<time data corrupt>")); 439 else 440 /* POSIX format: skip weekday and seconds from ctime output. */ 441 sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20); 442 443 mode_string (buf.st_mode, modebuf); 444 modebuf[10] = '\0'; 445 size = buf.st_size; 446 /* POSIX 1003.2/D11 says to skip first character (entry type). */ 447 fprintf (file, "%s %ld/%ld %6" BFD_VMA_FMT "u %s ", modebuf + 1, 448 (long) buf.st_uid, (long) buf.st_gid, 449 size, timebuf); 450 } 451 } 452 453 fprintf (file, "%s\n", bfd_get_filename (abfd)); 454 } 455 456 /* Return a path for a new temporary file in the same directory 457 as file PATH. */ 458 459 static char * 460 template_in_dir (const char *path) 461 { 462 #define template "stXXXXXX" 463 const char *slash = strrchr (path, '/'); 464 char *tmpname; 465 size_t len; 466 467 #ifdef HAVE_DOS_BASED_FILE_SYSTEM 468 { 469 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */ 470 char *bslash = strrchr (path, '\\'); 471 472 if (slash == NULL || (bslash != NULL && bslash > slash)) 473 slash = bslash; 474 if (slash == NULL && path[0] != '\0' && path[1] == ':') 475 slash = path + 1; 476 } 477 #endif 478 479 if (slash != (char *) NULL) 480 { 481 len = slash - path; 482 tmpname = (char *) xmalloc (len + sizeof (template) + 2); 483 memcpy (tmpname, path, len); 484 485 #ifdef HAVE_DOS_BASED_FILE_SYSTEM 486 /* If tmpname is "X:", appending a slash will make it a root 487 directory on drive X, which is NOT the same as the current 488 directory on drive X. */ 489 if (len == 2 && tmpname[1] == ':') 490 tmpname[len++] = '.'; 491 #endif 492 tmpname[len++] = '/'; 493 } 494 else 495 { 496 tmpname = (char *) xmalloc (sizeof (template)); 497 len = 0; 498 } 499 500 memcpy (tmpname + len, template, sizeof (template)); 501 return tmpname; 502 #undef template 503 } 504 505 /* Return the name of a created temporary file in the same directory 506 as FILENAME. */ 507 508 char * 509 make_tempname (char *filename) 510 { 511 char *tmpname = template_in_dir (filename); 512 int fd; 513 514 #ifdef HAVE_MKSTEMP 515 fd = mkstemp (tmpname); 516 #else 517 tmpname = mktemp (tmpname); 518 if (tmpname == NULL) 519 return NULL; 520 fd = open (tmpname, O_RDWR | O_CREAT | O_EXCL, 0600); 521 #endif 522 if (fd == -1) 523 { 524 free (tmpname); 525 return NULL; 526 } 527 close (fd); 528 return tmpname; 529 } 530 531 /* Return the name of a created temporary directory inside the 532 directory containing FILENAME. */ 533 534 char * 535 make_tempdir (char *filename) 536 { 537 char *tmpname = template_in_dir (filename); 538 539 #ifdef HAVE_MKDTEMP 540 return mkdtemp (tmpname); 541 #else 542 tmpname = mktemp (tmpname); 543 if (tmpname == NULL) 544 return NULL; 545 #if defined (_WIN32) && !defined (__CYGWIN32__) 546 if (mkdir (tmpname) != 0) 547 return NULL; 548 #else 549 if (mkdir (tmpname, 0700) != 0) 550 return NULL; 551 #endif 552 return tmpname; 553 #endif 554 } 555 556 /* Parse a string into a VMA, with a fatal error if it can't be 557 parsed. */ 558 559 bfd_vma 560 parse_vma (const char *s, const char *arg) 561 { 562 bfd_vma ret; 563 const char *end; 564 565 ret = bfd_scan_vma (s, &end, 0); 566 567 if (*end != '\0') 568 fatal (_("%s: bad number: %s"), arg, s); 569 570 return ret; 571 } 572 573 /* Returns the size of the named file. If the file does not 574 exist, or if it is not a real file, then a suitable non-fatal 575 error message is printed and (off_t) -1 is returned. */ 576 577 off_t 578 get_file_size (const char * file_name) 579 { 580 struct stat statbuf; 581 582 if (stat (file_name, &statbuf) < 0) 583 { 584 if (errno == ENOENT) 585 non_fatal (_("'%s': No such file"), file_name); 586 else 587 non_fatal (_("Warning: could not locate '%s'. reason: %s"), 588 file_name, strerror (errno)); 589 } 590 else if (! S_ISREG (statbuf.st_mode)) 591 non_fatal (_("Warning: '%s' is not an ordinary file"), file_name); 592 else if (statbuf.st_size < 0) 593 non_fatal (_("Warning: '%s' has negative size, probably it is too large"), 594 file_name); 595 else 596 return statbuf.st_size; 597 598 return (off_t) -1; 599 } 600 601 /* Return the filename in a static buffer. */ 602 603 const char * 604 bfd_get_archive_filename (const bfd *abfd) 605 { 606 static size_t curr = 0; 607 static char *buf; 608 size_t needed; 609 610 assert (abfd != NULL); 611 612 if (abfd->my_archive == NULL 613 || bfd_is_thin_archive (abfd->my_archive)) 614 return bfd_get_filename (abfd); 615 616 needed = (strlen (bfd_get_filename (abfd->my_archive)) 617 + strlen (bfd_get_filename (abfd)) + 3); 618 if (needed > curr) 619 { 620 if (curr) 621 free (buf); 622 curr = needed + (needed >> 1); 623 buf = (char *) bfd_malloc (curr); 624 /* If we can't malloc, fail safe by returning just the file name. 625 This function is only used when building error messages. */ 626 if (!buf) 627 { 628 curr = 0; 629 return bfd_get_filename (abfd); 630 } 631 } 632 sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive), 633 bfd_get_filename (abfd)); 634 return buf; 635 } 636 637 /* Returns TRUE iff PATHNAME, a filename of an archive member, 638 is valid for writing. For security reasons absolute paths 639 and paths containing /../ are not allowed. See PR 17533. */ 640 641 bfd_boolean 642 is_valid_archive_path (char const * pathname) 643 { 644 const char * n = pathname; 645 646 if (IS_ABSOLUTE_PATH (n)) 647 return FALSE; 648 649 while (*n) 650 { 651 if (*n == '.' && *++n == '.' && ( ! *++n || IS_DIR_SEPARATOR (*n))) 652 return FALSE; 653 654 while (*n && ! IS_DIR_SEPARATOR (*n)) 655 n++; 656 while (IS_DIR_SEPARATOR (*n)) 657 n++; 658 } 659 660 return TRUE; 661 } 662