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