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