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