collect2.c revision 70635
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 /* Do the link we avoided above if we are exiting. */ 1531 do_tlink (ld1_argv, object_lst); 1532 1533 /* But make sure we delete the export file we may have created. */ 1534 if (export_file != 0 && export_file[0]) 1535 maybe_unlink (export_file); 1536 if (import_file != 0 && import_file[0]) 1537 maybe_unlink (import_file); 1538#endif 1539 maybe_unlink (c_file); 1540 maybe_unlink (o_file); 1541 return 0; 1542 } 1543 1544 /* Examine the namelist with nm and search it for static constructors 1545 and destructors to call. 1546 Write the constructor and destructor tables to a .s file and reload. */ 1547 1548 /* On AIX we already done scanning for global constructors/destructors. */ 1549#ifndef COLLECT_EXPORT_LIST 1550 scan_prog_file (output_file, PASS_FIRST); 1551#endif 1552 1553#ifdef SCAN_LIBRARIES 1554 scan_libraries (output_file); 1555#endif 1556 1557 if (debug) 1558 { 1559 notice ("%d constructor(s) found\n", constructors.number); 1560 notice ("%d destructor(s) found\n", destructors.number); 1561 notice ("%d frame table(s) found\n", frame_tables.number); 1562 } 1563 1564 if (constructors.number == 0 && destructors.number == 0 1565 && frame_tables.number == 0 1566#if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST) 1567 /* If we will be running these functions ourselves, we want to emit 1568 stubs into the shared library so that we do not have to relink 1569 dependent programs when we add static objects. */ 1570 && ! shared_obj 1571#endif 1572 ) 1573 { 1574#ifdef COLLECT_EXPORT_LIST 1575 /* Doing tlink without additional code generation */ 1576 do_tlink (ld1_argv, object_lst); 1577#endif 1578 /* Strip now if it was requested on the command line. */ 1579 if (strip_flag) 1580 { 1581 char **strip_argv = (char **) xcalloc (sizeof (char *), 3); 1582 strip_argv[0] = strip_file_name; 1583 strip_argv[1] = output_file; 1584 strip_argv[2] = (char *) 0; 1585 fork_execute ("strip", strip_argv); 1586 } 1587 1588#ifdef COLLECT_EXPORT_LIST 1589 maybe_unlink (export_file); 1590 maybe_unlink (import_file); 1591#endif 1592 maybe_unlink (c_file); 1593 maybe_unlink (o_file); 1594 return 0; 1595 } 1596 1597 /* Sort ctor and dtor lists by priority. */ 1598 sort_ids (&constructors); 1599 sort_ids (&destructors); 1600 1601 maybe_unlink(output_file); 1602 outf = fopen (c_file, "w"); 1603 if (outf == (FILE *) 0) 1604 fatal_perror ("fopen %s", c_file); 1605 1606 write_c_file (outf, c_file); 1607 1608 if (fclose (outf)) 1609 fatal_perror ("fclose %s", c_file); 1610 1611 /* Tell the linker that we have initializer and finalizer functions. */ 1612#ifdef LD_INIT_SWITCH 1613 *ld2++ = LD_INIT_SWITCH; 1614 *ld2++ = initname; 1615 *ld2++ = LD_FINI_SWITCH; 1616 *ld2++ = fininame; 1617#endif 1618 *ld2 = (char*) 0; 1619 1620#ifdef COLLECT_EXPORT_LIST 1621 if (shared_obj) 1622 { 1623 add_to_list (&exports, initname); 1624 add_to_list (&exports, fininame); 1625 add_to_list (&exports, "_GLOBAL__DI"); 1626 add_to_list (&exports, "_GLOBAL__DD"); 1627 exportf = fopen (export_file, "w"); 1628 if (exportf == (FILE *) 0) 1629 fatal_perror ("fopen %s", export_file); 1630 write_export_file (exportf); 1631 if (fclose (exportf)) 1632 fatal_perror ("fclose %s", export_file); 1633 } 1634#endif 1635 1636 if (debug) 1637 { 1638 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n", 1639 output_file, c_file); 1640 write_c_file (stderr, "stderr"); 1641 fprintf (stderr, "========== end of c_file\n\n"); 1642#ifdef COLLECT_EXPORT_LIST 1643 fprintf (stderr, "\n========== export_file = %s\n", export_file); 1644 write_export_file (stderr); 1645 fprintf (stderr, "========== end of export_file\n\n"); 1646#endif 1647 } 1648 1649 /* Assemble the constructor and destructor tables. 1650 Link the tables in with the rest of the program. */ 1651 1652 fork_execute ("gcc", c_argv); 1653#ifdef COLLECT_EXPORT_LIST 1654 /* On AIX we must call tlink because of possible templates resolution */ 1655 do_tlink (ld2_argv, object_lst); 1656#else 1657 /* Otherwise, simply call ld because tlink is already done */ 1658 fork_execute ("ld", ld2_argv); 1659 1660 /* Let scan_prog_file do any final mods (OSF/rose needs this for 1661 constructors/destructors in shared libraries. */ 1662 scan_prog_file (output_file, PASS_SECOND); 1663#endif 1664 1665 maybe_unlink (c_file); 1666 maybe_unlink (o_file); 1667 1668#ifdef COLLECT_EXPORT_LIST 1669 maybe_unlink (export_file); 1670 maybe_unlink (import_file); 1671#endif 1672 1673 return 0; 1674} 1675 1676 1677/* Wait for a process to finish, and exit if a non-zero status is found. */ 1678 1679int 1680collect_wait (prog) 1681 char *prog; 1682{ 1683 int status; 1684 1685 pwait (pexecute_pid, &status, 0); 1686 if (status) 1687 { 1688 if (WIFSIGNALED (status)) 1689 { 1690 int sig = WTERMSIG (status); 1691 error ((status & 0200 1692 ? "%s terminated with signal %d [%s]" 1693 : "%s terminated with signal %d [%s], core dumped"), 1694 prog, 1695 sig, 1696 my_strsignal(sig)); 1697 collect_exit (FATAL_EXIT_CODE); 1698 } 1699 1700 if (WIFEXITED (status)) 1701 return WEXITSTATUS (status); 1702 } 1703 return 0; 1704} 1705 1706static void 1707do_wait (prog) 1708 char *prog; 1709{ 1710 int ret = collect_wait (prog); 1711 if (ret != 0) 1712 { 1713 error ("%s returned %d exit status", prog, ret); 1714 collect_exit (ret); 1715 } 1716} 1717 1718 1719/* Execute a program, and wait for the reply. */ 1720 1721void 1722collect_execute (prog, argv, redir) 1723 char *prog; 1724 char **argv; 1725 char *redir; 1726{ 1727 char *errmsg_fmt; 1728 char *errmsg_arg; 1729 int redir_handle = -1; 1730 int stdout_save = -1; 1731 int stderr_save = -1; 1732 1733 if (vflag || debug) 1734 { 1735 char **p_argv; 1736 char *str; 1737 1738 if (argv[0]) 1739 fprintf (stderr, "%s", argv[0]); 1740 else 1741 notice ("[cannot find %s]", prog); 1742 1743 for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++) 1744 fprintf (stderr, " %s", str); 1745 1746 fprintf (stderr, "\n"); 1747 } 1748 1749 fflush (stdout); 1750 fflush (stderr); 1751 1752 /* If we cannot find a program we need, complain error. Do this here 1753 since we might not end up needing something that we could not find. */ 1754 1755 if (argv[0] == 0) 1756 fatal ("cannot find `%s'", prog); 1757 1758 if (redir) 1759 { 1760 /* Open response file. */ 1761 redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT); 1762 1763 /* Duplicate the stdout and stderr file handles 1764 so they can be restored later. */ 1765 stdout_save = dup (STDOUT_FILENO); 1766 if (stdout_save == -1) 1767 fatal_perror ("redirecting stdout: %s", redir); 1768 stderr_save = dup (STDERR_FILENO); 1769 if (stderr_save == -1) 1770 fatal_perror ("redirecting stdout: %s", redir); 1771 1772 /* Redirect stdout & stderr to our response file. */ 1773 dup2 (redir_handle, STDOUT_FILENO); 1774 dup2 (redir_handle, STDERR_FILENO); 1775 } 1776 1777 pexecute_pid = pexecute (argv[0], argv, argv[0], NULL, 1778 &errmsg_fmt, &errmsg_arg, 1779 (PEXECUTE_FIRST | PEXECUTE_LAST | PEXECUTE_SEARCH)); 1780 1781 if (redir) 1782 { 1783 /* Restore stdout and stderr to their previous settings. */ 1784 dup2 (stdout_save, STDOUT_FILENO); 1785 dup2 (stderr_save, STDERR_FILENO); 1786 1787 /* Close reponse file. */ 1788 close (redir_handle); 1789 } 1790 1791 if (pexecute_pid == -1) 1792 fatal_perror (errmsg_fmt, errmsg_arg); 1793} 1794 1795static void 1796fork_execute (prog, argv) 1797 char *prog; 1798 char **argv; 1799{ 1800 collect_execute (prog, argv, NULL); 1801 do_wait (prog); 1802} 1803 1804/* Unlink a file unless we are debugging. */ 1805 1806static void 1807maybe_unlink (file) 1808 char *file; 1809{ 1810 if (!debug) 1811 unlink (file); 1812 else 1813 notice ("[Leaving %s]\n", file); 1814} 1815 1816 1817static long sequence_number = 0; 1818 1819/* Add a name to a linked list. */ 1820 1821static void 1822add_to_list (head_ptr, name) 1823 struct head *head_ptr; 1824 char *name; 1825{ 1826 struct id *newid 1827 = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1); 1828 struct id *p; 1829 strcpy (newid->name, name); 1830 1831 if (head_ptr->first) 1832 head_ptr->last->next = newid; 1833 else 1834 head_ptr->first = newid; 1835 1836 /* Check for duplicate symbols. */ 1837 for (p = head_ptr->first; 1838 strcmp (name, p->name) != 0; 1839 p = p->next) 1840 ; 1841 if (p != newid) 1842 { 1843 head_ptr->last->next = 0; 1844 free (newid); 1845 return; 1846 } 1847 1848 newid->sequence = ++sequence_number; 1849 head_ptr->last = newid; 1850 head_ptr->number++; 1851} 1852 1853/* Grab the init priority number from an init function name that 1854 looks like "_GLOBAL_.I.12345.foo". */ 1855 1856static int 1857extract_init_priority (name) 1858 char *name; 1859{ 1860 int pos = 0, pri; 1861 1862 while (name[pos] == '_') 1863 ++pos; 1864 pos += 10; /* strlen ("GLOBAL__X_") */ 1865 1866 /* Extract init_p number from ctor/dtor name. */ 1867 pri = atoi (name + pos); 1868 return pri ? pri : DEFAULT_INIT_PRIORITY; 1869} 1870 1871/* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order. 1872 ctors will be run from right to left, dtors from left to right. */ 1873 1874static void 1875sort_ids (head_ptr) 1876 struct head *head_ptr; 1877{ 1878 /* id holds the current element to insert. id_next holds the next 1879 element to insert. id_ptr iterates through the already sorted elements 1880 looking for the place to insert id. */ 1881 struct id *id, *id_next, **id_ptr; 1882 1883 id = head_ptr->first; 1884 1885 /* We don't have any sorted elements yet. */ 1886 head_ptr->first = NULL; 1887 1888 for (; id; id = id_next) 1889 { 1890 id_next = id->next; 1891 id->sequence = extract_init_priority (id->name); 1892 1893 for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next)) 1894 if (*id_ptr == NULL 1895 /* If the sequence numbers are the same, we put the id from the 1896 file later on the command line later in the list. */ 1897 || id->sequence > (*id_ptr)->sequence 1898 /* Hack: do lexical compare, too. 1899 || (id->sequence == (*id_ptr)->sequence 1900 && strcmp (id->name, (*id_ptr)->name) > 0) */ 1901 ) 1902 { 1903 id->next = *id_ptr; 1904 *id_ptr = id; 1905 break; 1906 } 1907 } 1908 1909 /* Now set the sequence numbers properly so write_c_file works. */ 1910 for (id = head_ptr->first; id; id = id->next) 1911 id->sequence = ++sequence_number; 1912} 1913 1914/* Write: `prefix', the names on list LIST, `suffix'. */ 1915 1916static void 1917write_list (stream, prefix, list) 1918 FILE *stream; 1919 char *prefix; 1920 struct id *list; 1921{ 1922 while (list) 1923 { 1924 fprintf (stream, "%sx%d,\n", prefix, list->sequence); 1925 list = list->next; 1926 } 1927} 1928 1929#ifdef COLLECT_EXPORT_LIST 1930/* This function is really used only on AIX, but may be useful. */ 1931static int 1932is_in_list (prefix, list) 1933 char *prefix; 1934 struct id *list; 1935{ 1936 while (list) 1937 { 1938 if (!strcmp (prefix, list->name)) return 1; 1939 list = list->next; 1940 } 1941 return 0; 1942} 1943#endif 1944 1945/* Added for debugging purpose. */ 1946#ifdef COLLECT_EXPORT_LIST 1947static void 1948dump_list (stream, prefix, list) 1949 FILE *stream; 1950 char *prefix; 1951 struct id *list; 1952{ 1953 while (list) 1954 { 1955 fprintf (stream, "%s%s,\n", prefix, list->name); 1956 list = list->next; 1957 } 1958} 1959#endif 1960 1961#if 0 1962static void 1963dump_prefix_list (stream, prefix, list) 1964 FILE *stream; 1965 char *prefix; 1966 struct prefix_list *list; 1967{ 1968 while (list) 1969 { 1970 fprintf (stream, "%s%s,\n", prefix, list->prefix); 1971 list = list->next; 1972 } 1973} 1974#endif 1975 1976static void 1977write_list_with_asm (stream, prefix, list) 1978 FILE *stream; 1979 char *prefix; 1980 struct id *list; 1981{ 1982 while (list) 1983 { 1984 fprintf (stream, "%sx%d __asm__ (\"%s\");\n", 1985 prefix, list->sequence, list->name); 1986 list = list->next; 1987 } 1988} 1989 1990/* Write out the constructor and destructor tables statically (for a shared 1991 object), along with the functions to execute them. */ 1992 1993static void 1994write_c_file_stat (stream, name) 1995 FILE *stream; 1996 char *name; 1997{ 1998 char *prefix, *p, *q; 1999 int frames = (frame_tables.number > 0); 2000 2001 /* Figure out name of output_file, stripping off .so version. */ 2002 p = rindex (output_file, '/'); 2003 if (p == 0) 2004 p = (char *) output_file; 2005 else 2006 p++; 2007 q = p; 2008 while (q) 2009 { 2010 q = index (q,'.'); 2011 if (q == 0) 2012 { 2013 q = p + strlen (p); 2014 break; 2015 } 2016 else 2017 { 2018 if (strncmp (q, ".so", 3) == 0) 2019 { 2020 q += 3; 2021 break; 2022 } 2023 else 2024 q++; 2025 } 2026 } 2027 /* q points to null at end of the string (or . of the .so version) */ 2028 prefix = xmalloc (q - p + 1); 2029 strncpy (prefix, p, q - p); 2030 prefix[q - p] = 0; 2031 for (q = prefix; *q; q++) 2032 if (!ISALNUM ((unsigned char)*q)) 2033 *q = '_'; 2034 if (debug) 2035 notice ("\nwrite_c_file - output name is %s, prefix is %s\n", 2036 output_file, prefix); 2037 2038#define INIT_NAME_FORMAT "_GLOBAL__FI_%s" 2039 initname = xmalloc (strlen (prefix) + sizeof (INIT_NAME_FORMAT) - 2); 2040 sprintf (initname, INIT_NAME_FORMAT, prefix); 2041 2042#define FINI_NAME_FORMAT "_GLOBAL__FD_%s" 2043 fininame = xmalloc (strlen (prefix) + sizeof (FINI_NAME_FORMAT) - 2); 2044 sprintf (fininame, FINI_NAME_FORMAT, prefix); 2045 2046 free (prefix); 2047 2048 /* Write the tables as C code */ 2049 2050 fprintf (stream, "static int count;\n"); 2051 fprintf (stream, "typedef void entry_pt();\n"); 2052 write_list_with_asm (stream, "extern entry_pt ", constructors.first); 2053 2054 if (frames) 2055 { 2056 write_list_with_asm (stream, "extern void *", frame_tables.first); 2057 2058 fprintf (stream, "\tstatic void *frame_table[] = {\n"); 2059 write_list (stream, "\t\t&", frame_tables.first); 2060 fprintf (stream, "\t0\n};\n"); 2061 2062 /* This must match what's in frame.h. */ 2063 fprintf (stream, "struct object {\n"); 2064 fprintf (stream, " void *pc_begin;\n"); 2065 fprintf (stream, " void *pc_end;\n"); 2066 fprintf (stream, " void *fde_begin;\n"); 2067 fprintf (stream, " void *fde_array;\n"); 2068 fprintf (stream, " __SIZE_TYPE__ count;\n"); 2069 fprintf (stream, " struct object *next;\n"); 2070 fprintf (stream, "};\n"); 2071 2072 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n"); 2073 fprintf (stream, "extern void *__deregister_frame_info (void *);\n"); 2074 2075 fprintf (stream, "static void reg_frame () {\n"); 2076 fprintf (stream, "\tstatic struct object ob;\n"); 2077 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n"); 2078 fprintf (stream, "\t}\n"); 2079 2080 fprintf (stream, "static void dereg_frame () {\n"); 2081 fprintf (stream, "\t__deregister_frame_info (frame_table);\n"); 2082 fprintf (stream, "\t}\n"); 2083 } 2084 2085 fprintf (stream, "void %s() {\n", initname); 2086 if (constructors.number > 0 || frames) 2087 { 2088 fprintf (stream, "\tstatic entry_pt *ctors[] = {\n"); 2089 write_list (stream, "\t\t", constructors.first); 2090 if (frames) 2091 fprintf (stream, "\treg_frame,\n"); 2092 fprintf (stream, "\t};\n"); 2093 fprintf (stream, "\tentry_pt **p;\n"); 2094 fprintf (stream, "\tif (count++ != 0) return;\n"); 2095 fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames); 2096 fprintf (stream, "\twhile (p > ctors) (*--p)();\n"); 2097 } 2098 else 2099 fprintf (stream, "\t++count;\n"); 2100 fprintf (stream, "}\n"); 2101 write_list_with_asm (stream, "extern entry_pt ", destructors.first); 2102 fprintf (stream, "void %s() {\n", fininame); 2103 if (destructors.number > 0 || frames) 2104 { 2105 fprintf (stream, "\tstatic entry_pt *dtors[] = {\n"); 2106 write_list (stream, "\t\t", destructors.first); 2107 if (frames) 2108 fprintf (stream, "\tdereg_frame,\n"); 2109 fprintf (stream, "\t};\n"); 2110 fprintf (stream, "\tentry_pt **p;\n"); 2111 fprintf (stream, "\tif (--count != 0) return;\n"); 2112 fprintf (stream, "\tp = dtors;\n"); 2113 fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n", 2114 destructors.number + frames); 2115 } 2116 fprintf (stream, "}\n"); 2117 2118 if (shared_obj) 2119 { 2120 fprintf (stream, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname); 2121 fprintf (stream, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame); 2122 } 2123} 2124 2125/* Write the constructor/destructor tables. */ 2126 2127#ifndef LD_INIT_SWITCH 2128static void 2129write_c_file_glob (stream, name) 2130 FILE *stream; 2131 char *name; 2132{ 2133 /* Write the tables as C code */ 2134 2135 int frames = (frame_tables.number > 0); 2136 2137 fprintf (stream, "typedef void entry_pt();\n\n"); 2138 2139 write_list_with_asm (stream, "extern entry_pt ", constructors.first); 2140 2141 if (frames) 2142 { 2143 write_list_with_asm (stream, "extern void *", frame_tables.first); 2144 2145 fprintf (stream, "\tstatic void *frame_table[] = {\n"); 2146 write_list (stream, "\t\t&", frame_tables.first); 2147 fprintf (stream, "\t0\n};\n"); 2148 2149 /* This must match what's in frame.h. */ 2150 fprintf (stream, "struct object {\n"); 2151 fprintf (stream, " void *pc_begin;\n"); 2152 fprintf (stream, " void *pc_end;\n"); 2153 fprintf (stream, " void *fde_begin;\n"); 2154 fprintf (stream, " void *fde_array;\n"); 2155 fprintf (stream, " __SIZE_TYPE__ count;\n"); 2156 fprintf (stream, " struct object *next;\n"); 2157 fprintf (stream, "};\n"); 2158 2159 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n"); 2160 fprintf (stream, "extern void *__deregister_frame_info (void *);\n"); 2161 2162 fprintf (stream, "static void reg_frame () {\n"); 2163 fprintf (stream, "\tstatic struct object ob;\n"); 2164 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n"); 2165 fprintf (stream, "\t}\n"); 2166 2167 fprintf (stream, "static void dereg_frame () {\n"); 2168 fprintf (stream, "\t__deregister_frame_info (frame_table);\n"); 2169 fprintf (stream, "\t}\n"); 2170 } 2171 2172 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n"); 2173 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames); 2174 write_list (stream, "\t", constructors.first); 2175 if (frames) 2176 fprintf (stream, "\treg_frame,\n"); 2177 fprintf (stream, "\t0\n};\n\n"); 2178 2179 write_list_with_asm (stream, "extern entry_pt ", destructors.first); 2180 2181 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n"); 2182 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames); 2183 write_list (stream, "\t", destructors.first); 2184 if (frames) 2185 fprintf (stream, "\tdereg_frame,\n"); 2186 fprintf (stream, "\t0\n};\n\n"); 2187 2188 fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN); 2189 fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN); 2190} 2191#endif /* ! LD_INIT_SWITCH */ 2192 2193static void 2194write_c_file (stream, name) 2195 FILE *stream; 2196 char *name; 2197{ 2198 fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n"); 2199#ifndef LD_INIT_SWITCH 2200 if (! shared_obj) 2201 write_c_file_glob (stream, name); 2202 else 2203#endif 2204 write_c_file_stat (stream, name); 2205 fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n"); 2206} 2207 2208#ifdef COLLECT_EXPORT_LIST 2209static void 2210write_export_file (stream) 2211 FILE *stream; 2212{ 2213 struct id *list = exports.first; 2214 for (; list; list = list->next) 2215 fprintf (stream, "%s\n", list->name); 2216} 2217 2218static void 2219write_import_file (stream) 2220 FILE *stream; 2221{ 2222 struct id *list = imports.first; 2223 fprintf (stream, "%s\n", "#! ."); 2224 for (; list; list = list->next) 2225 fprintf (stream, "%s\n", list->name); 2226} 2227#endif 2228 2229#ifdef OBJECT_FORMAT_NONE 2230 2231/* Generic version to scan the name list of the loaded program for 2232 the symbols g++ uses for static constructors and destructors. 2233 2234 The constructor table begins at __CTOR_LIST__ and contains a count 2235 of the number of pointers (or -1 if the constructors are built in a 2236 separate section by the linker), followed by the pointers to the 2237 constructor functions, terminated with a null pointer. The 2238 destructor table has the same format, and begins at __DTOR_LIST__. */ 2239 2240static void 2241scan_prog_file (prog_name, which_pass) 2242 char *prog_name; 2243 enum pass which_pass; 2244{ 2245 void (*int_handler) (); 2246 void (*quit_handler) (); 2247 char *nm_argv[4]; 2248 int pid; 2249 int argc = 0; 2250 int pipe_fd[2]; 2251 char *p, buf[1024]; 2252 FILE *inf; 2253 2254 if (which_pass == PASS_SECOND) 2255 return; 2256 2257 /* If we do not have an `nm', complain. */ 2258 if (nm_file_name == 0) 2259 fatal ("cannot find `nm'"); 2260 2261 nm_argv[argc++] = nm_file_name; 2262 if (NM_FLAGS[0] != '\0') 2263 nm_argv[argc++] = NM_FLAGS; 2264 2265 nm_argv[argc++] = prog_name; 2266 nm_argv[argc++] = (char *) 0; 2267 2268 if (pipe (pipe_fd) < 0) 2269 fatal_perror ("pipe"); 2270 2271 inf = fdopen (pipe_fd[0], "r"); 2272 if (inf == (FILE *) 0) 2273 fatal_perror ("fdopen"); 2274 2275 /* Trace if needed. */ 2276 if (vflag) 2277 { 2278 char **p_argv; 2279 char *str; 2280 2281 for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++) 2282 fprintf (stderr, " %s", str); 2283 2284 fprintf (stderr, "\n"); 2285 } 2286 2287 fflush (stdout); 2288 fflush (stderr); 2289 2290 /* Spawn child nm on pipe */ 2291 pid = vfork (); 2292 if (pid == -1) 2293 fatal_perror (VFORK_STRING); 2294 2295 if (pid == 0) /* child context */ 2296 { 2297 /* setup stdout */ 2298 if (dup2 (pipe_fd[1], 1) < 0) 2299 fatal_perror ("dup2 %d 1", pipe_fd[1]); 2300 2301 if (close (pipe_fd[0]) < 0) 2302 fatal_perror ("close %d", pipe_fd[0]); 2303 2304 if (close (pipe_fd[1]) < 0) 2305 fatal_perror ("close %d", pipe_fd[1]); 2306 2307 execv (nm_file_name, nm_argv); 2308 fatal_perror ("execvp %s", nm_file_name); 2309 } 2310 2311 /* Parent context from here on. */ 2312 int_handler = (void (*) ())signal (SIGINT, SIG_IGN); 2313#ifdef SIGQUIT 2314 quit_handler = (void (*) ())signal (SIGQUIT, SIG_IGN); 2315#endif 2316 2317 if (close (pipe_fd[1]) < 0) 2318 fatal_perror ("close %d", pipe_fd[1]); 2319 2320 if (debug) 2321 fprintf (stderr, "\nnm output with constructors/destructors.\n"); 2322 2323 /* Read each line of nm output. */ 2324 while (fgets (buf, sizeof buf, inf) != (char *) 0) 2325 { 2326 int ch, ch2; 2327 char *name, *end; 2328 2329 /* If it contains a constructor or destructor name, add the name 2330 to the appropriate list. */ 2331 2332 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++) 2333 if (ch == ' ' && p[1] == 'U' && p[2] == ' ') 2334 break; 2335 2336 if (ch != '_') 2337 continue; 2338 2339 name = p; 2340 /* Find the end of the symbol name. 2341 Do not include `|', because Encore nm can tack that on the end. */ 2342 for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|'; 2343 end++) 2344 continue; 2345 2346 2347 *end = '\0'; 2348 switch (is_ctor_dtor (name)) 2349 { 2350 case 1: 2351 if (which_pass != PASS_LIB) 2352 add_to_list (&constructors, name); 2353 break; 2354 2355 case 2: 2356 if (which_pass != PASS_LIB) 2357 add_to_list (&destructors, name); 2358 break; 2359 2360 case 3: 2361 if (which_pass != PASS_LIB) 2362 fatal ("init function found in object %s", prog_name); 2363#ifndef LD_INIT_SWITCH 2364 add_to_list (&constructors, name); 2365#endif 2366 break; 2367 2368 case 4: 2369 if (which_pass != PASS_LIB) 2370 fatal ("fini function found in object %s", prog_name); 2371#ifndef LD_FINI_SWITCH 2372 add_to_list (&destructors, name); 2373#endif 2374 break; 2375 2376 case 5: 2377 if (which_pass != PASS_LIB) 2378 add_to_list (&frame_tables, name); 2379 break; 2380 2381 default: /* not a constructor or destructor */ 2382 continue; 2383 } 2384 2385 if (debug) 2386 fprintf (stderr, "\t%s\n", buf); 2387 } 2388 2389 if (debug) 2390 fprintf (stderr, "\n"); 2391 2392 if (fclose (inf) != 0) 2393 fatal_perror ("fclose"); 2394 2395 do_wait (nm_file_name); 2396 2397 signal (SIGINT, int_handler); 2398#ifdef SIGQUIT 2399 signal (SIGQUIT, quit_handler); 2400#endif 2401} 2402 2403#if SUNOS4_SHARED_LIBRARIES 2404 2405/* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries 2406 that the output file depends upon and their initialization/finalization 2407 routines, if any. */ 2408 2409#include <a.out.h> 2410#include <fcntl.h> 2411#include <link.h> 2412#include <sys/mman.h> 2413#include <sys/param.h> 2414#include <unistd.h> 2415#include <sys/dir.h> 2416 2417/* pointers to the object file */ 2418unsigned object; /* address of memory mapped file */ 2419unsigned objsize; /* size of memory mapped to file */ 2420char * code; /* pointer to code segment */ 2421char * data; /* pointer to data segment */ 2422struct nlist *symtab; /* pointer to symbol table */ 2423struct link_dynamic *ld; 2424struct link_dynamic_2 *ld_2; 2425struct head libraries; 2426 2427/* Map the file indicated by NAME into memory and store its address. */ 2428 2429static void 2430mapfile (name) 2431 char *name; 2432{ 2433 int fp; 2434 struct stat s; 2435 if ((fp = open (name, O_RDONLY)) == -1) 2436 fatal ("unable to open file '%s'", name); 2437 if (fstat (fp, &s) == -1) 2438 fatal ("unable to stat file '%s'", name); 2439 2440 objsize = s.st_size; 2441 object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE, 2442 fp, 0); 2443 if (object == -1) 2444 fatal ("unable to mmap file '%s'", name); 2445 2446 close (fp); 2447} 2448 2449/* Helpers for locatelib. */ 2450 2451static char *libname; 2452 2453static int 2454libselect (d) 2455 struct direct *d; 2456{ 2457 return (strncmp (libname, d->d_name, strlen (libname)) == 0); 2458} 2459 2460/* If one file has an additional numeric extension past LIBNAME, then put 2461 that one first in the sort. If both files have additional numeric 2462 extensions, then put the one with the higher number first in the sort. 2463 2464 We must verify that the extension is numeric, because Sun saves the 2465 original versions of patched libraries with a .FCS extension. Files with 2466 invalid extensions must go last in the sort, so that they will not be used. */ 2467 2468static int 2469libcompare (d1, d2) 2470 struct direct **d1, **d2; 2471{ 2472 int i1, i2 = strlen (libname); 2473 char *e1 = (*d1)->d_name + i2; 2474 char *e2 = (*d2)->d_name + i2; 2475 2476 while (*e1 && *e2 && *e1 == '.' && *e2 == '.' 2477 && e1[1] && ISDIGIT (e1[1]) && e2[1] && ISDIGIT (e2[1])) 2478 { 2479 ++e1; 2480 ++e2; 2481 i1 = strtol (e1, &e1, 10); 2482 i2 = strtol (e2, &e2, 10); 2483 if (i1 != i2) 2484 return i1 - i2; 2485 } 2486 2487 if (*e1) 2488 { 2489 /* It has a valid numeric extension, prefer this one. */ 2490 if (*e1 == '.' && e1[1] && ISDIGIT (e1[1])) 2491 return 1; 2492 /* It has a invalid numeric extension, must prefer the other one. */ 2493 else 2494 return -1; 2495 } 2496 else if (*e2) 2497 { 2498 /* It has a valid numeric extension, prefer this one. */ 2499 if (*e2 == '.' && e2[1] && ISDIGIT (e2[1])) 2500 return -1; 2501 /* It has a invalid numeric extension, must prefer the other one. */ 2502 else 2503 return 1; 2504 } 2505 else 2506 return 0; 2507} 2508 2509/* Given the name NAME of a dynamic dependency, find its pathname and add 2510 it to the list of libraries. */ 2511 2512static void 2513locatelib (name) 2514 char *name; 2515{ 2516 static char **l; 2517 static int cnt; 2518 char buf[MAXPATHLEN]; 2519 char *p, *q; 2520 char **pp; 2521 2522 if (l == 0) 2523 { 2524 char *ld_rules; 2525 char *ldr = 0; 2526 /* counting elements in array, need 1 extra for null */ 2527 cnt = 1; 2528 ld_rules = (char *) (ld_2->ld_rules + code); 2529 if (ld_rules) 2530 { 2531 cnt++; 2532 for (; *ld_rules != 0; ld_rules++) 2533 if (*ld_rules == ':') 2534 cnt++; 2535 ld_rules = (char *) (ld_2->ld_rules + code); 2536 ldr = (char *) malloc (strlen (ld_rules) + 1); 2537 strcpy (ldr, ld_rules); 2538 } 2539 p = getenv ("LD_LIBRARY_PATH"); 2540 q = 0; 2541 if (p) 2542 { 2543 cnt++; 2544 for (q = p ; *q != 0; q++) 2545 if (*q == ':') 2546 cnt++; 2547 q = (char *) malloc (strlen (p) + 1); 2548 strcpy (q, p); 2549 } 2550 l = (char **) malloc ((cnt + 3) * sizeof (char *)); 2551 pp = l; 2552 if (ldr) 2553 { 2554 *pp++ = ldr; 2555 for (; *ldr != 0; ldr++) 2556 if (*ldr == ':') 2557 { 2558 *ldr++ = 0; 2559 *pp++ = ldr; 2560 } 2561 } 2562 if (q) 2563 { 2564 *pp++ = q; 2565 for (; *q != 0; q++) 2566 if (*q == ':') 2567 { 2568 *q++ = 0; 2569 *pp++ = q; 2570 } 2571 } 2572 /* built in directories are /lib, /usr/lib, and /usr/local/lib */ 2573 *pp++ = "/lib"; 2574 *pp++ = "/usr/lib"; 2575 *pp++ = "/usr/local/lib"; 2576 *pp = 0; 2577 } 2578 libname = name; 2579 for (pp = l; *pp != 0 ; pp++) 2580 { 2581 struct direct **namelist; 2582 int entries; 2583 if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0) 2584 { 2585 sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name); 2586 add_to_list (&libraries, buf); 2587 if (debug) 2588 fprintf (stderr, "%s\n", buf); 2589 break; 2590 } 2591 } 2592 if (*pp == 0) 2593 { 2594 if (debug) 2595 notice ("not found\n"); 2596 else 2597 fatal ("dynamic dependency %s not found", name); 2598 } 2599} 2600 2601/* Scan the _DYNAMIC structure of the output file to find shared libraries 2602 that it depends upon and any constructors or destructors they contain. */ 2603 2604static void 2605scan_libraries (prog_name) 2606 char *prog_name; 2607{ 2608 struct exec *header; 2609 char *base; 2610 struct link_object *lo; 2611 char buff[MAXPATHLEN]; 2612 struct id *list; 2613 2614 mapfile (prog_name); 2615 header = (struct exec *)object; 2616 if (N_BADMAG (*header)) 2617 fatal ("bad magic number in file '%s'", prog_name); 2618 if (header->a_dynamic == 0) 2619 return; 2620 2621 code = (char *) (N_TXTOFF (*header) + (long) header); 2622 data = (char *) (N_DATOFF (*header) + (long) header); 2623 symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header); 2624 2625 if (header->a_magic == ZMAGIC && header->a_entry == 0x20) 2626 { 2627 /* shared object */ 2628 ld = (struct link_dynamic *) (symtab->n_value + code); 2629 base = code; 2630 } 2631 else 2632 { 2633 /* executable */ 2634 ld = (struct link_dynamic *) data; 2635 base = code-PAGSIZ; 2636 } 2637 2638 if (debug) 2639 notice ("dynamic dependencies.\n"); 2640 2641 ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base); 2642 for (lo = (struct link_object *) ld_2->ld_need; lo; 2643 lo = (struct link_object *) lo->lo_next) 2644 { 2645 char *name; 2646 lo = (struct link_object *) ((long) lo + code); 2647 name = (char *) (code + lo->lo_name); 2648 if (lo->lo_library) 2649 { 2650 if (debug) 2651 fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major); 2652 sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor); 2653 locatelib (buff); 2654 } 2655 else 2656 { 2657 if (debug) 2658 fprintf (stderr, "\t%s\n", name); 2659 add_to_list (&libraries, name); 2660 } 2661 } 2662 2663 if (debug) 2664 fprintf (stderr, "\n"); 2665 2666 /* now iterate through the library list adding their symbols to 2667 the list. */ 2668 for (list = libraries.first; list; list = list->next) 2669 scan_prog_file (list->name, PASS_LIB); 2670} 2671 2672#else /* SUNOS4_SHARED_LIBRARIES */ 2673#ifdef LDD_SUFFIX 2674 2675/* Use the List Dynamic Dependencies program to find shared libraries that 2676 the output file depends upon and their initialization/finalization 2677 routines, if any. */ 2678 2679static void 2680scan_libraries (prog_name) 2681 char *prog_name; 2682{ 2683 static struct head libraries; /* list of shared libraries found */ 2684 struct id *list; 2685 void (*int_handler) (); 2686 void (*quit_handler) (); 2687 char *ldd_argv[4]; 2688 int pid; 2689 int argc = 0; 2690 int pipe_fd[2]; 2691 char buf[1024]; 2692 FILE *inf; 2693 2694 /* If we do not have an `ldd', complain. */ 2695 if (ldd_file_name == 0) 2696 { 2697 error ("cannot find `ldd'"); 2698 return; 2699 } 2700 2701 ldd_argv[argc++] = ldd_file_name; 2702 ldd_argv[argc++] = prog_name; 2703 ldd_argv[argc++] = (char *) 0; 2704 2705 if (pipe (pipe_fd) < 0) 2706 fatal_perror ("pipe"); 2707 2708 inf = fdopen (pipe_fd[0], "r"); 2709 if (inf == (FILE *) 0) 2710 fatal_perror ("fdopen"); 2711 2712 /* Trace if needed. */ 2713 if (vflag) 2714 { 2715 char **p_argv; 2716 char *str; 2717 2718 for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++) 2719 fprintf (stderr, " %s", str); 2720 2721 fprintf (stderr, "\n"); 2722 } 2723 2724 fflush (stdout); 2725 fflush (stderr); 2726 2727 /* Spawn child ldd on pipe */ 2728 pid = vfork (); 2729 if (pid == -1) 2730 fatal_perror (VFORK_STRING); 2731 2732 if (pid == 0) /* child context */ 2733 { 2734 /* setup stdout */ 2735 if (dup2 (pipe_fd[1], 1) < 0) 2736 fatal_perror ("dup2 %d 1", pipe_fd[1]); 2737 2738 if (close (pipe_fd[0]) < 0) 2739 fatal_perror ("close %d", pipe_fd[0]); 2740 2741 if (close (pipe_fd[1]) < 0) 2742 fatal_perror ("close %d", pipe_fd[1]); 2743 2744 execv (ldd_file_name, ldd_argv); 2745 fatal_perror ("execv %s", ldd_file_name); 2746 } 2747 2748 /* Parent context from here on. */ 2749 int_handler = (void (*) ()) signal (SIGINT, SIG_IGN); 2750#ifdef SIGQUIT 2751 quit_handler = (void (*) ()) signal (SIGQUIT, SIG_IGN); 2752#endif 2753 2754 if (close (pipe_fd[1]) < 0) 2755 fatal_perror ("close %d", pipe_fd[1]); 2756 2757 if (debug) 2758 notice ("\nldd output with constructors/destructors.\n"); 2759 2760 /* Read each line of ldd output. */ 2761 while (fgets (buf, sizeof buf, inf) != (char *) 0) 2762 { 2763 int ch, ch2; 2764 char *name, *end, *p = buf; 2765 2766 /* Extract names of libraries and add to list. */ 2767 PARSE_LDD_OUTPUT (p); 2768 if (p == 0) 2769 continue; 2770 2771 name = p; 2772 if (strncmp (name, "not found", sizeof ("not found") - 1) == 0) 2773 fatal ("dynamic dependency %s not found", buf); 2774 2775 /* Find the end of the symbol name. */ 2776 for (end = p; 2777 (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|'; 2778 end++) 2779 continue; 2780 *end = '\0'; 2781 2782 if (access (name, R_OK) == 0) 2783 add_to_list (&libraries, name); 2784 else 2785 fatal ("unable to open dynamic dependency '%s'", buf); 2786 2787 if (debug) 2788 fprintf (stderr, "\t%s\n", buf); 2789 } 2790 if (debug) 2791 fprintf (stderr, "\n"); 2792 2793 if (fclose (inf) != 0) 2794 fatal_perror ("fclose"); 2795 2796 do_wait (ldd_file_name); 2797 2798 signal (SIGINT, int_handler); 2799#ifdef SIGQUIT 2800 signal (SIGQUIT, quit_handler); 2801#endif 2802 2803 /* now iterate through the library list adding their symbols to 2804 the list. */ 2805 for (list = libraries.first; list; list = list->next) 2806 scan_prog_file (list->name, PASS_LIB); 2807} 2808 2809#endif /* LDD_SUFFIX */ 2810#endif /* SUNOS4_SHARED_LIBRARIES */ 2811 2812#endif /* OBJECT_FORMAT_NONE */ 2813 2814 2815/* 2816 * COFF specific stuff. 2817 */ 2818 2819#ifdef OBJECT_FORMAT_COFF 2820 2821#if defined(EXTENDED_COFF) 2822# define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax) 2823# define GCC_SYMENT SYMR 2824# define GCC_OK_SYMBOL(X) ((X).st == stProc || (X).st == stGlobal) 2825# define GCC_SYMINC(X) (1) 2826# define GCC_SYMZERO(X) (SYMHEADER(X).isymMax) 2827# define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0) 2828#else 2829# define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms) 2830# define GCC_SYMENT SYMENT 2831# define GCC_OK_SYMBOL(X) \ 2832 (((X).n_sclass == C_EXT) && \ 2833 ((X).n_scnum > N_UNDEF) && \ 2834 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \ 2835 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))) 2836# define GCC_UNDEF_SYMBOL(X) \ 2837 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF)) 2838# define GCC_SYMINC(X) ((X).n_numaux+1) 2839# define GCC_SYMZERO(X) 0 2840# define GCC_CHECK_HDR(X) \ 2841 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \ 2842 || (HEADER (X).f_magic == 0757 && aix64_flag)) 2843#endif 2844 2845extern char *ldgetname (); 2846 2847/* COFF version to scan the name list of the loaded program for 2848 the symbols g++ uses for static constructors and destructors. 2849 2850 The constructor table begins at __CTOR_LIST__ and contains a count 2851 of the number of pointers (or -1 if the constructors are built in a 2852 separate section by the linker), followed by the pointers to the 2853 constructor functions, terminated with a null pointer. The 2854 destructor table has the same format, and begins at __DTOR_LIST__. */ 2855 2856static void 2857scan_prog_file (prog_name, which_pass) 2858 char *prog_name; 2859 enum pass which_pass; 2860{ 2861 LDFILE *ldptr = NULL; 2862 int sym_index, sym_count; 2863 int is_shared = 0; 2864#ifdef COLLECT_EXPORT_LIST 2865 /* Should we generate an import list for given prog_name? */ 2866 int import_flag = (which_pass == PASS_OBJ ? 0 : use_import_list (prog_name)); 2867#endif 2868 2869 if (which_pass != PASS_FIRST && which_pass != PASS_OBJ) 2870 return; 2871 2872#ifdef COLLECT_EXPORT_LIST 2873 /* We do not need scanning for some standard C libraries. */ 2874 if (which_pass == PASS_FIRST && ignore_library (prog_name)) 2875 return; 2876 2877 /* On AIX we have a loop, because there is not much difference 2878 between an object and an archive. This trick allows us to 2879 eliminate scan_libraries() function. */ 2880 do 2881 { 2882#endif 2883 if ((ldptr = ldopen (prog_name, ldptr)) != NULL) 2884 { 2885 if (! MY_ISCOFF (HEADER (ldptr).f_magic)) 2886 fatal ("%s: not a COFF file", prog_name); 2887 2888 if (GCC_CHECK_HDR (ldptr)) 2889 { 2890 sym_count = GCC_SYMBOLS (ldptr); 2891 sym_index = GCC_SYMZERO (ldptr); 2892 2893#ifdef COLLECT_EXPORT_LIST 2894 /* Is current archive member a shared object? */ 2895 is_shared = HEADER (ldptr).f_flags & F_SHROBJ; 2896#endif 2897 2898 while (sym_index < sym_count) 2899 { 2900 GCC_SYMENT symbol; 2901 2902 if (ldtbread (ldptr, sym_index, &symbol) <= 0) 2903 break; 2904 sym_index += GCC_SYMINC (symbol); 2905 2906 if (GCC_OK_SYMBOL (symbol)) 2907 { 2908 char *name; 2909 2910 if ((name = ldgetname (ldptr, &symbol)) == NULL) 2911 continue; /* should never happen */ 2912 2913#ifdef XCOFF_DEBUGGING_INFO 2914 /* All AIX function names have a duplicate entry 2915 beginning with a dot. */ 2916 if (*name == '.') 2917 ++name; 2918#endif 2919 2920 switch (is_ctor_dtor (name)) 2921 { 2922 case 1: 2923 if (! is_shared) add_to_list (&constructors, name); 2924#ifdef COLLECT_EXPORT_LIST 2925 if (which_pass == PASS_OBJ) 2926 add_to_list (&exports, name); 2927 /* If this symbol was undefined and we are building 2928 an import list, we should add a symbol to this 2929 list. */ 2930 else 2931 if (import_flag 2932 && is_in_list (name, undefined.first)) 2933 add_to_list (&imports, name); 2934#endif 2935 break; 2936 2937 case 2: 2938 if (! is_shared) add_to_list (&destructors, name); 2939#ifdef COLLECT_EXPORT_LIST 2940 if (which_pass == PASS_OBJ) 2941 add_to_list (&exports, name); 2942 /* If this symbol was undefined and we are building 2943 an import list, we should add a symbol to this 2944 list. */ 2945 else 2946 if (import_flag 2947 && is_in_list (name, undefined.first)) 2948 add_to_list (&imports, name); 2949#endif 2950 break; 2951 2952#ifdef COLLECT_EXPORT_LIST 2953 case 3: 2954 if (is_shared) 2955 add_to_list (&constructors, name); 2956 break; 2957 2958 case 4: 2959 if (is_shared) 2960 add_to_list (&destructors, name); 2961 break; 2962#endif 2963 2964 case 5: 2965 if (! is_shared) 2966 add_to_list (&frame_tables, name); 2967 break; 2968 2969 default: /* not a constructor or destructor */ 2970#ifdef COLLECT_EXPORT_LIST 2971 /* If we are building a shared object on AIX we need 2972 to explicitly export all global symbols or add 2973 them to import list. */ 2974 if (shared_obj) 2975 { 2976 if (which_pass == PASS_OBJ && (! export_flag)) 2977 add_to_list (&exports, name); 2978 else if (! is_shared && which_pass == PASS_FIRST 2979 && import_flag 2980 && is_in_list(name, undefined.first)) 2981 add_to_list (&imports, name); 2982 } 2983#endif 2984 continue; 2985 } 2986 2987#if !defined(EXTENDED_COFF) 2988 if (debug) 2989 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n", 2990 symbol.n_scnum, symbol.n_sclass, 2991 (symbol.n_type ? "0" : ""), symbol.n_type, 2992 name); 2993#else 2994 if (debug) 2995 fprintf (stderr, 2996 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n", 2997 symbol.iss, (long) symbol.value, symbol.index, name); 2998#endif 2999 } 3000#ifdef COLLECT_EXPORT_LIST 3001 /* If we are building a shared object we should collect 3002 information about undefined symbols for later 3003 import list generation. */ 3004 else if (shared_obj && GCC_UNDEF_SYMBOL (symbol)) 3005 { 3006 char *name; 3007 3008 if ((name = ldgetname (ldptr, &symbol)) == NULL) 3009 continue; /* should never happen */ 3010 3011 /* All AIX function names have a duplicate entry 3012 beginning with a dot. */ 3013 if (*name == '.') 3014 ++name; 3015 add_to_list (&undefined, name); 3016 } 3017#endif 3018 } 3019 } 3020#ifdef COLLECT_EXPORT_LIST 3021 else 3022 { 3023 /* If archive contains both 32-bit and 64-bit objects, 3024 we want to skip objects in other mode so mismatch normal. */ 3025 if (debug) 3026 fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n", 3027 prog_name, HEADER (ldptr).f_magic, aix64_flag); 3028 } 3029#endif 3030 } 3031 else 3032 { 3033 fatal ("%s: cannot open as COFF file", prog_name); 3034 } 3035#ifdef COLLECT_EXPORT_LIST 3036 /* On AIX loop continues while there are more members in archive. */ 3037 } 3038 while (ldclose (ldptr) == FAILURE); 3039#else 3040 /* Otherwise we simply close ldptr. */ 3041 (void) ldclose(ldptr); 3042#endif 3043} 3044 3045 3046#ifdef COLLECT_EXPORT_LIST 3047 3048/* Never generate import list (gcc-2.95 branch). */ 3049static int 3050use_import_list (prog_name) 3051 char *prog_name; 3052{ 3053 return 0; 3054} 3055 3056/* Given a library name without "lib" prefix, this function 3057 returns a full library name including a path. */ 3058static char * 3059resolve_lib_name (name) 3060 char *name; 3061{ 3062 char *lib_buf; 3063 int i, j, l = 0; 3064 3065 for (i = 0; libpaths[i]; i++) 3066 if (libpaths[i]->max_len > l) 3067 l = libpaths[i]->max_len; 3068 3069 lib_buf = xmalloc (l + strlen(name) + 10); 3070 3071 for (i = 0; libpaths[i]; i++) 3072 { 3073 struct prefix_list *list = libpaths[i]->plist; 3074 for (; list; list = list->next) 3075 { 3076 for (j = 0; libexts[j]; j++) 3077 { 3078 /* The following lines are needed because path_prefix list 3079 may contain directories both with trailing '/' and 3080 without it. */ 3081 char *p = ""; 3082 if (list->prefix[strlen(list->prefix)-1] != '/') 3083 p = "/"; 3084 sprintf (lib_buf, "%s%slib%s.%s", 3085 list->prefix, p, name, libexts[j]); 3086if (debug) fprintf (stderr, "searching for: %s\n", lib_buf); 3087 if (file_exists (lib_buf)) 3088 { 3089if (debug) fprintf (stderr, "found: %s\n", lib_buf); 3090 return (lib_buf); 3091 } 3092 } 3093 } 3094 } 3095 if (debug) 3096 fprintf (stderr, "not found\n"); 3097 else 3098 fatal ("Library lib%s not found", name); 3099 return (NULL); 3100} 3101 3102/* Array of standard AIX libraries which should not 3103 be scanned for ctors/dtors. */ 3104static char* aix_std_libs[] = { 3105 "/unix", 3106 "/lib/libc.a", 3107 "/lib/libc_r.a", 3108 "/usr/lib/libc.a", 3109 "/usr/lib/libc_r.a", 3110 "/usr/lib/threads/libc.a", 3111 "/usr/ccs/lib/libc.a", 3112 "/usr/ccs/lib/libc_r.a", 3113 NULL 3114}; 3115 3116/* This function checks the filename and returns 1 3117 if this name matches the location of a standard AIX library. */ 3118static int 3119ignore_library (name) 3120 char *name; 3121{ 3122 char **p = &aix_std_libs[0]; 3123 while (*p++ != NULL) 3124 if (! strcmp (name, *p)) return 1; 3125 return 0; 3126} 3127 3128#endif 3129 3130#endif /* OBJECT_FORMAT_COFF */ 3131 3132 3133/* 3134 * OSF/rose specific stuff. 3135 */ 3136 3137#ifdef OBJECT_FORMAT_ROSE 3138 3139/* Union of the various load commands */ 3140 3141typedef union load_union 3142{ 3143 ldc_header_t hdr; /* common header */ 3144 load_cmd_map_command_t map; /* map indexing other load cmds */ 3145 interpreter_command_t iprtr; /* interpreter pathname */ 3146 strings_command_t str; /* load commands strings section */ 3147 region_command_t region; /* region load command */ 3148 reloc_command_t reloc; /* relocation section */ 3149 package_command_t pkg; /* package load command */ 3150 symbols_command_t sym; /* symbol sections */ 3151 entry_command_t ent; /* program start section */ 3152 gen_info_command_t info; /* object information */ 3153 func_table_command_t func; /* function constructors/destructors */ 3154} load_union_t; 3155 3156/* Structure to point to load command and data section in memory. */ 3157 3158typedef struct load_all 3159{ 3160 load_union_t *load; /* load command */ 3161 char *section; /* pointer to section */ 3162} load_all_t; 3163 3164/* Structure to contain information about a file mapped into memory. */ 3165 3166struct file_info 3167{ 3168 char *start; /* start of map */ 3169 char *name; /* filename */ 3170 long size; /* size of the file */ 3171 long rounded_size; /* size rounded to page boundary */ 3172 int fd; /* file descriptor */ 3173 int rw; /* != 0 if opened read/write */ 3174 int use_mmap; /* != 0 if mmap'ed */ 3175}; 3176 3177extern int decode_mach_o_hdr (); 3178extern int encode_mach_o_hdr (); 3179 3180static void add_func_table PROTO((mo_header_t *, load_all_t *, 3181 symbol_info_t *, int)); 3182static void print_header PROTO((mo_header_t *)); 3183static void print_load_command PROTO((load_union_t *, size_t, int)); 3184static void bad_header PROTO((int)); 3185static struct file_info *read_file PROTO((char *, int, int)); 3186static void end_file PROTO((struct file_info *)); 3187 3188/* OSF/rose specific version to scan the name list of the loaded 3189 program for the symbols g++ uses for static constructors and 3190 destructors. 3191 3192 The constructor table begins at __CTOR_LIST__ and contains a count 3193 of the number of pointers (or -1 if the constructors are built in a 3194 separate section by the linker), followed by the pointers to the 3195 constructor functions, terminated with a null pointer. The 3196 destructor table has the same format, and begins at __DTOR_LIST__. */ 3197 3198static void 3199scan_prog_file (prog_name, which_pass) 3200 char *prog_name; 3201 enum pass which_pass; 3202{ 3203 char *obj; 3204 mo_header_t hdr; 3205 load_all_t *load_array; 3206 load_all_t *load_end; 3207 load_all_t *load_cmd; 3208 int symbol_load_cmds; 3209 off_t offset; 3210 int i; 3211 int num_syms; 3212 int status; 3213 char *str_sect; 3214 struct file_info *obj_file; 3215 int prog_fd; 3216 mo_lcid_t cmd_strings = -1; 3217 symbol_info_t *main_sym = 0; 3218 int rw = (which_pass != PASS_FIRST); 3219 3220 prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY); 3221 if (prog_fd < 0) 3222 fatal_perror ("open %s", prog_name); 3223 3224 obj_file = read_file (prog_name, prog_fd, rw); 3225 obj = obj_file->start; 3226 3227 status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr); 3228 if (status != MO_HDR_CONV_SUCCESS) 3229 bad_header (status); 3230 3231 3232 /* Do some basic sanity checks. Note we explicitly use the big endian magic number, 3233 since the hardware will automatically swap bytes for us on loading little endian 3234 integers. */ 3235 3236#ifndef CROSS_COMPILE 3237 if (hdr.moh_magic != MOH_MAGIC_MSB 3238 || hdr.moh_header_version != MOH_HEADER_VERSION 3239 || hdr.moh_byte_order != OUR_BYTE_ORDER 3240 || hdr.moh_data_rep_id != OUR_DATA_REP_ID 3241 || hdr.moh_cpu_type != OUR_CPU_TYPE 3242 || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE 3243 || hdr.moh_vendor_type != OUR_VENDOR_TYPE) 3244 { 3245 fatal ("incompatibilities between object file & expected values"); 3246 } 3247#endif 3248 3249 if (debug) 3250 print_header (&hdr); 3251 3252 offset = hdr.moh_first_cmd_off; 3253 load_end = load_array 3254 = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2); 3255 3256 /* Build array of load commands, calculating the offsets */ 3257 for (i = 0; i < hdr.moh_n_load_cmds; i++) 3258 { 3259 load_union_t *load_hdr; /* load command header */ 3260 3261 load_cmd = load_end++; 3262 load_hdr = (load_union_t *) (obj + offset); 3263 3264 /* If modifying the program file, copy the header. */ 3265 if (rw) 3266 { 3267 load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size); 3268 bcopy ((char *)load_hdr, (char *)ptr, load_hdr->hdr.ldci_cmd_size); 3269 load_hdr = ptr; 3270 3271 /* null out old command map, because we will rewrite at the end. */ 3272 if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP) 3273 { 3274 cmd_strings = ptr->map.lcm_ld_cmd_strings; 3275 ptr->hdr.ldci_cmd_type = LDC_UNDEFINED; 3276 } 3277 } 3278 3279 load_cmd->load = load_hdr; 3280 if (load_hdr->hdr.ldci_section_off > 0) 3281 load_cmd->section = obj + load_hdr->hdr.ldci_section_off; 3282 3283 if (debug) 3284 print_load_command (load_hdr, offset, i); 3285 3286 offset += load_hdr->hdr.ldci_cmd_size; 3287 } 3288 3289 /* If the last command is the load command map and is not undefined, 3290 decrement the count of load commands. */ 3291 if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED) 3292 { 3293 load_end--; 3294 hdr.moh_n_load_cmds--; 3295 } 3296 3297 /* Go through and process each symbol table section. */ 3298 symbol_load_cmds = 0; 3299 for (load_cmd = load_array; load_cmd < load_end; load_cmd++) 3300 { 3301 load_union_t *load_hdr = load_cmd->load; 3302 3303 if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS) 3304 { 3305 symbol_load_cmds++; 3306 3307 if (debug) 3308 { 3309 char *kind = "unknown"; 3310 3311 switch (load_hdr->sym.symc_kind) 3312 { 3313 case SYMC_IMPORTS: kind = "imports"; break; 3314 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break; 3315 case SYMC_STABS: kind = "stabs"; break; 3316 } 3317 3318 notice ("\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n", 3319 symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind); 3320 } 3321 3322 if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS) 3323 continue; 3324 3325 str_sect = load_array[load_hdr->sym.symc_strings_section].section; 3326 if (str_sect == (char *) 0) 3327 fatal ("string section missing"); 3328 3329 if (load_cmd->section == (char *) 0) 3330 fatal ("section pointer missing"); 3331 3332 num_syms = load_hdr->sym.symc_nentries; 3333 for (i = 0; i < num_syms; i++) 3334 { 3335 symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i; 3336 char *name = sym->si_name.symbol_name + str_sect; 3337 3338 if (name[0] != '_') 3339 continue; 3340 3341 if (rw) 3342 { 3343 char *n = name + strlen (name) - strlen (NAME__MAIN); 3344 3345 if ((n - name) < 0 || strcmp (n, NAME__MAIN)) 3346 continue; 3347 while (n != name) 3348 if (*--n != '_') 3349 continue; 3350 3351 main_sym = sym; 3352 } 3353 else 3354 { 3355 switch (is_ctor_dtor (name)) 3356 { 3357 case 1: 3358 add_to_list (&constructors, name); 3359 break; 3360 3361 case 2: 3362 add_to_list (&destructors, name); 3363 break; 3364 3365 default: /* not a constructor or destructor */ 3366 continue; 3367 } 3368 } 3369 3370 if (debug) 3371 fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n", 3372 sym->si_type, sym->si_sc_type, sym->si_flags, name); 3373 } 3374 } 3375 } 3376 3377 if (symbol_load_cmds == 0) 3378 fatal ("no symbol table found"); 3379 3380 /* Update the program file now, rewrite header and load commands. At present, 3381 we assume that there is enough space after the last load command to insert 3382 one more. Since the first section written out is page aligned, and the 3383 number of load commands is small, this is ok for the present. */ 3384 3385 if (rw) 3386 { 3387 load_union_t *load_map; 3388 size_t size; 3389 3390 if (cmd_strings == -1) 3391 fatal ("no cmd_strings found"); 3392 3393 /* Add __main to initializer list. 3394 If we are building a program instead of a shared library, do not 3395 do anything, since in the current version, you cannot do mallocs 3396 and such in the constructors. */ 3397 3398 if (main_sym != (symbol_info_t *) 0 3399 && ((hdr.moh_flags & MOH_EXECABLE_F) == 0)) 3400 add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION); 3401 3402 if (debug) 3403 notice ("\nUpdating header and load commands.\n\n"); 3404 3405 hdr.moh_n_load_cmds++; 3406 size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1)); 3407 3408 /* Create new load command map. */ 3409 if (debug) 3410 notice ("load command map, %d cmds, new size %ld.\n", 3411 (int) hdr.moh_n_load_cmds, (long) size); 3412 3413 load_map = (load_union_t *) xcalloc (1, size); 3414 load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP; 3415 load_map->map.ldc_header.ldci_cmd_size = size; 3416 load_map->map.lcm_ld_cmd_strings = cmd_strings; 3417 load_map->map.lcm_nentries = hdr.moh_n_load_cmds; 3418 load_array[hdr.moh_n_load_cmds-1].load = load_map; 3419 3420 offset = hdr.moh_first_cmd_off; 3421 for (i = 0; i < hdr.moh_n_load_cmds; i++) 3422 { 3423 load_map->map.lcm_map[i] = offset; 3424 if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP) 3425 hdr.moh_load_map_cmd_off = offset; 3426 3427 offset += load_array[i].load->hdr.ldci_cmd_size; 3428 } 3429 3430 hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR; 3431 3432 if (debug) 3433 print_header (&hdr); 3434 3435 /* Write header */ 3436 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR); 3437 if (status != MO_HDR_CONV_SUCCESS) 3438 bad_header (status); 3439 3440 if (debug) 3441 notice ("writing load commands.\n\n"); 3442 3443 /* Write load commands */ 3444 offset = hdr.moh_first_cmd_off; 3445 for (i = 0; i < hdr.moh_n_load_cmds; i++) 3446 { 3447 load_union_t *load_hdr = load_array[i].load; 3448 size_t size = load_hdr->hdr.ldci_cmd_size; 3449 3450 if (debug) 3451 print_load_command (load_hdr, offset, i); 3452 3453 bcopy ((char *) load_hdr, (char *) (obj + offset), size); 3454 offset += size; 3455 } 3456 } 3457 3458 end_file (obj_file); 3459 3460 if (close (prog_fd)) 3461 fatal_perror ("close %s", prog_name); 3462 3463 if (debug) 3464 fprintf (stderr, "\n"); 3465} 3466 3467 3468/* Add a function table to the load commands to call a function 3469 on initiation or termination of the process. */ 3470 3471static void 3472add_func_table (hdr_p, load_array, sym, type) 3473 mo_header_t *hdr_p; /* pointer to global header */ 3474 load_all_t *load_array; /* array of ptrs to load cmds */ 3475 symbol_info_t *sym; /* pointer to symbol entry */ 3476 int type; /* fntc_type value */ 3477{ 3478 /* Add a new load command. */ 3479 int num_cmds = ++hdr_p->moh_n_load_cmds; 3480 int load_index = num_cmds - 1; 3481 size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t); 3482 load_union_t *ptr = xcalloc (1, size); 3483 load_all_t *load_cmd; 3484 int i; 3485 3486 /* Set the unresolved address bit in the header to force the loader to be 3487 used, since kernel exec does not call the initialization functions. */ 3488 hdr_p->moh_flags |= MOH_UNRESOLVED_F; 3489 3490 load_cmd = &load_array[load_index]; 3491 load_cmd->load = ptr; 3492 load_cmd->section = (char *) 0; 3493 3494 /* Fill in func table load command. */ 3495 ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE; 3496 ptr->func.ldc_header.ldci_cmd_size = size; 3497 ptr->func.ldc_header.ldci_section_off = 0; 3498 ptr->func.ldc_header.ldci_section_len = 0; 3499 ptr->func.fntc_type = type; 3500 ptr->func.fntc_nentries = 1; 3501 3502 /* copy address, turn it from abs. address to (region,offset) if necessary. */ 3503 /* Is the symbol already expressed as (region, offset)? */ 3504 if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0) 3505 { 3506 ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid; 3507 ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff; 3508 } 3509 3510 /* If not, figure out which region it's in. */ 3511 else 3512 { 3513 mo_vm_addr_t addr = sym->si_value.abs_val; 3514 int found = 0; 3515 3516 for (i = 0; i < load_index; i++) 3517 { 3518 if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION) 3519 { 3520 region_command_t *region_ptr = &load_array[i].load->region; 3521 3522 if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0 3523 && addr >= region_ptr->regc_addr.vm_addr 3524 && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size) 3525 { 3526 ptr->func.fntc_entry_loc[0].adr_lcid = i; 3527 ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr; 3528 found++; 3529 break; 3530 } 3531 } 3532 } 3533 3534 if (!found) 3535 fatal ("could not convert 0x%l.8x into a region", addr); 3536 } 3537 3538 if (debug) 3539 notice ("%s function, region %d, offset = %ld (0x%.8lx)\n", 3540 type == FNTC_INITIALIZATION ? "init" : "term", 3541 (int) ptr->func.fntc_entry_loc[i].adr_lcid, 3542 (long) ptr->func.fntc_entry_loc[i].adr_sctoff, 3543 (long) ptr->func.fntc_entry_loc[i].adr_sctoff); 3544 3545} 3546 3547 3548/* Print the global header for an OSF/rose object. */ 3549 3550static void 3551print_header (hdr_ptr) 3552 mo_header_t *hdr_ptr; 3553{ 3554 fprintf (stderr, "\nglobal header:\n"); 3555 fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic); 3556 fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version); 3557 fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version); 3558 fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version); 3559 fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size); 3560 fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order); 3561 fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id); 3562 fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type); 3563 fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype); 3564 fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type); 3565 fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off); 3566 fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off); 3567 fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds); 3568 fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds); 3569 fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags); 3570 3571 if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F) 3572 fprintf (stderr, ", relocatable"); 3573 3574 if (hdr_ptr->moh_flags & MOH_LINKABLE_F) 3575 fprintf (stderr, ", linkable"); 3576 3577 if (hdr_ptr->moh_flags & MOH_EXECABLE_F) 3578 fprintf (stderr, ", execable"); 3579 3580 if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F) 3581 fprintf (stderr, ", executable"); 3582 3583 if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F) 3584 fprintf (stderr, ", unresolved"); 3585 3586 fprintf (stderr, "\n\n"); 3587 return; 3588} 3589 3590 3591/* Print a short summary of a load command. */ 3592 3593static void 3594print_load_command (load_hdr, offset, number) 3595 load_union_t *load_hdr; 3596 size_t offset; 3597 int number; 3598{ 3599 mo_long_t type = load_hdr->hdr.ldci_cmd_type; 3600 char *type_str = (char *) 0; 3601 3602 switch (type) 3603 { 3604 case LDC_UNDEFINED: type_str = "UNDEFINED"; break; 3605 case LDC_CMD_MAP: type_str = "CMD_MAP"; break; 3606 case LDC_INTERPRETER: type_str = "INTERPRETER"; break; 3607 case LDC_STRINGS: type_str = "STRINGS"; break; 3608 case LDC_REGION: type_str = "REGION"; break; 3609 case LDC_RELOC: type_str = "RELOC"; break; 3610 case LDC_PACKAGE: type_str = "PACKAGE"; break; 3611 case LDC_SYMBOLS: type_str = "SYMBOLS"; break; 3612 case LDC_ENTRY: type_str = "ENTRY"; break; 3613 case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break; 3614 case LDC_GEN_INFO: type_str = "GEN_INFO"; break; 3615 } 3616 3617 fprintf (stderr, 3618 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx", 3619 number, 3620 (long) load_hdr->hdr.ldci_cmd_size, 3621 (long) offset, 3622 (long) load_hdr->hdr.ldci_section_off, 3623 (long) load_hdr->hdr.ldci_section_len); 3624 3625 if (type_str == (char *) 0) 3626 fprintf (stderr, ", ty: unknown (%ld)\n", (long) type); 3627 3628 else if (type != LDC_REGION) 3629 fprintf (stderr, ", ty: %s\n", type_str); 3630 3631 else 3632 { 3633 char *region = ""; 3634 switch (load_hdr->region.regc_usage_type) 3635 { 3636 case REG_TEXT_T: region = ", .text"; break; 3637 case REG_DATA_T: region = ", .data"; break; 3638 case REG_BSS_T: region = ", .bss"; break; 3639 case REG_GLUE_T: region = ", .glue"; break; 3640#if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/ 3641 case REG_RDATA_T: region = ", .rdata"; break; 3642 case REG_SDATA_T: region = ", .sdata"; break; 3643 case REG_SBSS_T: region = ", .sbss"; break; 3644#endif 3645 } 3646 3647 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n", 3648 type_str, 3649 (long) load_hdr->region.regc_vm_addr, 3650 (long) load_hdr->region.regc_vm_size, 3651 region); 3652 } 3653 3654 return; 3655} 3656 3657 3658/* Fatal error when {en,de}code_mach_o_header fails. */ 3659 3660static void 3661bad_header (status) 3662 int status; 3663{ 3664 switch (status) 3665 { 3666 case MO_ERROR_BAD_MAGIC: fatal ("bad magic number"); 3667 case MO_ERROR_BAD_HDR_VERS: fatal ("bad header version"); 3668 case MO_ERROR_BAD_RAW_HDR_VERS: fatal ("bad raw header version"); 3669 case MO_ERROR_BUF2SML: fatal ("raw header buffer too small"); 3670 case MO_ERROR_OLD_RAW_HDR_FILE: fatal ("old raw header file"); 3671 case MO_ERROR_UNSUPPORTED_VERS: fatal ("unsupported version"); 3672 default: 3673 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status); 3674 } 3675} 3676 3677 3678/* Read a file into a memory buffer. */ 3679 3680static struct file_info * 3681read_file (name, fd, rw) 3682 char *name; /* filename */ 3683 int fd; /* file descriptor */ 3684 int rw; /* read/write */ 3685{ 3686 struct stat stat_pkt; 3687 struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1); 3688#ifdef USE_MMAP 3689 static int page_size; 3690#endif 3691 3692 if (fstat (fd, &stat_pkt) < 0) 3693 fatal_perror ("fstat %s", name); 3694 3695 p->name = name; 3696 p->size = stat_pkt.st_size; 3697 p->rounded_size = stat_pkt.st_size; 3698 p->fd = fd; 3699 p->rw = rw; 3700 3701#ifdef USE_MMAP 3702 if (debug) 3703 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only"); 3704 3705 if (page_size == 0) 3706 page_size = sysconf (_SC_PAGE_SIZE); 3707 3708 p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size; 3709 p->start = mmap ((caddr_t) 0, 3710 (rw) ? p->rounded_size : p->size, 3711 (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ, 3712 MAP_FILE | MAP_VARIABLE | MAP_SHARED, 3713 fd, 3714 0L); 3715 3716 if (p->start != (char *) 0 && p->start != (char *) -1) 3717 p->use_mmap = 1; 3718 3719 else 3720#endif /* USE_MMAP */ 3721 { 3722 long len; 3723 3724 if (debug) 3725 fprintf (stderr, "read %s\n", name); 3726 3727 p->use_mmap = 0; 3728 p->start = xmalloc (p->size); 3729 if (lseek (fd, 0L, SEEK_SET) < 0) 3730 fatal_perror ("lseek %s 0", name); 3731 3732 len = read (fd, p->start, p->size); 3733 if (len < 0) 3734 fatal_perror ("read %s", name); 3735 3736 if (len != p->size) 3737 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name); 3738 } 3739 3740 return p; 3741} 3742 3743/* Do anything necessary to write a file back from memory. */ 3744 3745static void 3746end_file (ptr) 3747 struct file_info *ptr; /* file information block */ 3748{ 3749#ifdef USE_MMAP 3750 if (ptr->use_mmap) 3751 { 3752 if (ptr->rw) 3753 { 3754 if (debug) 3755 fprintf (stderr, "msync %s\n", ptr->name); 3756 3757 if (msync (ptr->start, ptr->rounded_size, MS_ASYNC)) 3758 fatal_perror ("msync %s", ptr->name); 3759 } 3760 3761 if (debug) 3762 fprintf (stderr, "munmap %s\n", ptr->name); 3763 3764 if (munmap (ptr->start, ptr->size)) 3765 fatal_perror ("munmap %s", ptr->name); 3766 } 3767 else 3768#endif /* USE_MMAP */ 3769 { 3770 if (ptr->rw) 3771 { 3772 long len; 3773 3774 if (debug) 3775 fprintf (stderr, "write %s\n", ptr->name); 3776 3777 if (lseek (ptr->fd, 0L, SEEK_SET) < 0) 3778 fatal_perror ("lseek %s 0", ptr->name); 3779 3780 len = write (ptr->fd, ptr->start, ptr->size); 3781 if (len < 0) 3782 fatal_perror ("write %s", ptr->name); 3783 3784 if (len != ptr->size) 3785 fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name); 3786 } 3787 3788 free (ptr->start); 3789 } 3790 3791 free (ptr); 3792} 3793 3794#endif /* OBJECT_FORMAT_ROSE */ 3795