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