collect2.c revision 132718
112657Skvn/* Collect static initialization info into data structures that can be 212657Skvn traversed by C++ initialization and finalization routines. 312657Skvn Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 412657Skvn 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. 512657Skvn Contributed by Chris Smith (csmith@convex.com). 612657Skvn Heavily modified by Michael Meissner (meissner@cygnus.com), 712657Skvn Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com). 812657Skvn 912657SkvnThis file is part of GCC. 1012657Skvn 1112657SkvnGCC is free software; you can redistribute it and/or modify it under 1212657Skvnthe terms of the GNU General Public License as published by the Free 1312657SkvnSoftware Foundation; either version 2, or (at your option) any later 1412657Skvnversion. 1512657Skvn 1612657SkvnGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1712657SkvnWARRANTY; without even the implied warranty of MERCHANTABILITY or 1812657SkvnFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1912657Skvnfor more details. 2012657Skvn 2112657SkvnYou should have received a copy of the GNU General Public License 2212657Skvnalong with GCC; see the file COPYING. If not, write to the Free 2312657SkvnSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA 2412657Skvn02111-1307, USA. */ 2512657Skvn 2612657Skvn 2712657Skvn/* Build tables of static constructors and destructors and run ld. */ 2812657Skvn 2912657Skvn#include "config.h" 3012657Skvn#include "system.h" 3112657Skvn#include "coretypes.h" 3212657Skvn#include "tm.h" 3312657Skvn#include <signal.h> 3412657Skvn#if ! defined( SIGCHLD ) && defined( SIGCLD ) 3512657Skvn# define SIGCHLD SIGCLD 3612657Skvn#endif 3712657Skvn 3812657Skvn#ifdef vfork /* Autoconf may define this to fork for us. */ 3912657Skvn# define VFORK_STRING "fork" 4012657Skvn#else 4112657Skvn# define VFORK_STRING "vfork" 4212657Skvn#endif 4312657Skvn#ifdef HAVE_VFORK_H 4412657Skvn#include <vfork.h> 4512657Skvn#endif 4612657Skvn#ifdef VMS 4712657Skvn#define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \ 4812657Skvn lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1) 4912657Skvn#endif /* VMS */ 5012657Skvn 5112657Skvn#ifndef LIBRARY_PATH_ENV 5212657Skvn#define LIBRARY_PATH_ENV "LIBRARY_PATH" 5312657Skvn#endif 5412657Skvn 5512657Skvn#define COLLECT 5612657Skvn 5712657Skvn#include "collect2.h" 5812657Skvn#include "demangle.h" 5912657Skvn#include "obstack.h" 6012657Skvn#include "intl.h" 6112657Skvn#include "version.h" 6212657Skvn 6312657Skvn/* On certain systems, we have code that works by scanning the object file 6412657Skvn directly. But this code uses system-specific header files and library 6512657Skvn functions, so turn it off in a cross-compiler. Likewise, the names of 6612657Skvn the utilities are not correct for a cross-compiler; we have to hope that 6712657Skvn cross-versions are in the proper directories. */ 6812657Skvn 6912657Skvn#ifdef CROSS_COMPILE 7012657Skvn#undef SUNOS4_SHARED_LIBRARIES 7112657Skvn#undef OBJECT_FORMAT_COFF 7212657Skvn#undef MD_EXEC_PREFIX 7312657Skvn#undef REAL_LD_FILE_NAME 7412657Skvn#undef REAL_NM_FILE_NAME 7512657Skvn#undef REAL_STRIP_FILE_NAME 7612657Skvn#endif 7712657Skvn 7812657Skvn/* If we cannot use a special method, use the ordinary one: 7912657Skvn run nm to find what symbols are present. 8012657Skvn In a cross-compiler, this means you need a cross nm, 8112657Skvn but that is not quite as unpleasant as special headers. */ 8212657Skvn 8312657Skvn#if !defined (OBJECT_FORMAT_COFF) 8412657Skvn#define OBJECT_FORMAT_NONE 8512657Skvn#endif 8612657Skvn 8712657Skvn#ifdef OBJECT_FORMAT_COFF 8812657Skvn 8912657Skvn#include <a.out.h> 9012657Skvn#include <ar.h> 9112657Skvn 9212657Skvn#ifdef UMAX 9312657Skvn#include <sgs.h> 9412657Skvn#endif 9512657Skvn 9612657Skvn/* Many versions of ldfcn.h define these. */ 9712657Skvn#ifdef FREAD 9812657Skvn#undef FREAD 9912657Skvn#undef FWRITE 10012657Skvn#endif 10112657Skvn 10212657Skvn#include <ldfcn.h> 10312657Skvn 10412657Skvn/* Some systems have an ISCOFF macro, but others do not. In some cases 10512657Skvn the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines 10612657Skvn that either do not have an ISCOFF macro in /usr/include or for those 10712657Skvn where it is wrong. */ 10812657Skvn 10912657Skvn#ifndef MY_ISCOFF 11012657Skvn#define MY_ISCOFF(X) ISCOFF (X) 11112657Skvn#endif 11212657Skvn 11312657Skvn#endif /* OBJECT_FORMAT_COFF */ 11412657Skvn 11512657Skvn#ifdef OBJECT_FORMAT_NONE 11612657Skvn 11712657Skvn/* Default flags to pass to nm. */ 11812657Skvn#ifndef NM_FLAGS 11912657Skvn#define NM_FLAGS "-n" 12012657Skvn#endif 12112657Skvn 12212657Skvn#endif /* OBJECT_FORMAT_NONE */ 12312657Skvn 12412657Skvn/* Some systems use __main in a way incompatible with its use in gcc, in these 12512657Skvn cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to 12612657Skvn give the same symbol without quotes for an alternative entry point. */ 12712968Siveresov#ifndef NAME__MAIN 12812657Skvn#define NAME__MAIN "__main" 12912657Skvn#endif 13012657Skvn 13112657Skvn/* This must match tree.h. */ 13212657Skvn#define DEFAULT_INIT_PRIORITY 65535 13312657Skvn 13412657Skvn#ifndef COLLECT_SHARED_INIT_FUNC 13512657Skvn#define COLLECT_SHARED_INIT_FUNC(STREAM, FUNC) \ 13612657Skvn fprintf ((STREAM), "void _GLOBAL__DI() {\n\t%s();\n}\n", (FUNC)) 13712657Skvn#endif 13812657Skvn#ifndef COLLECT_SHARED_FINI_FUNC 13912657Skvn#define COLLECT_SHARED_FINI_FUNC(STREAM, FUNC) \ 14012657Skvn fprintf ((STREAM), "void _GLOBAL__DD() {\n\t%s();\n}\n", (FUNC)) 14112657Skvn#endif 14212657Skvn 14312657Skvn#if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES 14412657Skvn#define SCAN_LIBRARIES 14512657Skvn#endif 14612657Skvn 14712657Skvn#ifdef USE_COLLECT2 14812657Skvnint do_collecting = 1; 14912657Skvn#else 15012657Skvnint do_collecting = 0; 15112657Skvn#endif 15212657Skvn 15312657Skvn#ifndef COLLECT_PARSE_FLAG 15412657Skvn#define COLLECT_PARSE_FLAG(FLAG) 15512657Skvn#endif 15612657Skvn 15712657Skvn/* Nonzero if we should suppress the automatic demangling of identifiers 15812657Skvn in linker error messages. Set from COLLECT_NO_DEMANGLE. */ 15912657Skvnint no_demangle; 16012657Skvn 16112657Skvn/* Linked lists of constructor and destructor names. */ 16212657Skvn 16312657Skvnstruct id 16412657Skvn{ 16512657Skvn struct id *next; 16612657Skvn int sequence; 16712657Skvn char name[1]; 16812657Skvn}; 16912657Skvn 17012657Skvnstruct head 17112657Skvn{ 17212657Skvn struct id *first; 17312657Skvn struct id *last; 17412657Skvn int number; 17512657Skvn}; 17612657Skvn 17712657Skvn/* Enumeration giving which pass this is for scanning the program file. */ 17812657Skvn 17912657Skvnenum pass { 18012657Skvn PASS_FIRST, /* without constructors */ 18112657Skvn PASS_OBJ, /* individual objects */ 18212657Skvn PASS_LIB, /* looking for shared libraries */ 18312657Skvn PASS_SECOND /* with constructors linked in */ 18412657Skvn}; 18512657Skvn 18612657Skvnint vflag; /* true if -v */ 18712657Skvnstatic int rflag; /* true if -r */ 18812657Skvnstatic int strip_flag; /* true if -s */ 18912657Skvn#ifdef COLLECT_EXPORT_LIST 19012657Skvnstatic int export_flag; /* true if -bE */ 19112657Skvnstatic int aix64_flag; /* true if -b64 */ 19212657Skvn#endif 19312657Skvn 19412657Skvnint debug; /* true if -debug */ 19512657Skvn 19612657Skvnstatic int shared_obj; /* true if -shared */ 19712657Skvn 19812657Skvnstatic const char *c_file; /* <xxx>.c for constructor/destructor list. */ 19912657Skvnstatic const char *o_file; /* <xxx>.o for constructor/destructor list. */ 20012657Skvn#ifdef COLLECT_EXPORT_LIST 20112657Skvnstatic const char *export_file; /* <xxx>.x for AIX export list. */ 20212657Skvn#endif 20312657Skvnconst char *ldout; /* File for ld errors. */ 20412657Skvnstatic const char *output_file; /* Output file for ld. */ 20512657Skvnstatic const char *nm_file_name; /* pathname of nm */ 20612657Skvn#ifdef LDD_SUFFIX 20712657Skvnstatic const char *ldd_file_name; /* pathname of ldd (or equivalent) */ 20812657Skvn#endif 20912657Skvnstatic const char *strip_file_name; /* pathname of strip */ 21012657Skvnconst char *c_file_name; /* pathname of gcc */ 21112657Skvnstatic char *initname, *fininame; /* names of init and fini funcs */ 21212657Skvn 21312657Skvnstatic struct head constructors; /* list of constructors found */ 21412657Skvnstatic struct head destructors; /* list of destructors found */ 21512657Skvn#ifdef COLLECT_EXPORT_LIST 21612657Skvnstatic struct head exports; /* list of exported symbols */ 21712657Skvn#endif 21812657Skvnstatic struct head frame_tables; /* list of frame unwind info tables */ 21912657Skvn 22012657Skvnstruct obstack temporary_obstack; 22112657Skvnchar * temporary_firstobj; 22212657Skvn 22312657Skvn/* Holds the return value of pexecute and fork. */ 22412657Skvnint pid; 22512657Skvn 22612657Skvn/* Structure to hold all the directories in which to search for files to 22712657Skvn execute. */ 22812657Skvn 22912657Skvnstruct prefix_list 23012657Skvn{ 23112657Skvn const char *prefix; /* String to prepend to the path. */ 23212657Skvn struct prefix_list *next; /* Next in linked list. */ 23312657Skvn}; 23412657Skvn 23512657Skvnstruct path_prefix 23612657Skvn{ 23712657Skvn struct prefix_list *plist; /* List of prefixes to try */ 23812657Skvn int max_len; /* Max length of a prefix in PLIST */ 23912657Skvn const char *name; /* Name of this list (used in config stuff) */ 24012657Skvn}; 24112657Skvn 24212657Skvn#ifdef COLLECT_EXPORT_LIST 24312657Skvn/* Lists to keep libraries to be scanned for global constructors/destructors. */ 24412657Skvnstatic struct head libs; /* list of libraries */ 24512657Skvnstatic struct path_prefix cmdline_lib_dirs; /* directories specified with -L */ 24612657Skvnstatic struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */ 24712657Skvnstatic struct path_prefix *libpaths[3] = {&cmdline_lib_dirs, 24812657Skvn &libpath_lib_dirs, NULL}; 24912657Skvnstatic const char *const libexts[3] = {"a", "so", NULL}; /* possible library extensions */ 25012657Skvn#endif 25112657Skvn 25212657Skvnstatic void handler (int); 25312657Skvnstatic int is_ctor_dtor (const char *); 25412657Skvnstatic char *find_a_file (struct path_prefix *, const char *); 25512657Skvnstatic void add_prefix (struct path_prefix *, const char *); 25612657Skvnstatic void prefix_from_env (const char *, struct path_prefix *); 25712657Skvnstatic void prefix_from_string (const char *, struct path_prefix *); 25812657Skvnstatic void do_wait (const char *); 25912657Skvnstatic void fork_execute (const char *, char **); 26012657Skvnstatic void maybe_unlink (const char *); 26112657Skvnstatic void add_to_list (struct head *, const char *); 26212657Skvnstatic int extract_init_priority (const char *); 26312657Skvnstatic void sort_ids (struct head *); 26412657Skvnstatic void write_list (FILE *, const char *, struct id *); 26512657Skvn#ifdef COLLECT_EXPORT_LIST 26612657Skvnstatic void dump_list (FILE *, const char *, struct id *); 26712657Skvn#endif 26812657Skvn#if 0 26912657Skvnstatic void dump_prefix_list (FILE *, const char *, struct prefix_list *); 27012657Skvn#endif 27112657Skvnstatic void write_list_with_asm (FILE *, const char *, struct id *); 27212657Skvnstatic void write_c_file (FILE *, const char *); 27312657Skvnstatic void write_c_file_stat (FILE *, const char *); 27412657Skvn#ifndef LD_INIT_SWITCH 27512657Skvnstatic void write_c_file_glob (FILE *, const char *); 27612657Skvn#endif 27712657Skvnstatic void scan_prog_file (const char *, enum pass); 27812657Skvn#ifdef SCAN_LIBRARIES 27912657Skvnstatic void scan_libraries (const char *); 28012657Skvn#endif 28112657Skvn#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES 28212657Skvnstatic int is_in_args (const char *, const char **, const char **); 28312657Skvn#endif 28412657Skvn#ifdef COLLECT_EXPORT_LIST 285#if 0 286static int is_in_list (const char *, struct id *); 287#endif 288static void write_aix_file (FILE *, struct id *); 289static char *resolve_lib_name (const char *); 290#endif 291static char *extract_string (const char **); 292 293#ifndef HAVE_DUP2 294static int 295dup2 (int oldfd, int newfd) 296{ 297 int fdtmp[256]; 298 int fdx = 0; 299 int fd; 300 301 if (oldfd == newfd) 302 return oldfd; 303 close (newfd); 304 while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */ 305 fdtmp[fdx++] = fd; 306 while (fdx > 0) 307 close (fdtmp[--fdx]); 308 309 return fd; 310} 311#endif /* ! HAVE_DUP2 */ 312 313/* Delete tempfiles and exit function. */ 314 315void 316collect_exit (int status) 317{ 318 if (c_file != 0 && c_file[0]) 319 maybe_unlink (c_file); 320 321 if (o_file != 0 && o_file[0]) 322 maybe_unlink (o_file); 323 324#ifdef COLLECT_EXPORT_LIST 325 if (export_file != 0 && export_file[0]) 326 maybe_unlink (export_file); 327#endif 328 329 if (ldout != 0 && ldout[0]) 330 { 331 dump_file (ldout); 332 maybe_unlink (ldout); 333 } 334 335 if (status != 0 && output_file != 0 && output_file[0]) 336 maybe_unlink (output_file); 337 338 exit (status); 339} 340 341 342/* Notify user of a non-error. */ 343void 344notice (const char *msgid, ...) 345{ 346 va_list ap; 347 348 va_start (ap, msgid); 349 vfprintf (stderr, _(msgid), ap); 350 va_end (ap); 351} 352 353/* Die when sys call fails. */ 354 355void 356fatal_perror (const char * msgid, ...) 357{ 358 int e = errno; 359 va_list ap; 360 361 va_start (ap, msgid); 362 fprintf (stderr, "collect2: "); 363 vfprintf (stderr, _(msgid), ap); 364 fprintf (stderr, ": %s\n", xstrerror (e)); 365 va_end (ap); 366 367 collect_exit (FATAL_EXIT_CODE); 368} 369 370/* Just die. */ 371 372void 373fatal (const char * msgid, ...) 374{ 375 va_list ap; 376 377 va_start (ap, msgid); 378 fprintf (stderr, "collect2: "); 379 vfprintf (stderr, _(msgid), ap); 380 fprintf (stderr, "\n"); 381 va_end (ap); 382 383 collect_exit (FATAL_EXIT_CODE); 384} 385 386/* Write error message. */ 387 388void 389error (const char * msgid, ...) 390{ 391 va_list ap; 392 393 va_start (ap, msgid); 394 fprintf (stderr, "collect2: "); 395 vfprintf (stderr, _(msgid), ap); 396 fprintf (stderr, "\n"); 397 va_end(ap); 398} 399 400/* In case obstack is linked in, and abort is defined to fancy_abort, 401 provide a default entry. */ 402 403void 404fancy_abort (void) 405{ 406 fatal ("internal error"); 407} 408 409static void 410handler (int signo) 411{ 412 if (c_file != 0 && c_file[0]) 413 maybe_unlink (c_file); 414 415 if (o_file != 0 && o_file[0]) 416 maybe_unlink (o_file); 417 418 if (ldout != 0 && ldout[0]) 419 maybe_unlink (ldout); 420 421#ifdef COLLECT_EXPORT_LIST 422 if (export_file != 0 && export_file[0]) 423 maybe_unlink (export_file); 424#endif 425 426 signal (signo, SIG_DFL); 427 kill (getpid (), signo); 428} 429 430 431int 432file_exists (const char *name) 433{ 434 return access (name, R_OK) == 0; 435} 436 437/* Parse a reasonable subset of shell quoting syntax. */ 438 439static char * 440extract_string (const char **pp) 441{ 442 const char *p = *pp; 443 int backquote = 0; 444 int inside = 0; 445 446 for (;;) 447 { 448 char c = *p; 449 if (c == '\0') 450 break; 451 ++p; 452 if (backquote) 453 obstack_1grow (&temporary_obstack, c); 454 else if (! inside && c == ' ') 455 break; 456 else if (! inside && c == '\\') 457 backquote = 1; 458 else if (c == '\'') 459 inside = !inside; 460 else 461 obstack_1grow (&temporary_obstack, c); 462 } 463 464 obstack_1grow (&temporary_obstack, '\0'); 465 *pp = p; 466 return obstack_finish (&temporary_obstack); 467} 468 469void 470dump_file (const char *name) 471{ 472 FILE *stream = fopen (name, "r"); 473 474 if (stream == 0) 475 return; 476 while (1) 477 { 478 int c; 479 while (c = getc (stream), 480 c != EOF && (ISIDNUM (c) || c == '$' || c == '.')) 481 obstack_1grow (&temporary_obstack, c); 482 if (obstack_object_size (&temporary_obstack) > 0) 483 { 484 const char *word, *p; 485 char *result; 486 obstack_1grow (&temporary_obstack, '\0'); 487 word = obstack_finish (&temporary_obstack); 488 489 if (*word == '.') 490 ++word, putc ('.', stderr); 491 p = word; 492 if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX))) 493 p += strlen (USER_LABEL_PREFIX); 494 495 if (no_demangle) 496 result = 0; 497 else 498 result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE); 499 500 if (result) 501 { 502 int diff; 503 fputs (result, stderr); 504 505 diff = strlen (word) - strlen (result); 506 while (diff > 0 && c == ' ') 507 --diff, putc (' ', stderr); 508 while (diff < 0 && c == ' ') 509 ++diff, c = getc (stream); 510 511 free (result); 512 } 513 else 514 fputs (word, stderr); 515 516 fflush (stderr); 517 obstack_free (&temporary_obstack, temporary_firstobj); 518 } 519 if (c == EOF) 520 break; 521 putc (c, stderr); 522 } 523 fclose (stream); 524} 525 526/* Decide whether the given symbol is: a constructor (1), a destructor 527 (2), a routine in a shared object that calls all the constructors 528 (3) or destructors (4), a DWARF exception-handling table (5), or 529 nothing special (0). */ 530 531static int 532is_ctor_dtor (const char *s) 533{ 534 struct names { const char *const name; const int len; const int ret; 535 const int two_underscores; }; 536 537 const struct names *p; 538 int ch; 539 const char *orig_s = s; 540 541 static const struct names special[] = { 542#ifndef NO_DOLLAR_IN_LABEL 543 { "GLOBAL__I$", sizeof ("GLOBAL__I$")-1, 1, 0 }, 544 { "GLOBAL__D$", sizeof ("GLOBAL__D$")-1, 2, 0 }, 545#else 546#ifndef NO_DOT_IN_LABEL 547 { "GLOBAL__I.", sizeof ("GLOBAL__I.")-1, 1, 0 }, 548 { "GLOBAL__D.", sizeof ("GLOBAL__D.")-1, 2, 0 }, 549#endif /* NO_DOT_IN_LABEL */ 550#endif /* NO_DOLLAR_IN_LABEL */ 551 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 }, 552 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 }, 553 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 }, 554 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 }, 555 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 }, 556 { NULL, 0, 0, 0 } 557 }; 558 559 while ((ch = *s) == '_') 560 ++s; 561 562 if (s == orig_s) 563 return 0; 564 565 for (p = &special[0]; p->len > 0; p++) 566 { 567 if (ch == p->name[0] 568 && (!p->two_underscores || ((s - orig_s) >= 2)) 569 && strncmp(s, p->name, p->len) == 0) 570 { 571 return p->ret; 572 } 573 } 574 return 0; 575} 576 577/* We maintain two prefix lists: one from COMPILER_PATH environment variable 578 and one from the PATH variable. */ 579 580static struct path_prefix cpath, path; 581 582#ifdef CROSS_COMPILE 583/* This is the name of the target machine. We use it to form the name 584 of the files to execute. */ 585 586static const char *const target_machine = TARGET_MACHINE; 587#endif 588 589/* Search for NAME using prefix list PPREFIX. We only look for executable 590 files. 591 592 Return 0 if not found, otherwise return its name, allocated with malloc. */ 593 594static char * 595find_a_file (struct path_prefix *pprefix, const char *name) 596{ 597 char *temp; 598 struct prefix_list *pl; 599 int len = pprefix->max_len + strlen (name) + 1; 600 601 if (debug) 602 fprintf (stderr, "Looking for '%s'\n", name); 603 604#ifdef HOST_EXECUTABLE_SUFFIX 605 len += strlen (HOST_EXECUTABLE_SUFFIX); 606#endif 607 608 temp = xmalloc (len); 609 610 /* Determine the filename to execute (special case for absolute paths). */ 611 612 if (*name == '/' 613#ifdef HAVE_DOS_BASED_FILE_SYSTEM 614 || (*name && name[1] == ':') 615#endif 616 ) 617 { 618 if (access (name, X_OK) == 0) 619 { 620 strcpy (temp, name); 621 622 if (debug) 623 fprintf (stderr, " - found: absolute path\n"); 624 625 return temp; 626 } 627 628#ifdef HOST_EXECUTABLE_SUFFIX 629 /* Some systems have a suffix for executable files. 630 So try appending that. */ 631 strcpy (temp, name); 632 strcat (temp, HOST_EXECUTABLE_SUFFIX); 633 634 if (access (temp, X_OK) == 0) 635 return temp; 636#endif 637 638 if (debug) 639 fprintf (stderr, " - failed to locate using absolute path\n"); 640 } 641 else 642 for (pl = pprefix->plist; pl; pl = pl->next) 643 { 644 struct stat st; 645 646 strcpy (temp, pl->prefix); 647 strcat (temp, name); 648 649 if (stat (temp, &st) >= 0 650 && ! S_ISDIR (st.st_mode) 651 && access (temp, X_OK) == 0) 652 return temp; 653 654#ifdef HOST_EXECUTABLE_SUFFIX 655 /* Some systems have a suffix for executable files. 656 So try appending that. */ 657 strcat (temp, HOST_EXECUTABLE_SUFFIX); 658 659 if (stat (temp, &st) >= 0 660 && ! S_ISDIR (st.st_mode) 661 && access (temp, X_OK) == 0) 662 return temp; 663#endif 664 } 665 666 if (debug && pprefix->plist == NULL) 667 fprintf (stderr, " - failed: no entries in prefix list\n"); 668 669 free (temp); 670 return 0; 671} 672 673/* Add an entry for PREFIX to prefix list PPREFIX. */ 674 675static void 676add_prefix (struct path_prefix *pprefix, const char *prefix) 677{ 678 struct prefix_list *pl, **prev; 679 int len; 680 681 if (pprefix->plist) 682 { 683 for (pl = pprefix->plist; pl->next; pl = pl->next) 684 ; 685 prev = &pl->next; 686 } 687 else 688 prev = &pprefix->plist; 689 690 /* Keep track of the longest prefix. */ 691 692 len = strlen (prefix); 693 if (len > pprefix->max_len) 694 pprefix->max_len = len; 695 696 pl = xmalloc (sizeof (struct prefix_list)); 697 pl->prefix = xstrdup (prefix); 698 699 if (*prev) 700 pl->next = *prev; 701 else 702 pl->next = (struct prefix_list *) 0; 703 *prev = pl; 704} 705 706/* Take the value of the environment variable ENV, break it into a path, and 707 add of the entries to PPREFIX. */ 708 709static void 710prefix_from_env (const char *env, struct path_prefix *pprefix) 711{ 712 const char *p; 713 GET_ENVIRONMENT (p, env); 714 715 if (p) 716 prefix_from_string (p, pprefix); 717} 718 719static void 720prefix_from_string (const char *p, struct path_prefix *pprefix) 721{ 722 const char *startp, *endp; 723 char *nstore = xmalloc (strlen (p) + 3); 724 725 if (debug) 726 fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR); 727 728 startp = endp = p; 729 while (1) 730 { 731 if (*endp == PATH_SEPARATOR || *endp == 0) 732 { 733 strncpy (nstore, startp, endp-startp); 734 if (endp == startp) 735 { 736 strcpy (nstore, "./"); 737 } 738 else if (! IS_DIR_SEPARATOR (endp[-1])) 739 { 740 nstore[endp-startp] = DIR_SEPARATOR; 741 nstore[endp-startp+1] = 0; 742 } 743 else 744 nstore[endp-startp] = 0; 745 746 if (debug) 747 fprintf (stderr, " - add prefix: %s\n", nstore); 748 749 add_prefix (pprefix, nstore); 750 if (*endp == 0) 751 break; 752 endp = startp = endp + 1; 753 } 754 else 755 endp++; 756 } 757} 758 759/* Main program. */ 760 761int 762main (int argc, char **argv) 763{ 764 static const char *const ld_suffix = "ld"; 765 static const char *const real_ld_suffix = "real-ld"; 766 static const char *const collect_ld_suffix = "collect-ld"; 767 static const char *const nm_suffix = "nm"; 768 static const char *const gnm_suffix = "gnm"; 769#ifdef LDD_SUFFIX 770 static const char *const ldd_suffix = LDD_SUFFIX; 771#endif 772 static const char *const strip_suffix = "strip"; 773 static const char *const gstrip_suffix = "gstrip"; 774 775#ifdef CROSS_COMPILE 776 /* If we look for a program in the compiler directories, we just use 777 the short name, since these directories are already system-specific. 778 But it we look for a program in the system directories, we need to 779 qualify the program name with the target machine. */ 780 781 const char *const full_ld_suffix = 782 concat(target_machine, "-", ld_suffix, NULL); 783 const char *const full_nm_suffix = 784 concat (target_machine, "-", nm_suffix, NULL); 785 const char *const full_gnm_suffix = 786 concat (target_machine, "-", gnm_suffix, NULL); 787#ifdef LDD_SUFFIX 788 const char *const full_ldd_suffix = 789 concat (target_machine, "-", ldd_suffix, NULL); 790#endif 791 const char *const full_strip_suffix = 792 concat (target_machine, "-", strip_suffix, NULL); 793 const char *const full_gstrip_suffix = 794 concat (target_machine, "-", gstrip_suffix, NULL); 795#else 796 const char *const full_ld_suffix = ld_suffix; 797 const char *const full_nm_suffix = nm_suffix; 798 const char *const full_gnm_suffix = gnm_suffix; 799#ifdef LDD_SUFFIX 800 const char *const full_ldd_suffix = ldd_suffix; 801#endif 802 const char *const full_strip_suffix = strip_suffix; 803 const char *const full_gstrip_suffix = gstrip_suffix; 804#endif /* CROSS_COMPILE */ 805 806 const char *arg; 807 FILE *outf; 808#ifdef COLLECT_EXPORT_LIST 809 FILE *exportf; 810#endif 811 const char *ld_file_name; 812 const char *p; 813 char **c_argv; 814 const char **c_ptr; 815 char **ld1_argv; 816 const char **ld1; 817 char **ld2_argv; 818 const char **ld2; 819 char **object_lst; 820 const char **object; 821 int first_file; 822 int num_c_args = argc+9; 823 824 no_demangle = !! getenv ("COLLECT_NO_DEMANGLE"); 825 826 /* Suppress demangling by the real linker, which may be broken. */ 827 putenv (xstrdup ("COLLECT_NO_DEMANGLE=")); 828 829#if defined (COLLECT2_HOST_INITIALIZATION) 830 /* Perform system dependent initialization, if necessary. */ 831 COLLECT2_HOST_INITIALIZATION; 832#endif 833 834#ifdef SIGCHLD 835 /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will 836 receive the signal. A different setting is inheritable */ 837 signal (SIGCHLD, SIG_DFL); 838#endif 839 840 gcc_init_libintl (); 841 842 /* Do not invoke xcalloc before this point, since locale needs to be 843 set first, in case a diagnostic is issued. */ 844 845 ld1 = (const char **)(ld1_argv = xcalloc(sizeof (char *), argc+3)); 846 ld2 = (const char **)(ld2_argv = xcalloc(sizeof (char *), argc+10)); 847 object = (const char **)(object_lst = xcalloc(sizeof (char *), argc)); 848 849#ifdef DEBUG 850 debug = 1; 851#endif 852 853 /* Parse command line early for instances of -debug. This allows 854 the debug flag to be set before functions like find_a_file() 855 are called. */ 856 { 857 int i; 858 859 for (i = 1; argv[i] != NULL; i ++) 860 { 861 if (! strcmp (argv[i], "-debug")) 862 debug = 1; 863 COLLECT_PARSE_FLAG (argv[i]); 864 } 865 vflag = debug; 866 } 867 868#ifndef DEFAULT_A_OUT_NAME 869 output_file = "a.out"; 870#else 871 output_file = DEFAULT_A_OUT_NAME; 872#endif 873 874 obstack_begin (&temporary_obstack, 0); 875 temporary_firstobj = obstack_alloc (&temporary_obstack, 0); 876 877 current_demangling_style = auto_demangling; 878 p = getenv ("COLLECT_GCC_OPTIONS"); 879 while (p && *p) 880 { 881 const char *q = extract_string (&p); 882 if (*q == '-' && (q[1] == 'm' || q[1] == 'f')) 883 num_c_args++; 884 } 885 obstack_free (&temporary_obstack, temporary_firstobj); 886 887 /* -fno-profile-arcs -fno-test-coverage -fno-branch-probabilities 888 -fno-exceptions -w */ 889 num_c_args += 5; 890 891 c_ptr = (const char **) (c_argv = xcalloc (sizeof (char *), num_c_args)); 892 893 if (argc < 2) 894 fatal ("no arguments"); 895 896#ifdef SIGQUIT 897 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN) 898 signal (SIGQUIT, handler); 899#endif 900 if (signal (SIGINT, SIG_IGN) != SIG_IGN) 901 signal (SIGINT, handler); 902#ifdef SIGALRM 903 if (signal (SIGALRM, SIG_IGN) != SIG_IGN) 904 signal (SIGALRM, handler); 905#endif 906#ifdef SIGHUP 907 if (signal (SIGHUP, SIG_IGN) != SIG_IGN) 908 signal (SIGHUP, handler); 909#endif 910 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN) 911 signal (SIGSEGV, handler); 912#ifdef SIGBUS 913 if (signal (SIGBUS, SIG_IGN) != SIG_IGN) 914 signal (SIGBUS, handler); 915#endif 916 917 /* Extract COMPILER_PATH and PATH into our prefix list. */ 918 prefix_from_env ("COMPILER_PATH", &cpath); 919 prefix_from_env ("PATH", &path); 920 921 /* Try to discover a valid linker/nm/strip to use. */ 922 923 /* Maybe we know the right file to use (if not cross). */ 924 ld_file_name = 0; 925#ifdef DEFAULT_LINKER 926 if (access (DEFAULT_LINKER, X_OK) == 0) 927 ld_file_name = DEFAULT_LINKER; 928 if (ld_file_name == 0) 929#endif 930#ifdef REAL_LD_FILE_NAME 931 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME); 932 if (ld_file_name == 0) 933#endif 934 /* Search the (target-specific) compiler dirs for ld'. */ 935 ld_file_name = find_a_file (&cpath, real_ld_suffix); 936 /* Likewise for `collect-ld'. */ 937 if (ld_file_name == 0) 938 ld_file_name = find_a_file (&cpath, collect_ld_suffix); 939 /* Search the compiler directories for `ld'. We have protection against 940 recursive calls in find_a_file. */ 941 if (ld_file_name == 0) 942 ld_file_name = find_a_file (&cpath, ld_suffix); 943 /* Search the ordinary system bin directories 944 for `ld' (if native linking) or `TARGET-ld' (if cross). */ 945 if (ld_file_name == 0) 946 ld_file_name = find_a_file (&path, full_ld_suffix); 947 948#ifdef REAL_NM_FILE_NAME 949 nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME); 950 if (nm_file_name == 0) 951#endif 952 nm_file_name = find_a_file (&cpath, gnm_suffix); 953 if (nm_file_name == 0) 954 nm_file_name = find_a_file (&path, full_gnm_suffix); 955 if (nm_file_name == 0) 956 nm_file_name = find_a_file (&cpath, nm_suffix); 957 if (nm_file_name == 0) 958 nm_file_name = find_a_file (&path, full_nm_suffix); 959 960#ifdef LDD_SUFFIX 961 ldd_file_name = find_a_file (&cpath, ldd_suffix); 962 if (ldd_file_name == 0) 963 ldd_file_name = find_a_file (&path, full_ldd_suffix); 964#endif 965 966#ifdef REAL_STRIP_FILE_NAME 967 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME); 968 if (strip_file_name == 0) 969#endif 970 strip_file_name = find_a_file (&cpath, gstrip_suffix); 971 if (strip_file_name == 0) 972 strip_file_name = find_a_file (&path, full_gstrip_suffix); 973 if (strip_file_name == 0) 974 strip_file_name = find_a_file (&cpath, strip_suffix); 975 if (strip_file_name == 0) 976 strip_file_name = find_a_file (&path, full_strip_suffix); 977 978 /* Determine the full path name of the C compiler to use. */ 979 c_file_name = getenv ("COLLECT_GCC"); 980 if (c_file_name == 0) 981 { 982#ifdef CROSS_COMPILE 983 c_file_name = concat (target_machine, "-gcc", NULL); 984#else 985 c_file_name = "gcc"; 986#endif 987 } 988 989 p = find_a_file (&cpath, c_file_name); 990 991 /* Here it should be safe to use the system search path since we should have 992 already qualified the name of the compiler when it is needed. */ 993 if (p == 0) 994 p = find_a_file (&path, c_file_name); 995 996 if (p) 997 c_file_name = p; 998 999 *ld1++ = *ld2++ = ld_file_name; 1000 1001 /* Make temp file names. */ 1002 c_file = make_temp_file (".c"); 1003 o_file = make_temp_file (".o"); 1004#ifdef COLLECT_EXPORT_LIST 1005 export_file = make_temp_file (".x"); 1006#endif 1007 ldout = make_temp_file (".ld"); 1008 *c_ptr++ = c_file_name; 1009 *c_ptr++ = "-x"; 1010 *c_ptr++ = "c"; 1011 *c_ptr++ = "-c"; 1012 *c_ptr++ = "-o"; 1013 *c_ptr++ = o_file; 1014 1015#ifdef COLLECT_EXPORT_LIST 1016 /* Generate a list of directories from LIBPATH. */ 1017 prefix_from_env ("LIBPATH", &libpath_lib_dirs); 1018 /* Add to this list also two standard directories where 1019 AIX loader always searches for libraries. */ 1020 add_prefix (&libpath_lib_dirs, "/lib"); 1021 add_prefix (&libpath_lib_dirs, "/usr/lib"); 1022#endif 1023 1024 /* Get any options that the upper GCC wants to pass to the sub-GCC. 1025 1026 AIX support needs to know if -shared has been specified before 1027 parsing commandline arguments. */ 1028 1029 p = getenv ("COLLECT_GCC_OPTIONS"); 1030 while (p && *p) 1031 { 1032 const char *q = extract_string (&p); 1033 if (*q == '-' && (q[1] == 'm' || q[1] == 'f')) 1034 *c_ptr++ = xstrdup (q); 1035 if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0) 1036 *c_ptr++ = xstrdup (q); 1037 if (strcmp (q, "-shared") == 0) 1038 shared_obj = 1; 1039 if (*q == '-' && q[1] == 'B') 1040 { 1041 *c_ptr++ = xstrdup (q); 1042 if (q[2] == 0) 1043 { 1044 q = extract_string (&p); 1045 *c_ptr++ = xstrdup (q); 1046 } 1047 } 1048 } 1049 obstack_free (&temporary_obstack, temporary_firstobj); 1050 *c_ptr++ = "-fno-profile-arcs"; 1051 *c_ptr++ = "-fno-test-coverage"; 1052 *c_ptr++ = "-fno-branch-probabilities"; 1053 *c_ptr++ = "-fno-exceptions"; 1054 *c_ptr++ = "-w"; 1055 1056 /* !!! When GCC calls collect2, 1057 it does not know whether it is calling collect2 or ld. 1058 So collect2 cannot meaningfully understand any options 1059 except those ld understands. 1060 If you propose to make GCC pass some other option, 1061 just imagine what will happen if ld is really ld!!! */ 1062 1063 /* Parse arguments. Remember output file spec, pass the rest to ld. */ 1064 /* After the first file, put in the c++ rt0. */ 1065 1066 first_file = 1; 1067 while ((arg = *++argv) != (char *) 0) 1068 { 1069 *ld1++ = *ld2++ = arg; 1070 1071 if (arg[0] == '-') 1072 { 1073 switch (arg[1]) 1074 { 1075#ifdef COLLECT_EXPORT_LIST 1076 /* We want to disable automatic exports on AIX when user 1077 explicitly puts an export list in command line */ 1078 case 'b': 1079 if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0) 1080 export_flag = 1; 1081 else if (arg[2] == '6' && arg[3] == '4') 1082 aix64_flag = 1; 1083 break; 1084#endif 1085 1086 case 'd': 1087 if (!strcmp (arg, "-debug")) 1088 { 1089 /* Already parsed. */ 1090 ld1--; 1091 ld2--; 1092 } 1093 break; 1094 1095 case 'l': 1096 if (first_file) 1097 { 1098 /* place o_file BEFORE this argument! */ 1099 first_file = 0; 1100 ld2--; 1101 *ld2++ = o_file; 1102 *ld2++ = arg; 1103 } 1104#ifdef COLLECT_EXPORT_LIST 1105 { 1106 /* Resolving full library name. */ 1107 const char *s = resolve_lib_name (arg+2); 1108 1109 /* Saving a full library name. */ 1110 add_to_list (&libs, s); 1111 } 1112#endif 1113 break; 1114 1115#ifdef COLLECT_EXPORT_LIST 1116 /* Saving directories where to search for libraries. */ 1117 case 'L': 1118 add_prefix (&cmdline_lib_dirs, arg+2); 1119 break; 1120#else 1121#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES 1122 case 'L': 1123 if (is_in_args (arg, (const char **) ld1_argv, ld1-1)) 1124 --ld1; 1125 break; 1126#endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */ 1127#endif 1128 1129 case 'o': 1130 if (arg[2] == '\0') 1131 output_file = *ld1++ = *ld2++ = *++argv; 1132 else if (1 1133#ifdef SWITCHES_NEED_SPACES 1134 && ! strchr (SWITCHES_NEED_SPACES, arg[1]) 1135#endif 1136 ) 1137 1138 output_file = &arg[2]; 1139 break; 1140 1141 case 'r': 1142 if (arg[2] == '\0') 1143 rflag = 1; 1144 break; 1145 1146 case 's': 1147 if (arg[2] == '\0' && do_collecting) 1148 { 1149 /* We must strip after the nm run, otherwise C++ linking 1150 will not work. Thus we strip in the second ld run, or 1151 else with strip if there is no second ld run. */ 1152 strip_flag = 1; 1153 ld1--; 1154 } 1155 break; 1156 1157 case 'v': 1158 if (arg[2] == '\0') 1159 vflag = 1; 1160 break; 1161 } 1162 } 1163 else if ((p = strrchr (arg, '.')) != (char *) 0 1164 && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0 1165 || strcmp (p, ".so") == 0 || strcmp (p, ".lo") == 0 1166 || strcmp (p, ".obj") == 0)) 1167 { 1168 if (first_file) 1169 { 1170 first_file = 0; 1171 if (p[1] == 'o') 1172 *ld2++ = o_file; 1173 else 1174 { 1175 /* place o_file BEFORE this argument! */ 1176 ld2--; 1177 *ld2++ = o_file; 1178 *ld2++ = arg; 1179 } 1180 } 1181 if (p[1] == 'o' || p[1] == 'l') 1182 *object++ = arg; 1183#ifdef COLLECT_EXPORT_LIST 1184 /* libraries can be specified directly, i.e. without -l flag. */ 1185 else 1186 { 1187 /* Saving a full library name. */ 1188 add_to_list (&libs, arg); 1189 } 1190#endif 1191 } 1192 } 1193 1194#ifdef COLLECT_EXPORT_LIST 1195 /* This is added only for debugging purposes. */ 1196 if (debug) 1197 { 1198 fprintf (stderr, "List of libraries:\n"); 1199 dump_list (stderr, "\t", libs.first); 1200 } 1201 1202 /* The AIX linker will discard static constructors in object files if 1203 nothing else in the file is referenced, so look at them first. */ 1204 { 1205 const char **export_object_lst = (const char **)object_lst; 1206 1207 while (export_object_lst < object) 1208 scan_prog_file (*export_object_lst++, PASS_OBJ); 1209 } 1210 { 1211 struct id *list = libs.first; 1212 1213 for (; list; list = list->next) 1214 scan_prog_file (list->name, PASS_FIRST); 1215 } 1216 1217 if (exports.first) 1218 { 1219 char *buf = concat ("-bE:", export_file, NULL); 1220 1221 *ld1++ = buf; 1222 *ld2++ = buf; 1223 1224 exportf = fopen (export_file, "w"); 1225 if (exportf == (FILE *) 0) 1226 fatal_perror ("fopen %s", export_file); 1227 write_aix_file (exportf, exports.first); 1228 if (fclose (exportf)) 1229 fatal_perror ("fclose %s", export_file); 1230 } 1231#endif 1232 1233 *c_ptr++ = c_file; 1234 *c_ptr = *ld1 = *object = (char *) 0; 1235 1236 if (vflag) 1237 { 1238 notice ("collect2 version %s", version_string); 1239#ifdef TARGET_VERSION 1240 TARGET_VERSION; 1241#endif 1242 fprintf (stderr, "\n"); 1243 } 1244 1245 if (debug) 1246 { 1247 const char *ptr; 1248 fprintf (stderr, "ld_file_name = %s\n", 1249 (ld_file_name ? ld_file_name : "not found")); 1250 fprintf (stderr, "c_file_name = %s\n", 1251 (c_file_name ? c_file_name : "not found")); 1252 fprintf (stderr, "nm_file_name = %s\n", 1253 (nm_file_name ? nm_file_name : "not found")); 1254#ifdef LDD_SUFFIX 1255 fprintf (stderr, "ldd_file_name = %s\n", 1256 (ldd_file_name ? ldd_file_name : "not found")); 1257#endif 1258 fprintf (stderr, "strip_file_name = %s\n", 1259 (strip_file_name ? strip_file_name : "not found")); 1260 fprintf (stderr, "c_file = %s\n", 1261 (c_file ? c_file : "not found")); 1262 fprintf (stderr, "o_file = %s\n", 1263 (o_file ? o_file : "not found")); 1264 1265 ptr = getenv ("COLLECT_GCC_OPTIONS"); 1266 if (ptr) 1267 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr); 1268 1269 ptr = getenv ("COLLECT_GCC"); 1270 if (ptr) 1271 fprintf (stderr, "COLLECT_GCC = %s\n", ptr); 1272 1273 ptr = getenv ("COMPILER_PATH"); 1274 if (ptr) 1275 fprintf (stderr, "COMPILER_PATH = %s\n", ptr); 1276 1277 ptr = getenv (LIBRARY_PATH_ENV); 1278 if (ptr) 1279 fprintf (stderr, "%-20s= %s\n", LIBRARY_PATH_ENV, ptr); 1280 1281 fprintf (stderr, "\n"); 1282 } 1283 1284 /* Load the program, searching all libraries and attempting to provide 1285 undefined symbols from repository information. */ 1286 1287 /* On AIX we do this later. */ 1288#ifndef COLLECT_EXPORT_LIST 1289 do_tlink (ld1_argv, object_lst); 1290#endif 1291 1292 /* If -r or they will be run via some other method, do not build the 1293 constructor or destructor list, just return now. */ 1294 if (rflag 1295#ifndef COLLECT_EXPORT_LIST 1296 || ! do_collecting 1297#endif 1298 ) 1299 { 1300#ifdef COLLECT_EXPORT_LIST 1301 /* Do the link we avoided above if we are exiting. */ 1302 do_tlink (ld1_argv, object_lst); 1303 1304 /* But make sure we delete the export file we may have created. */ 1305 if (export_file != 0 && export_file[0]) 1306 maybe_unlink (export_file); 1307#endif 1308 maybe_unlink (c_file); 1309 maybe_unlink (o_file); 1310 return 0; 1311 } 1312 1313 /* Examine the namelist with nm and search it for static constructors 1314 and destructors to call. 1315 Write the constructor and destructor tables to a .s file and reload. */ 1316 1317 /* On AIX we already scanned for global constructors/destructors. */ 1318#ifndef COLLECT_EXPORT_LIST 1319 scan_prog_file (output_file, PASS_FIRST); 1320#endif 1321 1322#ifdef SCAN_LIBRARIES 1323 scan_libraries (output_file); 1324#endif 1325 1326 if (debug) 1327 { 1328 notice ("%d constructor(s) found\n", constructors.number); 1329 notice ("%d destructor(s) found\n", destructors.number); 1330 notice ("%d frame table(s) found\n", frame_tables.number); 1331 } 1332 1333 if (constructors.number == 0 && destructors.number == 0 1334 && frame_tables.number == 0 1335#if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST) 1336 /* If we will be running these functions ourselves, we want to emit 1337 stubs into the shared library so that we do not have to relink 1338 dependent programs when we add static objects. */ 1339 && ! shared_obj 1340#endif 1341 ) 1342 { 1343#ifdef COLLECT_EXPORT_LIST 1344 /* Do tlink without additional code generation. */ 1345 do_tlink (ld1_argv, object_lst); 1346#endif 1347 /* Strip now if it was requested on the command line. */ 1348 if (strip_flag) 1349 { 1350 char **real_strip_argv = xcalloc (sizeof (char *), 3); 1351 const char ** strip_argv = (const char **) real_strip_argv; 1352 1353 strip_argv[0] = strip_file_name; 1354 strip_argv[1] = output_file; 1355 strip_argv[2] = (char *) 0; 1356 fork_execute ("strip", real_strip_argv); 1357 } 1358 1359#ifdef COLLECT_EXPORT_LIST 1360 maybe_unlink (export_file); 1361#endif 1362 maybe_unlink (c_file); 1363 maybe_unlink (o_file); 1364 return 0; 1365 } 1366 1367 /* Sort ctor and dtor lists by priority. */ 1368 sort_ids (&constructors); 1369 sort_ids (&destructors); 1370 1371 maybe_unlink(output_file); 1372 outf = fopen (c_file, "w"); 1373 if (outf == (FILE *) 0) 1374 fatal_perror ("fopen %s", c_file); 1375 1376 write_c_file (outf, c_file); 1377 1378 if (fclose (outf)) 1379 fatal_perror ("fclose %s", c_file); 1380 1381 /* Tell the linker that we have initializer and finalizer functions. */ 1382#ifdef LD_INIT_SWITCH 1383#ifdef COLLECT_EXPORT_LIST 1384 *ld2++ = concat (LD_INIT_SWITCH, ":", initname, ":", fininame, NULL); 1385#else 1386 *ld2++ = LD_INIT_SWITCH; 1387 *ld2++ = initname; 1388 *ld2++ = LD_FINI_SWITCH; 1389 *ld2++ = fininame; 1390#endif 1391#endif 1392 1393#ifdef COLLECT_EXPORT_LIST 1394 if (shared_obj) 1395 { 1396 /* If we did not add export flag to link arguments before, add it to 1397 second link phase now. No new exports should have been added. */ 1398 if (! exports.first) 1399 *ld2++ = concat ("-bE:", export_file, NULL); 1400 1401#ifndef LD_INIT_SWITCH 1402 add_to_list (&exports, initname); 1403 add_to_list (&exports, fininame); 1404 add_to_list (&exports, "_GLOBAL__DI"); 1405 add_to_list (&exports, "_GLOBAL__DD"); 1406#endif 1407 exportf = fopen (export_file, "w"); 1408 if (exportf == (FILE *) 0) 1409 fatal_perror ("fopen %s", export_file); 1410 write_aix_file (exportf, exports.first); 1411 if (fclose (exportf)) 1412 fatal_perror ("fclose %s", export_file); 1413 } 1414#endif 1415 1416 /* End of arguments to second link phase. */ 1417 *ld2 = (char*) 0; 1418 1419 if (debug) 1420 { 1421 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n", 1422 output_file, c_file); 1423 write_c_file (stderr, "stderr"); 1424 fprintf (stderr, "========== end of c_file\n\n"); 1425#ifdef COLLECT_EXPORT_LIST 1426 fprintf (stderr, "\n========== export_file = %s\n", export_file); 1427 write_aix_file (stderr, exports.first); 1428 fprintf (stderr, "========== end of export_file\n\n"); 1429#endif 1430 } 1431 1432 /* Assemble the constructor and destructor tables. 1433 Link the tables in with the rest of the program. */ 1434 1435 fork_execute ("gcc", c_argv); 1436#ifdef COLLECT_EXPORT_LIST 1437 /* On AIX we must call tlink because of possible templates resolution. */ 1438 do_tlink (ld2_argv, object_lst); 1439#else 1440 /* Otherwise, simply call ld because tlink is already done. */ 1441 fork_execute ("ld", ld2_argv); 1442 1443 /* Let scan_prog_file do any final mods (OSF/rose needs this for 1444 constructors/destructors in shared libraries. */ 1445 scan_prog_file (output_file, PASS_SECOND); 1446#endif 1447 1448 maybe_unlink (c_file); 1449 maybe_unlink (o_file); 1450 1451#ifdef COLLECT_EXPORT_LIST 1452 maybe_unlink (export_file); 1453#endif 1454 1455 return 0; 1456} 1457 1458 1459/* Wait for a process to finish, and exit if a nonzero status is found. */ 1460 1461int 1462collect_wait (const char *prog) 1463{ 1464 int status; 1465 1466 pwait (pid, &status, 0); 1467 if (status) 1468 { 1469 if (WIFSIGNALED (status)) 1470 { 1471 int sig = WTERMSIG (status); 1472 error ("%s terminated with signal %d [%s]%s", 1473 prog, sig, strsignal(sig), 1474 WCOREDUMP(status) ? ", core dumped" : ""); 1475 collect_exit (FATAL_EXIT_CODE); 1476 } 1477 1478 if (WIFEXITED (status)) 1479 return WEXITSTATUS (status); 1480 } 1481 return 0; 1482} 1483 1484static void 1485do_wait (const char *prog) 1486{ 1487 int ret = collect_wait (prog); 1488 if (ret != 0) 1489 { 1490 error ("%s returned %d exit status", prog, ret); 1491 collect_exit (ret); 1492 } 1493} 1494 1495 1496/* Execute a program, and wait for the reply. */ 1497 1498void 1499collect_execute (const char *prog, char **argv, const char *redir) 1500{ 1501 char *errmsg_fmt; 1502 char *errmsg_arg; 1503 int redir_handle = -1; 1504 int stdout_save = -1; 1505 int stderr_save = -1; 1506 1507 if (vflag || debug) 1508 { 1509 char **p_argv; 1510 const char *str; 1511 1512 if (argv[0]) 1513 fprintf (stderr, "%s", argv[0]); 1514 else 1515 notice ("[cannot find %s]", prog); 1516 1517 for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++) 1518 fprintf (stderr, " %s", str); 1519 1520 fprintf (stderr, "\n"); 1521 } 1522 1523 fflush (stdout); 1524 fflush (stderr); 1525 1526 /* If we cannot find a program we need, complain error. Do this here 1527 since we might not end up needing something that we could not find. */ 1528 1529 if (argv[0] == 0) 1530 fatal ("cannot find `%s'", prog); 1531 1532 if (redir) 1533 { 1534 /* Open response file. */ 1535 redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT); 1536 1537 /* Duplicate the stdout and stderr file handles 1538 so they can be restored later. */ 1539 stdout_save = dup (STDOUT_FILENO); 1540 if (stdout_save == -1) 1541 fatal_perror ("redirecting stdout: %s", redir); 1542 stderr_save = dup (STDERR_FILENO); 1543 if (stderr_save == -1) 1544 fatal_perror ("redirecting stdout: %s", redir); 1545 1546 /* Redirect stdout & stderr to our response file. */ 1547 dup2 (redir_handle, STDOUT_FILENO); 1548 dup2 (redir_handle, STDERR_FILENO); 1549 } 1550 1551 pid = pexecute (argv[0], argv, argv[0], NULL, &errmsg_fmt, &errmsg_arg, 1552 (PEXECUTE_FIRST | PEXECUTE_LAST | PEXECUTE_SEARCH)); 1553 1554 if (redir) 1555 { 1556 /* Restore stdout and stderr to their previous settings. */ 1557 dup2 (stdout_save, STDOUT_FILENO); 1558 dup2 (stderr_save, STDERR_FILENO); 1559 1560 /* Close response file. */ 1561 close (redir_handle); 1562 } 1563 1564 if (pid == -1) 1565 fatal_perror (errmsg_fmt, errmsg_arg); 1566} 1567 1568static void 1569fork_execute (const char *prog, char **argv) 1570{ 1571 collect_execute (prog, argv, NULL); 1572 do_wait (prog); 1573} 1574 1575/* Unlink a file unless we are debugging. */ 1576 1577static void 1578maybe_unlink (const char *file) 1579{ 1580 if (!debug) 1581 unlink (file); 1582 else 1583 notice ("[Leaving %s]\n", file); 1584} 1585 1586 1587static long sequence_number = 0; 1588 1589/* Add a name to a linked list. */ 1590 1591static void 1592add_to_list (struct head *head_ptr, const char *name) 1593{ 1594 struct id *newid = xcalloc (sizeof (struct id) + strlen (name), 1); 1595 struct id *p; 1596 strcpy (newid->name, name); 1597 1598 if (head_ptr->first) 1599 head_ptr->last->next = newid; 1600 else 1601 head_ptr->first = newid; 1602 1603 /* Check for duplicate symbols. */ 1604 for (p = head_ptr->first; 1605 strcmp (name, p->name) != 0; 1606 p = p->next) 1607 ; 1608 if (p != newid) 1609 { 1610 head_ptr->last->next = 0; 1611 free (newid); 1612 return; 1613 } 1614 1615 newid->sequence = ++sequence_number; 1616 head_ptr->last = newid; 1617 head_ptr->number++; 1618} 1619 1620/* Grab the init priority number from an init function name that 1621 looks like "_GLOBAL_.I.12345.foo". */ 1622 1623static int 1624extract_init_priority (const char *name) 1625{ 1626 int pos = 0, pri; 1627 1628 while (name[pos] == '_') 1629 ++pos; 1630 pos += 10; /* strlen ("GLOBAL__X_") */ 1631 1632 /* Extract init_p number from ctor/dtor name. */ 1633 pri = atoi (name + pos); 1634 return pri ? pri : DEFAULT_INIT_PRIORITY; 1635} 1636 1637/* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order. 1638 ctors will be run from right to left, dtors from left to right. */ 1639 1640static void 1641sort_ids (struct head *head_ptr) 1642{ 1643 /* id holds the current element to insert. id_next holds the next 1644 element to insert. id_ptr iterates through the already sorted elements 1645 looking for the place to insert id. */ 1646 struct id *id, *id_next, **id_ptr; 1647 1648 id = head_ptr->first; 1649 1650 /* We don't have any sorted elements yet. */ 1651 head_ptr->first = NULL; 1652 1653 for (; id; id = id_next) 1654 { 1655 id_next = id->next; 1656 id->sequence = extract_init_priority (id->name); 1657 1658 for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next)) 1659 if (*id_ptr == NULL 1660 /* If the sequence numbers are the same, we put the id from the 1661 file later on the command line later in the list. */ 1662 || id->sequence > (*id_ptr)->sequence 1663 /* Hack: do lexical compare, too. 1664 || (id->sequence == (*id_ptr)->sequence 1665 && strcmp (id->name, (*id_ptr)->name) > 0) */ 1666 ) 1667 { 1668 id->next = *id_ptr; 1669 *id_ptr = id; 1670 break; 1671 } 1672 } 1673 1674 /* Now set the sequence numbers properly so write_c_file works. */ 1675 for (id = head_ptr->first; id; id = id->next) 1676 id->sequence = ++sequence_number; 1677} 1678 1679/* Write: `prefix', the names on list LIST, `suffix'. */ 1680 1681static void 1682write_list (FILE *stream, const char *prefix, struct id *list) 1683{ 1684 while (list) 1685 { 1686 fprintf (stream, "%sx%d,\n", prefix, list->sequence); 1687 list = list->next; 1688 } 1689} 1690 1691#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES 1692/* Given a STRING, return nonzero if it occurs in the list in range 1693 [ARGS_BEGIN,ARGS_END). */ 1694 1695static int 1696is_in_args (const char *string, const char **args_begin, 1697 const char **args_end) 1698{ 1699 const char **args_pointer; 1700 for (args_pointer = args_begin; args_pointer != args_end; ++args_pointer) 1701 if (strcmp (string, *args_pointer) == 0) 1702 return 1; 1703 return 0; 1704} 1705#endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */ 1706 1707#ifdef COLLECT_EXPORT_LIST 1708/* This function is really used only on AIX, but may be useful. */ 1709#if 0 1710static int 1711is_in_list (const char *prefix, struct id *list) 1712{ 1713 while (list) 1714 { 1715 if (!strcmp (prefix, list->name)) return 1; 1716 list = list->next; 1717 } 1718 return 0; 1719} 1720#endif 1721#endif /* COLLECT_EXPORT_LIST */ 1722 1723/* Added for debugging purpose. */ 1724#ifdef COLLECT_EXPORT_LIST 1725static void 1726dump_list (FILE *stream, const char *prefix, struct id *list) 1727{ 1728 while (list) 1729 { 1730 fprintf (stream, "%s%s,\n", prefix, list->name); 1731 list = list->next; 1732 } 1733} 1734#endif 1735 1736#if 0 1737static void 1738dump_prefix_list (FILE *stream, const char *prefix, struct prefix_list *list) 1739{ 1740 while (list) 1741 { 1742 fprintf (stream, "%s%s,\n", prefix, list->prefix); 1743 list = list->next; 1744 } 1745} 1746#endif 1747 1748static void 1749write_list_with_asm (FILE *stream, const char *prefix, struct id *list) 1750{ 1751 while (list) 1752 { 1753 fprintf (stream, "%sx%d __asm__ (\"%s\");\n", 1754 prefix, list->sequence, list->name); 1755 list = list->next; 1756 } 1757} 1758 1759/* Write out the constructor and destructor tables statically (for a shared 1760 object), along with the functions to execute them. */ 1761 1762static void 1763write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED) 1764{ 1765 const char *p, *q; 1766 char *prefix, *r; 1767 int frames = (frame_tables.number > 0); 1768 1769 /* Figure out name of output_file, stripping off .so version. */ 1770 p = strrchr (output_file, '/'); 1771 if (p == 0) 1772 p = output_file; 1773 else 1774 p++; 1775 q = p; 1776 while (q) 1777 { 1778 q = strchr (q,'.'); 1779 if (q == 0) 1780 { 1781 q = p + strlen (p); 1782 break; 1783 } 1784 else 1785 { 1786 if (strncmp (q, ".so", 3) == 0) 1787 { 1788 q += 3; 1789 break; 1790 } 1791 else 1792 q++; 1793 } 1794 } 1795 /* q points to null at end of the string (or . of the .so version) */ 1796 prefix = xmalloc (q - p + 1); 1797 strncpy (prefix, p, q - p); 1798 prefix[q - p] = 0; 1799 for (r = prefix; *r; r++) 1800 if (!ISALNUM ((unsigned char)*r)) 1801 *r = '_'; 1802 if (debug) 1803 notice ("\nwrite_c_file - output name is %s, prefix is %s\n", 1804 output_file, prefix); 1805 1806 initname = concat ("_GLOBAL__FI_", prefix, NULL); 1807 fininame = concat ("_GLOBAL__FD_", prefix, NULL); 1808 1809 free (prefix); 1810 1811 /* Write the tables as C code. */ 1812 1813 fprintf (stream, "static int count;\n"); 1814 fprintf (stream, "typedef void entry_pt();\n"); 1815 write_list_with_asm (stream, "extern entry_pt ", constructors.first); 1816 1817 if (frames) 1818 { 1819 write_list_with_asm (stream, "extern void *", frame_tables.first); 1820 1821 fprintf (stream, "\tstatic void *frame_table[] = {\n"); 1822 write_list (stream, "\t\t&", frame_tables.first); 1823 fprintf (stream, "\t0\n};\n"); 1824 1825 /* This must match what's in frame.h. */ 1826 fprintf (stream, "struct object {\n"); 1827 fprintf (stream, " void *pc_begin;\n"); 1828 fprintf (stream, " void *pc_end;\n"); 1829 fprintf (stream, " void *fde_begin;\n"); 1830 fprintf (stream, " void *fde_array;\n"); 1831 fprintf (stream, " __SIZE_TYPE__ count;\n"); 1832 fprintf (stream, " struct object *next;\n"); 1833 fprintf (stream, "};\n"); 1834 1835 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n"); 1836 fprintf (stream, "extern void *__deregister_frame_info (void *);\n"); 1837 1838 fprintf (stream, "static void reg_frame () {\n"); 1839 fprintf (stream, "\tstatic struct object ob;\n"); 1840 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n"); 1841 fprintf (stream, "\t}\n"); 1842 1843 fprintf (stream, "static void dereg_frame () {\n"); 1844 fprintf (stream, "\t__deregister_frame_info (frame_table);\n"); 1845 fprintf (stream, "\t}\n"); 1846 } 1847 1848 fprintf (stream, "void %s() {\n", initname); 1849 if (constructors.number > 0 || frames) 1850 { 1851 fprintf (stream, "\tstatic entry_pt *ctors[] = {\n"); 1852 write_list (stream, "\t\t", constructors.first); 1853 if (frames) 1854 fprintf (stream, "\treg_frame,\n"); 1855 fprintf (stream, "\t};\n"); 1856 fprintf (stream, "\tentry_pt **p;\n"); 1857 fprintf (stream, "\tif (count++ != 0) return;\n"); 1858 fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames); 1859 fprintf (stream, "\twhile (p > ctors) (*--p)();\n"); 1860 } 1861 else 1862 fprintf (stream, "\t++count;\n"); 1863 fprintf (stream, "}\n"); 1864 write_list_with_asm (stream, "extern entry_pt ", destructors.first); 1865 fprintf (stream, "void %s() {\n", fininame); 1866 if (destructors.number > 0 || frames) 1867 { 1868 fprintf (stream, "\tstatic entry_pt *dtors[] = {\n"); 1869 write_list (stream, "\t\t", destructors.first); 1870 if (frames) 1871 fprintf (stream, "\tdereg_frame,\n"); 1872 fprintf (stream, "\t};\n"); 1873 fprintf (stream, "\tentry_pt **p;\n"); 1874 fprintf (stream, "\tif (--count != 0) return;\n"); 1875 fprintf (stream, "\tp = dtors;\n"); 1876 fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n", 1877 destructors.number + frames); 1878 } 1879 fprintf (stream, "}\n"); 1880 1881 if (shared_obj) 1882 { 1883 COLLECT_SHARED_INIT_FUNC(stream, initname); 1884 COLLECT_SHARED_FINI_FUNC(stream, fininame); 1885 } 1886} 1887 1888/* Write the constructor/destructor tables. */ 1889 1890#ifndef LD_INIT_SWITCH 1891static void 1892write_c_file_glob (FILE *stream, const char *name ATTRIBUTE_UNUSED) 1893{ 1894 /* Write the tables as C code. */ 1895 1896 int frames = (frame_tables.number > 0); 1897 1898 fprintf (stream, "typedef void entry_pt();\n\n"); 1899 1900 write_list_with_asm (stream, "extern entry_pt ", constructors.first); 1901 1902 if (frames) 1903 { 1904 write_list_with_asm (stream, "extern void *", frame_tables.first); 1905 1906 fprintf (stream, "\tstatic void *frame_table[] = {\n"); 1907 write_list (stream, "\t\t&", frame_tables.first); 1908 fprintf (stream, "\t0\n};\n"); 1909 1910 /* This must match what's in frame.h. */ 1911 fprintf (stream, "struct object {\n"); 1912 fprintf (stream, " void *pc_begin;\n"); 1913 fprintf (stream, " void *pc_end;\n"); 1914 fprintf (stream, " void *fde_begin;\n"); 1915 fprintf (stream, " void *fde_array;\n"); 1916 fprintf (stream, " __SIZE_TYPE__ count;\n"); 1917 fprintf (stream, " struct object *next;\n"); 1918 fprintf (stream, "};\n"); 1919 1920 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n"); 1921 fprintf (stream, "extern void *__deregister_frame_info (void *);\n"); 1922 1923 fprintf (stream, "static void reg_frame () {\n"); 1924 fprintf (stream, "\tstatic struct object ob;\n"); 1925 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n"); 1926 fprintf (stream, "\t}\n"); 1927 1928 fprintf (stream, "static void dereg_frame () {\n"); 1929 fprintf (stream, "\t__deregister_frame_info (frame_table);\n"); 1930 fprintf (stream, "\t}\n"); 1931 } 1932 1933 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n"); 1934 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames); 1935 write_list (stream, "\t", constructors.first); 1936 if (frames) 1937 fprintf (stream, "\treg_frame,\n"); 1938 fprintf (stream, "\t0\n};\n\n"); 1939 1940 write_list_with_asm (stream, "extern entry_pt ", destructors.first); 1941 1942 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n"); 1943 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames); 1944 write_list (stream, "\t", destructors.first); 1945 if (frames) 1946 fprintf (stream, "\tdereg_frame,\n"); 1947 fprintf (stream, "\t0\n};\n\n"); 1948 1949 fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN); 1950 fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN); 1951} 1952#endif /* ! LD_INIT_SWITCH */ 1953 1954static void 1955write_c_file (FILE *stream, const char *name) 1956{ 1957 fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n"); 1958#ifndef LD_INIT_SWITCH 1959 if (! shared_obj) 1960 write_c_file_glob (stream, name); 1961 else 1962#endif 1963 write_c_file_stat (stream, name); 1964 fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n"); 1965} 1966 1967#ifdef COLLECT_EXPORT_LIST 1968static void 1969write_aix_file (FILE *stream, struct id *list) 1970{ 1971 for (; list; list = list->next) 1972 { 1973 fputs (list->name, stream); 1974 putc ('\n', stream); 1975 } 1976} 1977#endif 1978 1979#ifdef OBJECT_FORMAT_NONE 1980 1981/* Generic version to scan the name list of the loaded program for 1982 the symbols g++ uses for static constructors and destructors. 1983 1984 The constructor table begins at __CTOR_LIST__ and contains a count 1985 of the number of pointers (or -1 if the constructors are built in a 1986 separate section by the linker), followed by the pointers to the 1987 constructor functions, terminated with a null pointer. The 1988 destructor table has the same format, and begins at __DTOR_LIST__. */ 1989 1990static void 1991scan_prog_file (const char *prog_name, enum pass which_pass) 1992{ 1993 void (*int_handler) (int); 1994 void (*quit_handler) (int); 1995 char *real_nm_argv[4]; 1996 const char **nm_argv = (const char **) real_nm_argv; 1997 int argc = 0; 1998 int pipe_fd[2]; 1999 char *p, buf[1024]; 2000 FILE *inf; 2001 2002 if (which_pass == PASS_SECOND) 2003 return; 2004 2005 /* If we do not have an `nm', complain. */ 2006 if (nm_file_name == 0) 2007 fatal ("cannot find `nm'"); 2008 2009 nm_argv[argc++] = nm_file_name; 2010 if (NM_FLAGS[0] != '\0') 2011 nm_argv[argc++] = NM_FLAGS; 2012 2013 nm_argv[argc++] = prog_name; 2014 nm_argv[argc++] = (char *) 0; 2015 2016 if (pipe (pipe_fd) < 0) 2017 fatal_perror ("pipe"); 2018 2019 inf = fdopen (pipe_fd[0], "r"); 2020 if (inf == (FILE *) 0) 2021 fatal_perror ("fdopen"); 2022 2023 /* Trace if needed. */ 2024 if (vflag) 2025 { 2026 const char **p_argv; 2027 const char *str; 2028 2029 for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++) 2030 fprintf (stderr, " %s", str); 2031 2032 fprintf (stderr, "\n"); 2033 } 2034 2035 fflush (stdout); 2036 fflush (stderr); 2037 2038 /* Spawn child nm on pipe. */ 2039 pid = vfork (); 2040 if (pid == -1) 2041 fatal_perror (VFORK_STRING); 2042 2043 if (pid == 0) /* child context */ 2044 { 2045 /* setup stdout */ 2046 if (dup2 (pipe_fd[1], 1) < 0) 2047 fatal_perror ("dup2 %d 1", pipe_fd[1]); 2048 2049 if (close (pipe_fd[0]) < 0) 2050 fatal_perror ("close %d", pipe_fd[0]); 2051 2052 if (close (pipe_fd[1]) < 0) 2053 fatal_perror ("close %d", pipe_fd[1]); 2054 2055 execv (nm_file_name, real_nm_argv); 2056 fatal_perror ("execv %s", nm_file_name); 2057 } 2058 2059 /* Parent context from here on. */ 2060 int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN); 2061#ifdef SIGQUIT 2062 quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN); 2063#endif 2064 2065 if (close (pipe_fd[1]) < 0) 2066 fatal_perror ("close %d", pipe_fd[1]); 2067 2068 if (debug) 2069 fprintf (stderr, "\nnm output with constructors/destructors.\n"); 2070 2071 /* Read each line of nm output. */ 2072 while (fgets (buf, sizeof buf, inf) != (char *) 0) 2073 { 2074 int ch, ch2; 2075 char *name, *end; 2076 2077 /* If it contains a constructor or destructor name, add the name 2078 to the appropriate list. */ 2079 2080 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++) 2081 if (ch == ' ' && p[1] == 'U' && p[2] == ' ') 2082 break; 2083 2084 if (ch != '_') 2085 continue; 2086 2087 name = p; 2088 /* Find the end of the symbol name. 2089 Do not include `|', because Encore nm can tack that on the end. */ 2090 for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|'; 2091 end++) 2092 continue; 2093 2094 2095 *end = '\0'; 2096 switch (is_ctor_dtor (name)) 2097 { 2098 case 1: 2099 if (which_pass != PASS_LIB) 2100 add_to_list (&constructors, name); 2101 break; 2102 2103 case 2: 2104 if (which_pass != PASS_LIB) 2105 add_to_list (&destructors, name); 2106 break; 2107 2108 case 3: 2109 if (which_pass != PASS_LIB) 2110 fatal ("init function found in object %s", prog_name); 2111#ifndef LD_INIT_SWITCH 2112 add_to_list (&constructors, name); 2113#endif 2114 break; 2115 2116 case 4: 2117 if (which_pass != PASS_LIB) 2118 fatal ("fini function found in object %s", prog_name); 2119#ifndef LD_FINI_SWITCH 2120 add_to_list (&destructors, name); 2121#endif 2122 break; 2123 2124 case 5: 2125 if (which_pass != PASS_LIB) 2126 add_to_list (&frame_tables, name); 2127 break; 2128 2129 default: /* not a constructor or destructor */ 2130 continue; 2131 } 2132 2133 if (debug) 2134 fprintf (stderr, "\t%s\n", buf); 2135 } 2136 2137 if (debug) 2138 fprintf (stderr, "\n"); 2139 2140 if (fclose (inf) != 0) 2141 fatal_perror ("fclose"); 2142 2143 do_wait (nm_file_name); 2144 2145 signal (SIGINT, int_handler); 2146#ifdef SIGQUIT 2147 signal (SIGQUIT, quit_handler); 2148#endif 2149} 2150 2151#if SUNOS4_SHARED_LIBRARIES 2152 2153/* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries 2154 that the output file depends upon and their initialization/finalization 2155 routines, if any. */ 2156 2157#include <a.out.h> 2158#include <fcntl.h> 2159#include <link.h> 2160#include <sys/mman.h> 2161#include <sys/param.h> 2162#include <unistd.h> 2163#include <sys/dir.h> 2164 2165/* pointers to the object file */ 2166unsigned object; /* address of memory mapped file */ 2167unsigned objsize; /* size of memory mapped to file */ 2168char * code; /* pointer to code segment */ 2169char * data; /* pointer to data segment */ 2170struct nlist *symtab; /* pointer to symbol table */ 2171struct link_dynamic *ld; 2172struct link_dynamic_2 *ld_2; 2173struct head libraries; 2174 2175/* Map the file indicated by NAME into memory and store its address. */ 2176 2177static void 2178mapfile (const char *name) 2179{ 2180 int fp; 2181 struct stat s; 2182 if ((fp = open (name, O_RDONLY)) == -1) 2183 fatal ("unable to open file '%s'", name); 2184 if (fstat (fp, &s) == -1) 2185 fatal ("unable to stat file '%s'", name); 2186 2187 objsize = s.st_size; 2188 object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE, 2189 fp, 0); 2190 if (object == (unsigned)-1) 2191 fatal ("unable to mmap file '%s'", name); 2192 2193 close (fp); 2194} 2195 2196/* Helpers for locatelib. */ 2197 2198static const char *libname; 2199 2200static int 2201libselect (struct direct *d) 2202{ 2203 return (strncmp (libname, d->d_name, strlen (libname)) == 0); 2204} 2205 2206/* If one file has an additional numeric extension past LIBNAME, then put 2207 that one first in the sort. If both files have additional numeric 2208 extensions, then put the one with the higher number first in the sort. 2209 2210 We must verify that the extension is numeric, because Sun saves the 2211 original versions of patched libraries with a .FCS extension. Files with 2212 invalid extensions must go last in the sort, so that they will not be used. */ 2213 2214static int 2215libcompare (struct direct **d1, struct direct **d2) 2216{ 2217 int i1, i2 = strlen (libname); 2218 char *e1 = (*d1)->d_name + i2; 2219 char *e2 = (*d2)->d_name + i2; 2220 2221 while (*e1 && *e2 && *e1 == '.' && *e2 == '.' 2222 && e1[1] && ISDIGIT (e1[1]) && e2[1] && ISDIGIT (e2[1])) 2223 { 2224 ++e1; 2225 ++e2; 2226 i1 = strtol (e1, &e1, 10); 2227 i2 = strtol (e2, &e2, 10); 2228 if (i1 != i2) 2229 return i1 - i2; 2230 } 2231 2232 if (*e1) 2233 { 2234 /* It has a valid numeric extension, prefer this one. */ 2235 if (*e1 == '.' && e1[1] && ISDIGIT (e1[1])) 2236 return 1; 2237 /* It has an invalid numeric extension, must prefer the other one. */ 2238 else 2239 return -1; 2240 } 2241 else if (*e2) 2242 { 2243 /* It has a valid numeric extension, prefer this one. */ 2244 if (*e2 == '.' && e2[1] && ISDIGIT (e2[1])) 2245 return -1; 2246 /* It has an invalid numeric extension, must prefer the other one. */ 2247 else 2248 return 1; 2249 } 2250 else 2251 return 0; 2252} 2253 2254/* Given the name NAME of a dynamic dependency, find its pathname and add 2255 it to the list of libraries. */ 2256 2257static void 2258locatelib (const char *name) 2259{ 2260 static const char **l; 2261 static int cnt; 2262 char buf[MAXPATHLEN]; 2263 char *p, *q; 2264 const char **pp; 2265 2266 if (l == 0) 2267 { 2268 char *ld_rules; 2269 char *ldr = 0; 2270 /* counting elements in array, need 1 extra for null */ 2271 cnt = 1; 2272 ld_rules = (char *) (ld_2->ld_rules + code); 2273 if (ld_rules) 2274 { 2275 cnt++; 2276 for (; *ld_rules != 0; ld_rules++) 2277 if (*ld_rules == ':') 2278 cnt++; 2279 ld_rules = (char *) (ld_2->ld_rules + code); 2280 ldr = xstrdup (ld_rules); 2281 } 2282 p = getenv ("LD_LIBRARY_PATH"); 2283 q = 0; 2284 if (p) 2285 { 2286 cnt++; 2287 for (q = p ; *q != 0; q++) 2288 if (*q == ':') 2289 cnt++; 2290 q = xstrdup (p); 2291 } 2292 l = xmalloc ((cnt + 3) * sizeof (char *)); 2293 pp = l; 2294 if (ldr) 2295 { 2296 *pp++ = ldr; 2297 for (; *ldr != 0; ldr++) 2298 if (*ldr == ':') 2299 { 2300 *ldr++ = 0; 2301 *pp++ = ldr; 2302 } 2303 } 2304 if (q) 2305 { 2306 *pp++ = q; 2307 for (; *q != 0; q++) 2308 if (*q == ':') 2309 { 2310 *q++ = 0; 2311 *pp++ = q; 2312 } 2313 } 2314 /* built in directories are /lib, /usr/lib, and /usr/local/lib */ 2315 *pp++ = "/lib"; 2316 *pp++ = "/usr/lib"; 2317 *pp++ = "/usr/local/lib"; 2318 *pp = 0; 2319 } 2320 libname = name; 2321 for (pp = l; *pp != 0 ; pp++) 2322 { 2323 struct direct **namelist; 2324 int entries; 2325 if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0) 2326 { 2327 sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name); 2328 add_to_list (&libraries, buf); 2329 if (debug) 2330 fprintf (stderr, "%s\n", buf); 2331 break; 2332 } 2333 } 2334 if (*pp == 0) 2335 { 2336 if (debug) 2337 notice ("not found\n"); 2338 else 2339 fatal ("dynamic dependency %s not found", name); 2340 } 2341} 2342 2343/* Scan the _DYNAMIC structure of the output file to find shared libraries 2344 that it depends upon and any constructors or destructors they contain. */ 2345 2346static void 2347scan_libraries (const char *prog_name) 2348{ 2349 struct exec *header; 2350 char *base; 2351 struct link_object *lo; 2352 char buff[MAXPATHLEN]; 2353 struct id *list; 2354 2355 mapfile (prog_name); 2356 header = (struct exec *)object; 2357 if (N_BADMAG (*header)) 2358 fatal ("bad magic number in file '%s'", prog_name); 2359 if (header->a_dynamic == 0) 2360 return; 2361 2362 code = (char *) (N_TXTOFF (*header) + (long) header); 2363 data = (char *) (N_DATOFF (*header) + (long) header); 2364 symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header); 2365 2366 if (header->a_magic == ZMAGIC && header->a_entry == 0x20) 2367 { 2368 /* shared object */ 2369 ld = (struct link_dynamic *) (symtab->n_value + code); 2370 base = code; 2371 } 2372 else 2373 { 2374 /* executable */ 2375 ld = (struct link_dynamic *) data; 2376 base = code-PAGSIZ; 2377 } 2378 2379 if (debug) 2380 notice ("dynamic dependencies.\n"); 2381 2382 ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base); 2383 for (lo = (struct link_object *) ld_2->ld_need; lo; 2384 lo = (struct link_object *) lo->lo_next) 2385 { 2386 char *name; 2387 lo = (struct link_object *) ((long) lo + code); 2388 name = (char *) (code + lo->lo_name); 2389 if (lo->lo_library) 2390 { 2391 if (debug) 2392 fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major); 2393 sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor); 2394 locatelib (buff); 2395 } 2396 else 2397 { 2398 if (debug) 2399 fprintf (stderr, "\t%s\n", name); 2400 add_to_list (&libraries, name); 2401 } 2402 } 2403 2404 if (debug) 2405 fprintf (stderr, "\n"); 2406 2407 /* Now iterate through the library list adding their symbols to 2408 the list. */ 2409 for (list = libraries.first; list; list = list->next) 2410 scan_prog_file (list->name, PASS_LIB); 2411} 2412 2413#else /* SUNOS4_SHARED_LIBRARIES */ 2414#ifdef LDD_SUFFIX 2415 2416/* Use the List Dynamic Dependencies program to find shared libraries that 2417 the output file depends upon and their initialization/finalization 2418 routines, if any. */ 2419 2420static void 2421scan_libraries (const char *prog_name) 2422{ 2423 static struct head libraries; /* list of shared libraries found */ 2424 struct id *list; 2425 void (*int_handler) (int); 2426 void (*quit_handler) (int); 2427 char *real_ldd_argv[4]; 2428 const char **ldd_argv = (const char **) real_ldd_argv; 2429 int argc = 0; 2430 int pipe_fd[2]; 2431 char buf[1024]; 2432 FILE *inf; 2433 2434 /* If we do not have an `ldd', complain. */ 2435 if (ldd_file_name == 0) 2436 { 2437 error ("cannot find `ldd'"); 2438 return; 2439 } 2440 2441 ldd_argv[argc++] = ldd_file_name; 2442 ldd_argv[argc++] = prog_name; 2443 ldd_argv[argc++] = (char *) 0; 2444 2445 if (pipe (pipe_fd) < 0) 2446 fatal_perror ("pipe"); 2447 2448 inf = fdopen (pipe_fd[0], "r"); 2449 if (inf == (FILE *) 0) 2450 fatal_perror ("fdopen"); 2451 2452 /* Trace if needed. */ 2453 if (vflag) 2454 { 2455 const char **p_argv; 2456 const char *str; 2457 2458 for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++) 2459 fprintf (stderr, " %s", str); 2460 2461 fprintf (stderr, "\n"); 2462 } 2463 2464 fflush (stdout); 2465 fflush (stderr); 2466 2467 /* Spawn child ldd on pipe. */ 2468 pid = vfork (); 2469 if (pid == -1) 2470 fatal_perror (VFORK_STRING); 2471 2472 if (pid == 0) /* child context */ 2473 { 2474 /* setup stdout */ 2475 if (dup2 (pipe_fd[1], 1) < 0) 2476 fatal_perror ("dup2 %d 1", pipe_fd[1]); 2477 2478 if (close (pipe_fd[0]) < 0) 2479 fatal_perror ("close %d", pipe_fd[0]); 2480 2481 if (close (pipe_fd[1]) < 0) 2482 fatal_perror ("close %d", pipe_fd[1]); 2483 2484 execv (ldd_file_name, real_ldd_argv); 2485 fatal_perror ("execv %s", ldd_file_name); 2486 } 2487 2488 /* Parent context from here on. */ 2489 int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN); 2490#ifdef SIGQUIT 2491 quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN); 2492#endif 2493 2494 if (close (pipe_fd[1]) < 0) 2495 fatal_perror ("close %d", pipe_fd[1]); 2496 2497 if (debug) 2498 notice ("\nldd output with constructors/destructors.\n"); 2499 2500 /* Read each line of ldd output. */ 2501 while (fgets (buf, sizeof buf, inf) != (char *) 0) 2502 { 2503 int ch2; 2504 char *name, *end, *p = buf; 2505 2506 /* Extract names of libraries and add to list. */ 2507 PARSE_LDD_OUTPUT (p); 2508 if (p == 0) 2509 continue; 2510 2511 name = p; 2512 if (strncmp (name, "not found", sizeof ("not found") - 1) == 0) 2513 fatal ("dynamic dependency %s not found", buf); 2514 2515 /* Find the end of the symbol name. */ 2516 for (end = p; 2517 (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|'; 2518 end++) 2519 continue; 2520 *end = '\0'; 2521 2522 if (access (name, R_OK) == 0) 2523 add_to_list (&libraries, name); 2524 else 2525 fatal ("unable to open dynamic dependency '%s'", buf); 2526 2527 if (debug) 2528 fprintf (stderr, "\t%s\n", buf); 2529 } 2530 if (debug) 2531 fprintf (stderr, "\n"); 2532 2533 if (fclose (inf) != 0) 2534 fatal_perror ("fclose"); 2535 2536 do_wait (ldd_file_name); 2537 2538 signal (SIGINT, int_handler); 2539#ifdef SIGQUIT 2540 signal (SIGQUIT, quit_handler); 2541#endif 2542 2543 /* Now iterate through the library list adding their symbols to 2544 the list. */ 2545 for (list = libraries.first; list; list = list->next) 2546 scan_prog_file (list->name, PASS_LIB); 2547} 2548 2549#endif /* LDD_SUFFIX */ 2550#endif /* SUNOS4_SHARED_LIBRARIES */ 2551 2552#endif /* OBJECT_FORMAT_NONE */ 2553 2554 2555/* 2556 * COFF specific stuff. 2557 */ 2558 2559#ifdef OBJECT_FORMAT_COFF 2560 2561#if defined (EXTENDED_COFF) 2562 2563# define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax) 2564# define GCC_SYMENT SYMR 2565# define GCC_OK_SYMBOL(X) ((X).st == stProc || (X).st == stGlobal) 2566# define GCC_SYMINC(X) (1) 2567# define GCC_SYMZERO(X) (SYMHEADER(X).isymMax) 2568# define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0) 2569 2570#else 2571 2572# define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms) 2573# define GCC_SYMENT SYMENT 2574# if defined (C_WEAKEXT) 2575# define GCC_OK_SYMBOL(X) \ 2576 (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \ 2577 ((X).n_scnum > N_UNDEF) && \ 2578 (aix64_flag \ 2579 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \ 2580 || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))) 2581# define GCC_UNDEF_SYMBOL(X) \ 2582 (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \ 2583 ((X).n_scnum == N_UNDEF)) 2584# else 2585# define GCC_OK_SYMBOL(X) \ 2586 (((X).n_sclass == C_EXT) && \ 2587 ((X).n_scnum > N_UNDEF) && \ 2588 (aix64_flag \ 2589 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \ 2590 || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))) 2591# define GCC_UNDEF_SYMBOL(X) \ 2592 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF)) 2593# endif 2594# define GCC_SYMINC(X) ((X).n_numaux+1) 2595# define GCC_SYMZERO(X) 0 2596 2597/* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */ 2598#ifdef _AIX51 2599# define GCC_CHECK_HDR(X) \ 2600 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \ 2601 || (HEADER (X).f_magic == 0767 && aix64_flag)) 2602#else 2603# define GCC_CHECK_HDR(X) \ 2604 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \ 2605 || (HEADER (X).f_magic == 0757 && aix64_flag)) 2606#endif 2607 2608#endif 2609 2610#ifdef COLLECT_EXPORT_LIST 2611/* Array of standard AIX libraries which should not 2612 be scanned for ctors/dtors. */ 2613static const char *const aix_std_libs[] = { 2614 "/unix", 2615 "/lib/libc.a", 2616 "/lib/libm.a", 2617 "/lib/libc_r.a", 2618 "/lib/libm_r.a", 2619 "/usr/lib/libc.a", 2620 "/usr/lib/libm.a", 2621 "/usr/lib/libc_r.a", 2622 "/usr/lib/libm_r.a", 2623 "/usr/lib/threads/libc.a", 2624 "/usr/ccs/lib/libc.a", 2625 "/usr/ccs/lib/libm.a", 2626 "/usr/ccs/lib/libc_r.a", 2627 "/usr/ccs/lib/libm_r.a", 2628 NULL 2629}; 2630 2631/* This function checks the filename and returns 1 2632 if this name matches the location of a standard AIX library. */ 2633static int ignore_library (const char *); 2634static int 2635ignore_library (const char *name) 2636{ 2637 const char *const *p = &aix_std_libs[0]; 2638 while (*p++ != NULL) 2639 if (! strcmp (name, *p)) return 1; 2640 return 0; 2641} 2642#endif /* COLLECT_EXPORT_LIST */ 2643 2644#if defined (HAVE_DECL_LDGETNAME) && !HAVE_DECL_LDGETNAME 2645extern char *ldgetname (LDFILE *, GCC_SYMENT *); 2646#endif 2647 2648/* COFF version to scan the name list of the loaded program for 2649 the symbols g++ uses for static constructors and destructors. 2650 2651 The constructor table begins at __CTOR_LIST__ and contains a count 2652 of the number of pointers (or -1 if the constructors are built in a 2653 separate section by the linker), followed by the pointers to the 2654 constructor functions, terminated with a null pointer. The 2655 destructor table has the same format, and begins at __DTOR_LIST__. */ 2656 2657static void 2658scan_prog_file (const char *prog_name, enum pass which_pass) 2659{ 2660 LDFILE *ldptr = NULL; 2661 int sym_index, sym_count; 2662 int is_shared = 0; 2663 2664 if (which_pass != PASS_FIRST && which_pass != PASS_OBJ) 2665 return; 2666 2667#ifdef COLLECT_EXPORT_LIST 2668 /* We do not need scanning for some standard C libraries. */ 2669 if (which_pass == PASS_FIRST && ignore_library (prog_name)) 2670 return; 2671 2672 /* On AIX we have a loop, because there is not much difference 2673 between an object and an archive. This trick allows us to 2674 eliminate scan_libraries() function. */ 2675 do 2676 { 2677#endif 2678 /* Some platforms (e.g. OSF4) declare ldopen as taking a 2679 non-const char * filename parameter, even though it will not 2680 modify that string. So we must cast away const-ness here, 2681 which will cause -Wcast-qual to burp. */ 2682 if ((ldptr = ldopen ((char *)prog_name, ldptr)) != NULL) 2683 { 2684 if (! MY_ISCOFF (HEADER (ldptr).f_magic)) 2685 fatal ("%s: not a COFF file", prog_name); 2686 2687 if (GCC_CHECK_HDR (ldptr)) 2688 { 2689 sym_count = GCC_SYMBOLS (ldptr); 2690 sym_index = GCC_SYMZERO (ldptr); 2691 2692#ifdef COLLECT_EXPORT_LIST 2693 /* Is current archive member a shared object? */ 2694 is_shared = HEADER (ldptr).f_flags & F_SHROBJ; 2695#endif 2696 2697 while (sym_index < sym_count) 2698 { 2699 GCC_SYMENT symbol; 2700 2701 if (ldtbread (ldptr, sym_index, &symbol) <= 0) 2702 break; 2703 sym_index += GCC_SYMINC (symbol); 2704 2705 if (GCC_OK_SYMBOL (symbol)) 2706 { 2707 char *name; 2708 2709 if ((name = ldgetname (ldptr, &symbol)) == NULL) 2710 continue; /* Should never happen. */ 2711 2712#ifdef XCOFF_DEBUGGING_INFO 2713 /* All AIX function names have a duplicate entry 2714 beginning with a dot. */ 2715 if (*name == '.') 2716 ++name; 2717#endif 2718 2719 switch (is_ctor_dtor (name)) 2720 { 2721 case 1: 2722 if (! is_shared) 2723 add_to_list (&constructors, name); 2724#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH) 2725 if (which_pass == PASS_OBJ) 2726 add_to_list (&exports, name); 2727#endif 2728 break; 2729 2730 case 2: 2731 if (! is_shared) 2732 add_to_list (&destructors, name); 2733#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH) 2734 if (which_pass == PASS_OBJ) 2735 add_to_list (&exports, name); 2736#endif 2737 break; 2738 2739#ifdef COLLECT_EXPORT_LIST 2740 case 3: 2741#ifndef LD_INIT_SWITCH 2742 if (is_shared) 2743 add_to_list (&constructors, name); 2744#endif 2745 break; 2746 2747 case 4: 2748#ifndef LD_INIT_SWITCH 2749 if (is_shared) 2750 add_to_list (&destructors, name); 2751#endif 2752 break; 2753#endif 2754 2755 case 5: 2756 if (! is_shared) 2757 add_to_list (&frame_tables, name); 2758#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH) 2759 if (which_pass == PASS_OBJ) 2760 add_to_list (&exports, name); 2761#endif 2762 break; 2763 2764 default: /* not a constructor or destructor */ 2765#ifdef COLLECT_EXPORT_LIST 2766 /* Explicitly export all global symbols when 2767 building a shared object on AIX, but do not 2768 re-export symbols from another shared object 2769 and do not export symbols if the user 2770 provides an explicit export list. */ 2771 if (shared_obj && !is_shared 2772 && which_pass == PASS_OBJ && !export_flag) 2773 add_to_list (&exports, name); 2774#endif 2775 continue; 2776 } 2777 2778 if (debug) 2779#if !defined(EXTENDED_COFF) 2780 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n", 2781 symbol.n_scnum, symbol.n_sclass, 2782 (symbol.n_type ? "0" : ""), symbol.n_type, 2783 name); 2784#else 2785 fprintf (stderr, 2786 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n", 2787 symbol.iss, (long) symbol.value, symbol.index, name); 2788#endif 2789 } 2790 } 2791 } 2792#ifdef COLLECT_EXPORT_LIST 2793 else 2794 { 2795 /* If archive contains both 32-bit and 64-bit objects, 2796 we want to skip objects in other mode so mismatch normal. */ 2797 if (debug) 2798 fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n", 2799 prog_name, HEADER (ldptr).f_magic, aix64_flag); 2800 } 2801#endif 2802 } 2803 else 2804 { 2805 fatal ("%s: cannot open as COFF file", prog_name); 2806 } 2807#ifdef COLLECT_EXPORT_LIST 2808 /* On AIX loop continues while there are more members in archive. */ 2809 } 2810 while (ldclose (ldptr) == FAILURE); 2811#else 2812 /* Otherwise we simply close ldptr. */ 2813 (void) ldclose(ldptr); 2814#endif 2815} 2816#endif /* OBJECT_FORMAT_COFF */ 2817 2818#ifdef COLLECT_EXPORT_LIST 2819/* Given a library name without "lib" prefix, this function 2820 returns a full library name including a path. */ 2821static char * 2822resolve_lib_name (const char *name) 2823{ 2824 char *lib_buf; 2825 int i, j, l = 0; 2826 2827 for (i = 0; libpaths[i]; i++) 2828 if (libpaths[i]->max_len > l) 2829 l = libpaths[i]->max_len; 2830 2831 lib_buf = xmalloc (l + strlen(name) + 10); 2832 2833 for (i = 0; libpaths[i]; i++) 2834 { 2835 struct prefix_list *list = libpaths[i]->plist; 2836 for (; list; list = list->next) 2837 { 2838 /* The following lines are needed because path_prefix list 2839 may contain directories both with trailing '/' and 2840 without it. */ 2841 const char *p = ""; 2842 if (list->prefix[strlen(list->prefix)-1] != '/') 2843 p = "/"; 2844 for (j = 0; libexts[j]; j++) 2845 { 2846 sprintf (lib_buf, "%s%slib%s.%s", 2847 list->prefix, p, name, libexts[j]); 2848if (debug) fprintf (stderr, "searching for: %s\n", lib_buf); 2849 if (file_exists (lib_buf)) 2850 { 2851if (debug) fprintf (stderr, "found: %s\n", lib_buf); 2852 return (lib_buf); 2853 } 2854 } 2855 } 2856 } 2857 if (debug) 2858 fprintf (stderr, "not found\n"); 2859 else 2860 fatal ("library lib%s not found", name); 2861 return (NULL); 2862} 2863#endif /* COLLECT_EXPORT_LIST */ 2864