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