collect2.c revision 102780
1/* Collect static initialization info into data structures that can be 2 traversed by C++ initialization and finalization routines. 3 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 4 1999, 2000, 2001, 2002 Free Software Foundation, Inc. 5 Contributed by Chris Smith (csmith@convex.com). 6 Heavily modified by Michael Meissner (meissner@cygnus.com), 7 Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com). 8 9This file is part of GCC. 10 11GCC is free software; you can redistribute it and/or modify it under 12the terms of the GNU General Public License as published by the Free 13Software Foundation; either version 2, or (at your option) any later 14version. 15 16GCC is distributed in the hope that it will be useful, but WITHOUT ANY 17WARRANTY; without even the implied warranty of MERCHANTABILITY or 18FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 19for more details. 20 21You should have received a copy of the GNU General Public License 22along with GCC; see the file COPYING. If not, write to the Free 23Software Foundation, 59 Temple Place - Suite 330, Boston, MA 2402111-1307, USA. */ 25 26 27/* Build tables of static constructors and destructors and run ld. */ 28 29#include "config.h" 30#include "system.h" 31#include <signal.h> 32#if ! defined( SIGCHLD ) && defined( SIGCLD ) 33# define SIGCHLD SIGCLD 34#endif 35 36#ifdef vfork /* Autoconf may define this to fork for us. */ 37# define VFORK_STRING "fork" 38#else 39# define VFORK_STRING "vfork" 40#endif 41#ifdef HAVE_VFORK_H 42#include <vfork.h> 43#endif 44#ifdef VMS 45#define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \ 46 lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1) 47#endif /* VMS */ 48 49#ifndef LIBRARY_PATH_ENV 50#define LIBRARY_PATH_ENV "LIBRARY_PATH" 51#endif 52 53#define COLLECT 54 55#include "collect2.h" 56#include "demangle.h" 57#include "obstack.h" 58#include "intl.h" 59#include "version.h" 60 61/* Obstack allocation and deallocation routines. */ 62#define obstack_chunk_alloc xmalloc 63#define obstack_chunk_free free 64 65/* On certain systems, we have code that works by scanning the object file 66 directly. But this code uses system-specific header files and library 67 functions, so turn it off in a cross-compiler. Likewise, the names of 68 the utilities are not correct for a cross-compiler; we have to hope that 69 cross-versions are in the proper directories. */ 70 71#ifdef CROSS_COMPILE 72#undef SUNOS4_SHARED_LIBRARIES 73#undef OBJECT_FORMAT_COFF 74#undef OBJECT_FORMAT_ROSE 75#undef MD_EXEC_PREFIX 76#undef REAL_LD_FILE_NAME 77#undef REAL_NM_FILE_NAME 78#undef REAL_STRIP_FILE_NAME 79#endif 80 81/* If we cannot use a special method, use the ordinary one: 82 run nm to find what symbols are present. 83 In a cross-compiler, this means you need a cross nm, 84 but that is not quite as unpleasant as special headers. */ 85 86#if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE) 87#define OBJECT_FORMAT_NONE 88#endif 89 90#ifdef OBJECT_FORMAT_COFF 91 92#include <a.out.h> 93#include <ar.h> 94 95#ifdef UMAX 96#include <sgs.h> 97#endif 98 99/* Many versions of ldfcn.h define these. */ 100#ifdef FREAD 101#undef FREAD 102#undef FWRITE 103#endif 104 105#include <ldfcn.h> 106 107/* Some systems have an ISCOFF macro, but others do not. In some cases 108 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines 109 that either do not have an ISCOFF macro in /usr/include or for those 110 where it is wrong. */ 111 112#ifndef MY_ISCOFF 113#define MY_ISCOFF(X) ISCOFF (X) 114#endif 115 116#endif /* OBJECT_FORMAT_COFF */ 117 118#ifdef OBJECT_FORMAT_ROSE 119 120#ifdef _OSF_SOURCE 121#define USE_MMAP 122#endif 123 124#ifdef USE_MMAP 125#include <sys/mman.h> 126#endif 127 128#include <unistd.h> 129#include <mach_o_format.h> 130#include <mach_o_header.h> 131#include <mach_o_vals.h> 132#include <mach_o_types.h> 133 134#endif /* OBJECT_FORMAT_ROSE */ 135 136#ifdef OBJECT_FORMAT_NONE 137 138/* Default flags to pass to nm. */ 139#ifndef NM_FLAGS 140#define NM_FLAGS "-n" 141#endif 142 143#endif /* OBJECT_FORMAT_NONE */ 144 145/* Some systems use __main in a way incompatible with its use in gcc, in these 146 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to 147 give the same symbol without quotes for an alternative entry point. You 148 must define both, or neither. */ 149#ifndef NAME__MAIN 150#define NAME__MAIN "__main" 151#define SYMBOL__MAIN __main 152#endif 153 154/* This must match tree.h. */ 155#define DEFAULT_INIT_PRIORITY 65535 156 157#ifndef COLLECT_SHARED_INIT_FUNC 158#define COLLECT_SHARED_INIT_FUNC(STREAM, FUNC) \ 159 fprintf ((STREAM), "void _GLOBAL__DI() {\n\t%s();\n}\n", (FUNC)) 160#endif 161#ifndef COLLECT_SHARED_FINI_FUNC 162#define COLLECT_SHARED_FINI_FUNC(STREAM, FUNC) \ 163 fprintf ((STREAM), "void _GLOBAL__DD() {\n\t%s();\n}\n", (FUNC)) 164#endif 165 166#if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES 167#define SCAN_LIBRARIES 168#endif 169 170#ifdef USE_COLLECT2 171int do_collecting = 1; 172#else 173int do_collecting = 0; 174#endif 175 176/* Nonzero if we should suppress the automatic demangling of identifiers 177 in linker error messages. Set from COLLECT_NO_DEMANGLE. */ 178int no_demangle; 179 180/* Linked lists of constructor and destructor names. */ 181 182struct id 183{ 184 struct id *next; 185 int sequence; 186 char name[1]; 187}; 188 189struct head 190{ 191 struct id *first; 192 struct id *last; 193 int number; 194}; 195 196/* Enumeration giving which pass this is for scanning the program file. */ 197 198enum pass { 199 PASS_FIRST, /* without constructors */ 200 PASS_OBJ, /* individual objects */ 201 PASS_LIB, /* looking for shared libraries */ 202 PASS_SECOND /* with constructors linked in */ 203}; 204 205int vflag; /* true if -v */ 206static int rflag; /* true if -r */ 207static int strip_flag; /* true if -s */ 208#ifdef COLLECT_EXPORT_LIST 209static int export_flag; /* true if -bE */ 210static int aix64_flag; /* true if -b64 */ 211#endif 212 213int debug; /* true if -debug */ 214 215static int shared_obj; /* true if -shared */ 216 217static const char *c_file; /* <xxx>.c for constructor/destructor list. */ 218static const char *o_file; /* <xxx>.o for constructor/destructor list. */ 219#ifdef COLLECT_EXPORT_LIST 220static const char *export_file; /* <xxx>.x for AIX export list. */ 221#endif 222const char *ldout; /* File for ld errors. */ 223static const char *output_file; /* Output file for ld. */ 224static const char *nm_file_name; /* pathname of nm */ 225#ifdef LDD_SUFFIX 226static const char *ldd_file_name; /* pathname of ldd (or equivalent) */ 227#endif 228static const char *strip_file_name; /* pathname of strip */ 229const char *c_file_name; /* pathname of gcc */ 230static char *initname, *fininame; /* names of init and fini funcs */ 231 232static struct head constructors; /* list of constructors found */ 233static struct head destructors; /* list of destructors found */ 234#ifdef COLLECT_EXPORT_LIST 235static struct head exports; /* list of exported symbols */ 236#endif 237static struct head frame_tables; /* list of frame unwind info tables */ 238 239struct obstack temporary_obstack; 240struct obstack permanent_obstack; 241char * temporary_firstobj; 242 243/* Holds the return value of pexecute. */ 244int pexecute_pid; 245 246/* Defined in the automatically-generated underscore.c. */ 247extern int prepends_underscore; 248 249#ifndef GET_ENV_PATH_LIST 250#define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0) 251#endif 252 253/* Structure to hold all the directories in which to search for files to 254 execute. */ 255 256struct prefix_list 257{ 258 const char *prefix; /* String to prepend to the path. */ 259 struct prefix_list *next; /* Next in linked list. */ 260}; 261 262struct path_prefix 263{ 264 struct prefix_list *plist; /* List of prefixes to try */ 265 int max_len; /* Max length of a prefix in PLIST */ 266 const char *name; /* Name of this list (used in config stuff) */ 267}; 268 269#ifdef COLLECT_EXPORT_LIST 270/* Lists to keep libraries to be scanned for global constructors/destructors. */ 271static struct head libs; /* list of libraries */ 272static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */ 273static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */ 274static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs, 275 &libpath_lib_dirs, NULL}; 276static const char *const libexts[3] = {"a", "so", NULL}; /* possible library extensions */ 277#endif 278 279static void handler PARAMS ((int)); 280static int is_ctor_dtor PARAMS ((const char *)); 281static char *find_a_file PARAMS ((struct path_prefix *, const char *)); 282static void add_prefix PARAMS ((struct path_prefix *, const char *)); 283static void prefix_from_env PARAMS ((const char *, struct path_prefix *)); 284static void prefix_from_string PARAMS ((const char *, struct path_prefix *)); 285static void do_wait PARAMS ((const char *)); 286static void fork_execute PARAMS ((const char *, char **)); 287static void maybe_unlink PARAMS ((const char *)); 288static void add_to_list PARAMS ((struct head *, const char *)); 289static int extract_init_priority PARAMS ((const char *)); 290static void sort_ids PARAMS ((struct head *)); 291static void write_list PARAMS ((FILE *, const char *, struct id *)); 292#ifdef COLLECT_EXPORT_LIST 293static void dump_list PARAMS ((FILE *, const char *, struct id *)); 294#endif 295#if 0 296static void dump_prefix_list PARAMS ((FILE *, const char *, struct prefix_list *)); 297#endif 298static void write_list_with_asm PARAMS ((FILE *, const char *, struct id *)); 299static void write_c_file PARAMS ((FILE *, const char *)); 300static void write_c_file_stat PARAMS ((FILE *, const char *)); 301#ifndef LD_INIT_SWITCH 302static void write_c_file_glob PARAMS ((FILE *, const char *)); 303#endif 304static void scan_prog_file PARAMS ((const char *, enum pass)); 305#ifdef SCAN_LIBRARIES 306static void scan_libraries PARAMS ((const char *)); 307#endif 308#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES 309static int is_in_args PARAMS ((const char *, const char **, const char **)); 310#endif 311#ifdef COLLECT_EXPORT_LIST 312#if 0 313static int is_in_list PARAMS ((const char *, struct id *)); 314#endif 315static void write_aix_file PARAMS ((FILE *, struct id *)); 316static char *resolve_lib_name PARAMS ((const char *)); 317static int ignore_library PARAMS ((const char *)); 318#endif 319static char *extract_string PARAMS ((const char **)); 320 321#ifndef HAVE_DUP2 322static int dup2 PARAMS ((int, int)); 323static int 324dup2 (oldfd, newfd) 325 int oldfd; 326 int newfd; 327{ 328 int fdtmp[256]; 329 int fdx = 0; 330 int fd; 331 332 if (oldfd == newfd) 333 return oldfd; 334 close (newfd); 335 while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */ 336 fdtmp[fdx++] = fd; 337 while (fdx > 0) 338 close (fdtmp[--fdx]); 339 340 return fd; 341} 342#endif /* ! HAVE_DUP2 */ 343 344/* Delete tempfiles and exit function. */ 345 346void 347collect_exit (status) 348 int status; 349{ 350 if (c_file != 0 && c_file[0]) 351 maybe_unlink (c_file); 352 353 if (o_file != 0 && o_file[0]) 354 maybe_unlink (o_file); 355 356#ifdef COLLECT_EXPORT_LIST 357 if (export_file != 0 && export_file[0]) 358 maybe_unlink (export_file); 359#endif 360 361 if (ldout != 0 && ldout[0]) 362 { 363 dump_file (ldout); 364 maybe_unlink (ldout); 365 } 366 367 if (status != 0 && output_file != 0 && output_file[0]) 368 maybe_unlink (output_file); 369 370 exit (status); 371} 372 373 374/* Notify user of a non-error. */ 375void 376notice VPARAMS ((const char *msgid, ...)) 377{ 378 VA_OPEN (ap, msgid); 379 VA_FIXEDARG (ap, const char *, msgid); 380 381 vfprintf (stderr, _(msgid), ap); 382 VA_CLOSE (ap); 383} 384 385/* Die when sys call fails. */ 386 387void 388fatal_perror VPARAMS ((const char * msgid, ...)) 389{ 390 int e = errno; 391 392 VA_OPEN (ap, msgid); 393 VA_FIXEDARG (ap, const char *, msgid); 394 395 fprintf (stderr, "collect2: "); 396 vfprintf (stderr, _(msgid), ap); 397 fprintf (stderr, ": %s\n", xstrerror (e)); 398 VA_CLOSE (ap); 399 400 collect_exit (FATAL_EXIT_CODE); 401} 402 403/* Just die. */ 404 405void 406fatal VPARAMS ((const char * msgid, ...)) 407{ 408 VA_OPEN (ap, msgid); 409 VA_FIXEDARG (ap, const char *, msgid); 410 411 fprintf (stderr, "collect2: "); 412 vfprintf (stderr, _(msgid), ap); 413 fprintf (stderr, "\n"); 414 VA_CLOSE (ap); 415 416 collect_exit (FATAL_EXIT_CODE); 417} 418 419/* Write error message. */ 420 421void 422error VPARAMS ((const char * msgid, ...)) 423{ 424 VA_OPEN (ap, msgid); 425 VA_FIXEDARG (ap, const char *, msgid); 426 427 fprintf (stderr, "collect2: "); 428 vfprintf (stderr, _(msgid), ap); 429 fprintf (stderr, "\n"); 430 VA_CLOSE(ap); 431} 432 433/* In case obstack is linked in, and abort is defined to fancy_abort, 434 provide a default entry. */ 435 436void 437fancy_abort () 438{ 439 fatal ("internal error"); 440} 441 442static void 443handler (signo) 444 int signo; 445{ 446 if (c_file != 0 && c_file[0]) 447 maybe_unlink (c_file); 448 449 if (o_file != 0 && o_file[0]) 450 maybe_unlink (o_file); 451 452 if (ldout != 0 && ldout[0]) 453 maybe_unlink (ldout); 454 455#ifdef COLLECT_EXPORT_LIST 456 if (export_file != 0 && export_file[0]) 457 maybe_unlink (export_file); 458#endif 459 460 signal (signo, SIG_DFL); 461 kill (getpid (), signo); 462} 463 464 465int 466file_exists (name) 467 const char *name; 468{ 469 return access (name, R_OK) == 0; 470} 471 472/* Parse a reasonable subset of shell quoting syntax. */ 473 474static char * 475extract_string (pp) 476 const char **pp; 477{ 478 const char *p = *pp; 479 int backquote = 0; 480 int inside = 0; 481 482 for (;;) 483 { 484 char c = *p; 485 if (c == '\0') 486 break; 487 ++p; 488 if (backquote) 489 obstack_1grow (&temporary_obstack, c); 490 else if (! inside && c == ' ') 491 break; 492 else if (! inside && c == '\\') 493 backquote = 1; 494 else if (c == '\'') 495 inside = !inside; 496 else 497 obstack_1grow (&temporary_obstack, c); 498 } 499 500 obstack_1grow (&temporary_obstack, '\0'); 501 *pp = p; 502 return obstack_finish (&temporary_obstack); 503} 504 505void 506dump_file (name) 507 const char *name; 508{ 509 FILE *stream = fopen (name, "r"); 510 511 if (stream == 0) 512 return; 513 while (1) 514 { 515 int c; 516 while (c = getc (stream), 517 c != EOF && (ISIDNUM (c) || c == '$' || c == '.')) 518 obstack_1grow (&temporary_obstack, c); 519 if (obstack_object_size (&temporary_obstack) > 0) 520 { 521 const char *word, *p; 522 char *result; 523 obstack_1grow (&temporary_obstack, '\0'); 524 word = obstack_finish (&temporary_obstack); 525 526 if (*word == '.') 527 ++word, putc ('.', stderr); 528 p = word; 529 if (*p == '_' && prepends_underscore) 530 ++p; 531 532 if (no_demangle) 533 result = 0; 534 else 535 result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE); 536 537 if (result) 538 { 539 int diff; 540 fputs (result, stderr); 541 542 diff = strlen (word) - strlen (result); 543 while (diff > 0 && c == ' ') 544 --diff, putc (' ', stderr); 545 while (diff < 0 && c == ' ') 546 ++diff, c = getc (stream); 547 548 free (result); 549 } 550 else 551 fputs (word, stderr); 552 553 fflush (stderr); 554 obstack_free (&temporary_obstack, temporary_firstobj); 555 } 556 if (c == EOF) 557 break; 558 putc (c, stderr); 559 } 560 fclose (stream); 561} 562 563/* Decide whether the given symbol is: a constructor (1), a destructor 564 (2), a routine in a shared object that calls all the constructors 565 (3) or destructors (4), a DWARF exception-handling table (5), or 566 nothing special (0). */ 567 568static int 569is_ctor_dtor (s) 570 const char *s; 571{ 572 struct names { const char *const name; const int len; const int ret; 573 const int two_underscores; }; 574 575 const struct names *p; 576 int ch; 577 const char *orig_s = s; 578 579 static const struct names special[] = { 580#ifndef NO_DOLLAR_IN_LABEL 581 { "GLOBAL__I$", sizeof ("GLOBAL__I$")-1, 1, 0 }, 582 { "GLOBAL__D$", sizeof ("GLOBAL__D$")-1, 2, 0 }, 583#else 584#ifndef NO_DOT_IN_LABEL 585 { "GLOBAL__I.", sizeof ("GLOBAL__I.")-1, 1, 0 }, 586 { "GLOBAL__D.", sizeof ("GLOBAL__D.")-1, 2, 0 }, 587#endif /* NO_DOT_IN_LABEL */ 588#endif /* NO_DOLLAR_IN_LABEL */ 589 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 }, 590 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 }, 591 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 }, 592 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 }, 593 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 }, 594#ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions. 595 cfront has its own linker procedure to collect them; 596 if collect2 gets them too, they get collected twice 597 when the cfront procedure is run and the compiler used 598 for linking happens to be GCC. */ 599 { "sti__", sizeof ("sti__")-1, 1, 1 }, 600 { "std__", sizeof ("std__")-1, 2, 1 }, 601#endif /* CFRONT_LOSSAGE */ 602 { NULL, 0, 0, 0 } 603 }; 604 605 while ((ch = *s) == '_') 606 ++s; 607 608 if (s == orig_s) 609 return 0; 610 611 for (p = &special[0]; p->len > 0; p++) 612 { 613 if (ch == p->name[0] 614 && (!p->two_underscores || ((s - orig_s) >= 2)) 615 && strncmp(s, p->name, p->len) == 0) 616 { 617 return p->ret; 618 } 619 } 620 return 0; 621} 622 623/* We maintain two prefix lists: one from COMPILER_PATH environment variable 624 and one from the PATH variable. */ 625 626static struct path_prefix cpath, path; 627 628#ifdef CROSS_COMPILE 629/* This is the name of the target machine. We use it to form the name 630 of the files to execute. */ 631 632static const char *const target_machine = TARGET_MACHINE; 633#endif 634 635/* Search for NAME using prefix list PPREFIX. We only look for executable 636 files. 637 638 Return 0 if not found, otherwise return its name, allocated with malloc. */ 639 640static char * 641find_a_file (pprefix, name) 642 struct path_prefix *pprefix; 643 const char *name; 644{ 645 char *temp; 646 struct prefix_list *pl; 647 int len = pprefix->max_len + strlen (name) + 1; 648 649 if (debug) 650 fprintf (stderr, "Looking for '%s'\n", name); 651 652#ifdef HOST_EXECUTABLE_SUFFIX 653 len += strlen (HOST_EXECUTABLE_SUFFIX); 654#endif 655 656 temp = xmalloc (len); 657 658 /* Determine the filename to execute (special case for absolute paths). */ 659 660 if (*name == '/' 661#ifdef HAVE_DOS_BASED_FILE_SYSTEM 662 || (*name && name[1] == ':') 663#endif 664 ) 665 { 666 if (access (name, X_OK) == 0) 667 { 668 strcpy (temp, name); 669 670 if (debug) 671 fprintf (stderr, " - found: absolute path\n"); 672 673 return temp; 674 } 675 676#ifdef HOST_EXECUTABLE_SUFFIX 677 /* Some systems have a suffix for executable files. 678 So try appending that. */ 679 strcpy (temp, name); 680 strcat (temp, HOST_EXECUTABLE_SUFFIX); 681 682 if (access (temp, X_OK) == 0) 683 return temp; 684#endif 685 686 if (debug) 687 fprintf (stderr, " - failed to locate using absolute path\n"); 688 } 689 else 690 for (pl = pprefix->plist; pl; pl = pl->next) 691 { 692 struct stat st; 693 694 strcpy (temp, pl->prefix); 695 strcat (temp, name); 696 697 if (stat (temp, &st) >= 0 698 && ! S_ISDIR (st.st_mode) 699 && access (temp, X_OK) == 0) 700 return temp; 701 702#ifdef HOST_EXECUTABLE_SUFFIX 703 /* Some systems have a suffix for executable files. 704 So try appending that. */ 705 strcat (temp, HOST_EXECUTABLE_SUFFIX); 706 707 if (stat (temp, &st) >= 0 708 && ! S_ISDIR (st.st_mode) 709 && access (temp, X_OK) == 0) 710 return temp; 711#endif 712 } 713 714 if (debug && pprefix->plist == NULL) 715 fprintf (stderr, " - failed: no entries in prefix list\n"); 716 717 free (temp); 718 return 0; 719} 720 721/* Add an entry for PREFIX to prefix list PPREFIX. */ 722 723static void 724add_prefix (pprefix, prefix) 725 struct path_prefix *pprefix; 726 const char *prefix; 727{ 728 struct prefix_list *pl, **prev; 729 int len; 730 731 if (pprefix->plist) 732 { 733 for (pl = pprefix->plist; pl->next; pl = pl->next) 734 ; 735 prev = &pl->next; 736 } 737 else 738 prev = &pprefix->plist; 739 740 /* Keep track of the longest prefix */ 741 742 len = strlen (prefix); 743 if (len > pprefix->max_len) 744 pprefix->max_len = len; 745 746 pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list)); 747 pl->prefix = xstrdup (prefix); 748 749 if (*prev) 750 pl->next = *prev; 751 else 752 pl->next = (struct prefix_list *) 0; 753 *prev = pl; 754} 755 756/* Take the value of the environment variable ENV, break it into a path, and 757 add of the entries to PPREFIX. */ 758 759static void 760prefix_from_env (env, pprefix) 761 const char *env; 762 struct path_prefix *pprefix; 763{ 764 const char *p; 765 GET_ENV_PATH_LIST (p, env); 766 767 if (p) 768 prefix_from_string (p, pprefix); 769} 770 771static void 772prefix_from_string (p, pprefix) 773 const char *p; 774 struct path_prefix *pprefix; 775{ 776 const char *startp, *endp; 777 char *nstore = (char *) xmalloc (strlen (p) + 3); 778 779 if (debug) 780 fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR); 781 782 startp = endp = p; 783 while (1) 784 { 785 if (*endp == PATH_SEPARATOR || *endp == 0) 786 { 787 strncpy (nstore, startp, endp-startp); 788 if (endp == startp) 789 { 790 strcpy (nstore, "./"); 791 } 792 else if (! IS_DIR_SEPARATOR (endp[-1])) 793 { 794 nstore[endp-startp] = DIR_SEPARATOR; 795 nstore[endp-startp+1] = 0; 796 } 797 else 798 nstore[endp-startp] = 0; 799 800 if (debug) 801 fprintf (stderr, " - add prefix: %s\n", nstore); 802 803 add_prefix (pprefix, nstore); 804 if (*endp == 0) 805 break; 806 endp = startp = endp + 1; 807 } 808 else 809 endp++; 810 } 811} 812 813/* Main program. */ 814 815int main PARAMS ((int, char *[])); 816int 817main (argc, argv) 818 int argc; 819 char *argv[]; 820{ 821 static const char *const ld_suffix = "ld"; 822 static const char *const real_ld_suffix = "real-ld"; 823 static const char *const collect_ld_suffix = "collect-ld"; 824 static const char *const nm_suffix = "nm"; 825 static const char *const gnm_suffix = "gnm"; 826#ifdef LDD_SUFFIX 827 static const char *const ldd_suffix = LDD_SUFFIX; 828#endif 829 static const char *const strip_suffix = "strip"; 830 static const char *const gstrip_suffix = "gstrip"; 831 832#ifdef CROSS_COMPILE 833 /* If we look for a program in the compiler directories, we just use 834 the short name, since these directories are already system-specific. 835 But it we look for a program in the system directories, we need to 836 qualify the program name with the target machine. */ 837 838 const char *const full_ld_suffix = 839 concat(target_machine, "-", ld_suffix, NULL); 840 const char *const full_nm_suffix = 841 concat (target_machine, "-", nm_suffix, NULL); 842 const char *const full_gnm_suffix = 843 concat (target_machine, "-", gnm_suffix, NULL); 844#ifdef LDD_SUFFIX 845 const char *const full_ldd_suffix = 846 concat (target_machine, "-", ldd_suffix, NULL); 847#endif 848 const char *const full_strip_suffix = 849 concat (target_machine, "-", strip_suffix, NULL); 850 const char *const full_gstrip_suffix = 851 concat (target_machine, "-", gstrip_suffix, NULL); 852#else 853 const char *const full_ld_suffix = ld_suffix; 854 const char *const full_nm_suffix = nm_suffix; 855 const char *const full_gnm_suffix = gnm_suffix; 856#ifdef LDD_SUFFIX 857 const char *const full_ldd_suffix = ldd_suffix; 858#endif 859 const char *const full_strip_suffix = strip_suffix; 860 const char *const full_gstrip_suffix = gstrip_suffix; 861#endif /* CROSS_COMPILE */ 862 863 const char *arg; 864 FILE *outf; 865#ifdef COLLECT_EXPORT_LIST 866 FILE *exportf; 867#endif 868 const char *ld_file_name; 869 const char *p; 870 char **c_argv; 871 const char **c_ptr; 872 char **ld1_argv; 873 const char **ld1; 874 char **ld2_argv; 875 const char **ld2; 876 char **object_lst; 877 const char **object; 878 int first_file; 879 int num_c_args = argc+9; 880 881 no_demangle = !! getenv ("COLLECT_NO_DEMANGLE"); 882 883 /* Suppress demangling by the real linker, which may be broken. */ 884 putenv (xstrdup ("COLLECT_NO_DEMANGLE=")); 885 886#if defined (COLLECT2_HOST_INITIALIZATION) 887 /* Perform system dependent initialization, if necessary. */ 888 COLLECT2_HOST_INITIALIZATION; 889#endif 890 891#ifdef SIGCHLD 892 /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will 893 receive the signal. A different setting is inheritable */ 894 signal (SIGCHLD, SIG_DFL); 895#endif 896 897 gcc_init_libintl (); 898 899 /* Do not invoke xcalloc before this point, since locale needs to be 900 set first, in case a diagnostic is issued. */ 901 902 ld1 = (const char **)(ld1_argv = (char **) xcalloc(sizeof (char *), argc+3)); 903 ld2 = (const char **)(ld2_argv = (char **) xcalloc(sizeof (char *), argc+10)); 904 object = (const char **)(object_lst = (char **) xcalloc(sizeof (char *), argc)); 905 906#ifdef DEBUG 907 debug = 1; 908#endif 909 910 /* Parse command line early for instances of -debug. This allows 911 the debug flag to be set before functions like find_a_file() 912 are called. */ 913 { 914 int i; 915 916 for (i = 1; argv[i] != NULL; i ++) 917 if (! strcmp (argv[i], "-debug")) 918 debug = 1; 919 vflag = debug; 920 } 921 922#ifndef DEFAULT_A_OUT_NAME 923 output_file = "a.out"; 924#else 925 output_file = DEFAULT_A_OUT_NAME; 926#endif 927 928 obstack_begin (&temporary_obstack, 0); 929 obstack_begin (&permanent_obstack, 0); 930 temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0); 931 932 current_demangling_style = auto_demangling; 933 p = getenv ("COLLECT_GCC_OPTIONS"); 934 while (p && *p) 935 { 936 const char *q = extract_string (&p); 937 if (*q == '-' && (q[1] == 'm' || q[1] == 'f')) 938 num_c_args++; 939 } 940 obstack_free (&temporary_obstack, temporary_firstobj); 941 942 /* -fno-exceptions -w */ 943 num_c_args += 2; 944 945 c_ptr = (const char **) 946 (c_argv = (char **) xcalloc (sizeof (char *), num_c_args)); 947 948 if (argc < 2) 949 fatal ("no arguments"); 950 951#ifdef SIGQUIT 952 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN) 953 signal (SIGQUIT, handler); 954#endif 955 if (signal (SIGINT, SIG_IGN) != SIG_IGN) 956 signal (SIGINT, handler); 957#ifdef SIGALRM 958 if (signal (SIGALRM, SIG_IGN) != SIG_IGN) 959 signal (SIGALRM, handler); 960#endif 961#ifdef SIGHUP 962 if (signal (SIGHUP, SIG_IGN) != SIG_IGN) 963 signal (SIGHUP, handler); 964#endif 965 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN) 966 signal (SIGSEGV, handler); 967#ifdef SIGBUS 968 if (signal (SIGBUS, SIG_IGN) != SIG_IGN) 969 signal (SIGBUS, handler); 970#endif 971 972 /* Extract COMPILER_PATH and PATH into our prefix list. */ 973 prefix_from_env ("COMPILER_PATH", &cpath); 974 prefix_from_env ("PATH", &path); 975 976 /* Try to discover a valid linker/nm/strip to use. */ 977 978 /* Maybe we know the right file to use (if not cross). */ 979 ld_file_name = 0; 980#ifdef DEFAULT_LINKER 981 if (access (DEFAULT_LINKER, X_OK) == 0) 982 ld_file_name = DEFAULT_LINKER; 983 if (ld_file_name == 0) 984#endif 985#ifdef REAL_LD_FILE_NAME 986 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME); 987 if (ld_file_name == 0) 988#endif 989 /* Search the (target-specific) compiler dirs for ld'. */ 990 ld_file_name = find_a_file (&cpath, real_ld_suffix); 991 /* Likewise for `collect-ld'. */ 992 if (ld_file_name == 0) 993 ld_file_name = find_a_file (&cpath, collect_ld_suffix); 994 /* Search the compiler directories for `ld'. We have protection against 995 recursive calls in find_a_file. */ 996 if (ld_file_name == 0) 997 ld_file_name = find_a_file (&cpath, ld_suffix); 998 /* Search the ordinary system bin directories 999 for `ld' (if native linking) or `TARGET-ld' (if cross). */ 1000 if (ld_file_name == 0) 1001 ld_file_name = find_a_file (&path, full_ld_suffix); 1002 1003#ifdef REAL_NM_FILE_NAME 1004 nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME); 1005 if (nm_file_name == 0) 1006#endif 1007 nm_file_name = find_a_file (&cpath, gnm_suffix); 1008 if (nm_file_name == 0) 1009 nm_file_name = find_a_file (&path, full_gnm_suffix); 1010 if (nm_file_name == 0) 1011 nm_file_name = find_a_file (&cpath, nm_suffix); 1012 if (nm_file_name == 0) 1013 nm_file_name = find_a_file (&path, full_nm_suffix); 1014 1015#ifdef LDD_SUFFIX 1016 ldd_file_name = find_a_file (&cpath, ldd_suffix); 1017 if (ldd_file_name == 0) 1018 ldd_file_name = find_a_file (&path, full_ldd_suffix); 1019#endif 1020 1021#ifdef REAL_STRIP_FILE_NAME 1022 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME); 1023 if (strip_file_name == 0) 1024#endif 1025 strip_file_name = find_a_file (&cpath, gstrip_suffix); 1026 if (strip_file_name == 0) 1027 strip_file_name = find_a_file (&path, full_gstrip_suffix); 1028 if (strip_file_name == 0) 1029 strip_file_name = find_a_file (&cpath, strip_suffix); 1030 if (strip_file_name == 0) 1031 strip_file_name = find_a_file (&path, full_strip_suffix); 1032 1033 /* Determine the full path name of the C compiler to use. */ 1034 c_file_name = getenv ("COLLECT_GCC"); 1035 if (c_file_name == 0) 1036 { 1037#ifdef CROSS_COMPILE 1038 c_file_name = concat (target_machine, "-gcc", NULL); 1039#else 1040 c_file_name = "gcc"; 1041#endif 1042 } 1043 1044 p = find_a_file (&cpath, c_file_name); 1045 1046 /* Here it should be safe to use the system search path since we should have 1047 already qualified the name of the compiler when it is needed. */ 1048 if (p == 0) 1049 p = find_a_file (&path, c_file_name); 1050 1051 if (p) 1052 c_file_name = p; 1053 1054 *ld1++ = *ld2++ = ld_file_name; 1055 1056 /* Make temp file names. */ 1057 c_file = make_temp_file (".c"); 1058 o_file = make_temp_file (".o"); 1059#ifdef COLLECT_EXPORT_LIST 1060 export_file = make_temp_file (".x"); 1061#endif 1062 ldout = make_temp_file (".ld"); 1063 *c_ptr++ = c_file_name; 1064 *c_ptr++ = "-x"; 1065 *c_ptr++ = "c"; 1066 *c_ptr++ = "-c"; 1067 *c_ptr++ = "-o"; 1068 *c_ptr++ = o_file; 1069 1070#ifdef COLLECT_EXPORT_LIST 1071 /* Generate a list of directories from LIBPATH. */ 1072 prefix_from_env ("LIBPATH", &libpath_lib_dirs); 1073 /* Add to this list also two standard directories where 1074 AIX loader always searches for libraries. */ 1075 add_prefix (&libpath_lib_dirs, "/lib"); 1076 add_prefix (&libpath_lib_dirs, "/usr/lib"); 1077#endif 1078 1079 /* Get any options that the upper GCC wants to pass to the sub-GCC. 1080 1081 AIX support needs to know if -shared has been specified before 1082 parsing commandline arguments. */ 1083 1084 p = getenv ("COLLECT_GCC_OPTIONS"); 1085 while (p && *p) 1086 { 1087 const char *q = extract_string (&p); 1088 if (*q == '-' && (q[1] == 'm' || q[1] == 'f')) 1089 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q)); 1090 if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0) 1091 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q)); 1092 if (strcmp (q, "-shared") == 0) 1093 shared_obj = 1; 1094 if (*q == '-' && q[1] == 'B') 1095 { 1096 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q)); 1097 if (q[2] == 0) 1098 { 1099 q = extract_string (&p); 1100 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q)); 1101 } 1102 } 1103 } 1104 obstack_free (&temporary_obstack, temporary_firstobj); 1105 *c_ptr++ = "-fno-exceptions"; 1106 *c_ptr++ = "-w"; 1107 1108 /* !!! When GCC calls collect2, 1109 it does not know whether it is calling collect2 or ld. 1110 So collect2 cannot meaningfully understand any options 1111 except those ld understands. 1112 If you propose to make GCC pass some other option, 1113 just imagine what will happen if ld is really ld!!! */ 1114 1115 /* Parse arguments. Remember output file spec, pass the rest to ld. */ 1116 /* After the first file, put in the c++ rt0. */ 1117 1118 first_file = 1; 1119 while ((arg = *++argv) != (char *) 0) 1120 { 1121 *ld1++ = *ld2++ = arg; 1122 1123 if (arg[0] == '-') 1124 { 1125 switch (arg[1]) 1126 { 1127#ifdef COLLECT_EXPORT_LIST 1128 /* We want to disable automatic exports on AIX when user 1129 explicitly puts an export list in command line */ 1130 case 'b': 1131 if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0) 1132 export_flag = 1; 1133 else if (arg[2] == '6' && arg[3] == '4') 1134 aix64_flag = 1; 1135 break; 1136#endif 1137 1138 case 'd': 1139 if (!strcmp (arg, "-debug")) 1140 { 1141 /* Already parsed. */ 1142 ld1--; 1143 ld2--; 1144 } 1145 break; 1146 1147 case 'l': 1148 if (first_file) 1149 { 1150 /* place o_file BEFORE this argument! */ 1151 first_file = 0; 1152 ld2--; 1153 *ld2++ = o_file; 1154 *ld2++ = arg; 1155 } 1156#ifdef COLLECT_EXPORT_LIST 1157 { 1158 /* Resolving full library name. */ 1159 const char *s = resolve_lib_name (arg+2); 1160 1161 /* Saving a full library name. */ 1162 add_to_list (&libs, s); 1163 } 1164#endif 1165 break; 1166 1167#ifdef COLLECT_EXPORT_LIST 1168 /* Saving directories where to search for libraries. */ 1169 case 'L': 1170 add_prefix (&cmdline_lib_dirs, arg+2); 1171 break; 1172#else 1173#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES 1174 case 'L': 1175 if (is_in_args (arg, (const char **) ld1_argv, ld1-1)) 1176 --ld1; 1177 break; 1178#endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */ 1179#endif 1180 1181 case 'o': 1182 if (arg[2] == '\0') 1183 output_file = *ld1++ = *ld2++ = *++argv; 1184 else if (1 1185#ifdef SWITCHES_NEED_SPACES 1186 && ! strchr (SWITCHES_NEED_SPACES, arg[1]) 1187#endif 1188 ) 1189 1190 output_file = &arg[2]; 1191 break; 1192 1193 case 'r': 1194 if (arg[2] == '\0') 1195 rflag = 1; 1196 break; 1197 1198 case 's': 1199 if (arg[2] == '\0' && do_collecting) 1200 { 1201 /* We must strip after the nm run, otherwise C++ linking 1202 will not work. Thus we strip in the second ld run, or 1203 else with strip if there is no second ld run. */ 1204 strip_flag = 1; 1205 ld1--; 1206 } 1207 break; 1208 1209 case 'v': 1210 if (arg[2] == '\0') 1211 vflag = 1; 1212 break; 1213 } 1214 } 1215 else if ((p = strrchr (arg, '.')) != (char *) 0 1216 && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0 1217 || strcmp (p, ".so") == 0 || strcmp (p, ".lo") == 0 1218 || strcmp (p, ".obj") == 0)) 1219 { 1220 if (first_file) 1221 { 1222 first_file = 0; 1223 if (p[1] == 'o') 1224 *ld2++ = o_file; 1225 else 1226 { 1227 /* place o_file BEFORE this argument! */ 1228 ld2--; 1229 *ld2++ = o_file; 1230 *ld2++ = arg; 1231 } 1232 } 1233 if (p[1] == 'o' || p[1] == 'l') 1234 *object++ = arg; 1235#ifdef COLLECT_EXPORT_LIST 1236 /* libraries can be specified directly, i.e. without -l flag. */ 1237 else 1238 { 1239 /* Saving a full library name. */ 1240 add_to_list (&libs, arg); 1241 } 1242#endif 1243 } 1244 } 1245 1246#ifdef COLLECT_EXPORT_LIST 1247 /* This is added only for debugging purposes. */ 1248 if (debug) 1249 { 1250 fprintf (stderr, "List of libraries:\n"); 1251 dump_list (stderr, "\t", libs.first); 1252 } 1253 1254 /* The AIX linker will discard static constructors in object files if 1255 nothing else in the file is referenced, so look at them first. */ 1256 { 1257 const char **export_object_lst = (const char **)object_lst; 1258 1259 while (export_object_lst < object) 1260 scan_prog_file (*export_object_lst++, PASS_OBJ); 1261 } 1262 { 1263 struct id *list = libs.first; 1264 1265 for (; list; list = list->next) 1266 scan_prog_file (list->name, PASS_FIRST); 1267 } 1268 1269 if (exports.first) 1270 { 1271 char *buf = concat ("-bE:", export_file, NULL); 1272 1273 *ld1++ = buf; 1274 *ld2++ = buf; 1275 1276 exportf = fopen (export_file, "w"); 1277 if (exportf == (FILE *) 0) 1278 fatal_perror ("fopen %s", export_file); 1279 write_aix_file (exportf, exports.first); 1280 if (fclose (exportf)) 1281 fatal_perror ("fclose %s", export_file); 1282 } 1283#endif 1284 1285 *c_ptr++ = c_file; 1286 *c_ptr = *ld1 = *object = (char *) 0; 1287 1288 if (vflag) 1289 { 1290 notice ("collect2 version %s", version_string); 1291#ifdef TARGET_VERSION 1292 TARGET_VERSION; 1293#endif 1294 fprintf (stderr, "\n"); 1295 } 1296 1297 if (debug) 1298 { 1299 const char *ptr; 1300 fprintf (stderr, "ld_file_name = %s\n", 1301 (ld_file_name ? ld_file_name : "not found")); 1302 fprintf (stderr, "c_file_name = %s\n", 1303 (c_file_name ? c_file_name : "not found")); 1304 fprintf (stderr, "nm_file_name = %s\n", 1305 (nm_file_name ? nm_file_name : "not found")); 1306#ifdef LDD_SUFFIX 1307 fprintf (stderr, "ldd_file_name = %s\n", 1308 (ldd_file_name ? ldd_file_name : "not found")); 1309#endif 1310 fprintf (stderr, "strip_file_name = %s\n", 1311 (strip_file_name ? strip_file_name : "not found")); 1312 fprintf (stderr, "c_file = %s\n", 1313 (c_file ? c_file : "not found")); 1314 fprintf (stderr, "o_file = %s\n", 1315 (o_file ? o_file : "not found")); 1316 1317 ptr = getenv ("COLLECT_GCC_OPTIONS"); 1318 if (ptr) 1319 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr); 1320 1321 ptr = getenv ("COLLECT_GCC"); 1322 if (ptr) 1323 fprintf (stderr, "COLLECT_GCC = %s\n", ptr); 1324 1325 ptr = getenv ("COMPILER_PATH"); 1326 if (ptr) 1327 fprintf (stderr, "COMPILER_PATH = %s\n", ptr); 1328 1329 ptr = getenv (LIBRARY_PATH_ENV); 1330 if (ptr) 1331 fprintf (stderr, "%-20s= %s\n", LIBRARY_PATH_ENV, ptr); 1332 1333 fprintf (stderr, "\n"); 1334 } 1335 1336 /* Load the program, searching all libraries and attempting to provide 1337 undefined symbols from repository information. */ 1338 1339 /* On AIX we do this later. */ 1340#ifndef COLLECT_EXPORT_LIST 1341 do_tlink (ld1_argv, object_lst); 1342#endif 1343 1344 /* If -r or they will be run via some other method, do not build the 1345 constructor or destructor list, just return now. */ 1346 if (rflag 1347#ifndef COLLECT_EXPORT_LIST 1348 || ! do_collecting 1349#endif 1350 ) 1351 { 1352#ifdef COLLECT_EXPORT_LIST 1353 /* Do the link we avoided above if we are exiting. */ 1354 do_tlink (ld1_argv, object_lst); 1355 1356 /* But make sure we delete the export file we may have created. */ 1357 if (export_file != 0 && export_file[0]) 1358 maybe_unlink (export_file); 1359#endif 1360 maybe_unlink (c_file); 1361 maybe_unlink (o_file); 1362 return 0; 1363 } 1364 1365 /* Examine the namelist with nm and search it for static constructors 1366 and destructors to call. 1367 Write the constructor and destructor tables to a .s file and reload. */ 1368 1369 /* On AIX we already scanned for global constructors/destructors. */ 1370#ifndef COLLECT_EXPORT_LIST 1371 scan_prog_file (output_file, PASS_FIRST); 1372#endif 1373 1374#ifdef SCAN_LIBRARIES 1375 scan_libraries (output_file); 1376#endif 1377 1378 if (debug) 1379 { 1380 notice ("%d constructor(s) found\n", constructors.number); 1381 notice ("%d destructor(s) found\n", destructors.number); 1382 notice ("%d frame table(s) found\n", frame_tables.number); 1383 } 1384 1385 if (constructors.number == 0 && destructors.number == 0 1386 && frame_tables.number == 0 1387#if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST) 1388 /* If we will be running these functions ourselves, we want to emit 1389 stubs into the shared library so that we do not have to relink 1390 dependent programs when we add static objects. */ 1391 && ! shared_obj 1392#endif 1393 ) 1394 { 1395#ifdef COLLECT_EXPORT_LIST 1396 /* Do tlink without additional code generation */ 1397 do_tlink (ld1_argv, object_lst); 1398#endif 1399 /* Strip now if it was requested on the command line. */ 1400 if (strip_flag) 1401 { 1402 char **real_strip_argv = (char **) xcalloc (sizeof (char *), 3); 1403 const char ** strip_argv = (const char **) real_strip_argv; 1404 1405 strip_argv[0] = strip_file_name; 1406 strip_argv[1] = output_file; 1407 strip_argv[2] = (char *) 0; 1408 fork_execute ("strip", real_strip_argv); 1409 } 1410 1411#ifdef COLLECT_EXPORT_LIST 1412 maybe_unlink (export_file); 1413#endif 1414 maybe_unlink (c_file); 1415 maybe_unlink (o_file); 1416 return 0; 1417 } 1418 1419 /* Sort ctor and dtor lists by priority. */ 1420 sort_ids (&constructors); 1421 sort_ids (&destructors); 1422 1423 maybe_unlink(output_file); 1424 outf = fopen (c_file, "w"); 1425 if (outf == (FILE *) 0) 1426 fatal_perror ("fopen %s", c_file); 1427 1428 write_c_file (outf, c_file); 1429 1430 if (fclose (outf)) 1431 fatal_perror ("fclose %s", c_file); 1432 1433 /* Tell the linker that we have initializer and finalizer functions. */ 1434#ifdef LD_INIT_SWITCH 1435#ifdef COLLECT_EXPORT_LIST 1436 *ld2++ = concat (LD_INIT_SWITCH, ":", initname, ":", fininame, NULL); 1437#else 1438 *ld2++ = LD_INIT_SWITCH; 1439 *ld2++ = initname; 1440 *ld2++ = LD_FINI_SWITCH; 1441 *ld2++ = fininame; 1442#endif 1443#endif 1444 1445#ifdef COLLECT_EXPORT_LIST 1446 if (shared_obj) 1447 { 1448 /* If we did not add export flag to link arguments before, add it to 1449 second link phase now. No new exports should have been added. */ 1450 if (! exports.first) 1451 *ld2++ = concat ("-bE:", export_file, NULL); 1452 1453 add_to_list (&exports, initname); 1454 add_to_list (&exports, fininame); 1455 add_to_list (&exports, "_GLOBAL__DI"); 1456 add_to_list (&exports, "_GLOBAL__DD"); 1457 exportf = fopen (export_file, "w"); 1458 if (exportf == (FILE *) 0) 1459 fatal_perror ("fopen %s", export_file); 1460 write_aix_file (exportf, exports.first); 1461 if (fclose (exportf)) 1462 fatal_perror ("fclose %s", export_file); 1463 } 1464#endif 1465 1466 /* End of arguments to second link phase. */ 1467 *ld2 = (char*) 0; 1468 1469 if (debug) 1470 { 1471 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n", 1472 output_file, c_file); 1473 write_c_file (stderr, "stderr"); 1474 fprintf (stderr, "========== end of c_file\n\n"); 1475#ifdef COLLECT_EXPORT_LIST 1476 fprintf (stderr, "\n========== export_file = %s\n", export_file); 1477 write_aix_file (stderr, exports.first); 1478 fprintf (stderr, "========== end of export_file\n\n"); 1479#endif 1480 } 1481 1482 /* Assemble the constructor and destructor tables. 1483 Link the tables in with the rest of the program. */ 1484 1485 fork_execute ("gcc", c_argv); 1486#ifdef COLLECT_EXPORT_LIST 1487 /* On AIX we must call tlink because of possible templates resolution */ 1488 do_tlink (ld2_argv, object_lst); 1489#else 1490 /* Otherwise, simply call ld because tlink is already done */ 1491 fork_execute ("ld", ld2_argv); 1492 1493 /* Let scan_prog_file do any final mods (OSF/rose needs this for 1494 constructors/destructors in shared libraries. */ 1495 scan_prog_file (output_file, PASS_SECOND); 1496#endif 1497 1498 maybe_unlink (c_file); 1499 maybe_unlink (o_file); 1500 1501#ifdef COLLECT_EXPORT_LIST 1502 maybe_unlink (export_file); 1503#endif 1504 1505 return 0; 1506} 1507 1508 1509/* Wait for a process to finish, and exit if a non-zero status is found. */ 1510 1511int 1512collect_wait (prog) 1513 const char *prog; 1514{ 1515 int status; 1516 1517 pwait (pexecute_pid, &status, 0); 1518 if (status) 1519 { 1520 if (WIFSIGNALED (status)) 1521 { 1522 int sig = WTERMSIG (status); 1523 error ("%s terminated with signal %d [%s]%s", 1524 prog, sig, strsignal(sig), 1525 status & 0200 ? "" : ", core dumped"); 1526 collect_exit (FATAL_EXIT_CODE); 1527 } 1528 1529 if (WIFEXITED (status)) 1530 return WEXITSTATUS (status); 1531 } 1532 return 0; 1533} 1534 1535static void 1536do_wait (prog) 1537 const char *prog; 1538{ 1539 int ret = collect_wait (prog); 1540 if (ret != 0) 1541 { 1542 error ("%s returned %d exit status", prog, ret); 1543 collect_exit (ret); 1544 } 1545} 1546 1547 1548/* Execute a program, and wait for the reply. */ 1549 1550void 1551collect_execute (prog, argv, redir) 1552 const char *prog; 1553 char **argv; 1554 const char *redir; 1555{ 1556 char *errmsg_fmt; 1557 char *errmsg_arg; 1558 int redir_handle = -1; 1559 int stdout_save = -1; 1560 int stderr_save = -1; 1561 1562 if (vflag || debug) 1563 { 1564 char **p_argv; 1565 const char *str; 1566 1567 if (argv[0]) 1568 fprintf (stderr, "%s", argv[0]); 1569 else 1570 notice ("[cannot find %s]", prog); 1571 1572 for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++) 1573 fprintf (stderr, " %s", str); 1574 1575 fprintf (stderr, "\n"); 1576 } 1577 1578 fflush (stdout); 1579 fflush (stderr); 1580 1581 /* If we cannot find a program we need, complain error. Do this here 1582 since we might not end up needing something that we could not find. */ 1583 1584 if (argv[0] == 0) 1585 fatal ("cannot find `%s'", prog); 1586 1587 if (redir) 1588 { 1589 /* Open response file. */ 1590 redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT); 1591 1592 /* Duplicate the stdout and stderr file handles 1593 so they can be restored later. */ 1594 stdout_save = dup (STDOUT_FILENO); 1595 if (stdout_save == -1) 1596 fatal_perror ("redirecting stdout: %s", redir); 1597 stderr_save = dup (STDERR_FILENO); 1598 if (stderr_save == -1) 1599 fatal_perror ("redirecting stdout: %s", redir); 1600 1601 /* Redirect stdout & stderr to our response file. */ 1602 dup2 (redir_handle, STDOUT_FILENO); 1603 dup2 (redir_handle, STDERR_FILENO); 1604 } 1605 1606 pexecute_pid = pexecute (argv[0], argv, argv[0], NULL, 1607 &errmsg_fmt, &errmsg_arg, 1608 (PEXECUTE_FIRST | PEXECUTE_LAST | PEXECUTE_SEARCH)); 1609 1610 if (redir) 1611 { 1612 /* Restore stdout and stderr to their previous settings. */ 1613 dup2 (stdout_save, STDOUT_FILENO); 1614 dup2 (stderr_save, STDERR_FILENO); 1615 1616 /* Close response file. */ 1617 close (redir_handle); 1618 } 1619 1620 if (pexecute_pid == -1) 1621 fatal_perror (errmsg_fmt, errmsg_arg); 1622} 1623 1624static void 1625fork_execute (prog, argv) 1626 const char *prog; 1627 char **argv; 1628{ 1629 collect_execute (prog, argv, NULL); 1630 do_wait (prog); 1631} 1632 1633/* Unlink a file unless we are debugging. */ 1634 1635static void 1636maybe_unlink (file) 1637 const char *file; 1638{ 1639 if (!debug) 1640 unlink (file); 1641 else 1642 notice ("[Leaving %s]\n", file); 1643} 1644 1645 1646static long sequence_number = 0; 1647 1648/* Add a name to a linked list. */ 1649 1650static void 1651add_to_list (head_ptr, name) 1652 struct head *head_ptr; 1653 const char *name; 1654{ 1655 struct id *newid 1656 = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1); 1657 struct id *p; 1658 strcpy (newid->name, name); 1659 1660 if (head_ptr->first) 1661 head_ptr->last->next = newid; 1662 else 1663 head_ptr->first = newid; 1664 1665 /* Check for duplicate symbols. */ 1666 for (p = head_ptr->first; 1667 strcmp (name, p->name) != 0; 1668 p = p->next) 1669 ; 1670 if (p != newid) 1671 { 1672 head_ptr->last->next = 0; 1673 free (newid); 1674 return; 1675 } 1676 1677 newid->sequence = ++sequence_number; 1678 head_ptr->last = newid; 1679 head_ptr->number++; 1680} 1681 1682/* Grab the init priority number from an init function name that 1683 looks like "_GLOBAL_.I.12345.foo". */ 1684 1685static int 1686extract_init_priority (name) 1687 const char *name; 1688{ 1689 int pos = 0, pri; 1690 1691 while (name[pos] == '_') 1692 ++pos; 1693 pos += 10; /* strlen ("GLOBAL__X_") */ 1694 1695 /* Extract init_p number from ctor/dtor name. */ 1696 pri = atoi (name + pos); 1697 return pri ? pri : DEFAULT_INIT_PRIORITY; 1698} 1699 1700/* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order. 1701 ctors will be run from right to left, dtors from left to right. */ 1702 1703static void 1704sort_ids (head_ptr) 1705 struct head *head_ptr; 1706{ 1707 /* id holds the current element to insert. id_next holds the next 1708 element to insert. id_ptr iterates through the already sorted elements 1709 looking for the place to insert id. */ 1710 struct id *id, *id_next, **id_ptr; 1711 1712 id = head_ptr->first; 1713 1714 /* We don't have any sorted elements yet. */ 1715 head_ptr->first = NULL; 1716 1717 for (; id; id = id_next) 1718 { 1719 id_next = id->next; 1720 id->sequence = extract_init_priority (id->name); 1721 1722 for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next)) 1723 if (*id_ptr == NULL 1724 /* If the sequence numbers are the same, we put the id from the 1725 file later on the command line later in the list. */ 1726 || id->sequence > (*id_ptr)->sequence 1727 /* Hack: do lexical compare, too. 1728 || (id->sequence == (*id_ptr)->sequence 1729 && strcmp (id->name, (*id_ptr)->name) > 0) */ 1730 ) 1731 { 1732 id->next = *id_ptr; 1733 *id_ptr = id; 1734 break; 1735 } 1736 } 1737 1738 /* Now set the sequence numbers properly so write_c_file works. */ 1739 for (id = head_ptr->first; id; id = id->next) 1740 id->sequence = ++sequence_number; 1741} 1742 1743/* Write: `prefix', the names on list LIST, `suffix'. */ 1744 1745static void 1746write_list (stream, prefix, list) 1747 FILE *stream; 1748 const char *prefix; 1749 struct id *list; 1750{ 1751 while (list) 1752 { 1753 fprintf (stream, "%sx%d,\n", prefix, list->sequence); 1754 list = list->next; 1755 } 1756} 1757 1758#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES 1759/* Given a STRING, return nonzero if it occurs in the list in range 1760 [ARGS_BEGIN,ARGS_END). */ 1761 1762static int 1763is_in_args (string, args_begin, args_end) 1764 const char *string; 1765 const char **args_begin; 1766 const char **args_end; 1767{ 1768 const char **args_pointer; 1769 for (args_pointer = args_begin; args_pointer != args_end; ++args_pointer) 1770 if (strcmp (string, *args_pointer) == 0) 1771 return 1; 1772 return 0; 1773} 1774#endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */ 1775 1776#ifdef COLLECT_EXPORT_LIST 1777/* This function is really used only on AIX, but may be useful. */ 1778#if 0 1779static int 1780is_in_list (prefix, list) 1781 const char *prefix; 1782 struct id *list; 1783{ 1784 while (list) 1785 { 1786 if (!strcmp (prefix, list->name)) return 1; 1787 list = list->next; 1788 } 1789 return 0; 1790} 1791#endif 1792#endif /* COLLECT_EXPORT_LIST */ 1793 1794/* Added for debugging purpose. */ 1795#ifdef COLLECT_EXPORT_LIST 1796static void 1797dump_list (stream, prefix, list) 1798 FILE *stream; 1799 const char *prefix; 1800 struct id *list; 1801{ 1802 while (list) 1803 { 1804 fprintf (stream, "%s%s,\n", prefix, list->name); 1805 list = list->next; 1806 } 1807} 1808#endif 1809 1810#if 0 1811static void 1812dump_prefix_list (stream, prefix, list) 1813 FILE *stream; 1814 const char *prefix; 1815 struct prefix_list *list; 1816{ 1817 while (list) 1818 { 1819 fprintf (stream, "%s%s,\n", prefix, list->prefix); 1820 list = list->next; 1821 } 1822} 1823#endif 1824 1825static void 1826write_list_with_asm (stream, prefix, list) 1827 FILE *stream; 1828 const char *prefix; 1829 struct id *list; 1830{ 1831 while (list) 1832 { 1833 fprintf (stream, "%sx%d __asm__ (\"%s\");\n", 1834 prefix, list->sequence, list->name); 1835 list = list->next; 1836 } 1837} 1838 1839/* Write out the constructor and destructor tables statically (for a shared 1840 object), along with the functions to execute them. */ 1841 1842static void 1843write_c_file_stat (stream, name) 1844 FILE *stream; 1845 const char *name ATTRIBUTE_UNUSED; 1846{ 1847 const char *p, *q; 1848 char *prefix, *r; 1849 int frames = (frame_tables.number > 0); 1850 1851 /* Figure out name of output_file, stripping off .so version. */ 1852 p = strrchr (output_file, '/'); 1853 if (p == 0) 1854 p = output_file; 1855 else 1856 p++; 1857 q = p; 1858 while (q) 1859 { 1860 q = strchr (q,'.'); 1861 if (q == 0) 1862 { 1863 q = p + strlen (p); 1864 break; 1865 } 1866 else 1867 { 1868 if (strncmp (q, ".so", 3) == 0) 1869 { 1870 q += 3; 1871 break; 1872 } 1873 else 1874 q++; 1875 } 1876 } 1877 /* q points to null at end of the string (or . of the .so version) */ 1878 prefix = xmalloc (q - p + 1); 1879 strncpy (prefix, p, q - p); 1880 prefix[q - p] = 0; 1881 for (r = prefix; *r; r++) 1882 if (!ISALNUM ((unsigned char)*r)) 1883 *r = '_'; 1884 if (debug) 1885 notice ("\nwrite_c_file - output name is %s, prefix is %s\n", 1886 output_file, prefix); 1887 1888 initname = concat ("_GLOBAL__FI_", prefix, NULL); 1889 fininame = concat ("_GLOBAL__FD_", prefix, NULL); 1890 1891 free (prefix); 1892 1893 /* Write the tables as C code */ 1894 1895 fprintf (stream, "static int count;\n"); 1896 fprintf (stream, "typedef void entry_pt();\n"); 1897 write_list_with_asm (stream, "extern entry_pt ", constructors.first); 1898 1899 if (frames) 1900 { 1901 write_list_with_asm (stream, "extern void *", frame_tables.first); 1902 1903 fprintf (stream, "\tstatic void *frame_table[] = {\n"); 1904 write_list (stream, "\t\t&", frame_tables.first); 1905 fprintf (stream, "\t0\n};\n"); 1906 1907 /* This must match what's in frame.h. */ 1908 fprintf (stream, "struct object {\n"); 1909 fprintf (stream, " void *pc_begin;\n"); 1910 fprintf (stream, " void *pc_end;\n"); 1911 fprintf (stream, " void *fde_begin;\n"); 1912 fprintf (stream, " void *fde_array;\n"); 1913 fprintf (stream, " __SIZE_TYPE__ count;\n"); 1914 fprintf (stream, " struct object *next;\n"); 1915 fprintf (stream, "};\n"); 1916 1917 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n"); 1918 fprintf (stream, "extern void *__deregister_frame_info (void *);\n"); 1919 1920 fprintf (stream, "static void reg_frame () {\n"); 1921 fprintf (stream, "\tstatic struct object ob;\n"); 1922 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n"); 1923 fprintf (stream, "\t}\n"); 1924 1925 fprintf (stream, "static void dereg_frame () {\n"); 1926 fprintf (stream, "\t__deregister_frame_info (frame_table);\n"); 1927 fprintf (stream, "\t}\n"); 1928 } 1929 1930 fprintf (stream, "void %s() {\n", initname); 1931 if (constructors.number > 0 || frames) 1932 { 1933 fprintf (stream, "\tstatic entry_pt *ctors[] = {\n"); 1934 write_list (stream, "\t\t", constructors.first); 1935 if (frames) 1936 fprintf (stream, "\treg_frame,\n"); 1937 fprintf (stream, "\t};\n"); 1938 fprintf (stream, "\tentry_pt **p;\n"); 1939 fprintf (stream, "\tif (count++ != 0) return;\n"); 1940 fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames); 1941 fprintf (stream, "\twhile (p > ctors) (*--p)();\n"); 1942 } 1943 else 1944 fprintf (stream, "\t++count;\n"); 1945 fprintf (stream, "}\n"); 1946 write_list_with_asm (stream, "extern entry_pt ", destructors.first); 1947 fprintf (stream, "void %s() {\n", fininame); 1948 if (destructors.number > 0 || frames) 1949 { 1950 fprintf (stream, "\tstatic entry_pt *dtors[] = {\n"); 1951 write_list (stream, "\t\t", destructors.first); 1952 if (frames) 1953 fprintf (stream, "\tdereg_frame,\n"); 1954 fprintf (stream, "\t};\n"); 1955 fprintf (stream, "\tentry_pt **p;\n"); 1956 fprintf (stream, "\tif (--count != 0) return;\n"); 1957 fprintf (stream, "\tp = dtors;\n"); 1958 fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n", 1959 destructors.number + frames); 1960 } 1961 fprintf (stream, "}\n"); 1962 1963 if (shared_obj) 1964 { 1965 COLLECT_SHARED_INIT_FUNC(stream, initname); 1966 COLLECT_SHARED_FINI_FUNC(stream, fininame); 1967 } 1968} 1969 1970/* Write the constructor/destructor tables. */ 1971 1972#ifndef LD_INIT_SWITCH 1973static void 1974write_c_file_glob (stream, name) 1975 FILE *stream; 1976 const char *name ATTRIBUTE_UNUSED; 1977{ 1978 /* Write the tables as C code */ 1979 1980 int frames = (frame_tables.number > 0); 1981 1982 fprintf (stream, "typedef void entry_pt();\n\n"); 1983 1984 write_list_with_asm (stream, "extern entry_pt ", constructors.first); 1985 1986 if (frames) 1987 { 1988 write_list_with_asm (stream, "extern void *", frame_tables.first); 1989 1990 fprintf (stream, "\tstatic void *frame_table[] = {\n"); 1991 write_list (stream, "\t\t&", frame_tables.first); 1992 fprintf (stream, "\t0\n};\n"); 1993 1994 /* This must match what's in frame.h. */ 1995 fprintf (stream, "struct object {\n"); 1996 fprintf (stream, " void *pc_begin;\n"); 1997 fprintf (stream, " void *pc_end;\n"); 1998 fprintf (stream, " void *fde_begin;\n"); 1999 fprintf (stream, " void *fde_array;\n"); 2000 fprintf (stream, " __SIZE_TYPE__ count;\n"); 2001 fprintf (stream, " struct object *next;\n"); 2002 fprintf (stream, "};\n"); 2003 2004 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n"); 2005 fprintf (stream, "extern void *__deregister_frame_info (void *);\n"); 2006 2007 fprintf (stream, "static void reg_frame () {\n"); 2008 fprintf (stream, "\tstatic struct object ob;\n"); 2009 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n"); 2010 fprintf (stream, "\t}\n"); 2011 2012 fprintf (stream, "static void dereg_frame () {\n"); 2013 fprintf (stream, "\t__deregister_frame_info (frame_table);\n"); 2014 fprintf (stream, "\t}\n"); 2015 } 2016 2017 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n"); 2018 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames); 2019 write_list (stream, "\t", constructors.first); 2020 if (frames) 2021 fprintf (stream, "\treg_frame,\n"); 2022 fprintf (stream, "\t0\n};\n\n"); 2023 2024 write_list_with_asm (stream, "extern entry_pt ", destructors.first); 2025 2026 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n"); 2027 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames); 2028 write_list (stream, "\t", destructors.first); 2029 if (frames) 2030 fprintf (stream, "\tdereg_frame,\n"); 2031 fprintf (stream, "\t0\n};\n\n"); 2032 2033 fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN); 2034 fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN); 2035} 2036#endif /* ! LD_INIT_SWITCH */ 2037 2038static void 2039write_c_file (stream, name) 2040 FILE *stream; 2041 const char *name; 2042{ 2043 fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n"); 2044#ifndef LD_INIT_SWITCH 2045 if (! shared_obj) 2046 write_c_file_glob (stream, name); 2047 else 2048#endif 2049 write_c_file_stat (stream, name); 2050 fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n"); 2051} 2052 2053#ifdef COLLECT_EXPORT_LIST 2054static void 2055write_aix_file (stream, list) 2056 FILE *stream; 2057 struct id *list; 2058{ 2059 for (; list; list = list->next) 2060 { 2061 fputs (list->name, stream); 2062 putc ('\n', stream); 2063 } 2064} 2065#endif 2066 2067#ifdef OBJECT_FORMAT_NONE 2068 2069/* Generic version to scan the name list of the loaded program for 2070 the symbols g++ uses for static constructors and destructors. 2071 2072 The constructor table begins at __CTOR_LIST__ and contains a count 2073 of the number of pointers (or -1 if the constructors are built in a 2074 separate section by the linker), followed by the pointers to the 2075 constructor functions, terminated with a null pointer. The 2076 destructor table has the same format, and begins at __DTOR_LIST__. */ 2077 2078static void 2079scan_prog_file (prog_name, which_pass) 2080 const char *prog_name; 2081 enum pass which_pass; 2082{ 2083 void (*int_handler) PARAMS ((int)); 2084 void (*quit_handler) PARAMS ((int)); 2085 char *real_nm_argv[4]; 2086 const char **nm_argv = (const char **) real_nm_argv; 2087 int pid; 2088 int argc = 0; 2089 int pipe_fd[2]; 2090 char *p, buf[1024]; 2091 FILE *inf; 2092 2093 if (which_pass == PASS_SECOND) 2094 return; 2095 2096 /* If we do not have an `nm', complain. */ 2097 if (nm_file_name == 0) 2098 fatal ("cannot find `nm'"); 2099 2100 nm_argv[argc++] = nm_file_name; 2101 if (NM_FLAGS[0] != '\0') 2102 nm_argv[argc++] = NM_FLAGS; 2103 2104 nm_argv[argc++] = prog_name; 2105 nm_argv[argc++] = (char *) 0; 2106 2107 if (pipe (pipe_fd) < 0) 2108 fatal_perror ("pipe"); 2109 2110 inf = fdopen (pipe_fd[0], "r"); 2111 if (inf == (FILE *) 0) 2112 fatal_perror ("fdopen"); 2113 2114 /* Trace if needed. */ 2115 if (vflag) 2116 { 2117 const char **p_argv; 2118 const char *str; 2119 2120 for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++) 2121 fprintf (stderr, " %s", str); 2122 2123 fprintf (stderr, "\n"); 2124 } 2125 2126 fflush (stdout); 2127 fflush (stderr); 2128 2129 /* Spawn child nm on pipe */ 2130 pid = vfork (); 2131 if (pid == -1) 2132 fatal_perror (VFORK_STRING); 2133 2134 if (pid == 0) /* child context */ 2135 { 2136 /* setup stdout */ 2137 if (dup2 (pipe_fd[1], 1) < 0) 2138 fatal_perror ("dup2 %d 1", pipe_fd[1]); 2139 2140 if (close (pipe_fd[0]) < 0) 2141 fatal_perror ("close %d", pipe_fd[0]); 2142 2143 if (close (pipe_fd[1]) < 0) 2144 fatal_perror ("close %d", pipe_fd[1]); 2145 2146 execv (nm_file_name, real_nm_argv); 2147 fatal_perror ("execvp %s", nm_file_name); 2148 } 2149 2150 /* Parent context from here on. */ 2151 int_handler = (void (*) PARAMS ((int))) signal (SIGINT, SIG_IGN); 2152#ifdef SIGQUIT 2153 quit_handler = (void (*) PARAMS ((int))) signal (SIGQUIT, SIG_IGN); 2154#endif 2155 2156 if (close (pipe_fd[1]) < 0) 2157 fatal_perror ("close %d", pipe_fd[1]); 2158 2159 if (debug) 2160 fprintf (stderr, "\nnm output with constructors/destructors.\n"); 2161 2162 /* Read each line of nm output. */ 2163 while (fgets (buf, sizeof buf, inf) != (char *) 0) 2164 { 2165 int ch, ch2; 2166 char *name, *end; 2167 2168 /* If it contains a constructor or destructor name, add the name 2169 to the appropriate list. */ 2170 2171 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++) 2172 if (ch == ' ' && p[1] == 'U' && p[2] == ' ') 2173 break; 2174 2175 if (ch != '_') 2176 continue; 2177 2178 name = p; 2179 /* Find the end of the symbol name. 2180 Do not include `|', because Encore nm can tack that on the end. */ 2181 for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|'; 2182 end++) 2183 continue; 2184 2185 2186 *end = '\0'; 2187 switch (is_ctor_dtor (name)) 2188 { 2189 case 1: 2190 if (which_pass != PASS_LIB) 2191 add_to_list (&constructors, name); 2192 break; 2193 2194 case 2: 2195 if (which_pass != PASS_LIB) 2196 add_to_list (&destructors, name); 2197 break; 2198 2199 case 3: 2200 if (which_pass != PASS_LIB) 2201 fatal ("init function found in object %s", prog_name); 2202#ifndef LD_INIT_SWITCH 2203 add_to_list (&constructors, name); 2204#endif 2205 break; 2206 2207 case 4: 2208 if (which_pass != PASS_LIB) 2209 fatal ("fini function found in object %s", prog_name); 2210#ifndef LD_FINI_SWITCH 2211 add_to_list (&destructors, name); 2212#endif 2213 break; 2214 2215 case 5: 2216 if (which_pass != PASS_LIB) 2217 add_to_list (&frame_tables, name); 2218 break; 2219 2220 default: /* not a constructor or destructor */ 2221 continue; 2222 } 2223 2224 if (debug) 2225 fprintf (stderr, "\t%s\n", buf); 2226 } 2227 2228 if (debug) 2229 fprintf (stderr, "\n"); 2230 2231 if (fclose (inf) != 0) 2232 fatal_perror ("fclose"); 2233 2234 do_wait (nm_file_name); 2235 2236 signal (SIGINT, int_handler); 2237#ifdef SIGQUIT 2238 signal (SIGQUIT, quit_handler); 2239#endif 2240} 2241 2242#if SUNOS4_SHARED_LIBRARIES 2243 2244/* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries 2245 that the output file depends upon and their initialization/finalization 2246 routines, if any. */ 2247 2248#include <a.out.h> 2249#include <fcntl.h> 2250#include <link.h> 2251#include <sys/mman.h> 2252#include <sys/param.h> 2253#include <unistd.h> 2254#include <sys/dir.h> 2255 2256/* pointers to the object file */ 2257unsigned object; /* address of memory mapped file */ 2258unsigned objsize; /* size of memory mapped to file */ 2259char * code; /* pointer to code segment */ 2260char * data; /* pointer to data segment */ 2261struct nlist *symtab; /* pointer to symbol table */ 2262struct link_dynamic *ld; 2263struct link_dynamic_2 *ld_2; 2264struct head libraries; 2265 2266/* Map the file indicated by NAME into memory and store its address. */ 2267 2268static void mapfile PARAMS ((const char *)); 2269 2270static void 2271mapfile (name) 2272 const char *name; 2273{ 2274 int fp; 2275 struct stat s; 2276 if ((fp = open (name, O_RDONLY)) == -1) 2277 fatal ("unable to open file '%s'", name); 2278 if (fstat (fp, &s) == -1) 2279 fatal ("unable to stat file '%s'", name); 2280 2281 objsize = s.st_size; 2282 object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE, 2283 fp, 0); 2284 if (object == (unsigned)-1) 2285 fatal ("unable to mmap file '%s'", name); 2286 2287 close (fp); 2288} 2289 2290/* Helpers for locatelib. */ 2291 2292static const char *libname; 2293 2294static int libselect PARAMS ((struct direct *)); 2295 2296static int 2297libselect (d) 2298 struct direct *d; 2299{ 2300 return (strncmp (libname, d->d_name, strlen (libname)) == 0); 2301} 2302 2303/* If one file has an additional numeric extension past LIBNAME, then put 2304 that one first in the sort. If both files have additional numeric 2305 extensions, then put the one with the higher number first in the sort. 2306 2307 We must verify that the extension is numeric, because Sun saves the 2308 original versions of patched libraries with a .FCS extension. Files with 2309 invalid extensions must go last in the sort, so that they will not be used. */ 2310static int libcompare PARAMS ((struct direct **, struct direct **)); 2311 2312static int 2313libcompare (d1, d2) 2314 struct direct **d1, **d2; 2315{ 2316 int i1, i2 = strlen (libname); 2317 char *e1 = (*d1)->d_name + i2; 2318 char *e2 = (*d2)->d_name + i2; 2319 2320 while (*e1 && *e2 && *e1 == '.' && *e2 == '.' 2321 && e1[1] && ISDIGIT (e1[1]) && e2[1] && ISDIGIT (e2[1])) 2322 { 2323 ++e1; 2324 ++e2; 2325 i1 = strtol (e1, &e1, 10); 2326 i2 = strtol (e2, &e2, 10); 2327 if (i1 != i2) 2328 return i1 - i2; 2329 } 2330 2331 if (*e1) 2332 { 2333 /* It has a valid numeric extension, prefer this one. */ 2334 if (*e1 == '.' && e1[1] && ISDIGIT (e1[1])) 2335 return 1; 2336 /* It has an invalid numeric extension, must prefer the other one. */ 2337 else 2338 return -1; 2339 } 2340 else if (*e2) 2341 { 2342 /* It has a valid numeric extension, prefer this one. */ 2343 if (*e2 == '.' && e2[1] && ISDIGIT (e2[1])) 2344 return -1; 2345 /* It has an invalid numeric extension, must prefer the other one. */ 2346 else 2347 return 1; 2348 } 2349 else 2350 return 0; 2351} 2352 2353/* Given the name NAME of a dynamic dependency, find its pathname and add 2354 it to the list of libraries. */ 2355static void locatelib PARAMS ((const char *)); 2356 2357static void 2358locatelib (name) 2359 const char *name; 2360{ 2361 static const char **l; 2362 static int cnt; 2363 char buf[MAXPATHLEN]; 2364 char *p, *q; 2365 const char **pp; 2366 2367 if (l == 0) 2368 { 2369 char *ld_rules; 2370 char *ldr = 0; 2371 /* counting elements in array, need 1 extra for null */ 2372 cnt = 1; 2373 ld_rules = (char *) (ld_2->ld_rules + code); 2374 if (ld_rules) 2375 { 2376 cnt++; 2377 for (; *ld_rules != 0; ld_rules++) 2378 if (*ld_rules == ':') 2379 cnt++; 2380 ld_rules = (char *) (ld_2->ld_rules + code); 2381 ldr = xstrdup (ld_rules); 2382 } 2383 p = getenv ("LD_LIBRARY_PATH"); 2384 q = 0; 2385 if (p) 2386 { 2387 cnt++; 2388 for (q = p ; *q != 0; q++) 2389 if (*q == ':') 2390 cnt++; 2391 q = xstrdup (p); 2392 } 2393 l = (const char **) xmalloc ((cnt + 3) * sizeof (char *)); 2394 pp = l; 2395 if (ldr) 2396 { 2397 *pp++ = ldr; 2398 for (; *ldr != 0; ldr++) 2399 if (*ldr == ':') 2400 { 2401 *ldr++ = 0; 2402 *pp++ = ldr; 2403 } 2404 } 2405 if (q) 2406 { 2407 *pp++ = q; 2408 for (; *q != 0; q++) 2409 if (*q == ':') 2410 { 2411 *q++ = 0; 2412 *pp++ = q; 2413 } 2414 } 2415 /* built in directories are /lib, /usr/lib, and /usr/local/lib */ 2416 *pp++ = "/lib"; 2417 *pp++ = "/usr/lib"; 2418 *pp++ = "/usr/local/lib"; 2419 *pp = 0; 2420 } 2421 libname = name; 2422 for (pp = l; *pp != 0 ; pp++) 2423 { 2424 struct direct **namelist; 2425 int entries; 2426 if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0) 2427 { 2428 sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name); 2429 add_to_list (&libraries, buf); 2430 if (debug) 2431 fprintf (stderr, "%s\n", buf); 2432 break; 2433 } 2434 } 2435 if (*pp == 0) 2436 { 2437 if (debug) 2438 notice ("not found\n"); 2439 else 2440 fatal ("dynamic dependency %s not found", name); 2441 } 2442} 2443 2444/* Scan the _DYNAMIC structure of the output file to find shared libraries 2445 that it depends upon and any constructors or destructors they contain. */ 2446 2447static void 2448scan_libraries (prog_name) 2449 const char *prog_name; 2450{ 2451 struct exec *header; 2452 char *base; 2453 struct link_object *lo; 2454 char buff[MAXPATHLEN]; 2455 struct id *list; 2456 2457 mapfile (prog_name); 2458 header = (struct exec *)object; 2459 if (N_BADMAG (*header)) 2460 fatal ("bad magic number in file '%s'", prog_name); 2461 if (header->a_dynamic == 0) 2462 return; 2463 2464 code = (char *) (N_TXTOFF (*header) + (long) header); 2465 data = (char *) (N_DATOFF (*header) + (long) header); 2466 symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header); 2467 2468 if (header->a_magic == ZMAGIC && header->a_entry == 0x20) 2469 { 2470 /* shared object */ 2471 ld = (struct link_dynamic *) (symtab->n_value + code); 2472 base = code; 2473 } 2474 else 2475 { 2476 /* executable */ 2477 ld = (struct link_dynamic *) data; 2478 base = code-PAGSIZ; 2479 } 2480 2481 if (debug) 2482 notice ("dynamic dependencies.\n"); 2483 2484 ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base); 2485 for (lo = (struct link_object *) ld_2->ld_need; lo; 2486 lo = (struct link_object *) lo->lo_next) 2487 { 2488 char *name; 2489 lo = (struct link_object *) ((long) lo + code); 2490 name = (char *) (code + lo->lo_name); 2491 if (lo->lo_library) 2492 { 2493 if (debug) 2494 fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major); 2495 sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor); 2496 locatelib (buff); 2497 } 2498 else 2499 { 2500 if (debug) 2501 fprintf (stderr, "\t%s\n", name); 2502 add_to_list (&libraries, name); 2503 } 2504 } 2505 2506 if (debug) 2507 fprintf (stderr, "\n"); 2508 2509 /* now iterate through the library list adding their symbols to 2510 the list. */ 2511 for (list = libraries.first; list; list = list->next) 2512 scan_prog_file (list->name, PASS_LIB); 2513} 2514 2515#else /* SUNOS4_SHARED_LIBRARIES */ 2516#ifdef LDD_SUFFIX 2517 2518/* Use the List Dynamic Dependencies program to find shared libraries that 2519 the output file depends upon and their initialization/finalization 2520 routines, if any. */ 2521 2522static void 2523scan_libraries (prog_name) 2524 const char *prog_name; 2525{ 2526 static struct head libraries; /* list of shared libraries found */ 2527 struct id *list; 2528 void (*int_handler) PARAMS ((int)); 2529 void (*quit_handler) PARAMS ((int)); 2530 char *real_ldd_argv[4]; 2531 const char **ldd_argv = (const char **) real_ldd_argv; 2532 int pid; 2533 int argc = 0; 2534 int pipe_fd[2]; 2535 char buf[1024]; 2536 FILE *inf; 2537 2538 /* If we do not have an `ldd', complain. */ 2539 if (ldd_file_name == 0) 2540 { 2541 error ("cannot find `ldd'"); 2542 return; 2543 } 2544 2545 ldd_argv[argc++] = ldd_file_name; 2546 ldd_argv[argc++] = prog_name; 2547 ldd_argv[argc++] = (char *) 0; 2548 2549 if (pipe (pipe_fd) < 0) 2550 fatal_perror ("pipe"); 2551 2552 inf = fdopen (pipe_fd[0], "r"); 2553 if (inf == (FILE *) 0) 2554 fatal_perror ("fdopen"); 2555 2556 /* Trace if needed. */ 2557 if (vflag) 2558 { 2559 const char **p_argv; 2560 const char *str; 2561 2562 for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++) 2563 fprintf (stderr, " %s", str); 2564 2565 fprintf (stderr, "\n"); 2566 } 2567 2568 fflush (stdout); 2569 fflush (stderr); 2570 2571 /* Spawn child ldd on pipe */ 2572 pid = vfork (); 2573 if (pid == -1) 2574 fatal_perror (VFORK_STRING); 2575 2576 if (pid == 0) /* child context */ 2577 { 2578 /* setup stdout */ 2579 if (dup2 (pipe_fd[1], 1) < 0) 2580 fatal_perror ("dup2 %d 1", pipe_fd[1]); 2581 2582 if (close (pipe_fd[0]) < 0) 2583 fatal_perror ("close %d", pipe_fd[0]); 2584 2585 if (close (pipe_fd[1]) < 0) 2586 fatal_perror ("close %d", pipe_fd[1]); 2587 2588 execv (ldd_file_name, real_ldd_argv); 2589 fatal_perror ("execv %s", ldd_file_name); 2590 } 2591 2592 /* Parent context from here on. */ 2593 int_handler = (void (*) PARAMS ((int))) signal (SIGINT, SIG_IGN); 2594#ifdef SIGQUIT 2595 quit_handler = (void (*) PARAMS ((int))) signal (SIGQUIT, SIG_IGN); 2596#endif 2597 2598 if (close (pipe_fd[1]) < 0) 2599 fatal_perror ("close %d", pipe_fd[1]); 2600 2601 if (debug) 2602 notice ("\nldd output with constructors/destructors.\n"); 2603 2604 /* Read each line of ldd output. */ 2605 while (fgets (buf, sizeof buf, inf) != (char *) 0) 2606 { 2607 int ch2; 2608 char *name, *end, *p = buf; 2609 2610 /* Extract names of libraries and add to list. */ 2611 PARSE_LDD_OUTPUT (p); 2612 if (p == 0) 2613 continue; 2614 2615 name = p; 2616 if (strncmp (name, "not found", sizeof ("not found") - 1) == 0) 2617 fatal ("dynamic dependency %s not found", buf); 2618 2619 /* Find the end of the symbol name. */ 2620 for (end = p; 2621 (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|'; 2622 end++) 2623 continue; 2624 *end = '\0'; 2625 2626 if (access (name, R_OK) == 0) 2627 add_to_list (&libraries, name); 2628 else 2629 fatal ("unable to open dynamic dependency '%s'", buf); 2630 2631 if (debug) 2632 fprintf (stderr, "\t%s\n", buf); 2633 } 2634 if (debug) 2635 fprintf (stderr, "\n"); 2636 2637 if (fclose (inf) != 0) 2638 fatal_perror ("fclose"); 2639 2640 do_wait (ldd_file_name); 2641 2642 signal (SIGINT, int_handler); 2643#ifdef SIGQUIT 2644 signal (SIGQUIT, quit_handler); 2645#endif 2646 2647 /* now iterate through the library list adding their symbols to 2648 the list. */ 2649 for (list = libraries.first; list; list = list->next) 2650 scan_prog_file (list->name, PASS_LIB); 2651} 2652 2653#endif /* LDD_SUFFIX */ 2654#endif /* SUNOS4_SHARED_LIBRARIES */ 2655 2656#endif /* OBJECT_FORMAT_NONE */ 2657 2658 2659/* 2660 * COFF specific stuff. 2661 */ 2662 2663#ifdef OBJECT_FORMAT_COFF 2664 2665#if defined(EXTENDED_COFF) 2666 2667# define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax) 2668# define GCC_SYMENT SYMR 2669# define GCC_OK_SYMBOL(X) ((X).st == stProc || (X).st == stGlobal) 2670# define GCC_SYMINC(X) (1) 2671# define GCC_SYMZERO(X) (SYMHEADER(X).isymMax) 2672# define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0) 2673 2674#else 2675 2676# define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms) 2677# define GCC_SYMENT SYMENT 2678# define GCC_OK_SYMBOL(X) \ 2679 (((X).n_sclass == C_EXT) && \ 2680 ((X).n_scnum > N_UNDEF) && \ 2681 (aix64_flag \ 2682 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \ 2683 || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))) 2684# define GCC_UNDEF_SYMBOL(X) \ 2685 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF)) 2686# define GCC_SYMINC(X) ((X).n_numaux+1) 2687# define GCC_SYMZERO(X) 0 2688 2689/* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */ 2690#ifdef _AIX51 2691# define GCC_CHECK_HDR(X) \ 2692 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \ 2693 || (HEADER (X).f_magic == 0767 && aix64_flag)) 2694#else 2695# define GCC_CHECK_HDR(X) \ 2696 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \ 2697 || (HEADER (X).f_magic == 0757 && aix64_flag)) 2698#endif 2699 2700#endif 2701 2702extern char *ldgetname (); 2703 2704/* COFF version to scan the name list of the loaded program for 2705 the symbols g++ uses for static constructors and destructors. 2706 2707 The constructor table begins at __CTOR_LIST__ and contains a count 2708 of the number of pointers (or -1 if the constructors are built in a 2709 separate section by the linker), followed by the pointers to the 2710 constructor functions, terminated with a null pointer. The 2711 destructor table has the same format, and begins at __DTOR_LIST__. */ 2712 2713static void 2714scan_prog_file (prog_name, which_pass) 2715 const char *prog_name; 2716 enum pass which_pass; 2717{ 2718 LDFILE *ldptr = NULL; 2719 int sym_index, sym_count; 2720 int is_shared = 0; 2721 2722 if (which_pass != PASS_FIRST && which_pass != PASS_OBJ) 2723 return; 2724 2725#ifdef COLLECT_EXPORT_LIST 2726 /* We do not need scanning for some standard C libraries. */ 2727 if (which_pass == PASS_FIRST && ignore_library (prog_name)) 2728 return; 2729 2730 /* On AIX we have a loop, because there is not much difference 2731 between an object and an archive. This trick allows us to 2732 eliminate scan_libraries() function. */ 2733 do 2734 { 2735#endif 2736 /* Some platforms (e.g. OSF4) declare ldopen as taking a 2737 non-const char * filename parameter, even though it will not 2738 modify that string. So we must cast away const-ness here, 2739 which will cause -Wcast-qual to burp. */ 2740 if ((ldptr = ldopen ((char *)prog_name, ldptr)) != NULL) 2741 { 2742 if (! MY_ISCOFF (HEADER (ldptr).f_magic)) 2743 fatal ("%s: not a COFF file", prog_name); 2744 2745 if (GCC_CHECK_HDR (ldptr)) 2746 { 2747 sym_count = GCC_SYMBOLS (ldptr); 2748 sym_index = GCC_SYMZERO (ldptr); 2749 2750#ifdef COLLECT_EXPORT_LIST 2751 /* Is current archive member a shared object? */ 2752 is_shared = HEADER (ldptr).f_flags & F_SHROBJ; 2753#endif 2754 2755 while (sym_index < sym_count) 2756 { 2757 GCC_SYMENT symbol; 2758 2759 if (ldtbread (ldptr, sym_index, &symbol) <= 0) 2760 break; 2761 sym_index += GCC_SYMINC (symbol); 2762 2763 if (GCC_OK_SYMBOL (symbol)) 2764 { 2765 char *name; 2766 2767 if ((name = ldgetname (ldptr, &symbol)) == NULL) 2768 continue; /* should never happen */ 2769 2770#ifdef XCOFF_DEBUGGING_INFO 2771 /* All AIX function names have a duplicate entry 2772 beginning with a dot. */ 2773 if (*name == '.') 2774 ++name; 2775#endif 2776 2777 switch (is_ctor_dtor (name)) 2778 { 2779 case 1: 2780 if (! is_shared) 2781 add_to_list (&constructors, name); 2782#ifdef COLLECT_EXPORT_LIST 2783 if (which_pass == PASS_OBJ) 2784 add_to_list (&exports, name); 2785#endif 2786 break; 2787 2788 case 2: 2789 if (! is_shared) 2790 add_to_list (&destructors, name); 2791#ifdef COLLECT_EXPORT_LIST 2792 if (which_pass == PASS_OBJ) 2793 add_to_list (&exports, name); 2794#endif 2795 break; 2796 2797#ifdef COLLECT_EXPORT_LIST 2798 case 3: 2799#ifndef LD_INIT_SWITCH 2800 if (is_shared) 2801 add_to_list (&constructors, name); 2802#endif 2803 break; 2804 2805 case 4: 2806#ifndef LD_INIT_SWITCH 2807 if (is_shared) 2808 add_to_list (&destructors, name); 2809#endif 2810 break; 2811#endif 2812 2813 case 5: 2814 if (! is_shared) 2815 add_to_list (&frame_tables, name); 2816#ifdef COLLECT_EXPORT_LIST 2817 if (which_pass == PASS_OBJ) 2818 add_to_list (&exports, name); 2819#endif 2820 break; 2821 2822 default: /* not a constructor or destructor */ 2823#ifdef COLLECT_EXPORT_LIST 2824 /* If we are building a shared object on AIX we need 2825 to explicitly export all global symbols. */ 2826 if (shared_obj) 2827 { 2828 if (which_pass == PASS_OBJ && (! export_flag)) 2829 add_to_list (&exports, name); 2830 } 2831#endif 2832 continue; 2833 } 2834 2835 if (debug) 2836#if !defined(EXTENDED_COFF) 2837 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n", 2838 symbol.n_scnum, symbol.n_sclass, 2839 (symbol.n_type ? "0" : ""), symbol.n_type, 2840 name); 2841#else 2842 fprintf (stderr, 2843 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n", 2844 symbol.iss, (long) symbol.value, symbol.index, name); 2845#endif 2846 } 2847 } 2848 } 2849#ifdef COLLECT_EXPORT_LIST 2850 else 2851 { 2852 /* If archive contains both 32-bit and 64-bit objects, 2853 we want to skip objects in other mode so mismatch normal. */ 2854 if (debug) 2855 fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n", 2856 prog_name, HEADER (ldptr).f_magic, aix64_flag); 2857 } 2858#endif 2859 } 2860 else 2861 { 2862 fatal ("%s: cannot open as COFF file", prog_name); 2863 } 2864#ifdef COLLECT_EXPORT_LIST 2865 /* On AIX loop continues while there are more members in archive. */ 2866 } 2867 while (ldclose (ldptr) == FAILURE); 2868#else 2869 /* Otherwise we simply close ldptr. */ 2870 (void) ldclose(ldptr); 2871#endif 2872} 2873 2874 2875#ifdef COLLECT_EXPORT_LIST 2876/* Given a library name without "lib" prefix, this function 2877 returns a full library name including a path. */ 2878static char * 2879resolve_lib_name (name) 2880 const char *name; 2881{ 2882 char *lib_buf; 2883 int i, j, l = 0; 2884 2885 for (i = 0; libpaths[i]; i++) 2886 if (libpaths[i]->max_len > l) 2887 l = libpaths[i]->max_len; 2888 2889 lib_buf = xmalloc (l + strlen(name) + 10); 2890 2891 for (i = 0; libpaths[i]; i++) 2892 { 2893 struct prefix_list *list = libpaths[i]->plist; 2894 for (; list; list = list->next) 2895 { 2896 /* The following lines are needed because path_prefix list 2897 may contain directories both with trailing '/' and 2898 without it. */ 2899 const char *p = ""; 2900 if (list->prefix[strlen(list->prefix)-1] != '/') 2901 p = "/"; 2902 for (j = 0; libexts[j]; j++) 2903 { 2904 sprintf (lib_buf, "%s%slib%s.%s", 2905 list->prefix, p, name, libexts[j]); 2906if (debug) fprintf (stderr, "searching for: %s\n", lib_buf); 2907 if (file_exists (lib_buf)) 2908 { 2909if (debug) fprintf (stderr, "found: %s\n", lib_buf); 2910 return (lib_buf); 2911 } 2912 } 2913 } 2914 } 2915 if (debug) 2916 fprintf (stderr, "not found\n"); 2917 else 2918 fatal ("library lib%s not found", name); 2919 return (NULL); 2920} 2921 2922/* Array of standard AIX libraries which should not 2923 be scanned for ctors/dtors. */ 2924static const char *const aix_std_libs[] = { 2925 "/unix", 2926 "/lib/libc.a", 2927 "/lib/libm.a", 2928 "/lib/libc_r.a", 2929 "/lib/libm_r.a", 2930 "/usr/lib/libc.a", 2931 "/usr/lib/libm.a", 2932 "/usr/lib/libc_r.a", 2933 "/usr/lib/libm_r.a", 2934 "/usr/lib/threads/libc.a", 2935 "/usr/ccs/lib/libc.a", 2936 "/usr/ccs/lib/libm.a", 2937 "/usr/ccs/lib/libc_r.a", 2938 "/usr/ccs/lib/libm_r.a", 2939 NULL 2940}; 2941 2942/* This function checks the filename and returns 1 2943 if this name matches the location of a standard AIX library. */ 2944static int 2945ignore_library (name) 2946 const char *name; 2947{ 2948 const char *const *p = &aix_std_libs[0]; 2949 while (*p++ != NULL) 2950 if (! strcmp (name, *p)) return 1; 2951 return 0; 2952} 2953#endif 2954 2955#endif /* OBJECT_FORMAT_COFF */ 2956 2957 2958/* 2959 * OSF/rose specific stuff. 2960 */ 2961 2962#ifdef OBJECT_FORMAT_ROSE 2963 2964/* Union of the various load commands */ 2965 2966typedef union load_union 2967{ 2968 ldc_header_t hdr; /* common header */ 2969 load_cmd_map_command_t map; /* map indexing other load cmds */ 2970 interpreter_command_t iprtr; /* interpreter pathname */ 2971 strings_command_t str; /* load commands strings section */ 2972 region_command_t region; /* region load command */ 2973 reloc_command_t reloc; /* relocation section */ 2974 package_command_t pkg; /* package load command */ 2975 symbols_command_t sym; /* symbol sections */ 2976 entry_command_t ent; /* program start section */ 2977 gen_info_command_t info; /* object information */ 2978 func_table_command_t func; /* function constructors/destructors */ 2979} load_union_t; 2980 2981/* Structure to point to load command and data section in memory. */ 2982 2983typedef struct load_all 2984{ 2985 load_union_t *load; /* load command */ 2986 char *section; /* pointer to section */ 2987} load_all_t; 2988 2989/* Structure to contain information about a file mapped into memory. */ 2990 2991struct file_info 2992{ 2993 char *start; /* start of map */ 2994 char *name; /* filename */ 2995 long size; /* size of the file */ 2996 long rounded_size; /* size rounded to page boundary */ 2997 int fd; /* file descriptor */ 2998 int rw; /* != 0 if opened read/write */ 2999 int use_mmap; /* != 0 if mmap'ed */ 3000}; 3001 3002extern int decode_mach_o_hdr (); 3003extern int encode_mach_o_hdr (); 3004 3005static void add_func_table PARAMS ((mo_header_t *, load_all_t *, 3006 symbol_info_t *, int)); 3007static void print_header PARAMS ((mo_header_t *)); 3008static void print_load_command PARAMS ((load_union_t *, size_t, int)); 3009static void bad_header PARAMS ((int)); 3010static struct file_info *read_file PARAMS ((const char *, int, int)); 3011static void end_file PARAMS ((struct file_info *)); 3012 3013/* OSF/rose specific version to scan the name list of the loaded 3014 program for the symbols g++ uses for static constructors and 3015 destructors. 3016 3017 The constructor table begins at __CTOR_LIST__ and contains a count 3018 of the number of pointers (or -1 if the constructors are built in a 3019 separate section by the linker), followed by the pointers to the 3020 constructor functions, terminated with a null pointer. The 3021 destructor table has the same format, and begins at __DTOR_LIST__. */ 3022 3023static void 3024scan_prog_file (prog_name, which_pass) 3025 const char *prog_name; 3026 enum pass which_pass; 3027{ 3028 char *obj; 3029 mo_header_t hdr; 3030 load_all_t *load_array; 3031 load_all_t *load_end; 3032 load_all_t *load_cmd; 3033 int symbol_load_cmds; 3034 off_t offset; 3035 int i; 3036 int num_syms; 3037 int status; 3038 char *str_sect; 3039 struct file_info *obj_file; 3040 int prog_fd; 3041 mo_lcid_t cmd_strings = -1; 3042 symbol_info_t *main_sym = 0; 3043 int rw = (which_pass != PASS_FIRST); 3044 3045 prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY); 3046 if (prog_fd < 0) 3047 fatal_perror ("open %s", prog_name); 3048 3049 obj_file = read_file (prog_name, prog_fd, rw); 3050 obj = obj_file->start; 3051 3052 status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr); 3053 if (status != MO_HDR_CONV_SUCCESS) 3054 bad_header (status); 3055 3056 3057 /* Do some basic sanity checks. Note we explicitly use the big endian magic number, 3058 since the hardware will automatically swap bytes for us on loading little endian 3059 integers. */ 3060 3061#ifndef CROSS_COMPILE 3062 if (hdr.moh_magic != MOH_MAGIC_MSB 3063 || hdr.moh_header_version != MOH_HEADER_VERSION 3064 || hdr.moh_byte_order != OUR_BYTE_ORDER 3065 || hdr.moh_data_rep_id != OUR_DATA_REP_ID 3066 || hdr.moh_cpu_type != OUR_CPU_TYPE 3067 || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE 3068 || hdr.moh_vendor_type != OUR_VENDOR_TYPE) 3069 { 3070 fatal ("incompatibilities between object file & expected values"); 3071 } 3072#endif 3073 3074 if (debug) 3075 print_header (&hdr); 3076 3077 offset = hdr.moh_first_cmd_off; 3078 load_end = load_array 3079 = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2); 3080 3081 /* Build array of load commands, calculating the offsets */ 3082 for (i = 0; i < hdr.moh_n_load_cmds; i++) 3083 { 3084 load_union_t *load_hdr; /* load command header */ 3085 3086 load_cmd = load_end++; 3087 load_hdr = (load_union_t *) (obj + offset); 3088 3089 /* If modifying the program file, copy the header. */ 3090 if (rw) 3091 { 3092 load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size); 3093 memcpy ((char *)ptr, (char *)load_hdr, load_hdr->hdr.ldci_cmd_size); 3094 load_hdr = ptr; 3095 3096 /* null out old command map, because we will rewrite at the end. */ 3097 if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP) 3098 { 3099 cmd_strings = ptr->map.lcm_ld_cmd_strings; 3100 ptr->hdr.ldci_cmd_type = LDC_UNDEFINED; 3101 } 3102 } 3103 3104 load_cmd->load = load_hdr; 3105 if (load_hdr->hdr.ldci_section_off > 0) 3106 load_cmd->section = obj + load_hdr->hdr.ldci_section_off; 3107 3108 if (debug) 3109 print_load_command (load_hdr, offset, i); 3110 3111 offset += load_hdr->hdr.ldci_cmd_size; 3112 } 3113 3114 /* If the last command is the load command map and is not undefined, 3115 decrement the count of load commands. */ 3116 if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED) 3117 { 3118 load_end--; 3119 hdr.moh_n_load_cmds--; 3120 } 3121 3122 /* Go through and process each symbol table section. */ 3123 symbol_load_cmds = 0; 3124 for (load_cmd = load_array; load_cmd < load_end; load_cmd++) 3125 { 3126 load_union_t *load_hdr = load_cmd->load; 3127 3128 if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS) 3129 { 3130 symbol_load_cmds++; 3131 3132 if (debug) 3133 { 3134 const char *kind = "unknown"; 3135 3136 switch (load_hdr->sym.symc_kind) 3137 { 3138 case SYMC_IMPORTS: kind = "imports"; break; 3139 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break; 3140 case SYMC_STABS: kind = "stabs"; break; 3141 } 3142 3143 notice ("\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n", 3144 symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind); 3145 } 3146 3147 if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS) 3148 continue; 3149 3150 str_sect = load_array[load_hdr->sym.symc_strings_section].section; 3151 if (str_sect == (char *) 0) 3152 fatal ("string section missing"); 3153 3154 if (load_cmd->section == (char *) 0) 3155 fatal ("section pointer missing"); 3156 3157 num_syms = load_hdr->sym.symc_nentries; 3158 for (i = 0; i < num_syms; i++) 3159 { 3160 symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i; 3161 char *name = sym->si_name.symbol_name + str_sect; 3162 3163 if (name[0] != '_') 3164 continue; 3165 3166 if (rw) 3167 { 3168 char *n = name + strlen (name) - strlen (NAME__MAIN); 3169 3170 if ((n - name) < 0 || strcmp (n, NAME__MAIN)) 3171 continue; 3172 while (n != name) 3173 if (*--n != '_') 3174 continue; 3175 3176 main_sym = sym; 3177 } 3178 else 3179 { 3180 switch (is_ctor_dtor (name)) 3181 { 3182 case 1: 3183 add_to_list (&constructors, name); 3184 break; 3185 3186 case 2: 3187 add_to_list (&destructors, name); 3188 break; 3189 3190 default: /* not a constructor or destructor */ 3191 continue; 3192 } 3193 } 3194 3195 if (debug) 3196 fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n", 3197 sym->si_type, sym->si_sc_type, sym->si_flags, name); 3198 } 3199 } 3200 } 3201 3202 if (symbol_load_cmds == 0) 3203 fatal ("no symbol table found"); 3204 3205 /* Update the program file now, rewrite header and load commands. At present, 3206 we assume that there is enough space after the last load command to insert 3207 one more. Since the first section written out is page aligned, and the 3208 number of load commands is small, this is ok for the present. */ 3209 3210 if (rw) 3211 { 3212 load_union_t *load_map; 3213 size_t size; 3214 3215 if (cmd_strings == -1) 3216 fatal ("no cmd_strings found"); 3217 3218 /* Add __main to initializer list. 3219 If we are building a program instead of a shared library, do not 3220 do anything, since in the current version, you cannot do mallocs 3221 and such in the constructors. */ 3222 3223 if (main_sym != (symbol_info_t *) 0 3224 && ((hdr.moh_flags & MOH_EXECABLE_F) == 0)) 3225 add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION); 3226 3227 if (debug) 3228 notice ("\nUpdating header and load commands.\n\n"); 3229 3230 hdr.moh_n_load_cmds++; 3231 size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1)); 3232 3233 /* Create new load command map. */ 3234 if (debug) 3235 notice ("load command map, %d cmds, new size %ld.\n", 3236 (int) hdr.moh_n_load_cmds, (long) size); 3237 3238 load_map = (load_union_t *) xcalloc (1, size); 3239 load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP; 3240 load_map->map.ldc_header.ldci_cmd_size = size; 3241 load_map->map.lcm_ld_cmd_strings = cmd_strings; 3242 load_map->map.lcm_nentries = hdr.moh_n_load_cmds; 3243 load_array[hdr.moh_n_load_cmds-1].load = load_map; 3244 3245 offset = hdr.moh_first_cmd_off; 3246 for (i = 0; i < hdr.moh_n_load_cmds; i++) 3247 { 3248 load_map->map.lcm_map[i] = offset; 3249 if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP) 3250 hdr.moh_load_map_cmd_off = offset; 3251 3252 offset += load_array[i].load->hdr.ldci_cmd_size; 3253 } 3254 3255 hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR; 3256 3257 if (debug) 3258 print_header (&hdr); 3259 3260 /* Write header */ 3261 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR); 3262 if (status != MO_HDR_CONV_SUCCESS) 3263 bad_header (status); 3264 3265 if (debug) 3266 notice ("writing load commands.\n\n"); 3267 3268 /* Write load commands */ 3269 offset = hdr.moh_first_cmd_off; 3270 for (i = 0; i < hdr.moh_n_load_cmds; i++) 3271 { 3272 load_union_t *load_hdr = load_array[i].load; 3273 size_t size = load_hdr->hdr.ldci_cmd_size; 3274 3275 if (debug) 3276 print_load_command (load_hdr, offset, i); 3277 3278 bcopy ((char *) load_hdr, (char *) (obj + offset), size); 3279 offset += size; 3280 } 3281 } 3282 3283 end_file (obj_file); 3284 3285 if (close (prog_fd)) 3286 fatal_perror ("close %s", prog_name); 3287 3288 if (debug) 3289 fprintf (stderr, "\n"); 3290} 3291 3292 3293/* Add a function table to the load commands to call a function 3294 on initiation or termination of the process. */ 3295 3296static void 3297add_func_table (hdr_p, load_array, sym, type) 3298 mo_header_t *hdr_p; /* pointer to global header */ 3299 load_all_t *load_array; /* array of ptrs to load cmds */ 3300 symbol_info_t *sym; /* pointer to symbol entry */ 3301 int type; /* fntc_type value */ 3302{ 3303 /* Add a new load command. */ 3304 int num_cmds = ++hdr_p->moh_n_load_cmds; 3305 int load_index = num_cmds - 1; 3306 size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t); 3307 load_union_t *ptr = xcalloc (1, size); 3308 load_all_t *load_cmd; 3309 int i; 3310 3311 /* Set the unresolved address bit in the header to force the loader to be 3312 used, since kernel exec does not call the initialization functions. */ 3313 hdr_p->moh_flags |= MOH_UNRESOLVED_F; 3314 3315 load_cmd = &load_array[load_index]; 3316 load_cmd->load = ptr; 3317 load_cmd->section = (char *) 0; 3318 3319 /* Fill in func table load command. */ 3320 ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE; 3321 ptr->func.ldc_header.ldci_cmd_size = size; 3322 ptr->func.ldc_header.ldci_section_off = 0; 3323 ptr->func.ldc_header.ldci_section_len = 0; 3324 ptr->func.fntc_type = type; 3325 ptr->func.fntc_nentries = 1; 3326 3327 /* copy address, turn it from abs. address to (region,offset) if necessary. */ 3328 /* Is the symbol already expressed as (region, offset)? */ 3329 if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0) 3330 { 3331 ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid; 3332 ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff; 3333 } 3334 3335 /* If not, figure out which region it's in. */ 3336 else 3337 { 3338 mo_vm_addr_t addr = sym->si_value.abs_val; 3339 int found = 0; 3340 3341 for (i = 0; i < load_index; i++) 3342 { 3343 if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION) 3344 { 3345 region_command_t *region_ptr = &load_array[i].load->region; 3346 3347 if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0 3348 && addr >= region_ptr->regc_addr.vm_addr 3349 && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size) 3350 { 3351 ptr->func.fntc_entry_loc[0].adr_lcid = i; 3352 ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr; 3353 found++; 3354 break; 3355 } 3356 } 3357 } 3358 3359 if (!found) 3360 fatal ("could not convert 0x%l.8x into a region", addr); 3361 } 3362 3363 if (debug) 3364 notice ("%s function, region %d, offset = %ld (0x%.8lx)\n", 3365 type == FNTC_INITIALIZATION ? "init" : "term", 3366 (int) ptr->func.fntc_entry_loc[i].adr_lcid, 3367 (long) ptr->func.fntc_entry_loc[i].adr_sctoff, 3368 (long) ptr->func.fntc_entry_loc[i].adr_sctoff); 3369 3370} 3371 3372 3373/* Print the global header for an OSF/rose object. */ 3374 3375static void 3376print_header (hdr_ptr) 3377 mo_header_t *hdr_ptr; 3378{ 3379 fprintf (stderr, "\nglobal header:\n"); 3380 fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic); 3381 fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version); 3382 fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version); 3383 fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version); 3384 fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size); 3385 fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order); 3386 fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id); 3387 fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type); 3388 fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype); 3389 fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type); 3390 fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off); 3391 fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off); 3392 fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds); 3393 fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds); 3394 fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags); 3395 3396 if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F) 3397 fprintf (stderr, ", relocatable"); 3398 3399 if (hdr_ptr->moh_flags & MOH_LINKABLE_F) 3400 fprintf (stderr, ", linkable"); 3401 3402 if (hdr_ptr->moh_flags & MOH_EXECABLE_F) 3403 fprintf (stderr, ", execable"); 3404 3405 if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F) 3406 fprintf (stderr, ", executable"); 3407 3408 if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F) 3409 fprintf (stderr, ", unresolved"); 3410 3411 fprintf (stderr, "\n\n"); 3412 return; 3413} 3414 3415 3416/* Print a short summary of a load command. */ 3417 3418static void 3419print_load_command (load_hdr, offset, number) 3420 load_union_t *load_hdr; 3421 size_t offset; 3422 int number; 3423{ 3424 mo_long_t type = load_hdr->hdr.ldci_cmd_type; 3425 const char *type_str = (char *) 0; 3426 3427 switch (type) 3428 { 3429 case LDC_UNDEFINED: type_str = "UNDEFINED"; break; 3430 case LDC_CMD_MAP: type_str = "CMD_MAP"; break; 3431 case LDC_INTERPRETER: type_str = "INTERPRETER"; break; 3432 case LDC_STRINGS: type_str = "STRINGS"; break; 3433 case LDC_REGION: type_str = "REGION"; break; 3434 case LDC_RELOC: type_str = "RELOC"; break; 3435 case LDC_PACKAGE: type_str = "PACKAGE"; break; 3436 case LDC_SYMBOLS: type_str = "SYMBOLS"; break; 3437 case LDC_ENTRY: type_str = "ENTRY"; break; 3438 case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break; 3439 case LDC_GEN_INFO: type_str = "GEN_INFO"; break; 3440 } 3441 3442 fprintf (stderr, 3443 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx", 3444 number, 3445 (long) load_hdr->hdr.ldci_cmd_size, 3446 (long) offset, 3447 (long) load_hdr->hdr.ldci_section_off, 3448 (long) load_hdr->hdr.ldci_section_len); 3449 3450 if (type_str == (char *) 0) 3451 fprintf (stderr, ", ty: unknown (%ld)\n", (long) type); 3452 3453 else if (type != LDC_REGION) 3454 fprintf (stderr, ", ty: %s\n", type_str); 3455 3456 else 3457 { 3458 const char *region = ""; 3459 switch (load_hdr->region.regc_usage_type) 3460 { 3461 case REG_TEXT_T: region = ", .text"; break; 3462 case REG_DATA_T: region = ", .data"; break; 3463 case REG_BSS_T: region = ", .bss"; break; 3464 case REG_GLUE_T: region = ", .glue"; break; 3465#if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/ 3466 case REG_RDATA_T: region = ", .rdata"; break; 3467 case REG_SDATA_T: region = ", .sdata"; break; 3468 case REG_SBSS_T: region = ", .sbss"; break; 3469#endif 3470 } 3471 3472 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n", 3473 type_str, 3474 (long) load_hdr->region.regc_vm_addr, 3475 (long) load_hdr->region.regc_vm_size, 3476 region); 3477 } 3478 3479 return; 3480} 3481 3482 3483/* Fatal error when {en,de}code_mach_o_header fails. */ 3484 3485static void 3486bad_header (status) 3487 int status; 3488{ 3489 switch (status) 3490 { 3491 case MO_ERROR_BAD_MAGIC: fatal ("bad magic number"); 3492 case MO_ERROR_BAD_HDR_VERS: fatal ("bad header version"); 3493 case MO_ERROR_BAD_RAW_HDR_VERS: fatal ("bad raw header version"); 3494 case MO_ERROR_BUF2SML: fatal ("raw header buffer too small"); 3495 case MO_ERROR_OLD_RAW_HDR_FILE: fatal ("old raw header file"); 3496 case MO_ERROR_UNSUPPORTED_VERS: fatal ("unsupported version"); 3497 default: 3498 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status); 3499 } 3500} 3501 3502 3503/* Read a file into a memory buffer. */ 3504 3505static struct file_info * 3506read_file (name, fd, rw) 3507 const char *name; /* filename */ 3508 int fd; /* file descriptor */ 3509 int rw; /* read/write */ 3510{ 3511 struct stat stat_pkt; 3512 struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1); 3513#ifdef USE_MMAP 3514 static int page_size; 3515#endif 3516 3517 if (fstat (fd, &stat_pkt) < 0) 3518 fatal_perror ("fstat %s", name); 3519 3520 p->name = name; 3521 p->size = stat_pkt.st_size; 3522 p->rounded_size = stat_pkt.st_size; 3523 p->fd = fd; 3524 p->rw = rw; 3525 3526#ifdef USE_MMAP 3527 if (debug) 3528 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only"); 3529 3530 if (page_size == 0) 3531 page_size = sysconf (_SC_PAGE_SIZE); 3532 3533 p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size; 3534 p->start = mmap ((caddr_t) 0, 3535 (rw) ? p->rounded_size : p->size, 3536 (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ, 3537 MAP_FILE | MAP_VARIABLE | MAP_SHARED, 3538 fd, 3539 0L); 3540 3541 if (p->start != (char *) 0 && p->start != (char *) -1) 3542 p->use_mmap = 1; 3543 3544 else 3545#endif /* USE_MMAP */ 3546 { 3547 long len; 3548 3549 if (debug) 3550 fprintf (stderr, "read %s\n", name); 3551 3552 p->use_mmap = 0; 3553 p->start = xmalloc (p->size); 3554 if (lseek (fd, 0L, SEEK_SET) < 0) 3555 fatal_perror ("lseek %s 0", name); 3556 3557 len = read (fd, p->start, p->size); 3558 if (len < 0) 3559 fatal_perror ("read %s", name); 3560 3561 if (len != p->size) 3562 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name); 3563 } 3564 3565 return p; 3566} 3567 3568/* Do anything necessary to write a file back from memory. */ 3569 3570static void 3571end_file (ptr) 3572 struct file_info *ptr; /* file information block */ 3573{ 3574#ifdef USE_MMAP 3575 if (ptr->use_mmap) 3576 { 3577 if (ptr->rw) 3578 { 3579 if (debug) 3580 fprintf (stderr, "msync %s\n", ptr->name); 3581 3582 if (msync (ptr->start, ptr->rounded_size, MS_ASYNC)) 3583 fatal_perror ("msync %s", ptr->name); 3584 } 3585 3586 if (debug) 3587 fprintf (stderr, "munmap %s\n", ptr->name); 3588 3589 if (munmap (ptr->start, ptr->size)) 3590 fatal_perror ("munmap %s", ptr->name); 3591 } 3592 else 3593#endif /* USE_MMAP */ 3594 { 3595 if (ptr->rw) 3596 { 3597 long len; 3598 3599 if (debug) 3600 fprintf (stderr, "write %s\n", ptr->name); 3601 3602 if (lseek (ptr->fd, 0L, SEEK_SET) < 0) 3603 fatal_perror ("lseek %s 0", ptr->name); 3604 3605 len = write (ptr->fd, ptr->start, ptr->size); 3606 if (len < 0) 3607 fatal_perror ("write %s", ptr->name); 3608 3609 if (len != ptr->size) 3610 fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name); 3611 } 3612 3613 free (ptr->start); 3614 } 3615 3616 free (ptr); 3617} 3618 3619#endif /* OBJECT_FORMAT_ROSE */ 3620