Improve support for arm-wince-pe target:
[official-gcc.git] / gcc / collect2.c
blob4b20afc125d133beea99587d0ca08d28fe03f8f5
1 /* Collect static initialization info into data structures that can be
2 traversed by C++ initialization and finalization routines.
3 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
4 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
5 Contributed by Chris Smith (csmith@convex.com).
6 Heavily modified by Michael Meissner (meissner@cygnus.com),
7 Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
9 This file is part of GCC.
11 GCC is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 2, or (at your option) any later
14 version.
16 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 for more details.
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING. If not, write to the Free
23 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
24 02111-1307, USA. */
27 /* Build tables of static constructors and destructors and run ld. */
29 #include "config.h"
30 #include "system.h"
31 #include "coretypes.h"
32 #include "tm.h"
33 #include <signal.h>
34 #if ! defined( SIGCHLD ) && defined( SIGCLD )
35 # define SIGCHLD SIGCLD
36 #endif
38 #ifdef vfork /* Autoconf may define this to fork for us. */
39 # define VFORK_STRING "fork"
40 #else
41 # define VFORK_STRING "vfork"
42 #endif
43 #ifdef HAVE_VFORK_H
44 #include <vfork.h>
45 #endif
46 #ifdef VMS
47 #define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
48 lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
49 #endif /* VMS */
51 #ifndef LIBRARY_PATH_ENV
52 #define LIBRARY_PATH_ENV "LIBRARY_PATH"
53 #endif
55 #define COLLECT
57 #include "collect2.h"
58 #include "demangle.h"
59 #include "obstack.h"
60 #include "intl.h"
61 #include "version.h"
63 /* On certain systems, we have code that works by scanning the object file
64 directly. But this code uses system-specific header files and library
65 functions, so turn it off in a cross-compiler. Likewise, the names of
66 the utilities are not correct for a cross-compiler; we have to hope that
67 cross-versions are in the proper directories. */
69 #ifdef CROSS_COMPILE
70 #undef SUNOS4_SHARED_LIBRARIES
71 #undef OBJECT_FORMAT_COFF
72 #undef OBJECT_FORMAT_ROSE
73 #undef MD_EXEC_PREFIX
74 #undef REAL_LD_FILE_NAME
75 #undef REAL_NM_FILE_NAME
76 #undef REAL_STRIP_FILE_NAME
77 #endif
79 /* If we cannot use a special method, use the ordinary one:
80 run nm to find what symbols are present.
81 In a cross-compiler, this means you need a cross nm,
82 but that is not quite as unpleasant as special headers. */
84 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
85 #define OBJECT_FORMAT_NONE
86 #endif
88 #ifdef OBJECT_FORMAT_COFF
90 #include <a.out.h>
91 #include <ar.h>
93 #ifdef UMAX
94 #include <sgs.h>
95 #endif
97 /* Many versions of ldfcn.h define these. */
98 #ifdef FREAD
99 #undef FREAD
100 #undef FWRITE
101 #endif
103 #include <ldfcn.h>
105 /* Some systems have an ISCOFF macro, but others do not. In some cases
106 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
107 that either do not have an ISCOFF macro in /usr/include or for those
108 where it is wrong. */
110 #ifndef MY_ISCOFF
111 #define MY_ISCOFF(X) ISCOFF (X)
112 #endif
114 #endif /* OBJECT_FORMAT_COFF */
116 #ifdef OBJECT_FORMAT_ROSE
118 #ifdef _OSF_SOURCE
119 #define USE_MMAP
120 #endif
122 #ifdef USE_MMAP
123 #include <sys/mman.h>
124 #endif
126 #include <unistd.h>
127 #include <mach_o_format.h>
128 #include <mach_o_header.h>
129 #include <mach_o_vals.h>
130 #include <mach_o_types.h>
132 #endif /* OBJECT_FORMAT_ROSE */
134 #ifdef OBJECT_FORMAT_NONE
136 /* Default flags to pass to nm. */
137 #ifndef NM_FLAGS
138 #define NM_FLAGS "-n"
139 #endif
141 #endif /* OBJECT_FORMAT_NONE */
143 /* Some systems use __main in a way incompatible with its use in gcc, in these
144 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
145 give the same symbol without quotes for an alternative entry point. */
146 #ifndef NAME__MAIN
147 #define NAME__MAIN "__main"
148 #endif
150 /* This must match tree.h. */
151 #define DEFAULT_INIT_PRIORITY 65535
153 #ifndef COLLECT_SHARED_INIT_FUNC
154 #define COLLECT_SHARED_INIT_FUNC(STREAM, FUNC) \
155 fprintf ((STREAM), "void _GLOBAL__DI() {\n\t%s();\n}\n", (FUNC))
156 #endif
157 #ifndef COLLECT_SHARED_FINI_FUNC
158 #define COLLECT_SHARED_FINI_FUNC(STREAM, FUNC) \
159 fprintf ((STREAM), "void _GLOBAL__DD() {\n\t%s();\n}\n", (FUNC))
160 #endif
162 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
163 #define SCAN_LIBRARIES
164 #endif
166 #ifdef USE_COLLECT2
167 int do_collecting = 1;
168 #else
169 int do_collecting = 0;
170 #endif
172 /* Nonzero if we should suppress the automatic demangling of identifiers
173 in linker error messages. Set from COLLECT_NO_DEMANGLE. */
174 int no_demangle;
176 /* Linked lists of constructor and destructor names. */
178 struct id
180 struct id *next;
181 int sequence;
182 char name[1];
185 struct head
187 struct id *first;
188 struct id *last;
189 int number;
192 /* Enumeration giving which pass this is for scanning the program file. */
194 enum pass {
195 PASS_FIRST, /* without constructors */
196 PASS_OBJ, /* individual objects */
197 PASS_LIB, /* looking for shared libraries */
198 PASS_SECOND /* with constructors linked in */
201 int vflag; /* true if -v */
202 static int rflag; /* true if -r */
203 static int strip_flag; /* true if -s */
204 #ifdef COLLECT_EXPORT_LIST
205 static int export_flag; /* true if -bE */
206 static int aix64_flag; /* true if -b64 */
207 #endif
209 int debug; /* true if -debug */
211 static int shared_obj; /* true if -shared */
213 static const char *c_file; /* <xxx>.c for constructor/destructor list. */
214 static const char *o_file; /* <xxx>.o for constructor/destructor list. */
215 #ifdef COLLECT_EXPORT_LIST
216 static const char *export_file; /* <xxx>.x for AIX export list. */
217 #endif
218 const char *ldout; /* File for ld errors. */
219 static const char *output_file; /* Output file for ld. */
220 static const char *nm_file_name; /* pathname of nm */
221 #ifdef LDD_SUFFIX
222 static const char *ldd_file_name; /* pathname of ldd (or equivalent) */
223 #endif
224 static const char *strip_file_name; /* pathname of strip */
225 const char *c_file_name; /* pathname of gcc */
226 static char *initname, *fininame; /* names of init and fini funcs */
228 static struct head constructors; /* list of constructors found */
229 static struct head destructors; /* list of destructors found */
230 #ifdef COLLECT_EXPORT_LIST
231 static struct head exports; /* list of exported symbols */
232 #endif
233 static struct head frame_tables; /* list of frame unwind info tables */
235 struct obstack temporary_obstack;
236 char * temporary_firstobj;
238 /* Holds the return value of pexecute and fork. */
239 int pid;
241 /* Structure to hold all the directories in which to search for files to
242 execute. */
244 struct prefix_list
246 const char *prefix; /* String to prepend to the path. */
247 struct prefix_list *next; /* Next in linked list. */
250 struct path_prefix
252 struct prefix_list *plist; /* List of prefixes to try */
253 int max_len; /* Max length of a prefix in PLIST */
254 const char *name; /* Name of this list (used in config stuff) */
257 #ifdef COLLECT_EXPORT_LIST
258 /* Lists to keep libraries to be scanned for global constructors/destructors. */
259 static struct head libs; /* list of libraries */
260 static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
261 static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
262 static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
263 &libpath_lib_dirs, NULL};
264 static const char *const libexts[3] = {"a", "so", NULL}; /* possible library extensions */
265 #endif
267 static void handler PARAMS ((int));
268 static int is_ctor_dtor PARAMS ((const char *));
269 static char *find_a_file PARAMS ((struct path_prefix *, const char *));
270 static void add_prefix PARAMS ((struct path_prefix *, const char *));
271 static void prefix_from_env PARAMS ((const char *, struct path_prefix *));
272 static void prefix_from_string PARAMS ((const char *, struct path_prefix *));
273 static void do_wait PARAMS ((const char *));
274 static void fork_execute PARAMS ((const char *, char **));
275 static void maybe_unlink PARAMS ((const char *));
276 static void add_to_list PARAMS ((struct head *, const char *));
277 static int extract_init_priority PARAMS ((const char *));
278 static void sort_ids PARAMS ((struct head *));
279 static void write_list PARAMS ((FILE *, const char *, struct id *));
280 #ifdef COLLECT_EXPORT_LIST
281 static void dump_list PARAMS ((FILE *, const char *, struct id *));
282 #endif
283 #if 0
284 static void dump_prefix_list PARAMS ((FILE *, const char *, struct prefix_list *));
285 #endif
286 static void write_list_with_asm PARAMS ((FILE *, const char *, struct id *));
287 static void write_c_file PARAMS ((FILE *, const char *));
288 static void write_c_file_stat PARAMS ((FILE *, const char *));
289 #ifndef LD_INIT_SWITCH
290 static void write_c_file_glob PARAMS ((FILE *, const char *));
291 #endif
292 static void scan_prog_file PARAMS ((const char *, enum pass));
293 #ifdef SCAN_LIBRARIES
294 static void scan_libraries PARAMS ((const char *));
295 #endif
296 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
297 static int is_in_args PARAMS ((const char *, const char **, const char **));
298 #endif
299 #ifdef COLLECT_EXPORT_LIST
300 #if 0
301 static int is_in_list PARAMS ((const char *, struct id *));
302 #endif
303 static void write_aix_file PARAMS ((FILE *, struct id *));
304 static char *resolve_lib_name PARAMS ((const char *));
305 #endif
306 static char *extract_string PARAMS ((const char **));
308 #ifndef HAVE_DUP2
309 static int dup2 PARAMS ((int, int));
310 static int
311 dup2 (oldfd, newfd)
312 int oldfd;
313 int newfd;
315 int fdtmp[256];
316 int fdx = 0;
317 int fd;
319 if (oldfd == newfd)
320 return oldfd;
321 close (newfd);
322 while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
323 fdtmp[fdx++] = fd;
324 while (fdx > 0)
325 close (fdtmp[--fdx]);
327 return fd;
329 #endif /* ! HAVE_DUP2 */
331 /* Delete tempfiles and exit function. */
333 void
334 collect_exit (status)
335 int status;
337 if (c_file != 0 && c_file[0])
338 maybe_unlink (c_file);
340 if (o_file != 0 && o_file[0])
341 maybe_unlink (o_file);
343 #ifdef COLLECT_EXPORT_LIST
344 if (export_file != 0 && export_file[0])
345 maybe_unlink (export_file);
346 #endif
348 if (ldout != 0 && ldout[0])
350 dump_file (ldout);
351 maybe_unlink (ldout);
354 if (status != 0 && output_file != 0 && output_file[0])
355 maybe_unlink (output_file);
357 exit (status);
361 /* Notify user of a non-error. */
362 void
363 notice (const char *msgid, ...)
365 va_list ap;
367 va_start (ap, msgid);
368 vfprintf (stderr, _(msgid), ap);
369 va_end (ap);
372 /* Die when sys call fails. */
374 void
375 fatal_perror (const char * msgid, ...)
377 int e = errno;
378 va_list ap;
380 va_start (ap, msgid);
381 fprintf (stderr, "collect2: ");
382 vfprintf (stderr, _(msgid), ap);
383 fprintf (stderr, ": %s\n", xstrerror (e));
384 va_end (ap);
386 collect_exit (FATAL_EXIT_CODE);
389 /* Just die. */
391 void
392 fatal (const char * msgid, ...)
394 va_list ap;
396 va_start (ap, msgid);
397 fprintf (stderr, "collect2: ");
398 vfprintf (stderr, _(msgid), ap);
399 fprintf (stderr, "\n");
400 va_end (ap);
402 collect_exit (FATAL_EXIT_CODE);
405 /* Write error message. */
407 void
408 error (const char * msgid, ...)
410 va_list ap;
412 va_start (ap, msgid);
413 fprintf (stderr, "collect2: ");
414 vfprintf (stderr, _(msgid), ap);
415 fprintf (stderr, "\n");
416 va_end(ap);
419 /* In case obstack is linked in, and abort is defined to fancy_abort,
420 provide a default entry. */
422 void
423 fancy_abort ()
425 fatal ("internal error");
428 static void
429 handler (signo)
430 int signo;
432 if (c_file != 0 && c_file[0])
433 maybe_unlink (c_file);
435 if (o_file != 0 && o_file[0])
436 maybe_unlink (o_file);
438 if (ldout != 0 && ldout[0])
439 maybe_unlink (ldout);
441 #ifdef COLLECT_EXPORT_LIST
442 if (export_file != 0 && export_file[0])
443 maybe_unlink (export_file);
444 #endif
446 signal (signo, SIG_DFL);
447 kill (getpid (), signo);
452 file_exists (name)
453 const char *name;
455 return access (name, R_OK) == 0;
458 /* Parse a reasonable subset of shell quoting syntax. */
460 static char *
461 extract_string (pp)
462 const char **pp;
464 const char *p = *pp;
465 int backquote = 0;
466 int inside = 0;
468 for (;;)
470 char c = *p;
471 if (c == '\0')
472 break;
473 ++p;
474 if (backquote)
475 obstack_1grow (&temporary_obstack, c);
476 else if (! inside && c == ' ')
477 break;
478 else if (! inside && c == '\\')
479 backquote = 1;
480 else if (c == '\'')
481 inside = !inside;
482 else
483 obstack_1grow (&temporary_obstack, c);
486 obstack_1grow (&temporary_obstack, '\0');
487 *pp = p;
488 return obstack_finish (&temporary_obstack);
491 void
492 dump_file (name)
493 const char *name;
495 FILE *stream = fopen (name, "r");
497 if (stream == 0)
498 return;
499 while (1)
501 int c;
502 while (c = getc (stream),
503 c != EOF && (ISIDNUM (c) || c == '$' || c == '.'))
504 obstack_1grow (&temporary_obstack, c);
505 if (obstack_object_size (&temporary_obstack) > 0)
507 const char *word, *p;
508 char *result;
509 obstack_1grow (&temporary_obstack, '\0');
510 word = obstack_finish (&temporary_obstack);
512 if (*word == '.')
513 ++word, putc ('.', stderr);
514 p = word;
515 if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)))
516 p += strlen (USER_LABEL_PREFIX);
518 if (no_demangle)
519 result = 0;
520 else
521 result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
523 if (result)
525 int diff;
526 fputs (result, stderr);
528 diff = strlen (word) - strlen (result);
529 while (diff > 0 && c == ' ')
530 --diff, putc (' ', stderr);
531 while (diff < 0 && c == ' ')
532 ++diff, c = getc (stream);
534 free (result);
536 else
537 fputs (word, stderr);
539 fflush (stderr);
540 obstack_free (&temporary_obstack, temporary_firstobj);
542 if (c == EOF)
543 break;
544 putc (c, stderr);
546 fclose (stream);
549 /* Decide whether the given symbol is: a constructor (1), a destructor
550 (2), a routine in a shared object that calls all the constructors
551 (3) or destructors (4), a DWARF exception-handling table (5), or
552 nothing special (0). */
554 static int
555 is_ctor_dtor (s)
556 const char *s;
558 struct names { const char *const name; const int len; const int ret;
559 const int two_underscores; };
561 const struct names *p;
562 int ch;
563 const char *orig_s = s;
565 static const struct names special[] = {
566 #ifndef NO_DOLLAR_IN_LABEL
567 { "GLOBAL__I$", sizeof ("GLOBAL__I$")-1, 1, 0 },
568 { "GLOBAL__D$", sizeof ("GLOBAL__D$")-1, 2, 0 },
569 #else
570 #ifndef NO_DOT_IN_LABEL
571 { "GLOBAL__I.", sizeof ("GLOBAL__I.")-1, 1, 0 },
572 { "GLOBAL__D.", sizeof ("GLOBAL__D.")-1, 2, 0 },
573 #endif /* NO_DOT_IN_LABEL */
574 #endif /* NO_DOLLAR_IN_LABEL */
575 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
576 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
577 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
578 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
579 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
580 { NULL, 0, 0, 0 }
583 while ((ch = *s) == '_')
584 ++s;
586 if (s == orig_s)
587 return 0;
589 for (p = &special[0]; p->len > 0; p++)
591 if (ch == p->name[0]
592 && (!p->two_underscores || ((s - orig_s) >= 2))
593 && strncmp(s, p->name, p->len) == 0)
595 return p->ret;
598 return 0;
601 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
602 and one from the PATH variable. */
604 static struct path_prefix cpath, path;
606 #ifdef CROSS_COMPILE
607 /* This is the name of the target machine. We use it to form the name
608 of the files to execute. */
610 static const char *const target_machine = TARGET_MACHINE;
611 #endif
613 /* Search for NAME using prefix list PPREFIX. We only look for executable
614 files.
616 Return 0 if not found, otherwise return its name, allocated with malloc. */
618 static char *
619 find_a_file (pprefix, name)
620 struct path_prefix *pprefix;
621 const char *name;
623 char *temp;
624 struct prefix_list *pl;
625 int len = pprefix->max_len + strlen (name) + 1;
627 if (debug)
628 fprintf (stderr, "Looking for '%s'\n", name);
630 #ifdef HOST_EXECUTABLE_SUFFIX
631 len += strlen (HOST_EXECUTABLE_SUFFIX);
632 #endif
634 temp = xmalloc (len);
636 /* Determine the filename to execute (special case for absolute paths). */
638 if (*name == '/'
639 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
640 || (*name && name[1] == ':')
641 #endif
644 if (access (name, X_OK) == 0)
646 strcpy (temp, name);
648 if (debug)
649 fprintf (stderr, " - found: absolute path\n");
651 return temp;
654 #ifdef HOST_EXECUTABLE_SUFFIX
655 /* Some systems have a suffix for executable files.
656 So try appending that. */
657 strcpy (temp, name);
658 strcat (temp, HOST_EXECUTABLE_SUFFIX);
660 if (access (temp, X_OK) == 0)
661 return temp;
662 #endif
664 if (debug)
665 fprintf (stderr, " - failed to locate using absolute path\n");
667 else
668 for (pl = pprefix->plist; pl; pl = pl->next)
670 struct stat st;
672 strcpy (temp, pl->prefix);
673 strcat (temp, name);
675 if (stat (temp, &st) >= 0
676 && ! S_ISDIR (st.st_mode)
677 && access (temp, X_OK) == 0)
678 return temp;
680 #ifdef HOST_EXECUTABLE_SUFFIX
681 /* Some systems have a suffix for executable files.
682 So try appending that. */
683 strcat (temp, HOST_EXECUTABLE_SUFFIX);
685 if (stat (temp, &st) >= 0
686 && ! S_ISDIR (st.st_mode)
687 && access (temp, X_OK) == 0)
688 return temp;
689 #endif
692 if (debug && pprefix->plist == NULL)
693 fprintf (stderr, " - failed: no entries in prefix list\n");
695 free (temp);
696 return 0;
699 /* Add an entry for PREFIX to prefix list PPREFIX. */
701 static void
702 add_prefix (pprefix, prefix)
703 struct path_prefix *pprefix;
704 const char *prefix;
706 struct prefix_list *pl, **prev;
707 int len;
709 if (pprefix->plist)
711 for (pl = pprefix->plist; pl->next; pl = pl->next)
713 prev = &pl->next;
715 else
716 prev = &pprefix->plist;
718 /* Keep track of the longest prefix */
720 len = strlen (prefix);
721 if (len > pprefix->max_len)
722 pprefix->max_len = len;
724 pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
725 pl->prefix = xstrdup (prefix);
727 if (*prev)
728 pl->next = *prev;
729 else
730 pl->next = (struct prefix_list *) 0;
731 *prev = pl;
734 /* Take the value of the environment variable ENV, break it into a path, and
735 add of the entries to PPREFIX. */
737 static void
738 prefix_from_env (env, pprefix)
739 const char *env;
740 struct path_prefix *pprefix;
742 const char *p;
743 GET_ENVIRONMENT (p, env);
745 if (p)
746 prefix_from_string (p, pprefix);
749 static void
750 prefix_from_string (p, pprefix)
751 const char *p;
752 struct path_prefix *pprefix;
754 const char *startp, *endp;
755 char *nstore = (char *) xmalloc (strlen (p) + 3);
757 if (debug)
758 fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
760 startp = endp = p;
761 while (1)
763 if (*endp == PATH_SEPARATOR || *endp == 0)
765 strncpy (nstore, startp, endp-startp);
766 if (endp == startp)
768 strcpy (nstore, "./");
770 else if (! IS_DIR_SEPARATOR (endp[-1]))
772 nstore[endp-startp] = DIR_SEPARATOR;
773 nstore[endp-startp+1] = 0;
775 else
776 nstore[endp-startp] = 0;
778 if (debug)
779 fprintf (stderr, " - add prefix: %s\n", nstore);
781 add_prefix (pprefix, nstore);
782 if (*endp == 0)
783 break;
784 endp = startp = endp + 1;
786 else
787 endp++;
791 /* Main program. */
793 int main PARAMS ((int, char *[]));
795 main (argc, argv)
796 int argc;
797 char *argv[];
799 static const char *const ld_suffix = "ld";
800 static const char *const real_ld_suffix = "real-ld";
801 static const char *const collect_ld_suffix = "collect-ld";
802 static const char *const nm_suffix = "nm";
803 static const char *const gnm_suffix = "gnm";
804 #ifdef LDD_SUFFIX
805 static const char *const ldd_suffix = LDD_SUFFIX;
806 #endif
807 static const char *const strip_suffix = "strip";
808 static const char *const gstrip_suffix = "gstrip";
810 #ifdef CROSS_COMPILE
811 /* If we look for a program in the compiler directories, we just use
812 the short name, since these directories are already system-specific.
813 But it we look for a program in the system directories, we need to
814 qualify the program name with the target machine. */
816 const char *const full_ld_suffix =
817 concat(target_machine, "-", ld_suffix, NULL);
818 const char *const full_nm_suffix =
819 concat (target_machine, "-", nm_suffix, NULL);
820 const char *const full_gnm_suffix =
821 concat (target_machine, "-", gnm_suffix, NULL);
822 #ifdef LDD_SUFFIX
823 const char *const full_ldd_suffix =
824 concat (target_machine, "-", ldd_suffix, NULL);
825 #endif
826 const char *const full_strip_suffix =
827 concat (target_machine, "-", strip_suffix, NULL);
828 const char *const full_gstrip_suffix =
829 concat (target_machine, "-", gstrip_suffix, NULL);
830 #else
831 const char *const full_ld_suffix = ld_suffix;
832 const char *const full_nm_suffix = nm_suffix;
833 const char *const full_gnm_suffix = gnm_suffix;
834 #ifdef LDD_SUFFIX
835 const char *const full_ldd_suffix = ldd_suffix;
836 #endif
837 const char *const full_strip_suffix = strip_suffix;
838 const char *const full_gstrip_suffix = gstrip_suffix;
839 #endif /* CROSS_COMPILE */
841 const char *arg;
842 FILE *outf;
843 #ifdef COLLECT_EXPORT_LIST
844 FILE *exportf;
845 #endif
846 const char *ld_file_name;
847 const char *p;
848 char **c_argv;
849 const char **c_ptr;
850 char **ld1_argv;
851 const char **ld1;
852 char **ld2_argv;
853 const char **ld2;
854 char **object_lst;
855 const char **object;
856 int first_file;
857 int num_c_args = argc+9;
859 no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
861 /* Suppress demangling by the real linker, which may be broken. */
862 putenv (xstrdup ("COLLECT_NO_DEMANGLE="));
864 #if defined (COLLECT2_HOST_INITIALIZATION)
865 /* Perform system dependent initialization, if necessary. */
866 COLLECT2_HOST_INITIALIZATION;
867 #endif
869 #ifdef SIGCHLD
870 /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
871 receive the signal. A different setting is inheritable */
872 signal (SIGCHLD, SIG_DFL);
873 #endif
875 gcc_init_libintl ();
877 /* Do not invoke xcalloc before this point, since locale needs to be
878 set first, in case a diagnostic is issued. */
880 ld1 = (const char **)(ld1_argv = (char **) xcalloc(sizeof (char *), argc+3));
881 ld2 = (const char **)(ld2_argv = (char **) xcalloc(sizeof (char *), argc+10));
882 object = (const char **)(object_lst = (char **) xcalloc(sizeof (char *), argc));
884 #ifdef DEBUG
885 debug = 1;
886 #endif
888 /* Parse command line early for instances of -debug. This allows
889 the debug flag to be set before functions like find_a_file()
890 are called. */
892 int i;
894 for (i = 1; argv[i] != NULL; i ++)
895 if (! strcmp (argv[i], "-debug"))
896 debug = 1;
897 vflag = debug;
900 #ifndef DEFAULT_A_OUT_NAME
901 output_file = "a.out";
902 #else
903 output_file = DEFAULT_A_OUT_NAME;
904 #endif
906 obstack_begin (&temporary_obstack, 0);
907 temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
909 current_demangling_style = auto_demangling;
910 p = getenv ("COLLECT_GCC_OPTIONS");
911 while (p && *p)
913 const char *q = extract_string (&p);
914 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
915 num_c_args++;
917 obstack_free (&temporary_obstack, temporary_firstobj);
919 /* -fno-exceptions -w */
920 num_c_args += 2;
922 c_ptr = (const char **)
923 (c_argv = (char **) xcalloc (sizeof (char *), num_c_args));
925 if (argc < 2)
926 fatal ("no arguments");
928 #ifdef SIGQUIT
929 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
930 signal (SIGQUIT, handler);
931 #endif
932 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
933 signal (SIGINT, handler);
934 #ifdef SIGALRM
935 if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
936 signal (SIGALRM, handler);
937 #endif
938 #ifdef SIGHUP
939 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
940 signal (SIGHUP, handler);
941 #endif
942 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
943 signal (SIGSEGV, handler);
944 #ifdef SIGBUS
945 if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
946 signal (SIGBUS, handler);
947 #endif
949 /* Extract COMPILER_PATH and PATH into our prefix list. */
950 prefix_from_env ("COMPILER_PATH", &cpath);
951 prefix_from_env ("PATH", &path);
953 /* Try to discover a valid linker/nm/strip to use. */
955 /* Maybe we know the right file to use (if not cross). */
956 ld_file_name = 0;
957 #ifdef DEFAULT_LINKER
958 if (access (DEFAULT_LINKER, X_OK) == 0)
959 ld_file_name = DEFAULT_LINKER;
960 if (ld_file_name == 0)
961 #endif
962 #ifdef REAL_LD_FILE_NAME
963 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
964 if (ld_file_name == 0)
965 #endif
966 /* Search the (target-specific) compiler dirs for ld'. */
967 ld_file_name = find_a_file (&cpath, real_ld_suffix);
968 /* Likewise for `collect-ld'. */
969 if (ld_file_name == 0)
970 ld_file_name = find_a_file (&cpath, collect_ld_suffix);
971 /* Search the compiler directories for `ld'. We have protection against
972 recursive calls in find_a_file. */
973 if (ld_file_name == 0)
974 ld_file_name = find_a_file (&cpath, ld_suffix);
975 /* Search the ordinary system bin directories
976 for `ld' (if native linking) or `TARGET-ld' (if cross). */
977 if (ld_file_name == 0)
978 ld_file_name = find_a_file (&path, full_ld_suffix);
980 #ifdef REAL_NM_FILE_NAME
981 nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
982 if (nm_file_name == 0)
983 #endif
984 nm_file_name = find_a_file (&cpath, gnm_suffix);
985 if (nm_file_name == 0)
986 nm_file_name = find_a_file (&path, full_gnm_suffix);
987 if (nm_file_name == 0)
988 nm_file_name = find_a_file (&cpath, nm_suffix);
989 if (nm_file_name == 0)
990 nm_file_name = find_a_file (&path, full_nm_suffix);
992 #ifdef LDD_SUFFIX
993 ldd_file_name = find_a_file (&cpath, ldd_suffix);
994 if (ldd_file_name == 0)
995 ldd_file_name = find_a_file (&path, full_ldd_suffix);
996 #endif
998 #ifdef REAL_STRIP_FILE_NAME
999 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
1000 if (strip_file_name == 0)
1001 #endif
1002 strip_file_name = find_a_file (&cpath, gstrip_suffix);
1003 if (strip_file_name == 0)
1004 strip_file_name = find_a_file (&path, full_gstrip_suffix);
1005 if (strip_file_name == 0)
1006 strip_file_name = find_a_file (&cpath, strip_suffix);
1007 if (strip_file_name == 0)
1008 strip_file_name = find_a_file (&path, full_strip_suffix);
1010 /* Determine the full path name of the C compiler to use. */
1011 c_file_name = getenv ("COLLECT_GCC");
1012 if (c_file_name == 0)
1014 #ifdef CROSS_COMPILE
1015 c_file_name = concat (target_machine, "-gcc", NULL);
1016 #else
1017 c_file_name = "gcc";
1018 #endif
1021 p = find_a_file (&cpath, c_file_name);
1023 /* Here it should be safe to use the system search path since we should have
1024 already qualified the name of the compiler when it is needed. */
1025 if (p == 0)
1026 p = find_a_file (&path, c_file_name);
1028 if (p)
1029 c_file_name = p;
1031 *ld1++ = *ld2++ = ld_file_name;
1033 /* Make temp file names. */
1034 c_file = make_temp_file (".c");
1035 o_file = make_temp_file (".o");
1036 #ifdef COLLECT_EXPORT_LIST
1037 export_file = make_temp_file (".x");
1038 #endif
1039 ldout = make_temp_file (".ld");
1040 *c_ptr++ = c_file_name;
1041 *c_ptr++ = "-x";
1042 *c_ptr++ = "c";
1043 *c_ptr++ = "-c";
1044 *c_ptr++ = "-o";
1045 *c_ptr++ = o_file;
1047 #ifdef COLLECT_EXPORT_LIST
1048 /* Generate a list of directories from LIBPATH. */
1049 prefix_from_env ("LIBPATH", &libpath_lib_dirs);
1050 /* Add to this list also two standard directories where
1051 AIX loader always searches for libraries. */
1052 add_prefix (&libpath_lib_dirs, "/lib");
1053 add_prefix (&libpath_lib_dirs, "/usr/lib");
1054 #endif
1056 /* Get any options that the upper GCC wants to pass to the sub-GCC.
1058 AIX support needs to know if -shared has been specified before
1059 parsing commandline arguments. */
1061 p = getenv ("COLLECT_GCC_OPTIONS");
1062 while (p && *p)
1064 const char *q = extract_string (&p);
1065 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1066 *c_ptr++ = xstrdup (q);
1067 if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0)
1068 *c_ptr++ = xstrdup (q);
1069 if (strcmp (q, "-shared") == 0)
1070 shared_obj = 1;
1071 if (*q == '-' && q[1] == 'B')
1073 *c_ptr++ = xstrdup (q);
1074 if (q[2] == 0)
1076 q = extract_string (&p);
1077 *c_ptr++ = xstrdup (q);
1081 obstack_free (&temporary_obstack, temporary_firstobj);
1082 *c_ptr++ = "-fno-exceptions";
1083 *c_ptr++ = "-w";
1085 /* !!! When GCC calls collect2,
1086 it does not know whether it is calling collect2 or ld.
1087 So collect2 cannot meaningfully understand any options
1088 except those ld understands.
1089 If you propose to make GCC pass some other option,
1090 just imagine what will happen if ld is really ld!!! */
1092 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1093 /* After the first file, put in the c++ rt0. */
1095 first_file = 1;
1096 while ((arg = *++argv) != (char *) 0)
1098 *ld1++ = *ld2++ = arg;
1100 if (arg[0] == '-')
1102 switch (arg[1])
1104 #ifdef COLLECT_EXPORT_LIST
1105 /* We want to disable automatic exports on AIX when user
1106 explicitly puts an export list in command line */
1107 case 'b':
1108 if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
1109 export_flag = 1;
1110 else if (arg[2] == '6' && arg[3] == '4')
1111 aix64_flag = 1;
1112 break;
1113 #endif
1115 case 'd':
1116 if (!strcmp (arg, "-debug"))
1118 /* Already parsed. */
1119 ld1--;
1120 ld2--;
1122 break;
1124 case 'l':
1125 if (first_file)
1127 /* place o_file BEFORE this argument! */
1128 first_file = 0;
1129 ld2--;
1130 *ld2++ = o_file;
1131 *ld2++ = arg;
1133 #ifdef COLLECT_EXPORT_LIST
1135 /* Resolving full library name. */
1136 const char *s = resolve_lib_name (arg+2);
1138 /* Saving a full library name. */
1139 add_to_list (&libs, s);
1141 #endif
1142 break;
1144 #ifdef COLLECT_EXPORT_LIST
1145 /* Saving directories where to search for libraries. */
1146 case 'L':
1147 add_prefix (&cmdline_lib_dirs, arg+2);
1148 break;
1149 #else
1150 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1151 case 'L':
1152 if (is_in_args (arg, (const char **) ld1_argv, ld1-1))
1153 --ld1;
1154 break;
1155 #endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1156 #endif
1158 case 'o':
1159 if (arg[2] == '\0')
1160 output_file = *ld1++ = *ld2++ = *++argv;
1161 else if (1
1162 #ifdef SWITCHES_NEED_SPACES
1163 && ! strchr (SWITCHES_NEED_SPACES, arg[1])
1164 #endif
1167 output_file = &arg[2];
1168 break;
1170 case 'r':
1171 if (arg[2] == '\0')
1172 rflag = 1;
1173 break;
1175 case 's':
1176 if (arg[2] == '\0' && do_collecting)
1178 /* We must strip after the nm run, otherwise C++ linking
1179 will not work. Thus we strip in the second ld run, or
1180 else with strip if there is no second ld run. */
1181 strip_flag = 1;
1182 ld1--;
1184 break;
1186 case 'v':
1187 if (arg[2] == '\0')
1188 vflag = 1;
1189 break;
1192 else if ((p = strrchr (arg, '.')) != (char *) 0
1193 && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
1194 || strcmp (p, ".so") == 0 || strcmp (p, ".lo") == 0
1195 || strcmp (p, ".obj") == 0))
1197 if (first_file)
1199 first_file = 0;
1200 if (p[1] == 'o')
1201 *ld2++ = o_file;
1202 else
1204 /* place o_file BEFORE this argument! */
1205 ld2--;
1206 *ld2++ = o_file;
1207 *ld2++ = arg;
1210 if (p[1] == 'o' || p[1] == 'l')
1211 *object++ = arg;
1212 #ifdef COLLECT_EXPORT_LIST
1213 /* libraries can be specified directly, i.e. without -l flag. */
1214 else
1216 /* Saving a full library name. */
1217 add_to_list (&libs, arg);
1219 #endif
1223 #ifdef COLLECT_EXPORT_LIST
1224 /* This is added only for debugging purposes. */
1225 if (debug)
1227 fprintf (stderr, "List of libraries:\n");
1228 dump_list (stderr, "\t", libs.first);
1231 /* The AIX linker will discard static constructors in object files if
1232 nothing else in the file is referenced, so look at them first. */
1234 const char **export_object_lst = (const char **)object_lst;
1236 while (export_object_lst < object)
1237 scan_prog_file (*export_object_lst++, PASS_OBJ);
1240 struct id *list = libs.first;
1242 for (; list; list = list->next)
1243 scan_prog_file (list->name, PASS_FIRST);
1246 if (exports.first)
1248 char *buf = concat ("-bE:", export_file, NULL);
1250 *ld1++ = buf;
1251 *ld2++ = buf;
1253 exportf = fopen (export_file, "w");
1254 if (exportf == (FILE *) 0)
1255 fatal_perror ("fopen %s", export_file);
1256 write_aix_file (exportf, exports.first);
1257 if (fclose (exportf))
1258 fatal_perror ("fclose %s", export_file);
1260 #endif
1262 *c_ptr++ = c_file;
1263 *c_ptr = *ld1 = *object = (char *) 0;
1265 if (vflag)
1267 notice ("collect2 version %s", version_string);
1268 #ifdef TARGET_VERSION
1269 TARGET_VERSION;
1270 #endif
1271 fprintf (stderr, "\n");
1274 if (debug)
1276 const char *ptr;
1277 fprintf (stderr, "ld_file_name = %s\n",
1278 (ld_file_name ? ld_file_name : "not found"));
1279 fprintf (stderr, "c_file_name = %s\n",
1280 (c_file_name ? c_file_name : "not found"));
1281 fprintf (stderr, "nm_file_name = %s\n",
1282 (nm_file_name ? nm_file_name : "not found"));
1283 #ifdef LDD_SUFFIX
1284 fprintf (stderr, "ldd_file_name = %s\n",
1285 (ldd_file_name ? ldd_file_name : "not found"));
1286 #endif
1287 fprintf (stderr, "strip_file_name = %s\n",
1288 (strip_file_name ? strip_file_name : "not found"));
1289 fprintf (stderr, "c_file = %s\n",
1290 (c_file ? c_file : "not found"));
1291 fprintf (stderr, "o_file = %s\n",
1292 (o_file ? o_file : "not found"));
1294 ptr = getenv ("COLLECT_GCC_OPTIONS");
1295 if (ptr)
1296 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1298 ptr = getenv ("COLLECT_GCC");
1299 if (ptr)
1300 fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
1302 ptr = getenv ("COMPILER_PATH");
1303 if (ptr)
1304 fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
1306 ptr = getenv (LIBRARY_PATH_ENV);
1307 if (ptr)
1308 fprintf (stderr, "%-20s= %s\n", LIBRARY_PATH_ENV, ptr);
1310 fprintf (stderr, "\n");
1313 /* Load the program, searching all libraries and attempting to provide
1314 undefined symbols from repository information. */
1316 /* On AIX we do this later. */
1317 #ifndef COLLECT_EXPORT_LIST
1318 do_tlink (ld1_argv, object_lst);
1319 #endif
1321 /* If -r or they will be run via some other method, do not build the
1322 constructor or destructor list, just return now. */
1323 if (rflag
1324 #ifndef COLLECT_EXPORT_LIST
1325 || ! do_collecting
1326 #endif
1329 #ifdef COLLECT_EXPORT_LIST
1330 /* Do the link we avoided above if we are exiting. */
1331 do_tlink (ld1_argv, object_lst);
1333 /* But make sure we delete the export file we may have created. */
1334 if (export_file != 0 && export_file[0])
1335 maybe_unlink (export_file);
1336 #endif
1337 maybe_unlink (c_file);
1338 maybe_unlink (o_file);
1339 return 0;
1342 /* Examine the namelist with nm and search it for static constructors
1343 and destructors to call.
1344 Write the constructor and destructor tables to a .s file and reload. */
1346 /* On AIX we already scanned for global constructors/destructors. */
1347 #ifndef COLLECT_EXPORT_LIST
1348 scan_prog_file (output_file, PASS_FIRST);
1349 #endif
1351 #ifdef SCAN_LIBRARIES
1352 scan_libraries (output_file);
1353 #endif
1355 if (debug)
1357 notice ("%d constructor(s) found\n", constructors.number);
1358 notice ("%d destructor(s) found\n", destructors.number);
1359 notice ("%d frame table(s) found\n", frame_tables.number);
1362 if (constructors.number == 0 && destructors.number == 0
1363 && frame_tables.number == 0
1364 #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1365 /* If we will be running these functions ourselves, we want to emit
1366 stubs into the shared library so that we do not have to relink
1367 dependent programs when we add static objects. */
1368 && ! shared_obj
1369 #endif
1372 #ifdef COLLECT_EXPORT_LIST
1373 /* Do tlink without additional code generation */
1374 do_tlink (ld1_argv, object_lst);
1375 #endif
1376 /* Strip now if it was requested on the command line. */
1377 if (strip_flag)
1379 char **real_strip_argv = (char **) xcalloc (sizeof (char *), 3);
1380 const char ** strip_argv = (const char **) real_strip_argv;
1382 strip_argv[0] = strip_file_name;
1383 strip_argv[1] = output_file;
1384 strip_argv[2] = (char *) 0;
1385 fork_execute ("strip", real_strip_argv);
1388 #ifdef COLLECT_EXPORT_LIST
1389 maybe_unlink (export_file);
1390 #endif
1391 maybe_unlink (c_file);
1392 maybe_unlink (o_file);
1393 return 0;
1396 /* Sort ctor and dtor lists by priority. */
1397 sort_ids (&constructors);
1398 sort_ids (&destructors);
1400 maybe_unlink(output_file);
1401 outf = fopen (c_file, "w");
1402 if (outf == (FILE *) 0)
1403 fatal_perror ("fopen %s", c_file);
1405 write_c_file (outf, c_file);
1407 if (fclose (outf))
1408 fatal_perror ("fclose %s", c_file);
1410 /* Tell the linker that we have initializer and finalizer functions. */
1411 #ifdef LD_INIT_SWITCH
1412 #ifdef COLLECT_EXPORT_LIST
1413 *ld2++ = concat (LD_INIT_SWITCH, ":", initname, ":", fininame, NULL);
1414 #else
1415 *ld2++ = LD_INIT_SWITCH;
1416 *ld2++ = initname;
1417 *ld2++ = LD_FINI_SWITCH;
1418 *ld2++ = fininame;
1419 #endif
1420 #endif
1422 #ifdef COLLECT_EXPORT_LIST
1423 if (shared_obj)
1425 /* If we did not add export flag to link arguments before, add it to
1426 second link phase now. No new exports should have been added. */
1427 if (! exports.first)
1428 *ld2++ = concat ("-bE:", export_file, NULL);
1430 add_to_list (&exports, initname);
1431 add_to_list (&exports, fininame);
1432 add_to_list (&exports, "_GLOBAL__DI");
1433 add_to_list (&exports, "_GLOBAL__DD");
1434 exportf = fopen (export_file, "w");
1435 if (exportf == (FILE *) 0)
1436 fatal_perror ("fopen %s", export_file);
1437 write_aix_file (exportf, exports.first);
1438 if (fclose (exportf))
1439 fatal_perror ("fclose %s", export_file);
1441 #endif
1443 /* End of arguments to second link phase. */
1444 *ld2 = (char*) 0;
1446 if (debug)
1448 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1449 output_file, c_file);
1450 write_c_file (stderr, "stderr");
1451 fprintf (stderr, "========== end of c_file\n\n");
1452 #ifdef COLLECT_EXPORT_LIST
1453 fprintf (stderr, "\n========== export_file = %s\n", export_file);
1454 write_aix_file (stderr, exports.first);
1455 fprintf (stderr, "========== end of export_file\n\n");
1456 #endif
1459 /* Assemble the constructor and destructor tables.
1460 Link the tables in with the rest of the program. */
1462 fork_execute ("gcc", c_argv);
1463 #ifdef COLLECT_EXPORT_LIST
1464 /* On AIX we must call tlink because of possible templates resolution */
1465 do_tlink (ld2_argv, object_lst);
1466 #else
1467 /* Otherwise, simply call ld because tlink is already done */
1468 fork_execute ("ld", ld2_argv);
1470 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1471 constructors/destructors in shared libraries. */
1472 scan_prog_file (output_file, PASS_SECOND);
1473 #endif
1475 maybe_unlink (c_file);
1476 maybe_unlink (o_file);
1478 #ifdef COLLECT_EXPORT_LIST
1479 maybe_unlink (export_file);
1480 #endif
1482 return 0;
1486 /* Wait for a process to finish, and exit if a nonzero status is found. */
1489 collect_wait (prog)
1490 const char *prog;
1492 int status;
1494 pwait (pid, &status, 0);
1495 if (status)
1497 if (WIFSIGNALED (status))
1499 int sig = WTERMSIG (status);
1500 error ("%s terminated with signal %d [%s]%s",
1501 prog, sig, strsignal(sig),
1502 WCOREDUMP(status) ? ", core dumped" : "");
1503 collect_exit (FATAL_EXIT_CODE);
1506 if (WIFEXITED (status))
1507 return WEXITSTATUS (status);
1509 return 0;
1512 static void
1513 do_wait (prog)
1514 const char *prog;
1516 int ret = collect_wait (prog);
1517 if (ret != 0)
1519 error ("%s returned %d exit status", prog, ret);
1520 collect_exit (ret);
1525 /* Execute a program, and wait for the reply. */
1527 void
1528 collect_execute (prog, argv, redir)
1529 const char *prog;
1530 char **argv;
1531 const char *redir;
1533 char *errmsg_fmt;
1534 char *errmsg_arg;
1535 int redir_handle = -1;
1536 int stdout_save = -1;
1537 int stderr_save = -1;
1539 if (vflag || debug)
1541 char **p_argv;
1542 const char *str;
1544 if (argv[0])
1545 fprintf (stderr, "%s", argv[0]);
1546 else
1547 notice ("[cannot find %s]", prog);
1549 for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
1550 fprintf (stderr, " %s", str);
1552 fprintf (stderr, "\n");
1555 fflush (stdout);
1556 fflush (stderr);
1558 /* If we cannot find a program we need, complain error. Do this here
1559 since we might not end up needing something that we could not find. */
1561 if (argv[0] == 0)
1562 fatal ("cannot find `%s'", prog);
1564 if (redir)
1566 /* Open response file. */
1567 redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT);
1569 /* Duplicate the stdout and stderr file handles
1570 so they can be restored later. */
1571 stdout_save = dup (STDOUT_FILENO);
1572 if (stdout_save == -1)
1573 fatal_perror ("redirecting stdout: %s", redir);
1574 stderr_save = dup (STDERR_FILENO);
1575 if (stderr_save == -1)
1576 fatal_perror ("redirecting stdout: %s", redir);
1578 /* Redirect stdout & stderr to our response file. */
1579 dup2 (redir_handle, STDOUT_FILENO);
1580 dup2 (redir_handle, STDERR_FILENO);
1583 pid = pexecute (argv[0], argv, argv[0], NULL, &errmsg_fmt, &errmsg_arg,
1584 (PEXECUTE_FIRST | PEXECUTE_LAST | PEXECUTE_SEARCH));
1586 if (redir)
1588 /* Restore stdout and stderr to their previous settings. */
1589 dup2 (stdout_save, STDOUT_FILENO);
1590 dup2 (stderr_save, STDERR_FILENO);
1592 /* Close response file. */
1593 close (redir_handle);
1596 if (pid == -1)
1597 fatal_perror (errmsg_fmt, errmsg_arg);
1600 static void
1601 fork_execute (prog, argv)
1602 const char *prog;
1603 char **argv;
1605 collect_execute (prog, argv, NULL);
1606 do_wait (prog);
1609 /* Unlink a file unless we are debugging. */
1611 static void
1612 maybe_unlink (file)
1613 const char *file;
1615 if (!debug)
1616 unlink (file);
1617 else
1618 notice ("[Leaving %s]\n", file);
1622 static long sequence_number = 0;
1624 /* Add a name to a linked list. */
1626 static void
1627 add_to_list (head_ptr, name)
1628 struct head *head_ptr;
1629 const char *name;
1631 struct id *newid
1632 = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
1633 struct id *p;
1634 strcpy (newid->name, name);
1636 if (head_ptr->first)
1637 head_ptr->last->next = newid;
1638 else
1639 head_ptr->first = newid;
1641 /* Check for duplicate symbols. */
1642 for (p = head_ptr->first;
1643 strcmp (name, p->name) != 0;
1644 p = p->next)
1646 if (p != newid)
1648 head_ptr->last->next = 0;
1649 free (newid);
1650 return;
1653 newid->sequence = ++sequence_number;
1654 head_ptr->last = newid;
1655 head_ptr->number++;
1658 /* Grab the init priority number from an init function name that
1659 looks like "_GLOBAL_.I.12345.foo". */
1661 static int
1662 extract_init_priority (name)
1663 const char *name;
1665 int pos = 0, pri;
1667 while (name[pos] == '_')
1668 ++pos;
1669 pos += 10; /* strlen ("GLOBAL__X_") */
1671 /* Extract init_p number from ctor/dtor name. */
1672 pri = atoi (name + pos);
1673 return pri ? pri : DEFAULT_INIT_PRIORITY;
1676 /* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
1677 ctors will be run from right to left, dtors from left to right. */
1679 static void
1680 sort_ids (head_ptr)
1681 struct head *head_ptr;
1683 /* id holds the current element to insert. id_next holds the next
1684 element to insert. id_ptr iterates through the already sorted elements
1685 looking for the place to insert id. */
1686 struct id *id, *id_next, **id_ptr;
1688 id = head_ptr->first;
1690 /* We don't have any sorted elements yet. */
1691 head_ptr->first = NULL;
1693 for (; id; id = id_next)
1695 id_next = id->next;
1696 id->sequence = extract_init_priority (id->name);
1698 for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next))
1699 if (*id_ptr == NULL
1700 /* If the sequence numbers are the same, we put the id from the
1701 file later on the command line later in the list. */
1702 || id->sequence > (*id_ptr)->sequence
1703 /* Hack: do lexical compare, too.
1704 || (id->sequence == (*id_ptr)->sequence
1705 && strcmp (id->name, (*id_ptr)->name) > 0) */
1708 id->next = *id_ptr;
1709 *id_ptr = id;
1710 break;
1714 /* Now set the sequence numbers properly so write_c_file works. */
1715 for (id = head_ptr->first; id; id = id->next)
1716 id->sequence = ++sequence_number;
1719 /* Write: `prefix', the names on list LIST, `suffix'. */
1721 static void
1722 write_list (stream, prefix, list)
1723 FILE *stream;
1724 const char *prefix;
1725 struct id *list;
1727 while (list)
1729 fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1730 list = list->next;
1734 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1735 /* Given a STRING, return nonzero if it occurs in the list in range
1736 [ARGS_BEGIN,ARGS_END). */
1738 static int
1739 is_in_args (string, args_begin, args_end)
1740 const char *string;
1741 const char **args_begin;
1742 const char **args_end;
1744 const char **args_pointer;
1745 for (args_pointer = args_begin; args_pointer != args_end; ++args_pointer)
1746 if (strcmp (string, *args_pointer) == 0)
1747 return 1;
1748 return 0;
1750 #endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1752 #ifdef COLLECT_EXPORT_LIST
1753 /* This function is really used only on AIX, but may be useful. */
1754 #if 0
1755 static int
1756 is_in_list (prefix, list)
1757 const char *prefix;
1758 struct id *list;
1760 while (list)
1762 if (!strcmp (prefix, list->name)) return 1;
1763 list = list->next;
1765 return 0;
1767 #endif
1768 #endif /* COLLECT_EXPORT_LIST */
1770 /* Added for debugging purpose. */
1771 #ifdef COLLECT_EXPORT_LIST
1772 static void
1773 dump_list (stream, prefix, list)
1774 FILE *stream;
1775 const char *prefix;
1776 struct id *list;
1778 while (list)
1780 fprintf (stream, "%s%s,\n", prefix, list->name);
1781 list = list->next;
1784 #endif
1786 #if 0
1787 static void
1788 dump_prefix_list (stream, prefix, list)
1789 FILE *stream;
1790 const char *prefix;
1791 struct prefix_list *list;
1793 while (list)
1795 fprintf (stream, "%s%s,\n", prefix, list->prefix);
1796 list = list->next;
1799 #endif
1801 static void
1802 write_list_with_asm (stream, prefix, list)
1803 FILE *stream;
1804 const char *prefix;
1805 struct id *list;
1807 while (list)
1809 fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1810 prefix, list->sequence, list->name);
1811 list = list->next;
1815 /* Write out the constructor and destructor tables statically (for a shared
1816 object), along with the functions to execute them. */
1818 static void
1819 write_c_file_stat (stream, name)
1820 FILE *stream;
1821 const char *name ATTRIBUTE_UNUSED;
1823 const char *p, *q;
1824 char *prefix, *r;
1825 int frames = (frame_tables.number > 0);
1827 /* Figure out name of output_file, stripping off .so version. */
1828 p = strrchr (output_file, '/');
1829 if (p == 0)
1830 p = output_file;
1831 else
1832 p++;
1833 q = p;
1834 while (q)
1836 q = strchr (q,'.');
1837 if (q == 0)
1839 q = p + strlen (p);
1840 break;
1842 else
1844 if (strncmp (q, ".so", 3) == 0)
1846 q += 3;
1847 break;
1849 else
1850 q++;
1853 /* q points to null at end of the string (or . of the .so version) */
1854 prefix = xmalloc (q - p + 1);
1855 strncpy (prefix, p, q - p);
1856 prefix[q - p] = 0;
1857 for (r = prefix; *r; r++)
1858 if (!ISALNUM ((unsigned char)*r))
1859 *r = '_';
1860 if (debug)
1861 notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
1862 output_file, prefix);
1864 initname = concat ("_GLOBAL__FI_", prefix, NULL);
1865 fininame = concat ("_GLOBAL__FD_", prefix, NULL);
1867 free (prefix);
1869 /* Write the tables as C code */
1871 fprintf (stream, "static int count;\n");
1872 fprintf (stream, "typedef void entry_pt();\n");
1873 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1875 if (frames)
1877 write_list_with_asm (stream, "extern void *", frame_tables.first);
1879 fprintf (stream, "\tstatic void *frame_table[] = {\n");
1880 write_list (stream, "\t\t&", frame_tables.first);
1881 fprintf (stream, "\t0\n};\n");
1883 /* This must match what's in frame.h. */
1884 fprintf (stream, "struct object {\n");
1885 fprintf (stream, " void *pc_begin;\n");
1886 fprintf (stream, " void *pc_end;\n");
1887 fprintf (stream, " void *fde_begin;\n");
1888 fprintf (stream, " void *fde_array;\n");
1889 fprintf (stream, " __SIZE_TYPE__ count;\n");
1890 fprintf (stream, " struct object *next;\n");
1891 fprintf (stream, "};\n");
1893 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
1894 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
1896 fprintf (stream, "static void reg_frame () {\n");
1897 fprintf (stream, "\tstatic struct object ob;\n");
1898 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
1899 fprintf (stream, "\t}\n");
1901 fprintf (stream, "static void dereg_frame () {\n");
1902 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
1903 fprintf (stream, "\t}\n");
1906 fprintf (stream, "void %s() {\n", initname);
1907 if (constructors.number > 0 || frames)
1909 fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
1910 write_list (stream, "\t\t", constructors.first);
1911 if (frames)
1912 fprintf (stream, "\treg_frame,\n");
1913 fprintf (stream, "\t};\n");
1914 fprintf (stream, "\tentry_pt **p;\n");
1915 fprintf (stream, "\tif (count++ != 0) return;\n");
1916 fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
1917 fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
1919 else
1920 fprintf (stream, "\t++count;\n");
1921 fprintf (stream, "}\n");
1922 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1923 fprintf (stream, "void %s() {\n", fininame);
1924 if (destructors.number > 0 || frames)
1926 fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
1927 write_list (stream, "\t\t", destructors.first);
1928 if (frames)
1929 fprintf (stream, "\tdereg_frame,\n");
1930 fprintf (stream, "\t};\n");
1931 fprintf (stream, "\tentry_pt **p;\n");
1932 fprintf (stream, "\tif (--count != 0) return;\n");
1933 fprintf (stream, "\tp = dtors;\n");
1934 fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
1935 destructors.number + frames);
1937 fprintf (stream, "}\n");
1939 if (shared_obj)
1941 COLLECT_SHARED_INIT_FUNC(stream, initname);
1942 COLLECT_SHARED_FINI_FUNC(stream, fininame);
1946 /* Write the constructor/destructor tables. */
1948 #ifndef LD_INIT_SWITCH
1949 static void
1950 write_c_file_glob (stream, name)
1951 FILE *stream;
1952 const char *name ATTRIBUTE_UNUSED;
1954 /* Write the tables as C code */
1956 int frames = (frame_tables.number > 0);
1958 fprintf (stream, "typedef void entry_pt();\n\n");
1960 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1962 if (frames)
1964 write_list_with_asm (stream, "extern void *", frame_tables.first);
1966 fprintf (stream, "\tstatic void *frame_table[] = {\n");
1967 write_list (stream, "\t\t&", frame_tables.first);
1968 fprintf (stream, "\t0\n};\n");
1970 /* This must match what's in frame.h. */
1971 fprintf (stream, "struct object {\n");
1972 fprintf (stream, " void *pc_begin;\n");
1973 fprintf (stream, " void *pc_end;\n");
1974 fprintf (stream, " void *fde_begin;\n");
1975 fprintf (stream, " void *fde_array;\n");
1976 fprintf (stream, " __SIZE_TYPE__ count;\n");
1977 fprintf (stream, " struct object *next;\n");
1978 fprintf (stream, "};\n");
1980 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
1981 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
1983 fprintf (stream, "static void reg_frame () {\n");
1984 fprintf (stream, "\tstatic struct object ob;\n");
1985 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
1986 fprintf (stream, "\t}\n");
1988 fprintf (stream, "static void dereg_frame () {\n");
1989 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
1990 fprintf (stream, "\t}\n");
1993 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
1994 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
1995 write_list (stream, "\t", constructors.first);
1996 if (frames)
1997 fprintf (stream, "\treg_frame,\n");
1998 fprintf (stream, "\t0\n};\n\n");
2000 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
2002 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
2003 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
2004 write_list (stream, "\t", destructors.first);
2005 if (frames)
2006 fprintf (stream, "\tdereg_frame,\n");
2007 fprintf (stream, "\t0\n};\n\n");
2009 fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
2010 fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
2012 #endif /* ! LD_INIT_SWITCH */
2014 static void
2015 write_c_file (stream, name)
2016 FILE *stream;
2017 const char *name;
2019 fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
2020 #ifndef LD_INIT_SWITCH
2021 if (! shared_obj)
2022 write_c_file_glob (stream, name);
2023 else
2024 #endif
2025 write_c_file_stat (stream, name);
2026 fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
2029 #ifdef COLLECT_EXPORT_LIST
2030 static void
2031 write_aix_file (stream, list)
2032 FILE *stream;
2033 struct id *list;
2035 for (; list; list = list->next)
2037 fputs (list->name, stream);
2038 putc ('\n', stream);
2041 #endif
2043 #ifdef OBJECT_FORMAT_NONE
2045 /* Generic version to scan the name list of the loaded program for
2046 the symbols g++ uses for static constructors and destructors.
2048 The constructor table begins at __CTOR_LIST__ and contains a count
2049 of the number of pointers (or -1 if the constructors are built in a
2050 separate section by the linker), followed by the pointers to the
2051 constructor functions, terminated with a null pointer. The
2052 destructor table has the same format, and begins at __DTOR_LIST__. */
2054 static void
2055 scan_prog_file (prog_name, which_pass)
2056 const char *prog_name;
2057 enum pass which_pass;
2059 void (*int_handler) PARAMS ((int));
2060 void (*quit_handler) PARAMS ((int));
2061 char *real_nm_argv[4];
2062 const char **nm_argv = (const char **) real_nm_argv;
2063 int argc = 0;
2064 int pipe_fd[2];
2065 char *p, buf[1024];
2066 FILE *inf;
2068 if (which_pass == PASS_SECOND)
2069 return;
2071 /* If we do not have an `nm', complain. */
2072 if (nm_file_name == 0)
2073 fatal ("cannot find `nm'");
2075 nm_argv[argc++] = nm_file_name;
2076 if (NM_FLAGS[0] != '\0')
2077 nm_argv[argc++] = NM_FLAGS;
2079 nm_argv[argc++] = prog_name;
2080 nm_argv[argc++] = (char *) 0;
2082 if (pipe (pipe_fd) < 0)
2083 fatal_perror ("pipe");
2085 inf = fdopen (pipe_fd[0], "r");
2086 if (inf == (FILE *) 0)
2087 fatal_perror ("fdopen");
2089 /* Trace if needed. */
2090 if (vflag)
2092 const char **p_argv;
2093 const char *str;
2095 for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2096 fprintf (stderr, " %s", str);
2098 fprintf (stderr, "\n");
2101 fflush (stdout);
2102 fflush (stderr);
2104 /* Spawn child nm on pipe */
2105 pid = vfork ();
2106 if (pid == -1)
2107 fatal_perror (VFORK_STRING);
2109 if (pid == 0) /* child context */
2111 /* setup stdout */
2112 if (dup2 (pipe_fd[1], 1) < 0)
2113 fatal_perror ("dup2 %d 1", pipe_fd[1]);
2115 if (close (pipe_fd[0]) < 0)
2116 fatal_perror ("close %d", pipe_fd[0]);
2118 if (close (pipe_fd[1]) < 0)
2119 fatal_perror ("close %d", pipe_fd[1]);
2121 execv (nm_file_name, real_nm_argv);
2122 fatal_perror ("execv %s", nm_file_name);
2125 /* Parent context from here on. */
2126 int_handler = (void (*) PARAMS ((int))) signal (SIGINT, SIG_IGN);
2127 #ifdef SIGQUIT
2128 quit_handler = (void (*) PARAMS ((int))) signal (SIGQUIT, SIG_IGN);
2129 #endif
2131 if (close (pipe_fd[1]) < 0)
2132 fatal_perror ("close %d", pipe_fd[1]);
2134 if (debug)
2135 fprintf (stderr, "\nnm output with constructors/destructors.\n");
2137 /* Read each line of nm output. */
2138 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2140 int ch, ch2;
2141 char *name, *end;
2143 /* If it contains a constructor or destructor name, add the name
2144 to the appropriate list. */
2146 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
2147 if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
2148 break;
2150 if (ch != '_')
2151 continue;
2153 name = p;
2154 /* Find the end of the symbol name.
2155 Do not include `|', because Encore nm can tack that on the end. */
2156 for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|';
2157 end++)
2158 continue;
2161 *end = '\0';
2162 switch (is_ctor_dtor (name))
2164 case 1:
2165 if (which_pass != PASS_LIB)
2166 add_to_list (&constructors, name);
2167 break;
2169 case 2:
2170 if (which_pass != PASS_LIB)
2171 add_to_list (&destructors, name);
2172 break;
2174 case 3:
2175 if (which_pass != PASS_LIB)
2176 fatal ("init function found in object %s", prog_name);
2177 #ifndef LD_INIT_SWITCH
2178 add_to_list (&constructors, name);
2179 #endif
2180 break;
2182 case 4:
2183 if (which_pass != PASS_LIB)
2184 fatal ("fini function found in object %s", prog_name);
2185 #ifndef LD_FINI_SWITCH
2186 add_to_list (&destructors, name);
2187 #endif
2188 break;
2190 case 5:
2191 if (which_pass != PASS_LIB)
2192 add_to_list (&frame_tables, name);
2193 break;
2195 default: /* not a constructor or destructor */
2196 continue;
2199 if (debug)
2200 fprintf (stderr, "\t%s\n", buf);
2203 if (debug)
2204 fprintf (stderr, "\n");
2206 if (fclose (inf) != 0)
2207 fatal_perror ("fclose");
2209 do_wait (nm_file_name);
2211 signal (SIGINT, int_handler);
2212 #ifdef SIGQUIT
2213 signal (SIGQUIT, quit_handler);
2214 #endif
2217 #if SUNOS4_SHARED_LIBRARIES
2219 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2220 that the output file depends upon and their initialization/finalization
2221 routines, if any. */
2223 #include <a.out.h>
2224 #include <fcntl.h>
2225 #include <link.h>
2226 #include <sys/mman.h>
2227 #include <sys/param.h>
2228 #include <unistd.h>
2229 #include <sys/dir.h>
2231 /* pointers to the object file */
2232 unsigned object; /* address of memory mapped file */
2233 unsigned objsize; /* size of memory mapped to file */
2234 char * code; /* pointer to code segment */
2235 char * data; /* pointer to data segment */
2236 struct nlist *symtab; /* pointer to symbol table */
2237 struct link_dynamic *ld;
2238 struct link_dynamic_2 *ld_2;
2239 struct head libraries;
2241 /* Map the file indicated by NAME into memory and store its address. */
2243 static void mapfile PARAMS ((const char *));
2245 static void
2246 mapfile (name)
2247 const char *name;
2249 int fp;
2250 struct stat s;
2251 if ((fp = open (name, O_RDONLY)) == -1)
2252 fatal ("unable to open file '%s'", name);
2253 if (fstat (fp, &s) == -1)
2254 fatal ("unable to stat file '%s'", name);
2256 objsize = s.st_size;
2257 object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE,
2258 fp, 0);
2259 if (object == (unsigned)-1)
2260 fatal ("unable to mmap file '%s'", name);
2262 close (fp);
2265 /* Helpers for locatelib. */
2267 static const char *libname;
2269 static int libselect PARAMS ((struct direct *));
2271 static int
2272 libselect (d)
2273 struct direct *d;
2275 return (strncmp (libname, d->d_name, strlen (libname)) == 0);
2278 /* If one file has an additional numeric extension past LIBNAME, then put
2279 that one first in the sort. If both files have additional numeric
2280 extensions, then put the one with the higher number first in the sort.
2282 We must verify that the extension is numeric, because Sun saves the
2283 original versions of patched libraries with a .FCS extension. Files with
2284 invalid extensions must go last in the sort, so that they will not be used. */
2285 static int libcompare PARAMS ((struct direct **, struct direct **));
2287 static int
2288 libcompare (d1, d2)
2289 struct direct **d1, **d2;
2291 int i1, i2 = strlen (libname);
2292 char *e1 = (*d1)->d_name + i2;
2293 char *e2 = (*d2)->d_name + i2;
2295 while (*e1 && *e2 && *e1 == '.' && *e2 == '.'
2296 && e1[1] && ISDIGIT (e1[1]) && e2[1] && ISDIGIT (e2[1]))
2298 ++e1;
2299 ++e2;
2300 i1 = strtol (e1, &e1, 10);
2301 i2 = strtol (e2, &e2, 10);
2302 if (i1 != i2)
2303 return i1 - i2;
2306 if (*e1)
2308 /* It has a valid numeric extension, prefer this one. */
2309 if (*e1 == '.' && e1[1] && ISDIGIT (e1[1]))
2310 return 1;
2311 /* It has an invalid numeric extension, must prefer the other one. */
2312 else
2313 return -1;
2315 else if (*e2)
2317 /* It has a valid numeric extension, prefer this one. */
2318 if (*e2 == '.' && e2[1] && ISDIGIT (e2[1]))
2319 return -1;
2320 /* It has an invalid numeric extension, must prefer the other one. */
2321 else
2322 return 1;
2324 else
2325 return 0;
2328 /* Given the name NAME of a dynamic dependency, find its pathname and add
2329 it to the list of libraries. */
2330 static void locatelib PARAMS ((const char *));
2332 static void
2333 locatelib (name)
2334 const char *name;
2336 static const char **l;
2337 static int cnt;
2338 char buf[MAXPATHLEN];
2339 char *p, *q;
2340 const char **pp;
2342 if (l == 0)
2344 char *ld_rules;
2345 char *ldr = 0;
2346 /* counting elements in array, need 1 extra for null */
2347 cnt = 1;
2348 ld_rules = (char *) (ld_2->ld_rules + code);
2349 if (ld_rules)
2351 cnt++;
2352 for (; *ld_rules != 0; ld_rules++)
2353 if (*ld_rules == ':')
2354 cnt++;
2355 ld_rules = (char *) (ld_2->ld_rules + code);
2356 ldr = xstrdup (ld_rules);
2358 p = getenv ("LD_LIBRARY_PATH");
2359 q = 0;
2360 if (p)
2362 cnt++;
2363 for (q = p ; *q != 0; q++)
2364 if (*q == ':')
2365 cnt++;
2366 q = xstrdup (p);
2368 l = (const char **) xmalloc ((cnt + 3) * sizeof (char *));
2369 pp = l;
2370 if (ldr)
2372 *pp++ = ldr;
2373 for (; *ldr != 0; ldr++)
2374 if (*ldr == ':')
2376 *ldr++ = 0;
2377 *pp++ = ldr;
2380 if (q)
2382 *pp++ = q;
2383 for (; *q != 0; q++)
2384 if (*q == ':')
2386 *q++ = 0;
2387 *pp++ = q;
2390 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2391 *pp++ = "/lib";
2392 *pp++ = "/usr/lib";
2393 *pp++ = "/usr/local/lib";
2394 *pp = 0;
2396 libname = name;
2397 for (pp = l; *pp != 0 ; pp++)
2399 struct direct **namelist;
2400 int entries;
2401 if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0)
2403 sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name);
2404 add_to_list (&libraries, buf);
2405 if (debug)
2406 fprintf (stderr, "%s\n", buf);
2407 break;
2410 if (*pp == 0)
2412 if (debug)
2413 notice ("not found\n");
2414 else
2415 fatal ("dynamic dependency %s not found", name);
2419 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2420 that it depends upon and any constructors or destructors they contain. */
2422 static void
2423 scan_libraries (prog_name)
2424 const char *prog_name;
2426 struct exec *header;
2427 char *base;
2428 struct link_object *lo;
2429 char buff[MAXPATHLEN];
2430 struct id *list;
2432 mapfile (prog_name);
2433 header = (struct exec *)object;
2434 if (N_BADMAG (*header))
2435 fatal ("bad magic number in file '%s'", prog_name);
2436 if (header->a_dynamic == 0)
2437 return;
2439 code = (char *) (N_TXTOFF (*header) + (long) header);
2440 data = (char *) (N_DATOFF (*header) + (long) header);
2441 symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header);
2443 if (header->a_magic == ZMAGIC && header->a_entry == 0x20)
2445 /* shared object */
2446 ld = (struct link_dynamic *) (symtab->n_value + code);
2447 base = code;
2449 else
2451 /* executable */
2452 ld = (struct link_dynamic *) data;
2453 base = code-PAGSIZ;
2456 if (debug)
2457 notice ("dynamic dependencies.\n");
2459 ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);
2460 for (lo = (struct link_object *) ld_2->ld_need; lo;
2461 lo = (struct link_object *) lo->lo_next)
2463 char *name;
2464 lo = (struct link_object *) ((long) lo + code);
2465 name = (char *) (code + lo->lo_name);
2466 if (lo->lo_library)
2468 if (debug)
2469 fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major);
2470 sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor);
2471 locatelib (buff);
2473 else
2475 if (debug)
2476 fprintf (stderr, "\t%s\n", name);
2477 add_to_list (&libraries, name);
2481 if (debug)
2482 fprintf (stderr, "\n");
2484 /* now iterate through the library list adding their symbols to
2485 the list. */
2486 for (list = libraries.first; list; list = list->next)
2487 scan_prog_file (list->name, PASS_LIB);
2490 #else /* SUNOS4_SHARED_LIBRARIES */
2491 #ifdef LDD_SUFFIX
2493 /* Use the List Dynamic Dependencies program to find shared libraries that
2494 the output file depends upon and their initialization/finalization
2495 routines, if any. */
2497 static void
2498 scan_libraries (prog_name)
2499 const char *prog_name;
2501 static struct head libraries; /* list of shared libraries found */
2502 struct id *list;
2503 void (*int_handler) PARAMS ((int));
2504 void (*quit_handler) PARAMS ((int));
2505 char *real_ldd_argv[4];
2506 const char **ldd_argv = (const char **) real_ldd_argv;
2507 int argc = 0;
2508 int pipe_fd[2];
2509 char buf[1024];
2510 FILE *inf;
2512 /* If we do not have an `ldd', complain. */
2513 if (ldd_file_name == 0)
2515 error ("cannot find `ldd'");
2516 return;
2519 ldd_argv[argc++] = ldd_file_name;
2520 ldd_argv[argc++] = prog_name;
2521 ldd_argv[argc++] = (char *) 0;
2523 if (pipe (pipe_fd) < 0)
2524 fatal_perror ("pipe");
2526 inf = fdopen (pipe_fd[0], "r");
2527 if (inf == (FILE *) 0)
2528 fatal_perror ("fdopen");
2530 /* Trace if needed. */
2531 if (vflag)
2533 const char **p_argv;
2534 const char *str;
2536 for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2537 fprintf (stderr, " %s", str);
2539 fprintf (stderr, "\n");
2542 fflush (stdout);
2543 fflush (stderr);
2545 /* Spawn child ldd on pipe */
2546 pid = vfork ();
2547 if (pid == -1)
2548 fatal_perror (VFORK_STRING);
2550 if (pid == 0) /* child context */
2552 /* setup stdout */
2553 if (dup2 (pipe_fd[1], 1) < 0)
2554 fatal_perror ("dup2 %d 1", pipe_fd[1]);
2556 if (close (pipe_fd[0]) < 0)
2557 fatal_perror ("close %d", pipe_fd[0]);
2559 if (close (pipe_fd[1]) < 0)
2560 fatal_perror ("close %d", pipe_fd[1]);
2562 execv (ldd_file_name, real_ldd_argv);
2563 fatal_perror ("execv %s", ldd_file_name);
2566 /* Parent context from here on. */
2567 int_handler = (void (*) PARAMS ((int))) signal (SIGINT, SIG_IGN);
2568 #ifdef SIGQUIT
2569 quit_handler = (void (*) PARAMS ((int))) signal (SIGQUIT, SIG_IGN);
2570 #endif
2572 if (close (pipe_fd[1]) < 0)
2573 fatal_perror ("close %d", pipe_fd[1]);
2575 if (debug)
2576 notice ("\nldd output with constructors/destructors.\n");
2578 /* Read each line of ldd output. */
2579 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2581 int ch2;
2582 char *name, *end, *p = buf;
2584 /* Extract names of libraries and add to list. */
2585 PARSE_LDD_OUTPUT (p);
2586 if (p == 0)
2587 continue;
2589 name = p;
2590 if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
2591 fatal ("dynamic dependency %s not found", buf);
2593 /* Find the end of the symbol name. */
2594 for (end = p;
2595 (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|';
2596 end++)
2597 continue;
2598 *end = '\0';
2600 if (access (name, R_OK) == 0)
2601 add_to_list (&libraries, name);
2602 else
2603 fatal ("unable to open dynamic dependency '%s'", buf);
2605 if (debug)
2606 fprintf (stderr, "\t%s\n", buf);
2608 if (debug)
2609 fprintf (stderr, "\n");
2611 if (fclose (inf) != 0)
2612 fatal_perror ("fclose");
2614 do_wait (ldd_file_name);
2616 signal (SIGINT, int_handler);
2617 #ifdef SIGQUIT
2618 signal (SIGQUIT, quit_handler);
2619 #endif
2621 /* now iterate through the library list adding their symbols to
2622 the list. */
2623 for (list = libraries.first; list; list = list->next)
2624 scan_prog_file (list->name, PASS_LIB);
2627 #endif /* LDD_SUFFIX */
2628 #endif /* SUNOS4_SHARED_LIBRARIES */
2630 #endif /* OBJECT_FORMAT_NONE */
2634 * COFF specific stuff.
2637 #ifdef OBJECT_FORMAT_COFF
2639 #if defined(EXTENDED_COFF)
2641 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2642 # define GCC_SYMENT SYMR
2643 # define GCC_OK_SYMBOL(X) ((X).st == stProc || (X).st == stGlobal)
2644 # define GCC_SYMINC(X) (1)
2645 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2646 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2648 #else
2650 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2651 # define GCC_SYMENT SYMENT
2652 # define GCC_OK_SYMBOL(X) \
2653 (((X).n_sclass == C_EXT) && \
2654 ((X).n_scnum > N_UNDEF) && \
2655 (aix64_flag \
2656 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2657 || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2658 # define GCC_UNDEF_SYMBOL(X) \
2659 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2660 # define GCC_SYMINC(X) ((X).n_numaux+1)
2661 # define GCC_SYMZERO(X) 0
2663 /* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
2664 #ifdef _AIX51
2665 # define GCC_CHECK_HDR(X) \
2666 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2667 || (HEADER (X).f_magic == 0767 && aix64_flag))
2668 #else
2669 # define GCC_CHECK_HDR(X) \
2670 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2671 || (HEADER (X).f_magic == 0757 && aix64_flag))
2672 #endif
2674 #endif
2676 #ifdef COLLECT_EXPORT_LIST
2677 /* Array of standard AIX libraries which should not
2678 be scanned for ctors/dtors. */
2679 static const char *const aix_std_libs[] = {
2680 "/unix",
2681 "/lib/libc.a",
2682 "/lib/libm.a",
2683 "/lib/libc_r.a",
2684 "/lib/libm_r.a",
2685 "/usr/lib/libc.a",
2686 "/usr/lib/libm.a",
2687 "/usr/lib/libc_r.a",
2688 "/usr/lib/libm_r.a",
2689 "/usr/lib/threads/libc.a",
2690 "/usr/ccs/lib/libc.a",
2691 "/usr/ccs/lib/libm.a",
2692 "/usr/ccs/lib/libc_r.a",
2693 "/usr/ccs/lib/libm_r.a",
2694 NULL
2697 /* This function checks the filename and returns 1
2698 if this name matches the location of a standard AIX library. */
2699 static int ignore_library PARAMS ((const char *));
2700 static int
2701 ignore_library (name)
2702 const char *name;
2704 const char *const *p = &aix_std_libs[0];
2705 while (*p++ != NULL)
2706 if (! strcmp (name, *p)) return 1;
2707 return 0;
2709 #endif /* COLLECT_EXPORT_LIST */
2711 #if defined (HAVE_DECL_LDGETNAME) && !HAVE_DECL_LDGETNAME
2712 extern char *ldgetname PARAMS ((LDFILE *, GCC_SYMENT *));
2713 #endif
2715 /* COFF version to scan the name list of the loaded program for
2716 the symbols g++ uses for static constructors and destructors.
2718 The constructor table begins at __CTOR_LIST__ and contains a count
2719 of the number of pointers (or -1 if the constructors are built in a
2720 separate section by the linker), followed by the pointers to the
2721 constructor functions, terminated with a null pointer. The
2722 destructor table has the same format, and begins at __DTOR_LIST__. */
2724 static void
2725 scan_prog_file (prog_name, which_pass)
2726 const char *prog_name;
2727 enum pass which_pass;
2729 LDFILE *ldptr = NULL;
2730 int sym_index, sym_count;
2731 int is_shared = 0;
2733 if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2734 return;
2736 #ifdef COLLECT_EXPORT_LIST
2737 /* We do not need scanning for some standard C libraries. */
2738 if (which_pass == PASS_FIRST && ignore_library (prog_name))
2739 return;
2741 /* On AIX we have a loop, because there is not much difference
2742 between an object and an archive. This trick allows us to
2743 eliminate scan_libraries() function. */
2746 #endif
2747 /* Some platforms (e.g. OSF4) declare ldopen as taking a
2748 non-const char * filename parameter, even though it will not
2749 modify that string. So we must cast away const-ness here,
2750 which will cause -Wcast-qual to burp. */
2751 if ((ldptr = ldopen ((char *)prog_name, ldptr)) != NULL)
2753 if (! MY_ISCOFF (HEADER (ldptr).f_magic))
2754 fatal ("%s: not a COFF file", prog_name);
2756 if (GCC_CHECK_HDR (ldptr))
2758 sym_count = GCC_SYMBOLS (ldptr);
2759 sym_index = GCC_SYMZERO (ldptr);
2761 #ifdef COLLECT_EXPORT_LIST
2762 /* Is current archive member a shared object? */
2763 is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
2764 #endif
2766 while (sym_index < sym_count)
2768 GCC_SYMENT symbol;
2770 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2771 break;
2772 sym_index += GCC_SYMINC (symbol);
2774 if (GCC_OK_SYMBOL (symbol))
2776 char *name;
2778 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2779 continue; /* should never happen */
2781 #ifdef XCOFF_DEBUGGING_INFO
2782 /* All AIX function names have a duplicate entry
2783 beginning with a dot. */
2784 if (*name == '.')
2785 ++name;
2786 #endif
2788 switch (is_ctor_dtor (name))
2790 case 1:
2791 if (! is_shared)
2792 add_to_list (&constructors, name);
2793 #ifdef COLLECT_EXPORT_LIST
2794 if (which_pass == PASS_OBJ)
2795 add_to_list (&exports, name);
2796 #endif
2797 break;
2799 case 2:
2800 if (! is_shared)
2801 add_to_list (&destructors, name);
2802 #ifdef COLLECT_EXPORT_LIST
2803 if (which_pass == PASS_OBJ)
2804 add_to_list (&exports, name);
2805 #endif
2806 break;
2808 #ifdef COLLECT_EXPORT_LIST
2809 case 3:
2810 #ifndef LD_INIT_SWITCH
2811 if (is_shared)
2812 add_to_list (&constructors, name);
2813 #endif
2814 break;
2816 case 4:
2817 #ifndef LD_INIT_SWITCH
2818 if (is_shared)
2819 add_to_list (&destructors, name);
2820 #endif
2821 break;
2822 #endif
2824 case 5:
2825 if (! is_shared)
2826 add_to_list (&frame_tables, name);
2827 #ifdef COLLECT_EXPORT_LIST
2828 if (which_pass == PASS_OBJ)
2829 add_to_list (&exports, name);
2830 #endif
2831 break;
2833 default: /* not a constructor or destructor */
2834 #ifdef COLLECT_EXPORT_LIST
2835 /* If we are building a shared object on AIX we need
2836 to explicitly export all global symbols. */
2837 if (shared_obj)
2839 if (which_pass == PASS_OBJ && (! export_flag))
2840 add_to_list (&exports, name);
2842 #endif
2843 continue;
2846 if (debug)
2847 #if !defined(EXTENDED_COFF)
2848 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
2849 symbol.n_scnum, symbol.n_sclass,
2850 (symbol.n_type ? "0" : ""), symbol.n_type,
2851 name);
2852 #else
2853 fprintf (stderr,
2854 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
2855 symbol.iss, (long) symbol.value, symbol.index, name);
2856 #endif
2860 #ifdef COLLECT_EXPORT_LIST
2861 else
2863 /* If archive contains both 32-bit and 64-bit objects,
2864 we want to skip objects in other mode so mismatch normal. */
2865 if (debug)
2866 fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n",
2867 prog_name, HEADER (ldptr).f_magic, aix64_flag);
2869 #endif
2871 else
2873 fatal ("%s: cannot open as COFF file", prog_name);
2875 #ifdef COLLECT_EXPORT_LIST
2876 /* On AIX loop continues while there are more members in archive. */
2878 while (ldclose (ldptr) == FAILURE);
2879 #else
2880 /* Otherwise we simply close ldptr. */
2881 (void) ldclose(ldptr);
2882 #endif
2884 #endif /* OBJECT_FORMAT_COFF */
2886 #ifdef COLLECT_EXPORT_LIST
2887 /* Given a library name without "lib" prefix, this function
2888 returns a full library name including a path. */
2889 static char *
2890 resolve_lib_name (name)
2891 const char *name;
2893 char *lib_buf;
2894 int i, j, l = 0;
2896 for (i = 0; libpaths[i]; i++)
2897 if (libpaths[i]->max_len > l)
2898 l = libpaths[i]->max_len;
2900 lib_buf = xmalloc (l + strlen(name) + 10);
2902 for (i = 0; libpaths[i]; i++)
2904 struct prefix_list *list = libpaths[i]->plist;
2905 for (; list; list = list->next)
2907 /* The following lines are needed because path_prefix list
2908 may contain directories both with trailing '/' and
2909 without it. */
2910 const char *p = "";
2911 if (list->prefix[strlen(list->prefix)-1] != '/')
2912 p = "/";
2913 for (j = 0; libexts[j]; j++)
2915 sprintf (lib_buf, "%s%slib%s.%s",
2916 list->prefix, p, name, libexts[j]);
2917 if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
2918 if (file_exists (lib_buf))
2920 if (debug) fprintf (stderr, "found: %s\n", lib_buf);
2921 return (lib_buf);
2926 if (debug)
2927 fprintf (stderr, "not found\n");
2928 else
2929 fatal ("library lib%s not found", name);
2930 return (NULL);
2932 #endif /* COLLECT_EXPORT_LIST */
2936 * OSF/rose specific stuff.
2939 #ifdef OBJECT_FORMAT_ROSE
2941 /* Union of the various load commands */
2943 typedef union load_union
2945 ldc_header_t hdr; /* common header */
2946 load_cmd_map_command_t map; /* map indexing other load cmds */
2947 interpreter_command_t iprtr; /* interpreter pathname */
2948 strings_command_t str; /* load commands strings section */
2949 region_command_t region; /* region load command */
2950 reloc_command_t reloc; /* relocation section */
2951 package_command_t pkg; /* package load command */
2952 symbols_command_t sym; /* symbol sections */
2953 entry_command_t ent; /* program start section */
2954 gen_info_command_t info; /* object information */
2955 func_table_command_t func; /* function constructors/destructors */
2956 } load_union_t;
2958 /* Structure to point to load command and data section in memory. */
2960 typedef struct load_all
2962 load_union_t *load; /* load command */
2963 char *section; /* pointer to section */
2964 } load_all_t;
2966 /* Structure to contain information about a file mapped into memory. */
2968 struct file_info
2970 char *start; /* start of map */
2971 char *name; /* filename */
2972 long size; /* size of the file */
2973 long rounded_size; /* size rounded to page boundary */
2974 int fd; /* file descriptor */
2975 int rw; /* != 0 if opened read/write */
2976 int use_mmap; /* != 0 if mmap'ed */
2979 extern int decode_mach_o_hdr ();
2980 extern int encode_mach_o_hdr ();
2982 static void add_func_table PARAMS ((mo_header_t *, load_all_t *,
2983 symbol_info_t *, int));
2984 static void print_header PARAMS ((mo_header_t *));
2985 static void print_load_command PARAMS ((load_union_t *, size_t, int));
2986 static void bad_header PARAMS ((int));
2987 static struct file_info *read_file PARAMS ((const char *, int, int));
2988 static void end_file PARAMS ((struct file_info *));
2990 /* OSF/rose specific version to scan the name list of the loaded
2991 program for the symbols g++ uses for static constructors and
2992 destructors.
2994 The constructor table begins at __CTOR_LIST__ and contains a count
2995 of the number of pointers (or -1 if the constructors are built in a
2996 separate section by the linker), followed by the pointers to the
2997 constructor functions, terminated with a null pointer. The
2998 destructor table has the same format, and begins at __DTOR_LIST__. */
3000 static void
3001 scan_prog_file (prog_name, which_pass)
3002 const char *prog_name;
3003 enum pass which_pass;
3005 char *obj;
3006 mo_header_t hdr;
3007 load_all_t *load_array;
3008 load_all_t *load_end;
3009 load_all_t *load_cmd;
3010 int symbol_load_cmds;
3011 off_t offset;
3012 int i;
3013 int num_syms;
3014 int status;
3015 char *str_sect;
3016 struct file_info *obj_file;
3017 int prog_fd;
3018 mo_lcid_t cmd_strings = -1;
3019 symbol_info_t *main_sym = 0;
3020 int rw = (which_pass != PASS_FIRST);
3022 prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
3023 if (prog_fd < 0)
3024 fatal_perror ("open %s", prog_name);
3026 obj_file = read_file (prog_name, prog_fd, rw);
3027 obj = obj_file->start;
3029 status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);
3030 if (status != MO_HDR_CONV_SUCCESS)
3031 bad_header (status);
3034 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
3035 since the hardware will automatically swap bytes for us on loading little endian
3036 integers. */
3038 #ifndef CROSS_COMPILE
3039 if (hdr.moh_magic != MOH_MAGIC_MSB
3040 || hdr.moh_header_version != MOH_HEADER_VERSION
3041 || hdr.moh_byte_order != OUR_BYTE_ORDER
3042 || hdr.moh_data_rep_id != OUR_DATA_REP_ID
3043 || hdr.moh_cpu_type != OUR_CPU_TYPE
3044 || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE
3045 || hdr.moh_vendor_type != OUR_VENDOR_TYPE)
3047 fatal ("incompatibilities between object file & expected values");
3049 #endif
3051 if (debug)
3052 print_header (&hdr);
3054 offset = hdr.moh_first_cmd_off;
3055 load_end = load_array
3056 = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);
3058 /* Build array of load commands, calculating the offsets */
3059 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3061 load_union_t *load_hdr; /* load command header */
3063 load_cmd = load_end++;
3064 load_hdr = (load_union_t *) (obj + offset);
3066 /* If modifying the program file, copy the header. */
3067 if (rw)
3069 load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
3070 memcpy ((char *)ptr, (char *)load_hdr, load_hdr->hdr.ldci_cmd_size);
3071 load_hdr = ptr;
3073 /* null out old command map, because we will rewrite at the end. */
3074 if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
3076 cmd_strings = ptr->map.lcm_ld_cmd_strings;
3077 ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
3081 load_cmd->load = load_hdr;
3082 if (load_hdr->hdr.ldci_section_off > 0)
3083 load_cmd->section = obj + load_hdr->hdr.ldci_section_off;
3085 if (debug)
3086 print_load_command (load_hdr, offset, i);
3088 offset += load_hdr->hdr.ldci_cmd_size;
3091 /* If the last command is the load command map and is not undefined,
3092 decrement the count of load commands. */
3093 if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)
3095 load_end--;
3096 hdr.moh_n_load_cmds--;
3099 /* Go through and process each symbol table section. */
3100 symbol_load_cmds = 0;
3101 for (load_cmd = load_array; load_cmd < load_end; load_cmd++)
3103 load_union_t *load_hdr = load_cmd->load;
3105 if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
3107 symbol_load_cmds++;
3109 if (debug)
3111 const char *kind = "unknown";
3113 switch (load_hdr->sym.symc_kind)
3115 case SYMC_IMPORTS: kind = "imports"; break;
3116 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
3117 case SYMC_STABS: kind = "stabs"; break;
3120 notice ("\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
3121 symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
3124 if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
3125 continue;
3127 str_sect = load_array[load_hdr->sym.symc_strings_section].section;
3128 if (str_sect == (char *) 0)
3129 fatal ("string section missing");
3131 if (load_cmd->section == (char *) 0)
3132 fatal ("section pointer missing");
3134 num_syms = load_hdr->sym.symc_nentries;
3135 for (i = 0; i < num_syms; i++)
3137 symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
3138 char *name = sym->si_name.symbol_name + str_sect;
3140 if (name[0] != '_')
3141 continue;
3143 if (rw)
3145 char *n = name + strlen (name) - strlen (NAME__MAIN);
3147 if ((n - name) < 0 || strcmp (n, NAME__MAIN))
3148 continue;
3149 while (n != name)
3150 if (*--n != '_')
3151 continue;
3153 main_sym = sym;
3155 else
3157 switch (is_ctor_dtor (name))
3159 case 1:
3160 add_to_list (&constructors, name);
3161 break;
3163 case 2:
3164 add_to_list (&destructors, name);
3165 break;
3167 default: /* not a constructor or destructor */
3168 continue;
3172 if (debug)
3173 fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
3174 sym->si_type, sym->si_sc_type, sym->si_flags, name);
3179 if (symbol_load_cmds == 0)
3180 fatal ("no symbol table found");
3182 /* Update the program file now, rewrite header and load commands. At present,
3183 we assume that there is enough space after the last load command to insert
3184 one more. Since the first section written out is page aligned, and the
3185 number of load commands is small, this is ok for the present. */
3187 if (rw)
3189 load_union_t *load_map;
3190 size_t size;
3192 if (cmd_strings == -1)
3193 fatal ("no cmd_strings found");
3195 /* Add __main to initializer list.
3196 If we are building a program instead of a shared library, do not
3197 do anything, since in the current version, you cannot do mallocs
3198 and such in the constructors. */
3200 if (main_sym != (symbol_info_t *) 0
3201 && ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
3202 add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
3204 if (debug)
3205 notice ("\nUpdating header and load commands.\n\n");
3207 hdr.moh_n_load_cmds++;
3208 size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
3210 /* Create new load command map. */
3211 if (debug)
3212 notice ("load command map, %d cmds, new size %ld.\n",
3213 (int) hdr.moh_n_load_cmds, (long) size);
3215 load_map = (load_union_t *) xcalloc (1, size);
3216 load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
3217 load_map->map.ldc_header.ldci_cmd_size = size;
3218 load_map->map.lcm_ld_cmd_strings = cmd_strings;
3219 load_map->map.lcm_nentries = hdr.moh_n_load_cmds;
3220 load_array[hdr.moh_n_load_cmds-1].load = load_map;
3222 offset = hdr.moh_first_cmd_off;
3223 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3225 load_map->map.lcm_map[i] = offset;
3226 if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)
3227 hdr.moh_load_map_cmd_off = offset;
3229 offset += load_array[i].load->hdr.ldci_cmd_size;
3232 hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
3234 if (debug)
3235 print_header (&hdr);
3237 /* Write header */
3238 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
3239 if (status != MO_HDR_CONV_SUCCESS)
3240 bad_header (status);
3242 if (debug)
3243 notice ("writing load commands.\n\n");
3245 /* Write load commands */
3246 offset = hdr.moh_first_cmd_off;
3247 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3249 load_union_t *load_hdr = load_array[i].load;
3250 size_t size = load_hdr->hdr.ldci_cmd_size;
3252 if (debug)
3253 print_load_command (load_hdr, offset, i);
3255 bcopy ((char *) load_hdr, (char *) (obj + offset), size);
3256 offset += size;
3260 end_file (obj_file);
3262 if (close (prog_fd))
3263 fatal_perror ("close %s", prog_name);
3265 if (debug)
3266 fprintf (stderr, "\n");
3270 /* Add a function table to the load commands to call a function
3271 on initiation or termination of the process. */
3273 static void
3274 add_func_table (hdr_p, load_array, sym, type)
3275 mo_header_t *hdr_p; /* pointer to global header */
3276 load_all_t *load_array; /* array of ptrs to load cmds */
3277 symbol_info_t *sym; /* pointer to symbol entry */
3278 int type; /* fntc_type value */
3280 /* Add a new load command. */
3281 int num_cmds = ++hdr_p->moh_n_load_cmds;
3282 int load_index = num_cmds - 1;
3283 size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);
3284 load_union_t *ptr = xcalloc (1, size);
3285 load_all_t *load_cmd;
3286 int i;
3288 /* Set the unresolved address bit in the header to force the loader to be
3289 used, since kernel exec does not call the initialization functions. */
3290 hdr_p->moh_flags |= MOH_UNRESOLVED_F;
3292 load_cmd = &load_array[load_index];
3293 load_cmd->load = ptr;
3294 load_cmd->section = (char *) 0;
3296 /* Fill in func table load command. */
3297 ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
3298 ptr->func.ldc_header.ldci_cmd_size = size;
3299 ptr->func.ldc_header.ldci_section_off = 0;
3300 ptr->func.ldc_header.ldci_section_len = 0;
3301 ptr->func.fntc_type = type;
3302 ptr->func.fntc_nentries = 1;
3304 /* copy address, turn it from abs. address to (region,offset) if necessary. */
3305 /* Is the symbol already expressed as (region, offset)? */
3306 if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)
3308 ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;
3309 ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;
3312 /* If not, figure out which region it's in. */
3313 else
3315 mo_vm_addr_t addr = sym->si_value.abs_val;
3316 int found = 0;
3318 for (i = 0; i < load_index; i++)
3320 if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
3322 region_command_t *region_ptr = &load_array[i].load->region;
3324 if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0
3325 && addr >= region_ptr->regc_addr.vm_addr
3326 && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)
3328 ptr->func.fntc_entry_loc[0].adr_lcid = i;
3329 ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;
3330 found++;
3331 break;
3336 if (!found)
3337 fatal ("could not convert 0x%l.8x into a region", addr);
3340 if (debug)
3341 notice ("%s function, region %d, offset = %ld (0x%.8lx)\n",
3342 type == FNTC_INITIALIZATION ? "init" : "term",
3343 (int) ptr->func.fntc_entry_loc[i].adr_lcid,
3344 (long) ptr->func.fntc_entry_loc[i].adr_sctoff,
3345 (long) ptr->func.fntc_entry_loc[i].adr_sctoff);
3350 /* Print the global header for an OSF/rose object. */
3352 static void
3353 print_header (hdr_ptr)
3354 mo_header_t *hdr_ptr;
3356 fprintf (stderr, "\nglobal header:\n");
3357 fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic);
3358 fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version);
3359 fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version);
3360 fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version);
3361 fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size);
3362 fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order);
3363 fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id);
3364 fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type);
3365 fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype);
3366 fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type);
3367 fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);
3368 fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off);
3369 fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds);
3370 fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds);
3371 fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags);
3373 if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
3374 fprintf (stderr, ", relocatable");
3376 if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
3377 fprintf (stderr, ", linkable");
3379 if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
3380 fprintf (stderr, ", execable");
3382 if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
3383 fprintf (stderr, ", executable");
3385 if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
3386 fprintf (stderr, ", unresolved");
3388 fprintf (stderr, "\n\n");
3389 return;
3393 /* Print a short summary of a load command. */
3395 static void
3396 print_load_command (load_hdr, offset, number)
3397 load_union_t *load_hdr;
3398 size_t offset;
3399 int number;
3401 mo_long_t type = load_hdr->hdr.ldci_cmd_type;
3402 const char *type_str = (char *) 0;
3404 switch (type)
3406 case LDC_UNDEFINED: type_str = "UNDEFINED"; break;
3407 case LDC_CMD_MAP: type_str = "CMD_MAP"; break;
3408 case LDC_INTERPRETER: type_str = "INTERPRETER"; break;
3409 case LDC_STRINGS: type_str = "STRINGS"; break;
3410 case LDC_REGION: type_str = "REGION"; break;
3411 case LDC_RELOC: type_str = "RELOC"; break;
3412 case LDC_PACKAGE: type_str = "PACKAGE"; break;
3413 case LDC_SYMBOLS: type_str = "SYMBOLS"; break;
3414 case LDC_ENTRY: type_str = "ENTRY"; break;
3415 case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break;
3416 case LDC_GEN_INFO: type_str = "GEN_INFO"; break;
3419 fprintf (stderr,
3420 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3421 number,
3422 (long) load_hdr->hdr.ldci_cmd_size,
3423 (long) offset,
3424 (long) load_hdr->hdr.ldci_section_off,
3425 (long) load_hdr->hdr.ldci_section_len);
3427 if (type_str == (char *) 0)
3428 fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
3430 else if (type != LDC_REGION)
3431 fprintf (stderr, ", ty: %s\n", type_str);
3433 else
3435 const char *region = "";
3436 switch (load_hdr->region.regc_usage_type)
3438 case REG_TEXT_T: region = ", .text"; break;
3439 case REG_DATA_T: region = ", .data"; break;
3440 case REG_BSS_T: region = ", .bss"; break;
3441 case REG_GLUE_T: region = ", .glue"; break;
3442 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3443 case REG_RDATA_T: region = ", .rdata"; break;
3444 case REG_SDATA_T: region = ", .sdata"; break;
3445 case REG_SBSS_T: region = ", .sbss"; break;
3446 #endif
3449 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3450 type_str,
3451 (long) load_hdr->region.regc_vm_addr,
3452 (long) load_hdr->region.regc_vm_size,
3453 region);
3456 return;
3460 /* Fatal error when {en,de}code_mach_o_header fails. */
3462 static void
3463 bad_header (status)
3464 int status;
3466 switch (status)
3468 case MO_ERROR_BAD_MAGIC: fatal ("bad magic number");
3469 case MO_ERROR_BAD_HDR_VERS: fatal ("bad header version");
3470 case MO_ERROR_BAD_RAW_HDR_VERS: fatal ("bad raw header version");
3471 case MO_ERROR_BUF2SML: fatal ("raw header buffer too small");
3472 case MO_ERROR_OLD_RAW_HDR_FILE: fatal ("old raw header file");
3473 case MO_ERROR_UNSUPPORTED_VERS: fatal ("unsupported version");
3474 default:
3475 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
3480 /* Read a file into a memory buffer. */
3482 static struct file_info *
3483 read_file (name, fd, rw)
3484 const char *name; /* filename */
3485 int fd; /* file descriptor */
3486 int rw; /* read/write */
3488 struct stat stat_pkt;
3489 struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
3490 #ifdef USE_MMAP
3491 static int page_size;
3492 #endif
3494 if (fstat (fd, &stat_pkt) < 0)
3495 fatal_perror ("fstat %s", name);
3497 p->name = name;
3498 p->size = stat_pkt.st_size;
3499 p->rounded_size = stat_pkt.st_size;
3500 p->fd = fd;
3501 p->rw = rw;
3503 #ifdef USE_MMAP
3504 if (debug)
3505 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
3507 if (page_size == 0)
3508 page_size = sysconf (_SC_PAGE_SIZE);
3510 p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
3511 p->start = mmap ((caddr_t) 0,
3512 (rw) ? p->rounded_size : p->size,
3513 (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
3514 MAP_FILE | MAP_VARIABLE | MAP_SHARED,
3516 0L);
3518 if (p->start != (char *) 0 && p->start != (char *) -1)
3519 p->use_mmap = 1;
3521 else
3522 #endif /* USE_MMAP */
3524 long len;
3526 if (debug)
3527 fprintf (stderr, "read %s\n", name);
3529 p->use_mmap = 0;
3530 p->start = xmalloc (p->size);
3531 if (lseek (fd, 0L, SEEK_SET) < 0)
3532 fatal_perror ("lseek %s 0", name);
3534 len = read (fd, p->start, p->size);
3535 if (len < 0)
3536 fatal_perror ("read %s", name);
3538 if (len != p->size)
3539 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
3542 return p;
3545 /* Do anything necessary to write a file back from memory. */
3547 static void
3548 end_file (ptr)
3549 struct file_info *ptr; /* file information block */
3551 #ifdef USE_MMAP
3552 if (ptr->use_mmap)
3554 if (ptr->rw)
3556 if (debug)
3557 fprintf (stderr, "msync %s\n", ptr->name);
3559 if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
3560 fatal_perror ("msync %s", ptr->name);
3563 if (debug)
3564 fprintf (stderr, "munmap %s\n", ptr->name);
3566 if (munmap (ptr->start, ptr->size))
3567 fatal_perror ("munmap %s", ptr->name);
3569 else
3570 #endif /* USE_MMAP */
3572 if (ptr->rw)
3574 long len;
3576 if (debug)
3577 fprintf (stderr, "write %s\n", ptr->name);
3579 if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
3580 fatal_perror ("lseek %s 0", ptr->name);
3582 len = write (ptr->fd, ptr->start, ptr->size);
3583 if (len < 0)
3584 fatal_perror ("write %s", ptr->name);
3586 if (len != ptr->size)
3587 fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
3590 free (ptr->start);
3593 free (ptr);
3596 #endif /* OBJECT_FORMAT_ROSE */