* Makefile.in (SYSTEM_H): Define.
[official-gcc.git] / gcc / collect2.c
blob732ed4b34254a3dc883bf8be9b7dc903999da842
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 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 GNU CC.
11 GNU CC is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
16 GNU CC is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with GNU CC; see the file COPYING. If not, write to
23 the Free Software Foundation, 59 Temple Place - Suite 330,
24 Boston, MA 02111-1307, USA. */
27 /* Build tables of static constructors and destructors and run ld. */
29 #include "config.h"
30 #include "system.h"
31 #include <signal.h>
32 #if ! defined( SIGCHLD ) && defined( SIGCLD )
33 # define SIGCHLD SIGCLD
34 #endif
36 #ifdef vfork /* Autoconf may define this to fork for us. */
37 # define VFORK_STRING "fork"
38 #else
39 # define VFORK_STRING "vfork"
40 #endif
41 #ifdef HAVE_VFORK_H
42 #include <vfork.h>
43 #endif
44 #ifdef VMS
45 #define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
46 lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
47 #endif /* VMS */
49 #ifndef LIBRARY_PATH_ENV
50 #define LIBRARY_PATH_ENV "LIBRARY_PATH"
51 #endif
53 #define COLLECT
55 #include "collect2.h"
56 #include "demangle.h"
57 #include "obstack.h"
58 #include "intl.h"
59 #include "version.h"
61 /* Obstack allocation and deallocation routines. */
62 #define obstack_chunk_alloc xmalloc
63 #define obstack_chunk_free free
65 /* On certain systems, we have code that works by scanning the object file
66 directly. But this code uses system-specific header files and library
67 functions, so turn it off in a cross-compiler. Likewise, the names of
68 the utilities are not correct for a cross-compiler; we have to hope that
69 cross-versions are in the proper directories. */
71 #ifdef CROSS_COMPILE
72 #undef SUNOS4_SHARED_LIBRARIES
73 #undef OBJECT_FORMAT_COFF
74 #undef OBJECT_FORMAT_ROSE
75 #undef MD_EXEC_PREFIX
76 #undef REAL_LD_FILE_NAME
77 #undef REAL_NM_FILE_NAME
78 #undef REAL_STRIP_FILE_NAME
79 #endif
81 /* If we cannot use a special method, use the ordinary one:
82 run nm to find what symbols are present.
83 In a cross-compiler, this means you need a cross nm,
84 but that is not quite as unpleasant as special headers. */
86 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
87 #define OBJECT_FORMAT_NONE
88 #endif
90 #ifdef OBJECT_FORMAT_COFF
92 #include <a.out.h>
93 #include <ar.h>
95 #ifdef UMAX
96 #include <sgs.h>
97 #endif
99 /* Many versions of ldfcn.h define these. */
100 #ifdef FREAD
101 #undef FREAD
102 #undef FWRITE
103 #endif
105 #include <ldfcn.h>
107 /* Some systems have an ISCOFF macro, but others do not. In some cases
108 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
109 that either do not have an ISCOFF macro in /usr/include or for those
110 where it is wrong. */
112 #ifndef MY_ISCOFF
113 #define MY_ISCOFF(X) ISCOFF (X)
114 #endif
116 #endif /* OBJECT_FORMAT_COFF */
118 #ifdef OBJECT_FORMAT_ROSE
120 #ifdef _OSF_SOURCE
121 #define USE_MMAP
122 #endif
124 #ifdef USE_MMAP
125 #include <sys/mman.h>
126 #endif
128 #include <unistd.h>
129 #include <mach_o_format.h>
130 #include <mach_o_header.h>
131 #include <mach_o_vals.h>
132 #include <mach_o_types.h>
134 #endif /* OBJECT_FORMAT_ROSE */
136 #ifdef OBJECT_FORMAT_NONE
138 /* Default flags to pass to nm. */
139 #ifndef NM_FLAGS
140 #define NM_FLAGS "-n"
141 #endif
143 #endif /* OBJECT_FORMAT_NONE */
145 /* Some systems use __main in a way incompatible with its use in gcc, in these
146 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
147 give the same symbol without quotes for an alternative entry point. You
148 must define both, or neither. */
149 #ifndef NAME__MAIN
150 #define NAME__MAIN "__main"
151 #define SYMBOL__MAIN __main
152 #endif
154 /* This must match tree.h. */
155 #define DEFAULT_INIT_PRIORITY 65535
157 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
158 #define SCAN_LIBRARIES
159 #endif
161 #ifdef USE_COLLECT2
162 int do_collecting = 1;
163 #else
164 int do_collecting = 0;
165 #endif
167 /* Linked lists of constructor and destructor names. */
169 struct id
171 struct id *next;
172 int sequence;
173 char name[1];
176 struct head
178 struct id *first;
179 struct id *last;
180 int number;
183 /* Enumeration giving which pass this is for scanning the program file. */
185 enum pass {
186 PASS_FIRST, /* without constructors */
187 PASS_OBJ, /* individual objects */
188 PASS_LIB, /* looking for shared libraries */
189 PASS_SECOND /* with constructors linked in */
192 int vflag; /* true if -v */
193 static int rflag; /* true if -r */
194 static int strip_flag; /* true if -s */
195 #ifdef COLLECT_EXPORT_LIST
196 static int export_flag; /* true if -bE */
197 static int aix64_flag; /* true if -b64 */
198 #endif
200 int debug; /* true if -debug */
202 static int shared_obj; /* true if -shared */
204 static const char *c_file; /* <xxx>.c for constructor/destructor list. */
205 static const char *o_file; /* <xxx>.o for constructor/destructor list. */
206 #ifdef COLLECT_EXPORT_LIST
207 static const char *export_file; /* <xxx>.x for AIX export list. */
208 #endif
209 const char *ldout; /* File for ld errors. */
210 static const char *output_file; /* Output file for ld. */
211 static const char *nm_file_name; /* pathname of nm */
212 #ifdef LDD_SUFFIX
213 static const char *ldd_file_name; /* pathname of ldd (or equivalent) */
214 #endif
215 static const char *strip_file_name; /* pathname of strip */
216 const char *c_file_name; /* pathname of gcc */
217 static char *initname, *fininame; /* names of init and fini funcs */
219 static struct head constructors; /* list of constructors found */
220 static struct head destructors; /* list of destructors found */
221 #ifdef COLLECT_EXPORT_LIST
222 static struct head exports; /* list of exported symbols */
223 #endif
224 static struct head frame_tables; /* list of frame unwind info tables */
226 struct obstack temporary_obstack;
227 struct obstack permanent_obstack;
228 char * temporary_firstobj;
230 /* Holds the return value of pexecute. */
231 int pexecute_pid;
233 /* Defined in the automatically-generated underscore.c. */
234 extern int prepends_underscore;
236 #ifndef GET_ENV_PATH_LIST
237 #define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
238 #endif
240 /* Structure to hold all the directories in which to search for files to
241 execute. */
243 struct prefix_list
245 const char *prefix; /* String to prepend to the path. */
246 struct prefix_list *next; /* Next in linked list. */
249 struct path_prefix
251 struct prefix_list *plist; /* List of prefixes to try */
252 int max_len; /* Max length of a prefix in PLIST */
253 const char *name; /* Name of this list (used in config stuff) */
256 #ifdef COLLECT_EXPORT_LIST
257 /* Lists to keep libraries to be scanned for global constructors/destructors. */
258 static struct head libs; /* list of libraries */
259 static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
260 static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
261 static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
262 &libpath_lib_dirs, NULL};
263 static const char *libexts[3] = {"a", "so", NULL}; /* possible library extentions */
264 #endif
266 static void handler PARAMS ((int));
267 static int is_ctor_dtor PARAMS ((const char *));
268 static char *find_a_file PARAMS ((struct path_prefix *, const char *));
269 static void add_prefix PARAMS ((struct path_prefix *, const char *));
270 static void prefix_from_env PARAMS ((const char *, struct path_prefix *));
271 static void prefix_from_string PARAMS ((const char *, struct path_prefix *));
272 static void do_wait PARAMS ((const char *));
273 static void fork_execute PARAMS ((const char *, char **));
274 static void maybe_unlink PARAMS ((const char *));
275 static void add_to_list PARAMS ((struct head *, const char *));
276 static int extract_init_priority PARAMS ((const char *));
277 static void sort_ids PARAMS ((struct head *));
278 static void write_list PARAMS ((FILE *, const char *, struct id *));
279 #ifdef COLLECT_EXPORT_LIST
280 static void dump_list PARAMS ((FILE *, const char *, struct id *));
281 #endif
282 #if 0
283 static void dump_prefix_list PARAMS ((FILE *, const char *, struct prefix_list *));
284 #endif
285 static void write_list_with_asm PARAMS ((FILE *, const char *, struct id *));
286 static void write_c_file PARAMS ((FILE *, const char *));
287 static void write_c_file_stat PARAMS ((FILE *, const char *));
288 #ifndef LD_INIT_SWITCH
289 static void write_c_file_glob PARAMS ((FILE *, const char *));
290 #endif
291 static void scan_prog_file PARAMS ((const char *, enum pass));
292 #ifdef SCAN_LIBRARIES
293 static void scan_libraries PARAMS ((const char *));
294 #endif
295 #ifdef COLLECT_EXPORT_LIST
296 static int is_in_list PARAMS ((const char *, struct id *));
297 static void write_aix_file PARAMS ((FILE *, struct id *));
298 static char *resolve_lib_name PARAMS ((const char *));
299 static int ignore_library PARAMS ((const char *));
300 #endif
301 static char *extract_string PARAMS ((const char **));
303 #ifdef NO_DUP2
305 dup2 (oldfd, newfd)
306 int oldfd;
307 int newfd;
309 int fdtmp[256];
310 int fdx = 0;
311 int fd;
313 if (oldfd == newfd)
314 return oldfd;
315 close (newfd);
316 while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
317 fdtmp[fdx++] = fd;
318 while (fdx > 0)
319 close (fdtmp[--fdx]);
321 return fd;
323 #endif
325 /* Delete tempfiles and exit function. */
327 void
328 collect_exit (status)
329 int status;
331 if (c_file != 0 && c_file[0])
332 maybe_unlink (c_file);
334 if (o_file != 0 && o_file[0])
335 maybe_unlink (o_file);
337 #ifdef COLLECT_EXPORT_LIST
338 if (export_file != 0 && export_file[0])
339 maybe_unlink (export_file);
340 #endif
342 if (ldout != 0 && ldout[0])
344 dump_file (ldout);
345 maybe_unlink (ldout);
348 if (status != 0 && output_file != 0 && output_file[0])
349 maybe_unlink (output_file);
351 exit (status);
355 /* Notify user of a non-error. */
356 void
357 notice VPARAMS ((const char *msgid, ...))
359 #ifndef ANSI_PROTOTYPES
360 const char *msgid;
361 #endif
362 va_list ap;
364 VA_START (ap, msgid);
366 #ifndef ANSI_PROTOTYPES
367 msgid = va_arg (ap, const char *);
368 #endif
370 vfprintf (stderr, _(msgid), ap);
371 va_end (ap);
374 /* Die when sys call fails. */
376 void
377 fatal_perror VPARAMS ((const char * msgid, ...))
379 #ifndef ANSI_PROTOTYPES
380 const char *msgid;
381 #endif
382 int e = errno;
383 va_list ap;
385 VA_START (ap, msgid);
387 #ifndef ANSI_PROTOTYPES
388 msgid = va_arg (ap, const char *);
389 #endif
391 fprintf (stderr, "collect2: ");
392 vfprintf (stderr, _(msgid), ap);
393 fprintf (stderr, ": %s\n", xstrerror (e));
394 va_end (ap);
396 collect_exit (FATAL_EXIT_CODE);
399 /* Just die. */
401 void
402 fatal VPARAMS ((const char * msgid, ...))
404 #ifndef ANSI_PROTOTYPES
405 const char *msgid;
406 #endif
407 va_list ap;
409 VA_START (ap, msgid);
411 #ifndef ANSI_PROTOTYPES
412 msgid = va_arg (ap, const char *);
413 #endif
415 fprintf (stderr, "collect2: ");
416 vfprintf (stderr, _(msgid), ap);
417 fprintf (stderr, "\n");
418 va_end (ap);
420 collect_exit (FATAL_EXIT_CODE);
423 /* Write error message. */
425 void
426 error VPARAMS ((const char * msgid, ...))
428 #ifndef ANSI_PROTOTYPES
429 const char * msgid;
430 #endif
431 va_list ap;
433 VA_START (ap, msgid);
435 #ifndef ANSI_PROTOTYPES
436 msgid = va_arg (ap, const char *);
437 #endif
439 fprintf (stderr, "collect2: ");
440 vfprintf (stderr, _(msgid), ap);
441 fprintf (stderr, "\n");
442 va_end(ap);
445 /* In case obstack is linked in, and abort is defined to fancy_abort,
446 provide a default entry. */
448 void
449 fancy_abort ()
451 fatal ("internal error");
454 static void
455 handler (signo)
456 int signo;
458 if (c_file != 0 && c_file[0])
459 maybe_unlink (c_file);
461 if (o_file != 0 && o_file[0])
462 maybe_unlink (o_file);
464 if (ldout != 0 && ldout[0])
465 maybe_unlink (ldout);
467 #ifdef COLLECT_EXPORT_LIST
468 if (export_file != 0 && export_file[0])
469 maybe_unlink (export_file);
470 #endif
472 signal (signo, SIG_DFL);
473 kill (getpid (), signo);
478 file_exists (name)
479 const char *name;
481 return access (name, R_OK) == 0;
484 /* Parse a reasonable subset of shell quoting syntax. */
486 static char *
487 extract_string (pp)
488 const char **pp;
490 const char *p = *pp;
491 int backquote = 0;
492 int inside = 0;
494 for (;;)
496 char c = *p;
497 if (c == '\0')
498 break;
499 ++p;
500 if (backquote)
501 obstack_1grow (&temporary_obstack, c);
502 else if (! inside && c == ' ')
503 break;
504 else if (! inside && c == '\\')
505 backquote = 1;
506 else if (c == '\'')
507 inside = !inside;
508 else
509 obstack_1grow (&temporary_obstack, c);
512 obstack_1grow (&temporary_obstack, '\0');
513 *pp = p;
514 return obstack_finish (&temporary_obstack);
517 void
518 dump_file (name)
519 const char *name;
521 FILE *stream = fopen (name, "r");
522 int no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
524 if (stream == 0)
525 return;
526 while (1)
528 int c;
529 while (c = getc (stream),
530 c != EOF && (ISALNUM (c) || c == '_' || c == '$' || c == '.'))
531 obstack_1grow (&temporary_obstack, c);
532 if (obstack_object_size (&temporary_obstack) > 0)
534 const char *word, *p;
535 char *result;
536 obstack_1grow (&temporary_obstack, '\0');
537 word = obstack_finish (&temporary_obstack);
539 if (*word == '.')
540 ++word, putc ('.', stderr);
541 p = word;
542 if (*p == '_' && prepends_underscore)
543 ++p;
545 if (no_demangle)
546 result = 0;
547 else
548 result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI);
550 if (result)
552 int diff;
553 fputs (result, stderr);
555 diff = strlen (word) - strlen (result);
556 while (diff > 0)
557 --diff, putc (' ', stderr);
558 while (diff < 0 && c == ' ')
559 ++diff, c = getc (stream);
561 free (result);
563 else
564 fputs (word, stderr);
566 fflush (stderr);
567 obstack_free (&temporary_obstack, temporary_firstobj);
569 if (c == EOF)
570 break;
571 putc (c, stderr);
573 fclose (stream);
576 /* Decide whether the given symbol is: a constructor (1), a destructor
577 (2), a routine in a shared object that calls all the constructors
578 (3) or destructors (4), a DWARF exception-handling table (5), or
579 nothing special (0). */
581 static int
582 is_ctor_dtor (s)
583 const char *s;
585 struct names { const char *name; int len; int ret; int two_underscores; };
587 register struct names *p;
588 register int ch;
589 register const char *orig_s = s;
591 static struct names special[] = {
592 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
593 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
594 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
595 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
596 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
597 #ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions.
598 cfront has its own linker procedure to collect them;
599 if collect2 gets them too, they get collected twice
600 when the cfront procedure is run and the compiler used
601 for linking happens to be GCC. */
602 { "sti__", sizeof ("sti__")-1, 1, 1 },
603 { "std__", sizeof ("std__")-1, 2, 1 },
604 #endif /* CFRONT_LOSSAGE */
605 { NULL, 0, 0, 0 }
608 while ((ch = *s) == '_')
609 ++s;
611 if (s == orig_s)
612 return 0;
614 for (p = &special[0]; p->len > 0; p++)
616 if (ch == p->name[0]
617 && (!p->two_underscores || ((s - orig_s) >= 2))
618 && strncmp(s, p->name, p->len) == 0)
620 return p->ret;
623 return 0;
626 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
627 and one from the PATH variable. */
629 static struct path_prefix cpath, path;
631 #ifdef CROSS_COMPILE
632 /* This is the name of the target machine. We use it to form the name
633 of the files to execute. */
635 static const char *const target_machine = TARGET_MACHINE;
636 #endif
638 /* Search for NAME using prefix list PPREFIX. We only look for executable
639 files.
641 Return 0 if not found, otherwise return its name, allocated with malloc. */
643 static char *
644 find_a_file (pprefix, name)
645 struct path_prefix *pprefix;
646 const char *name;
648 char *temp;
649 struct prefix_list *pl;
650 int len = pprefix->max_len + strlen (name) + 1;
652 if (debug)
653 fprintf (stderr, "Looking for '%s'\n", name);
655 #ifdef EXECUTABLE_SUFFIX
656 len += strlen (EXECUTABLE_SUFFIX);
657 #endif
659 temp = xmalloc (len);
661 /* Determine the filename to execute (special case for absolute paths). */
663 if (*name == '/'
664 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
665 || (*name && name[1] == ':')
666 #endif
669 if (access (name, X_OK) == 0)
671 strcpy (temp, name);
673 if (debug)
674 fprintf (stderr, " - found: absolute path\n");
676 return temp;
679 #ifdef EXECUTABLE_SUFFIX
680 /* Some systems have a suffix for executable files.
681 So try appending that. */
682 strcpy (temp, name);
683 strcat (temp, EXECUTABLE_SUFFIX);
685 if (access (temp, X_OK) == 0)
686 return temp;
687 #endif
689 if (debug)
690 fprintf (stderr, " - failed to locate using absolute path\n");
692 else
693 for (pl = pprefix->plist; pl; pl = pl->next)
695 struct stat st;
697 strcpy (temp, pl->prefix);
698 strcat (temp, name);
700 if (stat (temp, &st) >= 0
701 && ! S_ISDIR (st.st_mode)
702 && access (temp, X_OK) == 0)
703 return temp;
705 #ifdef EXECUTABLE_SUFFIX
706 /* Some systems have a suffix for executable files.
707 So try appending that. */
708 strcat (temp, EXECUTABLE_SUFFIX);
710 if (stat (temp, &st) >= 0
711 && ! S_ISDIR (st.st_mode)
712 && access (temp, X_OK) == 0)
713 return temp;
714 #endif
717 if (debug && pprefix->plist == NULL)
718 fprintf (stderr, " - failed: no entries in prefix list\n");
720 free (temp);
721 return 0;
724 /* Add an entry for PREFIX to prefix list PPREFIX. */
726 static void
727 add_prefix (pprefix, prefix)
728 struct path_prefix *pprefix;
729 const char *prefix;
731 struct prefix_list *pl, **prev;
732 int len;
734 if (pprefix->plist)
736 for (pl = pprefix->plist; pl->next; pl = pl->next)
738 prev = &pl->next;
740 else
741 prev = &pprefix->plist;
743 /* Keep track of the longest prefix */
745 len = strlen (prefix);
746 if (len > pprefix->max_len)
747 pprefix->max_len = len;
749 pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
750 pl->prefix = xstrdup (prefix);
752 if (*prev)
753 pl->next = *prev;
754 else
755 pl->next = (struct prefix_list *) 0;
756 *prev = pl;
759 /* Take the value of the environment variable ENV, break it into a path, and
760 add of the entries to PPREFIX. */
762 static void
763 prefix_from_env (env, pprefix)
764 const char *env;
765 struct path_prefix *pprefix;
767 const char *p;
768 GET_ENV_PATH_LIST (p, env);
770 if (p)
771 prefix_from_string (p, pprefix);
774 static void
775 prefix_from_string (p, pprefix)
776 const char *p;
777 struct path_prefix *pprefix;
779 const char *startp, *endp;
780 char *nstore = (char *) xmalloc (strlen (p) + 3);
782 if (debug)
783 fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
785 startp = endp = p;
786 while (1)
788 if (*endp == PATH_SEPARATOR || *endp == 0)
790 strncpy (nstore, startp, endp-startp);
791 if (endp == startp)
793 strcpy (nstore, "./");
795 else if (! IS_DIR_SEPARATOR (endp[-1]))
797 nstore[endp-startp] = DIR_SEPARATOR;
798 nstore[endp-startp+1] = 0;
800 else
801 nstore[endp-startp] = 0;
803 if (debug)
804 fprintf (stderr, " - add prefix: %s\n", nstore);
806 add_prefix (pprefix, nstore);
807 if (*endp == 0)
808 break;
809 endp = startp = endp + 1;
811 else
812 endp++;
816 /* Main program. */
818 int main PARAMS ((int, char *[]));
820 main (argc, argv)
821 int argc;
822 char *argv[];
824 const char *ld_suffix = "ld";
825 const char *full_ld_suffix = ld_suffix;
826 const char *real_ld_suffix = "real-ld";
827 const char *collect_ld_suffix = "collect-ld";
828 const char *nm_suffix = "nm";
829 const char *full_nm_suffix = nm_suffix;
830 const char *gnm_suffix = "gnm";
831 const char *full_gnm_suffix = gnm_suffix;
832 #ifdef LDD_SUFFIX
833 const char *ldd_suffix = LDD_SUFFIX;
834 const char *full_ldd_suffix = ldd_suffix;
835 #endif
836 const char *strip_suffix = "strip";
837 const char *full_strip_suffix = strip_suffix;
838 const char *gstrip_suffix = "gstrip";
839 const char *full_gstrip_suffix = gstrip_suffix;
840 const char *arg;
841 FILE *outf;
842 #ifdef COLLECT_EXPORT_LIST
843 FILE *exportf;
844 #endif
845 const char *ld_file_name;
846 const char *p;
847 char **c_argv;
848 const char **c_ptr;
849 char **ld1_argv;
850 const char **ld1;
851 char **ld2_argv;
852 const char **ld2;
853 char **object_lst;
854 const char **object;
855 int first_file;
856 int num_c_args = argc+9;
858 #if defined (COLLECT2_HOST_INITIALIZATION)
859 /* Perform system dependent initialization, if neccessary. */
860 COLLECT2_HOST_INITIALIZATION;
861 #endif
863 #ifdef SIGCHLD
864 /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
865 receive the signal. A different setting is inheritable */
866 signal (SIGCHLD, SIG_DFL);
867 #endif
869 /* LC_CTYPE determines the character set used by the terminal so it has be set
870 to output messages correctly. */
872 #ifdef HAVE_LC_MESSAGES
873 setlocale (LC_CTYPE, "");
874 setlocale (LC_MESSAGES, "");
875 #else
876 setlocale (LC_ALL, "");
877 #endif
879 (void) bindtextdomain (PACKAGE, localedir);
880 (void) textdomain (PACKAGE);
882 /* Do not invoke xcalloc before this point, since locale needs to be
883 set first, in case a diagnostic is issued. */
885 ld1 = (const char **)(ld1_argv = (char **) xcalloc(sizeof (char *), argc+3));
886 ld2 = (const char **)(ld2_argv = (char **) xcalloc(sizeof (char *), argc+10));
887 object = (const char **)(object_lst = (char **) xcalloc(sizeof (char *), argc));
889 #ifdef DEBUG
890 debug = 1;
891 #endif
893 /* Parse command line early for instances of -debug. This allows
894 the debug flag to be set before functions like find_a_file()
895 are called. */
897 int i;
899 for (i = 1; argv[i] != NULL; i ++)
900 if (! strcmp (argv[i], "-debug"))
901 debug = 1;
902 vflag = debug;
905 #ifndef DEFAULT_A_OUT_NAME
906 output_file = "a.out";
907 #else
908 output_file = DEFAULT_A_OUT_NAME;
909 #endif
911 obstack_begin (&temporary_obstack, 0);
912 obstack_begin (&permanent_obstack, 0);
913 temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
915 current_demangling_style = auto_demangling;
916 p = getenv ("COLLECT_GCC_OPTIONS");
917 while (p && *p)
919 const char *q = extract_string (&p);
920 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
921 num_c_args++;
923 obstack_free (&temporary_obstack, temporary_firstobj);
925 /* -fno-exceptions -w */
926 num_c_args += 2;
928 c_ptr = (const char **)
929 (c_argv = (char **) xcalloc (sizeof (char *), num_c_args));
931 if (argc < 2)
932 fatal ("no arguments");
934 #ifdef SIGQUIT
935 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
936 signal (SIGQUIT, handler);
937 #endif
938 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
939 signal (SIGINT, handler);
940 #ifdef SIGALRM
941 if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
942 signal (SIGALRM, handler);
943 #endif
944 #ifdef SIGHUP
945 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
946 signal (SIGHUP, handler);
947 #endif
948 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
949 signal (SIGSEGV, handler);
950 #ifdef SIGBUS
951 if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
952 signal (SIGBUS, handler);
953 #endif
955 /* Extract COMPILER_PATH and PATH into our prefix list. */
956 prefix_from_env ("COMPILER_PATH", &cpath);
957 prefix_from_env ("PATH", &path);
959 #ifdef CROSS_COMPILE
960 /* If we look for a program in the compiler directories, we just use
961 the short name, since these directories are already system-specific.
962 But it we look for a program in the system directories, we need to
963 qualify the program name with the target machine. */
965 full_ld_suffix = concat(target_machine, "-", ld_suffix, NULL);
967 #if 0
968 full_gld_suffix = concat (target_machine, "-", gld_suffix, NULL);
969 #endif
971 full_nm_suffix = concat (target_machine, "-", nm_suffix, NULL);
973 full_gnm_suffix = concat (target_machine, "-", gnm_suffix, NULL);
975 #ifdef LDD_SUFFIX
976 full_ldd_suffix = concat (target_machine, "-", ldd_suffix, NULL);
977 #endif
979 full_strip_suffix = concat (target_machine, "-", strip_suffix, NULL);
981 full_gstrip_suffix = concat (target_machine, "-", gstrip_suffix, NULL);
982 #endif /* CROSS_COMPILE */
984 /* Try to discover a valid linker/nm/strip to use. */
986 /* Maybe we know the right file to use (if not cross). */
987 ld_file_name = 0;
988 #ifdef DEFAULT_LINKER
989 if (access (DEFAULT_LINKER, X_OK) == 0)
990 ld_file_name = DEFAULT_LINKER;
991 if (ld_file_name == 0)
992 #endif
993 #ifdef REAL_LD_FILE_NAME
994 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
995 if (ld_file_name == 0)
996 #endif
997 /* Search the (target-specific) compiler dirs for ld'. */
998 ld_file_name = find_a_file (&cpath, real_ld_suffix);
999 /* Likewise for `collect-ld'. */
1000 if (ld_file_name == 0)
1001 ld_file_name = find_a_file (&cpath, collect_ld_suffix);
1002 /* Search the compiler directories for `ld'. We have protection against
1003 recursive calls in find_a_file. */
1004 if (ld_file_name == 0)
1005 ld_file_name = find_a_file (&cpath, ld_suffix);
1006 /* Search the ordinary system bin directories
1007 for `ld' (if native linking) or `TARGET-ld' (if cross). */
1008 if (ld_file_name == 0)
1009 ld_file_name = find_a_file (&path, full_ld_suffix);
1011 #ifdef REAL_NM_FILE_NAME
1012 nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
1013 if (nm_file_name == 0)
1014 #endif
1015 nm_file_name = find_a_file (&cpath, gnm_suffix);
1016 if (nm_file_name == 0)
1017 nm_file_name = find_a_file (&path, full_gnm_suffix);
1018 if (nm_file_name == 0)
1019 nm_file_name = find_a_file (&cpath, nm_suffix);
1020 if (nm_file_name == 0)
1021 nm_file_name = find_a_file (&path, full_nm_suffix);
1023 #ifdef LDD_SUFFIX
1024 ldd_file_name = find_a_file (&cpath, ldd_suffix);
1025 if (ldd_file_name == 0)
1026 ldd_file_name = find_a_file (&path, full_ldd_suffix);
1027 #endif
1029 #ifdef REAL_STRIP_FILE_NAME
1030 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
1031 if (strip_file_name == 0)
1032 #endif
1033 strip_file_name = find_a_file (&cpath, gstrip_suffix);
1034 if (strip_file_name == 0)
1035 strip_file_name = find_a_file (&path, full_gstrip_suffix);
1036 if (strip_file_name == 0)
1037 strip_file_name = find_a_file (&cpath, strip_suffix);
1038 if (strip_file_name == 0)
1039 strip_file_name = find_a_file (&path, full_strip_suffix);
1041 /* Determine the full path name of the C compiler to use. */
1042 c_file_name = getenv ("COLLECT_GCC");
1043 if (c_file_name == 0)
1045 #ifdef CROSS_COMPILE
1046 c_file_name = concat (target_machine, "-gcc", NULL);
1047 #else
1048 c_file_name = "gcc";
1049 #endif
1052 p = find_a_file (&cpath, c_file_name);
1054 /* Here it should be safe to use the system search path since we should have
1055 already qualified the name of the compiler when it is needed. */
1056 if (p == 0)
1057 p = find_a_file (&path, c_file_name);
1059 if (p)
1060 c_file_name = p;
1062 *ld1++ = *ld2++ = ld_file_name;
1064 /* Make temp file names. */
1065 c_file = make_temp_file (".c");
1066 o_file = make_temp_file (".o");
1067 #ifdef COLLECT_EXPORT_LIST
1068 export_file = make_temp_file (".x");
1069 #endif
1070 ldout = make_temp_file (".ld");
1071 *c_ptr++ = c_file_name;
1072 *c_ptr++ = "-x";
1073 *c_ptr++ = "c";
1074 *c_ptr++ = "-c";
1075 *c_ptr++ = "-o";
1076 *c_ptr++ = o_file;
1078 #ifdef COLLECT_EXPORT_LIST
1079 /* Generate a list of directories from LIBPATH. */
1080 prefix_from_env ("LIBPATH", &libpath_lib_dirs);
1081 /* Add to this list also two standard directories where
1082 AIX loader always searches for libraries. */
1083 add_prefix (&libpath_lib_dirs, "/lib");
1084 add_prefix (&libpath_lib_dirs, "/usr/lib");
1085 #endif
1087 /* Get any options that the upper GCC wants to pass to the sub-GCC.
1089 AIX support needs to know if -shared has been specified before
1090 parsing commandline arguments. */
1092 p = getenv ("COLLECT_GCC_OPTIONS");
1093 while (p && *p)
1095 const char *q = extract_string (&p);
1096 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1097 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1098 if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0)
1099 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1100 if (strncmp (q, "-shared", sizeof ("-shared") - 1) == 0)
1101 shared_obj = 1;
1102 if (*q == '-' && q[1] == 'B')
1104 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1105 if (q[2] == 0)
1107 q = extract_string (&p);
1108 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1112 obstack_free (&temporary_obstack, temporary_firstobj);
1113 *c_ptr++ = "-fno-exceptions";
1114 *c_ptr++ = "-w";
1116 /* !!! When GCC calls collect2,
1117 it does not know whether it is calling collect2 or ld.
1118 So collect2 cannot meaningfully understand any options
1119 except those ld understands.
1120 If you propose to make GCC pass some other option,
1121 just imagine what will happen if ld is really ld!!! */
1123 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1124 /* After the first file, put in the c++ rt0. */
1126 first_file = 1;
1127 while ((arg = *++argv) != (char *) 0)
1129 *ld1++ = *ld2++ = arg;
1131 if (arg[0] == '-')
1133 switch (arg[1])
1135 #ifdef COLLECT_EXPORT_LIST
1136 /* We want to disable automatic exports on AIX when user
1137 explicitly puts an export list in command line */
1138 case 'b':
1139 if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
1140 export_flag = 1;
1141 else if (arg[2] == '6' && arg[3] == '4')
1142 aix64_flag = 1;
1143 break;
1144 #endif
1146 case 'd':
1147 if (!strcmp (arg, "-debug"))
1149 /* Already parsed. */
1150 ld1--;
1151 ld2--;
1153 break;
1155 case 'l':
1156 if (first_file)
1158 /* place o_file BEFORE this argument! */
1159 first_file = 0;
1160 ld2--;
1161 *ld2++ = o_file;
1162 *ld2++ = arg;
1164 #ifdef COLLECT_EXPORT_LIST
1166 /* Resolving full library name. */
1167 const char *s = resolve_lib_name (arg+2);
1169 /* Saving a full library name. */
1170 add_to_list (&libs, s);
1172 #endif
1173 break;
1175 #ifdef COLLECT_EXPORT_LIST
1176 /* Saving directories where to search for libraries. */
1177 case 'L':
1178 add_prefix (&cmdline_lib_dirs, arg+2);
1179 break;
1180 #endif
1182 case 'o':
1183 if (arg[2] == '\0')
1184 output_file = *ld1++ = *ld2++ = *++argv;
1185 else if (1
1186 #ifdef SWITCHES_NEED_SPACES
1187 && ! strchr (SWITCHES_NEED_SPACES, arg[1])
1188 #endif
1191 output_file = &arg[2];
1192 break;
1194 case 'r':
1195 if (arg[2] == '\0')
1196 rflag = 1;
1197 break;
1199 case 's':
1200 if (arg[2] == '\0' && do_collecting)
1202 /* We must strip after the nm run, otherwise C++ linking
1203 will not work. Thus we strip in the second ld run, or
1204 else with strip if there is no second ld run. */
1205 strip_flag = 1;
1206 ld1--;
1208 break;
1210 case 'v':
1211 if (arg[2] == '\0')
1212 vflag = 1;
1213 break;
1216 else if ((p = strrchr (arg, '.')) != (char *) 0
1217 && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
1218 || strcmp (p, ".so") == 0 || strcmp (p, ".lo") == 0
1219 || strcmp (p, ".obj") == 0))
1221 if (first_file)
1223 first_file = 0;
1224 if (p[1] == 'o')
1225 *ld2++ = o_file;
1226 else
1228 /* place o_file BEFORE this argument! */
1229 ld2--;
1230 *ld2++ = o_file;
1231 *ld2++ = arg;
1234 if (p[1] == 'o' || p[1] == 'l')
1235 *object++ = arg;
1236 #ifdef COLLECT_EXPORT_LIST
1237 /* libraries can be specified directly, i.e. without -l flag. */
1238 else
1240 /* Saving a full library name. */
1241 add_to_list (&libs, arg);
1243 #endif
1247 #ifdef COLLECT_EXPORT_LIST
1248 /* This is added only for debugging purposes. */
1249 if (debug)
1251 fprintf (stderr, "List of libraries:\n");
1252 dump_list (stderr, "\t", libs.first);
1255 /* The AIX linker will discard static constructors in object files if
1256 nothing else in the file is referenced, so look at them first. */
1258 const char **export_object_lst = (const char **)object_lst;
1260 while (export_object_lst < object)
1261 scan_prog_file (*export_object_lst++, PASS_OBJ);
1264 struct id *list = libs.first;
1266 for (; list; list = list->next)
1267 scan_prog_file (list->name, PASS_FIRST);
1270 if (exports.first)
1272 char *buf = xmalloc (strlen (export_file) + 5);
1274 sprintf (buf, "-bE:%s", export_file);
1275 *ld1++ = buf;
1276 *ld2++ = buf;
1278 exportf = fopen (export_file, "w");
1279 if (exportf == (FILE *) 0)
1280 fatal_perror ("fopen %s", export_file);
1281 write_aix_file (exportf, exports.first);
1282 if (fclose (exportf))
1283 fatal_perror ("fclose %s", export_file);
1285 #endif
1287 *c_ptr++ = c_file;
1288 *c_ptr = *ld1 = *object = (char *) 0;
1290 if (vflag)
1292 notice ("collect2 version %s", version_string);
1293 #ifdef TARGET_VERSION
1294 TARGET_VERSION;
1295 #endif
1296 fprintf (stderr, "\n");
1299 if (debug)
1301 const char *ptr;
1302 fprintf (stderr, "ld_file_name = %s\n",
1303 (ld_file_name ? ld_file_name : "not found"));
1304 fprintf (stderr, "c_file_name = %s\n",
1305 (c_file_name ? c_file_name : "not found"));
1306 fprintf (stderr, "nm_file_name = %s\n",
1307 (nm_file_name ? nm_file_name : "not found"));
1308 #ifdef LDD_SUFFIX
1309 fprintf (stderr, "ldd_file_name = %s\n",
1310 (ldd_file_name ? ldd_file_name : "not found"));
1311 #endif
1312 fprintf (stderr, "strip_file_name = %s\n",
1313 (strip_file_name ? strip_file_name : "not found"));
1314 fprintf (stderr, "c_file = %s\n",
1315 (c_file ? c_file : "not found"));
1316 fprintf (stderr, "o_file = %s\n",
1317 (o_file ? o_file : "not found"));
1319 ptr = getenv ("COLLECT_GCC_OPTIONS");
1320 if (ptr)
1321 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1323 ptr = getenv ("COLLECT_GCC");
1324 if (ptr)
1325 fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
1327 ptr = getenv ("COMPILER_PATH");
1328 if (ptr)
1329 fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
1331 ptr = getenv (LIBRARY_PATH_ENV);
1332 if (ptr)
1333 fprintf (stderr, "%-20s= %s\n", LIBRARY_PATH_ENV, ptr);
1335 fprintf (stderr, "\n");
1338 /* Load the program, searching all libraries and attempting to provide
1339 undefined symbols from repository information. */
1341 /* On AIX we do this later. */
1342 #ifndef COLLECT_EXPORT_LIST
1343 do_tlink (ld1_argv, object_lst);
1344 #endif
1346 /* If -r or they will be run via some other method, do not build the
1347 constructor or destructor list, just return now. */
1348 if (rflag
1349 #ifndef COLLECT_EXPORT_LIST
1350 || ! do_collecting
1351 #endif
1354 #ifdef COLLECT_EXPORT_LIST
1355 /* Do the link we avoided above if we are exiting. */
1356 do_tlink (ld1_argv, object_lst);
1358 /* But make sure we delete the export file we may have created. */
1359 if (export_file != 0 && export_file[0])
1360 maybe_unlink (export_file);
1361 #endif
1362 maybe_unlink (c_file);
1363 maybe_unlink (o_file);
1364 return 0;
1367 /* Examine the namelist with nm and search it for static constructors
1368 and destructors to call.
1369 Write the constructor and destructor tables to a .s file and reload. */
1371 /* On AIX we already scanned for global constructors/destructors. */
1372 #ifndef COLLECT_EXPORT_LIST
1373 scan_prog_file (output_file, PASS_FIRST);
1374 #endif
1376 #ifdef SCAN_LIBRARIES
1377 scan_libraries (output_file);
1378 #endif
1380 if (debug)
1382 notice ("%d constructor(s) found\n", constructors.number);
1383 notice ("%d destructor(s) found\n", destructors.number);
1384 notice ("%d frame table(s) found\n", frame_tables.number);
1387 if (constructors.number == 0 && destructors.number == 0
1388 && frame_tables.number == 0
1389 #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1390 /* If we will be running these functions ourselves, we want to emit
1391 stubs into the shared library so that we do not have to relink
1392 dependent programs when we add static objects. */
1393 && ! shared_obj
1394 #endif
1397 #ifdef COLLECT_EXPORT_LIST
1398 /* Do tlink without additional code generation */
1399 do_tlink (ld1_argv, object_lst);
1400 #endif
1401 /* Strip now if it was requested on the command line. */
1402 if (strip_flag)
1404 char **real_strip_argv = (char **) xcalloc (sizeof (char *), 3);
1405 const char ** strip_argv = (const char **) real_strip_argv;
1407 strip_argv[0] = strip_file_name;
1408 strip_argv[1] = output_file;
1409 strip_argv[2] = (char *) 0;
1410 fork_execute ("strip", real_strip_argv);
1413 #ifdef COLLECT_EXPORT_LIST
1414 maybe_unlink (export_file);
1415 #endif
1416 maybe_unlink (c_file);
1417 maybe_unlink (o_file);
1418 return 0;
1421 /* Sort ctor and dtor lists by priority. */
1422 sort_ids (&constructors);
1423 sort_ids (&destructors);
1425 maybe_unlink(output_file);
1426 outf = fopen (c_file, "w");
1427 if (outf == (FILE *) 0)
1428 fatal_perror ("fopen %s", c_file);
1430 write_c_file (outf, c_file);
1432 if (fclose (outf))
1433 fatal_perror ("fclose %s", c_file);
1435 /* Tell the linker that we have initializer and finalizer functions. */
1436 #ifdef LD_INIT_SWITCH
1437 #ifdef COLLECT_EXPORT_LIST
1439 /* option name + functions + colons + NULL */
1440 char *buf = xmalloc (strlen (LD_INIT_SWITCH)
1441 + strlen(initname) + strlen(fininame) + 3);
1442 sprintf (buf, "%s:%s:%s", LD_INIT_SWITCH, initname, fininame);
1443 *ld2++ = buf;
1445 #else
1446 *ld2++ = LD_INIT_SWITCH;
1447 *ld2++ = initname;
1448 *ld2++ = LD_FINI_SWITCH;
1449 *ld2++ = fininame;
1450 #endif
1451 #endif
1453 #ifdef COLLECT_EXPORT_LIST
1454 if (shared_obj)
1456 /* If we did not add export flag to link arguments before, add it to
1457 second link phase now. No new exports should have been added. */
1458 if (! exports.first)
1460 char *buf = xmalloc (strlen (export_file) + 5);
1462 sprintf (buf, "-bE:%s", export_file);
1463 *ld2++ = buf;
1466 add_to_list (&exports, initname);
1467 add_to_list (&exports, fininame);
1468 add_to_list (&exports, "_GLOBAL__DI");
1469 add_to_list (&exports, "_GLOBAL__DD");
1470 exportf = fopen (export_file, "w");
1471 if (exportf == (FILE *) 0)
1472 fatal_perror ("fopen %s", export_file);
1473 write_aix_file (exportf, exports.first);
1474 if (fclose (exportf))
1475 fatal_perror ("fclose %s", export_file);
1477 #endif
1479 /* End of arguments to second link phase. */
1480 *ld2 = (char*) 0;
1482 if (debug)
1484 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1485 output_file, c_file);
1486 write_c_file (stderr, "stderr");
1487 fprintf (stderr, "========== end of c_file\n\n");
1488 #ifdef COLLECT_EXPORT_LIST
1489 fprintf (stderr, "\n========== export_file = %s\n", export_file);
1490 write_aix_file (stderr, exports.first);
1491 fprintf (stderr, "========== end of export_file\n\n");
1492 #endif
1495 /* Assemble the constructor and destructor tables.
1496 Link the tables in with the rest of the program. */
1498 fork_execute ("gcc", c_argv);
1499 #ifdef COLLECT_EXPORT_LIST
1500 /* On AIX we must call tlink because of possible templates resolution */
1501 do_tlink (ld2_argv, object_lst);
1502 #else
1503 /* Otherwise, simply call ld because tlink is already done */
1504 fork_execute ("ld", ld2_argv);
1506 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1507 constructors/destructors in shared libraries. */
1508 scan_prog_file (output_file, PASS_SECOND);
1509 #endif
1511 maybe_unlink (c_file);
1512 maybe_unlink (o_file);
1514 #ifdef COLLECT_EXPORT_LIST
1515 maybe_unlink (export_file);
1516 #endif
1518 return 0;
1522 /* Wait for a process to finish, and exit if a non-zero status is found. */
1525 collect_wait (prog)
1526 const char *prog;
1528 int status;
1530 pwait (pexecute_pid, &status, 0);
1531 if (status)
1533 if (WIFSIGNALED (status))
1535 int sig = WTERMSIG (status);
1536 error ("%s terminated with signal %d [%s]%s",
1537 prog, sig, strsignal(sig),
1538 status & 0200 ? "" : ", core dumped");
1539 collect_exit (FATAL_EXIT_CODE);
1542 if (WIFEXITED (status))
1543 return WEXITSTATUS (status);
1545 return 0;
1548 static void
1549 do_wait (prog)
1550 const char *prog;
1552 int ret = collect_wait (prog);
1553 if (ret != 0)
1555 error ("%s returned %d exit status", prog, ret);
1556 collect_exit (ret);
1561 /* Execute a program, and wait for the reply. */
1563 void
1564 collect_execute (prog, argv, redir)
1565 const char *prog;
1566 char **argv;
1567 const char *redir;
1569 char *errmsg_fmt;
1570 char *errmsg_arg;
1571 int redir_handle = -1;
1572 int stdout_save = -1;
1573 int stderr_save = -1;
1575 if (vflag || debug)
1577 char **p_argv;
1578 const char *str;
1580 if (argv[0])
1581 fprintf (stderr, "%s", argv[0]);
1582 else
1583 notice ("[cannot find %s]", prog);
1585 for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
1586 fprintf (stderr, " %s", str);
1588 fprintf (stderr, "\n");
1591 fflush (stdout);
1592 fflush (stderr);
1594 /* If we cannot find a program we need, complain error. Do this here
1595 since we might not end up needing something that we could not find. */
1597 if (argv[0] == 0)
1598 fatal ("cannot find `%s'", prog);
1600 if (redir)
1602 /* Open response file. */
1603 redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT);
1605 /* Duplicate the stdout and stderr file handles
1606 so they can be restored later. */
1607 stdout_save = dup (STDOUT_FILENO);
1608 if (stdout_save == -1)
1609 fatal_perror ("redirecting stdout: %s", redir);
1610 stderr_save = dup (STDERR_FILENO);
1611 if (stderr_save == -1)
1612 fatal_perror ("redirecting stdout: %s", redir);
1614 /* Redirect stdout & stderr to our response file. */
1615 dup2 (redir_handle, STDOUT_FILENO);
1616 dup2 (redir_handle, STDERR_FILENO);
1619 pexecute_pid = pexecute (argv[0], argv, argv[0], NULL,
1620 &errmsg_fmt, &errmsg_arg,
1621 (PEXECUTE_FIRST | PEXECUTE_LAST | PEXECUTE_SEARCH));
1623 if (redir)
1625 /* Restore stdout and stderr to their previous settings. */
1626 dup2 (stdout_save, STDOUT_FILENO);
1627 dup2 (stderr_save, STDERR_FILENO);
1629 /* Close reponse file. */
1630 close (redir_handle);
1633 if (pexecute_pid == -1)
1634 fatal_perror (errmsg_fmt, errmsg_arg);
1637 static void
1638 fork_execute (prog, argv)
1639 const char *prog;
1640 char **argv;
1642 collect_execute (prog, argv, NULL);
1643 do_wait (prog);
1646 /* Unlink a file unless we are debugging. */
1648 static void
1649 maybe_unlink (file)
1650 const char *file;
1652 if (!debug)
1653 unlink (file);
1654 else
1655 notice ("[Leaving %s]\n", file);
1659 static long sequence_number = 0;
1661 /* Add a name to a linked list. */
1663 static void
1664 add_to_list (head_ptr, name)
1665 struct head *head_ptr;
1666 const char *name;
1668 struct id *newid
1669 = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
1670 struct id *p;
1671 strcpy (newid->name, name);
1673 if (head_ptr->first)
1674 head_ptr->last->next = newid;
1675 else
1676 head_ptr->first = newid;
1678 /* Check for duplicate symbols. */
1679 for (p = head_ptr->first;
1680 strcmp (name, p->name) != 0;
1681 p = p->next)
1683 if (p != newid)
1685 head_ptr->last->next = 0;
1686 free (newid);
1687 return;
1690 newid->sequence = ++sequence_number;
1691 head_ptr->last = newid;
1692 head_ptr->number++;
1695 /* Grab the init priority number from an init function name that
1696 looks like "_GLOBAL_.I.12345.foo". */
1698 static int
1699 extract_init_priority (name)
1700 const char *name;
1702 int pos = 0, pri;
1704 while (name[pos] == '_')
1705 ++pos;
1706 pos += 10; /* strlen ("GLOBAL__X_") */
1708 /* Extract init_p number from ctor/dtor name. */
1709 pri = atoi (name + pos);
1710 return pri ? pri : DEFAULT_INIT_PRIORITY;
1713 /* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
1714 ctors will be run from right to left, dtors from left to right. */
1716 static void
1717 sort_ids (head_ptr)
1718 struct head *head_ptr;
1720 /* id holds the current element to insert. id_next holds the next
1721 element to insert. id_ptr iterates through the already sorted elements
1722 looking for the place to insert id. */
1723 struct id *id, *id_next, **id_ptr;
1725 id = head_ptr->first;
1727 /* We don't have any sorted elements yet. */
1728 head_ptr->first = NULL;
1730 for (; id; id = id_next)
1732 id_next = id->next;
1733 id->sequence = extract_init_priority (id->name);
1735 for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next))
1736 if (*id_ptr == NULL
1737 /* If the sequence numbers are the same, we put the id from the
1738 file later on the command line later in the list. */
1739 || id->sequence > (*id_ptr)->sequence
1740 /* Hack: do lexical compare, too.
1741 || (id->sequence == (*id_ptr)->sequence
1742 && strcmp (id->name, (*id_ptr)->name) > 0) */
1745 id->next = *id_ptr;
1746 *id_ptr = id;
1747 break;
1751 /* Now set the sequence numbers properly so write_c_file works. */
1752 for (id = head_ptr->first; id; id = id->next)
1753 id->sequence = ++sequence_number;
1756 /* Write: `prefix', the names on list LIST, `suffix'. */
1758 static void
1759 write_list (stream, prefix, list)
1760 FILE *stream;
1761 const char *prefix;
1762 struct id *list;
1764 while (list)
1766 fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1767 list = list->next;
1771 #ifdef COLLECT_EXPORT_LIST
1772 /* This function is really used only on AIX, but may be useful. */
1773 static int
1774 is_in_list (prefix, list)
1775 const char *prefix;
1776 struct id *list;
1778 while (list)
1780 if (!strcmp (prefix, list->name)) return 1;
1781 list = list->next;
1783 return 0;
1785 #endif
1787 /* Added for debugging purpose. */
1788 #ifdef COLLECT_EXPORT_LIST
1789 static void
1790 dump_list (stream, prefix, list)
1791 FILE *stream;
1792 const char *prefix;
1793 struct id *list;
1795 while (list)
1797 fprintf (stream, "%s%s,\n", prefix, list->name);
1798 list = list->next;
1801 #endif
1803 #if 0
1804 static void
1805 dump_prefix_list (stream, prefix, list)
1806 FILE *stream;
1807 const char *prefix;
1808 struct prefix_list *list;
1810 while (list)
1812 fprintf (stream, "%s%s,\n", prefix, list->prefix);
1813 list = list->next;
1816 #endif
1818 static void
1819 write_list_with_asm (stream, prefix, list)
1820 FILE *stream;
1821 const char *prefix;
1822 struct id *list;
1824 while (list)
1826 fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1827 prefix, list->sequence, list->name);
1828 list = list->next;
1832 /* Write out the constructor and destructor tables statically (for a shared
1833 object), along with the functions to execute them. */
1835 static void
1836 write_c_file_stat (stream, name)
1837 FILE *stream;
1838 const char *name ATTRIBUTE_UNUSED;
1840 const char *p, *q;
1841 char *prefix, *r;
1842 int frames = (frame_tables.number > 0);
1844 /* Figure out name of output_file, stripping off .so version. */
1845 p = strrchr (output_file, '/');
1846 if (p == 0)
1847 p = output_file;
1848 else
1849 p++;
1850 q = p;
1851 while (q)
1853 q = strchr (q,'.');
1854 if (q == 0)
1856 q = p + strlen (p);
1857 break;
1859 else
1861 if (strncmp (q, ".so", 3) == 0)
1863 q += 3;
1864 break;
1866 else
1867 q++;
1870 /* q points to null at end of the string (or . of the .so version) */
1871 prefix = xmalloc (q - p + 1);
1872 strncpy (prefix, p, q - p);
1873 prefix[q - p] = 0;
1874 for (r = prefix; *r; r++)
1875 if (!ISALNUM ((unsigned char)*r))
1876 *r = '_';
1877 if (debug)
1878 notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
1879 output_file, prefix);
1881 #define INIT_NAME_FORMAT "_GLOBAL__FI_%s"
1882 initname = xmalloc (strlen (prefix) + sizeof (INIT_NAME_FORMAT) - 2);
1883 sprintf (initname, INIT_NAME_FORMAT, prefix);
1885 #define FINI_NAME_FORMAT "_GLOBAL__FD_%s"
1886 fininame = xmalloc (strlen (prefix) + sizeof (FINI_NAME_FORMAT) - 2);
1887 sprintf (fininame, FINI_NAME_FORMAT, prefix);
1889 free (prefix);
1891 /* Write the tables as C code */
1893 fprintf (stream, "static int count;\n");
1894 fprintf (stream, "typedef void entry_pt();\n");
1895 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1897 if (frames)
1899 write_list_with_asm (stream, "extern void *", frame_tables.first);
1901 fprintf (stream, "\tstatic void *frame_table[] = {\n");
1902 write_list (stream, "\t\t&", frame_tables.first);
1903 fprintf (stream, "\t0\n};\n");
1905 /* This must match what's in frame.h. */
1906 fprintf (stream, "struct object {\n");
1907 fprintf (stream, " void *pc_begin;\n");
1908 fprintf (stream, " void *pc_end;\n");
1909 fprintf (stream, " void *fde_begin;\n");
1910 fprintf (stream, " void *fde_array;\n");
1911 fprintf (stream, " __SIZE_TYPE__ count;\n");
1912 fprintf (stream, " struct object *next;\n");
1913 fprintf (stream, "};\n");
1915 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
1916 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
1918 fprintf (stream, "static void reg_frame () {\n");
1919 fprintf (stream, "\tstatic struct object ob;\n");
1920 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
1921 fprintf (stream, "\t}\n");
1923 fprintf (stream, "static void dereg_frame () {\n");
1924 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
1925 fprintf (stream, "\t}\n");
1928 fprintf (stream, "void %s() {\n", initname);
1929 if (constructors.number > 0 || frames)
1931 fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
1932 write_list (stream, "\t\t", constructors.first);
1933 if (frames)
1934 fprintf (stream, "\treg_frame,\n");
1935 fprintf (stream, "\t};\n");
1936 fprintf (stream, "\tentry_pt **p;\n");
1937 fprintf (stream, "\tif (count++ != 0) return;\n");
1938 fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
1939 fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
1941 else
1942 fprintf (stream, "\t++count;\n");
1943 fprintf (stream, "}\n");
1944 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1945 fprintf (stream, "void %s() {\n", fininame);
1946 if (destructors.number > 0 || frames)
1948 fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
1949 write_list (stream, "\t\t", destructors.first);
1950 if (frames)
1951 fprintf (stream, "\tdereg_frame,\n");
1952 fprintf (stream, "\t};\n");
1953 fprintf (stream, "\tentry_pt **p;\n");
1954 fprintf (stream, "\tif (--count != 0) return;\n");
1955 fprintf (stream, "\tp = dtors;\n");
1956 fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
1957 destructors.number + frames);
1959 fprintf (stream, "}\n");
1961 if (shared_obj)
1963 fprintf (stream, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname);
1964 fprintf (stream, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame);
1968 /* Write the constructor/destructor tables. */
1970 #ifndef LD_INIT_SWITCH
1971 static void
1972 write_c_file_glob (stream, name)
1973 FILE *stream;
1974 const char *name ATTRIBUTE_UNUSED;
1976 /* Write the tables as C code */
1978 int frames = (frame_tables.number > 0);
1980 fprintf (stream, "typedef void entry_pt();\n\n");
1982 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1984 if (frames)
1986 write_list_with_asm (stream, "extern void *", frame_tables.first);
1988 fprintf (stream, "\tstatic void *frame_table[] = {\n");
1989 write_list (stream, "\t\t&", frame_tables.first);
1990 fprintf (stream, "\t0\n};\n");
1992 /* This must match what's in frame.h. */
1993 fprintf (stream, "struct object {\n");
1994 fprintf (stream, " void *pc_begin;\n");
1995 fprintf (stream, " void *pc_end;\n");
1996 fprintf (stream, " void *fde_begin;\n");
1997 fprintf (stream, " void *fde_array;\n");
1998 fprintf (stream, " __SIZE_TYPE__ count;\n");
1999 fprintf (stream, " struct object *next;\n");
2000 fprintf (stream, "};\n");
2002 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
2003 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
2005 fprintf (stream, "static void reg_frame () {\n");
2006 fprintf (stream, "\tstatic struct object ob;\n");
2007 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
2008 fprintf (stream, "\t}\n");
2010 fprintf (stream, "static void dereg_frame () {\n");
2011 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
2012 fprintf (stream, "\t}\n");
2015 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
2016 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
2017 write_list (stream, "\t", constructors.first);
2018 if (frames)
2019 fprintf (stream, "\treg_frame,\n");
2020 fprintf (stream, "\t0\n};\n\n");
2022 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
2024 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
2025 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
2026 write_list (stream, "\t", destructors.first);
2027 if (frames)
2028 fprintf (stream, "\tdereg_frame,\n");
2029 fprintf (stream, "\t0\n};\n\n");
2031 fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
2032 fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
2034 #endif /* ! LD_INIT_SWITCH */
2036 static void
2037 write_c_file (stream, name)
2038 FILE *stream;
2039 const char *name;
2041 fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
2042 #ifndef LD_INIT_SWITCH
2043 if (! shared_obj)
2044 write_c_file_glob (stream, name);
2045 else
2046 #endif
2047 write_c_file_stat (stream, name);
2048 fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
2051 #ifdef COLLECT_EXPORT_LIST
2052 static void
2053 write_aix_file (stream, list)
2054 FILE *stream;
2055 struct id *list;
2057 for (; list; list = list->next)
2059 fputs (list->name, stream);
2060 putc ('\n', stream);
2063 #endif
2065 #ifdef OBJECT_FORMAT_NONE
2067 /* Generic version to scan the name list of the loaded program for
2068 the symbols g++ uses for static constructors and destructors.
2070 The constructor table begins at __CTOR_LIST__ and contains a count
2071 of the number of pointers (or -1 if the constructors are built in a
2072 separate section by the linker), followed by the pointers to the
2073 constructor functions, terminated with a null pointer. The
2074 destructor table has the same format, and begins at __DTOR_LIST__. */
2076 static void
2077 scan_prog_file (prog_name, which_pass)
2078 const char *prog_name;
2079 enum pass which_pass;
2081 void (*int_handler) PARAMS ((int));
2082 void (*quit_handler) PARAMS ((int));
2083 char *real_nm_argv[4];
2084 const char **nm_argv = (const char **) real_nm_argv;
2085 int pid;
2086 int argc = 0;
2087 int pipe_fd[2];
2088 char *p, buf[1024];
2089 FILE *inf;
2091 if (which_pass == PASS_SECOND)
2092 return;
2094 /* If we do not have an `nm', complain. */
2095 if (nm_file_name == 0)
2096 fatal ("cannot find `nm'");
2098 nm_argv[argc++] = nm_file_name;
2099 if (NM_FLAGS[0] != '\0')
2100 nm_argv[argc++] = NM_FLAGS;
2102 nm_argv[argc++] = prog_name;
2103 nm_argv[argc++] = (char *) 0;
2105 if (pipe (pipe_fd) < 0)
2106 fatal_perror ("pipe");
2108 inf = fdopen (pipe_fd[0], "r");
2109 if (inf == (FILE *) 0)
2110 fatal_perror ("fdopen");
2112 /* Trace if needed. */
2113 if (vflag)
2115 const char **p_argv;
2116 const char *str;
2118 for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2119 fprintf (stderr, " %s", str);
2121 fprintf (stderr, "\n");
2124 fflush (stdout);
2125 fflush (stderr);
2127 /* Spawn child nm on pipe */
2128 pid = vfork ();
2129 if (pid == -1)
2130 fatal_perror (VFORK_STRING);
2132 if (pid == 0) /* child context */
2134 /* setup stdout */
2135 if (dup2 (pipe_fd[1], 1) < 0)
2136 fatal_perror ("dup2 %d 1", pipe_fd[1]);
2138 if (close (pipe_fd[0]) < 0)
2139 fatal_perror ("close %d", pipe_fd[0]);
2141 if (close (pipe_fd[1]) < 0)
2142 fatal_perror ("close %d", pipe_fd[1]);
2144 execv (nm_file_name, real_nm_argv);
2145 fatal_perror ("execvp %s", nm_file_name);
2148 /* Parent context from here on. */
2149 int_handler = (void (*) PARAMS ((int))) signal (SIGINT, SIG_IGN);
2150 #ifdef SIGQUIT
2151 quit_handler = (void (*) PARAMS ((int))) signal (SIGQUIT, SIG_IGN);
2152 #endif
2154 if (close (pipe_fd[1]) < 0)
2155 fatal_perror ("close %d", pipe_fd[1]);
2157 if (debug)
2158 fprintf (stderr, "\nnm output with constructors/destructors.\n");
2160 /* Read each line of nm output. */
2161 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2163 int ch, ch2;
2164 char *name, *end;
2166 /* If it contains a constructor or destructor name, add the name
2167 to the appropriate list. */
2169 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
2170 if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
2171 break;
2173 if (ch != '_')
2174 continue;
2176 name = p;
2177 /* Find the end of the symbol name.
2178 Do not include `|', because Encore nm can tack that on the end. */
2179 for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|';
2180 end++)
2181 continue;
2184 *end = '\0';
2185 switch (is_ctor_dtor (name))
2187 case 1:
2188 if (which_pass != PASS_LIB)
2189 add_to_list (&constructors, name);
2190 break;
2192 case 2:
2193 if (which_pass != PASS_LIB)
2194 add_to_list (&destructors, name);
2195 break;
2197 case 3:
2198 if (which_pass != PASS_LIB)
2199 fatal ("init function found in object %s", prog_name);
2200 #ifndef LD_INIT_SWITCH
2201 add_to_list (&constructors, name);
2202 #endif
2203 break;
2205 case 4:
2206 if (which_pass != PASS_LIB)
2207 fatal ("fini function found in object %s", prog_name);
2208 #ifndef LD_FINI_SWITCH
2209 add_to_list (&destructors, name);
2210 #endif
2211 break;
2213 case 5:
2214 if (which_pass != PASS_LIB)
2215 add_to_list (&frame_tables, name);
2216 break;
2218 default: /* not a constructor or destructor */
2219 continue;
2222 if (debug)
2223 fprintf (stderr, "\t%s\n", buf);
2226 if (debug)
2227 fprintf (stderr, "\n");
2229 if (fclose (inf) != 0)
2230 fatal_perror ("fclose");
2232 do_wait (nm_file_name);
2234 signal (SIGINT, int_handler);
2235 #ifdef SIGQUIT
2236 signal (SIGQUIT, quit_handler);
2237 #endif
2240 #if SUNOS4_SHARED_LIBRARIES
2242 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2243 that the output file depends upon and their initialization/finalization
2244 routines, if any. */
2246 #include <a.out.h>
2247 #include <fcntl.h>
2248 #include <link.h>
2249 #include <sys/mman.h>
2250 #include <sys/param.h>
2251 #include <unistd.h>
2252 #include <sys/dir.h>
2254 /* pointers to the object file */
2255 unsigned object; /* address of memory mapped file */
2256 unsigned objsize; /* size of memory mapped to file */
2257 char * code; /* pointer to code segment */
2258 char * data; /* pointer to data segment */
2259 struct nlist *symtab; /* pointer to symbol table */
2260 struct link_dynamic *ld;
2261 struct link_dynamic_2 *ld_2;
2262 struct head libraries;
2264 /* Map the file indicated by NAME into memory and store its address. */
2266 static void mapfile PARAMS ((const char *));
2268 static void
2269 mapfile (name)
2270 const char *name;
2272 int fp;
2273 struct stat s;
2274 if ((fp = open (name, O_RDONLY)) == -1)
2275 fatal ("unable to open file '%s'", name);
2276 if (fstat (fp, &s) == -1)
2277 fatal ("unable to stat file '%s'", name);
2279 objsize = s.st_size;
2280 object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE,
2281 fp, 0);
2282 if (object == (unsigned)-1)
2283 fatal ("unable to mmap file '%s'", name);
2285 close (fp);
2288 /* Helpers for locatelib. */
2290 static const char *libname;
2292 static int libselect PARAMS ((struct direct *));
2294 static int
2295 libselect (d)
2296 struct direct *d;
2298 return (strncmp (libname, d->d_name, strlen (libname)) == 0);
2301 /* If one file has an additional numeric extension past LIBNAME, then put
2302 that one first in the sort. If both files have additional numeric
2303 extensions, then put the one with the higher number first in the sort.
2305 We must verify that the extension is numeric, because Sun saves the
2306 original versions of patched libraries with a .FCS extension. Files with
2307 invalid extensions must go last in the sort, so that they will not be used. */
2308 static int libcompare PARAMS ((struct direct **, struct direct **));
2310 static int
2311 libcompare (d1, d2)
2312 struct direct **d1, **d2;
2314 int i1, i2 = strlen (libname);
2315 char *e1 = (*d1)->d_name + i2;
2316 char *e2 = (*d2)->d_name + i2;
2318 while (*e1 && *e2 && *e1 == '.' && *e2 == '.'
2319 && e1[1] && ISDIGIT (e1[1]) && e2[1] && ISDIGIT (e2[1]))
2321 ++e1;
2322 ++e2;
2323 i1 = strtol (e1, &e1, 10);
2324 i2 = strtol (e2, &e2, 10);
2325 if (i1 != i2)
2326 return i1 - i2;
2329 if (*e1)
2331 /* It has a valid numeric extension, prefer this one. */
2332 if (*e1 == '.' && e1[1] && ISDIGIT (e1[1]))
2333 return 1;
2334 /* It has a invalid numeric extension, must prefer the other one. */
2335 else
2336 return -1;
2338 else if (*e2)
2340 /* It has a valid numeric extension, prefer this one. */
2341 if (*e2 == '.' && e2[1] && ISDIGIT (e2[1]))
2342 return -1;
2343 /* It has a invalid numeric extension, must prefer the other one. */
2344 else
2345 return 1;
2347 else
2348 return 0;
2351 /* Given the name NAME of a dynamic dependency, find its pathname and add
2352 it to the list of libraries. */
2353 static void locatelib PARAMS ((const char *));
2355 static void
2356 locatelib (name)
2357 const char *name;
2359 static const char **l;
2360 static int cnt;
2361 char buf[MAXPATHLEN];
2362 char *p, *q;
2363 const char **pp;
2365 if (l == 0)
2367 char *ld_rules;
2368 char *ldr = 0;
2369 /* counting elements in array, need 1 extra for null */
2370 cnt = 1;
2371 ld_rules = (char *) (ld_2->ld_rules + code);
2372 if (ld_rules)
2374 cnt++;
2375 for (; *ld_rules != 0; ld_rules++)
2376 if (*ld_rules == ':')
2377 cnt++;
2378 ld_rules = (char *) (ld_2->ld_rules + code);
2379 ldr = xstrdup (ld_rules);
2381 p = getenv ("LD_LIBRARY_PATH");
2382 q = 0;
2383 if (p)
2385 cnt++;
2386 for (q = p ; *q != 0; q++)
2387 if (*q == ':')
2388 cnt++;
2389 q = xstrdup (p);
2391 l = (const char **) xmalloc ((cnt + 3) * sizeof (char *));
2392 pp = l;
2393 if (ldr)
2395 *pp++ = ldr;
2396 for (; *ldr != 0; ldr++)
2397 if (*ldr == ':')
2399 *ldr++ = 0;
2400 *pp++ = ldr;
2403 if (q)
2405 *pp++ = q;
2406 for (; *q != 0; q++)
2407 if (*q == ':')
2409 *q++ = 0;
2410 *pp++ = q;
2413 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2414 *pp++ = "/lib";
2415 *pp++ = "/usr/lib";
2416 *pp++ = "/usr/local/lib";
2417 *pp = 0;
2419 libname = name;
2420 for (pp = l; *pp != 0 ; pp++)
2422 struct direct **namelist;
2423 int entries;
2424 if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0)
2426 sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name);
2427 add_to_list (&libraries, buf);
2428 if (debug)
2429 fprintf (stderr, "%s\n", buf);
2430 break;
2433 if (*pp == 0)
2435 if (debug)
2436 notice ("not found\n");
2437 else
2438 fatal ("dynamic dependency %s not found", name);
2442 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2443 that it depends upon and any constructors or destructors they contain. */
2445 static void
2446 scan_libraries (prog_name)
2447 const char *prog_name;
2449 struct exec *header;
2450 char *base;
2451 struct link_object *lo;
2452 char buff[MAXPATHLEN];
2453 struct id *list;
2455 mapfile (prog_name);
2456 header = (struct exec *)object;
2457 if (N_BADMAG (*header))
2458 fatal ("bad magic number in file '%s'", prog_name);
2459 if (header->a_dynamic == 0)
2460 return;
2462 code = (char *) (N_TXTOFF (*header) + (long) header);
2463 data = (char *) (N_DATOFF (*header) + (long) header);
2464 symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header);
2466 if (header->a_magic == ZMAGIC && header->a_entry == 0x20)
2468 /* shared object */
2469 ld = (struct link_dynamic *) (symtab->n_value + code);
2470 base = code;
2472 else
2474 /* executable */
2475 ld = (struct link_dynamic *) data;
2476 base = code-PAGSIZ;
2479 if (debug)
2480 notice ("dynamic dependencies.\n");
2482 ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);
2483 for (lo = (struct link_object *) ld_2->ld_need; lo;
2484 lo = (struct link_object *) lo->lo_next)
2486 char *name;
2487 lo = (struct link_object *) ((long) lo + code);
2488 name = (char *) (code + lo->lo_name);
2489 if (lo->lo_library)
2491 if (debug)
2492 fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major);
2493 sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor);
2494 locatelib (buff);
2496 else
2498 if (debug)
2499 fprintf (stderr, "\t%s\n", name);
2500 add_to_list (&libraries, name);
2504 if (debug)
2505 fprintf (stderr, "\n");
2507 /* now iterate through the library list adding their symbols to
2508 the list. */
2509 for (list = libraries.first; list; list = list->next)
2510 scan_prog_file (list->name, PASS_LIB);
2513 #else /* SUNOS4_SHARED_LIBRARIES */
2514 #ifdef LDD_SUFFIX
2516 /* Use the List Dynamic Dependencies program to find shared libraries that
2517 the output file depends upon and their initialization/finalization
2518 routines, if any. */
2520 static void
2521 scan_libraries (prog_name)
2522 const char *prog_name;
2524 static struct head libraries; /* list of shared libraries found */
2525 struct id *list;
2526 void (*int_handler) PARAMS ((int));
2527 void (*quit_handler) PARAMS ((int));
2528 char *real_ldd_argv[4];
2529 const char **ldd_argv = (const char **) real_ldd_argv;
2530 int pid;
2531 int argc = 0;
2532 int pipe_fd[2];
2533 char buf[1024];
2534 FILE *inf;
2536 /* If we do not have an `ldd', complain. */
2537 if (ldd_file_name == 0)
2539 error ("cannot find `ldd'");
2540 return;
2543 ldd_argv[argc++] = ldd_file_name;
2544 ldd_argv[argc++] = prog_name;
2545 ldd_argv[argc++] = (char *) 0;
2547 if (pipe (pipe_fd) < 0)
2548 fatal_perror ("pipe");
2550 inf = fdopen (pipe_fd[0], "r");
2551 if (inf == (FILE *) 0)
2552 fatal_perror ("fdopen");
2554 /* Trace if needed. */
2555 if (vflag)
2557 const char **p_argv;
2558 const char *str;
2560 for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2561 fprintf (stderr, " %s", str);
2563 fprintf (stderr, "\n");
2566 fflush (stdout);
2567 fflush (stderr);
2569 /* Spawn child ldd on pipe */
2570 pid = vfork ();
2571 if (pid == -1)
2572 fatal_perror (VFORK_STRING);
2574 if (pid == 0) /* child context */
2576 /* setup stdout */
2577 if (dup2 (pipe_fd[1], 1) < 0)
2578 fatal_perror ("dup2 %d 1", pipe_fd[1]);
2580 if (close (pipe_fd[0]) < 0)
2581 fatal_perror ("close %d", pipe_fd[0]);
2583 if (close (pipe_fd[1]) < 0)
2584 fatal_perror ("close %d", pipe_fd[1]);
2586 execv (ldd_file_name, real_ldd_argv);
2587 fatal_perror ("execv %s", ldd_file_name);
2590 /* Parent context from here on. */
2591 int_handler = (void (*) PARAMS ((int))) signal (SIGINT, SIG_IGN);
2592 #ifdef SIGQUIT
2593 quit_handler = (void (*) PARAMS ((int))) signal (SIGQUIT, SIG_IGN);
2594 #endif
2596 if (close (pipe_fd[1]) < 0)
2597 fatal_perror ("close %d", pipe_fd[1]);
2599 if (debug)
2600 notice ("\nldd output with constructors/destructors.\n");
2602 /* Read each line of ldd output. */
2603 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2605 int ch2;
2606 char *name, *end, *p = buf;
2608 /* Extract names of libraries and add to list. */
2609 PARSE_LDD_OUTPUT (p);
2610 if (p == 0)
2611 continue;
2613 name = p;
2614 if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
2615 fatal ("dynamic dependency %s not found", buf);
2617 /* Find the end of the symbol name. */
2618 for (end = p;
2619 (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|';
2620 end++)
2621 continue;
2622 *end = '\0';
2624 if (access (name, R_OK) == 0)
2625 add_to_list (&libraries, name);
2626 else
2627 fatal ("unable to open dynamic dependency '%s'", buf);
2629 if (debug)
2630 fprintf (stderr, "\t%s\n", buf);
2632 if (debug)
2633 fprintf (stderr, "\n");
2635 if (fclose (inf) != 0)
2636 fatal_perror ("fclose");
2638 do_wait (ldd_file_name);
2640 signal (SIGINT, int_handler);
2641 #ifdef SIGQUIT
2642 signal (SIGQUIT, quit_handler);
2643 #endif
2645 /* now iterate through the library list adding their symbols to
2646 the list. */
2647 for (list = libraries.first; list; list = list->next)
2648 scan_prog_file (list->name, PASS_LIB);
2651 #endif /* LDD_SUFFIX */
2652 #endif /* SUNOS4_SHARED_LIBRARIES */
2654 #endif /* OBJECT_FORMAT_NONE */
2658 * COFF specific stuff.
2661 #ifdef OBJECT_FORMAT_COFF
2663 #if defined(EXTENDED_COFF)
2665 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2666 # define GCC_SYMENT SYMR
2667 # define GCC_OK_SYMBOL(X) ((X).st == stProc || (X).st == stGlobal)
2668 # define GCC_SYMINC(X) (1)
2669 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2670 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2672 #else
2674 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2675 # define GCC_SYMENT SYMENT
2676 # define GCC_OK_SYMBOL(X) \
2677 (((X).n_sclass == C_EXT) && \
2678 ((X).n_scnum > N_UNDEF) && \
2679 (aix64_flag \
2680 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2681 || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2682 # define GCC_UNDEF_SYMBOL(X) \
2683 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2684 # define GCC_SYMINC(X) ((X).n_numaux+1)
2685 # define GCC_SYMZERO(X) 0
2687 /* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
2688 #ifdef _AIX51
2689 # define GCC_CHECK_HDR(X) \
2690 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2691 || (HEADER (X).f_magic == 0767 && aix64_flag))
2692 #else
2693 # define GCC_CHECK_HDR(X) \
2694 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2695 || (HEADER (X).f_magic == 0757 && aix64_flag))
2696 #endif
2698 #endif
2700 extern char *ldgetname ();
2702 /* COFF version to scan the name list of the loaded program for
2703 the symbols g++ uses for static constructors and destructors.
2705 The constructor table begins at __CTOR_LIST__ and contains a count
2706 of the number of pointers (or -1 if the constructors are built in a
2707 separate section by the linker), followed by the pointers to the
2708 constructor functions, terminated with a null pointer. The
2709 destructor table has the same format, and begins at __DTOR_LIST__. */
2711 static void
2712 scan_prog_file (prog_name, which_pass)
2713 const char *prog_name;
2714 enum pass which_pass;
2716 LDFILE *ldptr = NULL;
2717 int sym_index, sym_count;
2718 int is_shared = 0;
2720 if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2721 return;
2723 #ifdef COLLECT_EXPORT_LIST
2724 /* We do not need scanning for some standard C libraries. */
2725 if (which_pass == PASS_FIRST && ignore_library (prog_name))
2726 return;
2728 /* On AIX we have a loop, because there is not much difference
2729 between an object and an archive. This trick allows us to
2730 eliminate scan_libraries() function. */
2733 #endif
2734 /* Some platforms (e.g. OSF4) declare ldopen as taking a
2735 non-const char * filename parameter, even though it will not
2736 modify that string. So we must cast away const-ness here,
2737 which will cause -Wcast-qual to burp. */
2738 if ((ldptr = ldopen ((char *)prog_name, ldptr)) != NULL)
2740 if (! MY_ISCOFF (HEADER (ldptr).f_magic))
2741 fatal ("%s: not a COFF file", prog_name);
2743 if (GCC_CHECK_HDR (ldptr))
2745 sym_count = GCC_SYMBOLS (ldptr);
2746 sym_index = GCC_SYMZERO (ldptr);
2748 #ifdef COLLECT_EXPORT_LIST
2749 /* Is current archive member a shared object? */
2750 is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
2751 #endif
2753 while (sym_index < sym_count)
2755 GCC_SYMENT symbol;
2757 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2758 break;
2759 sym_index += GCC_SYMINC (symbol);
2761 if (GCC_OK_SYMBOL (symbol))
2763 char *name;
2765 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2766 continue; /* should never happen */
2768 #ifdef XCOFF_DEBUGGING_INFO
2769 /* All AIX function names have a duplicate entry
2770 beginning with a dot. */
2771 if (*name == '.')
2772 ++name;
2773 #endif
2775 switch (is_ctor_dtor (name))
2777 case 1:
2778 if (! is_shared)
2779 add_to_list (&constructors, name);
2780 #ifdef COLLECT_EXPORT_LIST
2781 if (which_pass == PASS_OBJ)
2782 add_to_list (&exports, name);
2783 #endif
2784 break;
2786 case 2:
2787 if (! is_shared)
2788 add_to_list (&destructors, name);
2789 #ifdef COLLECT_EXPORT_LIST
2790 if (which_pass == PASS_OBJ)
2791 add_to_list (&exports, name);
2792 #endif
2793 break;
2795 #ifdef COLLECT_EXPORT_LIST
2796 case 3:
2797 #ifndef LD_INIT_SWITCH
2798 if (is_shared)
2799 add_to_list (&constructors, name);
2800 #endif
2801 break;
2803 case 4:
2804 #ifndef LD_INIT_SWITCH
2805 if (is_shared)
2806 add_to_list (&destructors, name);
2807 #endif
2808 break;
2809 #endif
2811 case 5:
2812 if (! is_shared)
2813 add_to_list (&frame_tables, name);
2814 #ifdef COLLECT_EXPORT_LIST
2815 if (which_pass == PASS_OBJ)
2816 add_to_list (&exports, name);
2817 #endif
2818 break;
2820 default: /* not a constructor or destructor */
2821 #ifdef COLLECT_EXPORT_LIST
2822 /* If we are building a shared object on AIX we need
2823 to explicitly export all global symbols. */
2824 if (shared_obj)
2826 if (which_pass == PASS_OBJ && (! export_flag))
2827 add_to_list (&exports, name);
2829 #endif
2830 continue;
2833 if (debug)
2834 #if !defined(EXTENDED_COFF)
2835 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
2836 symbol.n_scnum, symbol.n_sclass,
2837 (symbol.n_type ? "0" : ""), symbol.n_type,
2838 name);
2839 #else
2840 fprintf (stderr,
2841 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
2842 symbol.iss, (long) symbol.value, symbol.index, name);
2843 #endif
2847 #ifdef COLLECT_EXPORT_LIST
2848 else
2850 /* If archive contains both 32-bit and 64-bit objects,
2851 we want to skip objects in other mode so mismatch normal. */
2852 if (debug)
2853 fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n",
2854 prog_name, HEADER (ldptr).f_magic, aix64_flag);
2856 #endif
2858 else
2860 fatal ("%s: cannot open as COFF file", prog_name);
2862 #ifdef COLLECT_EXPORT_LIST
2863 /* On AIX loop continues while there are more members in archive. */
2865 while (ldclose (ldptr) == FAILURE);
2866 #else
2867 /* Otherwise we simply close ldptr. */
2868 (void) ldclose(ldptr);
2869 #endif
2873 #ifdef COLLECT_EXPORT_LIST
2874 /* Given a library name without "lib" prefix, this function
2875 returns a full library name including a path. */
2876 static char *
2877 resolve_lib_name (name)
2878 const char *name;
2880 char *lib_buf;
2881 int i, j, l = 0;
2883 for (i = 0; libpaths[i]; i++)
2884 if (libpaths[i]->max_len > l)
2885 l = libpaths[i]->max_len;
2887 lib_buf = xmalloc (l + strlen(name) + 10);
2889 for (i = 0; libpaths[i]; i++)
2891 struct prefix_list *list = libpaths[i]->plist;
2892 for (; list; list = list->next)
2894 /* The following lines are needed because path_prefix list
2895 may contain directories both with trailing '/' and
2896 without it. */
2897 const char *p = "";
2898 if (list->prefix[strlen(list->prefix)-1] != '/')
2899 p = "/";
2900 for (j = 0; libexts[j]; j++)
2902 sprintf (lib_buf, "%s%slib%s.%s",
2903 list->prefix, p, name, libexts[j]);
2904 if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
2905 if (file_exists (lib_buf))
2907 if (debug) fprintf (stderr, "found: %s\n", lib_buf);
2908 return (lib_buf);
2913 if (debug)
2914 fprintf (stderr, "not found\n");
2915 else
2916 fatal ("Library lib%s not found", name);
2917 return (NULL);
2920 /* Array of standard AIX libraries which should not
2921 be scanned for ctors/dtors. */
2922 static const char *aix_std_libs[] = {
2923 "/unix",
2924 "/lib/libc.a",
2925 "/lib/libm.a",
2926 "/lib/libc_r.a",
2927 "/lib/libm_r.a",
2928 "/usr/lib/libc.a",
2929 "/usr/lib/libm.a",
2930 "/usr/lib/libc_r.a",
2931 "/usr/lib/libm_r.a",
2932 "/usr/lib/threads/libc.a",
2933 "/usr/ccs/lib/libc.a",
2934 "/usr/ccs/lib/libm.a",
2935 "/usr/ccs/lib/libc_r.a",
2936 "/usr/ccs/lib/libm_r.a",
2937 NULL
2940 /* This function checks the filename and returns 1
2941 if this name matches the location of a standard AIX library. */
2942 static int
2943 ignore_library (name)
2944 const char *name;
2946 const char **p = &aix_std_libs[0];
2947 while (*p++ != NULL)
2948 if (! strcmp (name, *p)) return 1;
2949 return 0;
2951 #endif
2953 #endif /* OBJECT_FORMAT_COFF */
2957 * OSF/rose specific stuff.
2960 #ifdef OBJECT_FORMAT_ROSE
2962 /* Union of the various load commands */
2964 typedef union load_union
2966 ldc_header_t hdr; /* common header */
2967 load_cmd_map_command_t map; /* map indexing other load cmds */
2968 interpreter_command_t iprtr; /* interpreter pathname */
2969 strings_command_t str; /* load commands strings section */
2970 region_command_t region; /* region load command */
2971 reloc_command_t reloc; /* relocation section */
2972 package_command_t pkg; /* package load command */
2973 symbols_command_t sym; /* symbol sections */
2974 entry_command_t ent; /* program start section */
2975 gen_info_command_t info; /* object information */
2976 func_table_command_t func; /* function constructors/destructors */
2977 } load_union_t;
2979 /* Structure to point to load command and data section in memory. */
2981 typedef struct load_all
2983 load_union_t *load; /* load command */
2984 char *section; /* pointer to section */
2985 } load_all_t;
2987 /* Structure to contain information about a file mapped into memory. */
2989 struct file_info
2991 char *start; /* start of map */
2992 char *name; /* filename */
2993 long size; /* size of the file */
2994 long rounded_size; /* size rounded to page boundary */
2995 int fd; /* file descriptor */
2996 int rw; /* != 0 if opened read/write */
2997 int use_mmap; /* != 0 if mmap'ed */
3000 extern int decode_mach_o_hdr ();
3001 extern int encode_mach_o_hdr ();
3003 static void add_func_table PARAMS ((mo_header_t *, load_all_t *,
3004 symbol_info_t *, int));
3005 static void print_header PARAMS ((mo_header_t *));
3006 static void print_load_command PARAMS ((load_union_t *, size_t, int));
3007 static void bad_header PARAMS ((int));
3008 static struct file_info *read_file PARAMS ((const char *, int, int));
3009 static void end_file PARAMS ((struct file_info *));
3011 /* OSF/rose specific version to scan the name list of the loaded
3012 program for the symbols g++ uses for static constructors and
3013 destructors.
3015 The constructor table begins at __CTOR_LIST__ and contains a count
3016 of the number of pointers (or -1 if the constructors are built in a
3017 separate section by the linker), followed by the pointers to the
3018 constructor functions, terminated with a null pointer. The
3019 destructor table has the same format, and begins at __DTOR_LIST__. */
3021 static void
3022 scan_prog_file (prog_name, which_pass)
3023 const char *prog_name;
3024 enum pass which_pass;
3026 char *obj;
3027 mo_header_t hdr;
3028 load_all_t *load_array;
3029 load_all_t *load_end;
3030 load_all_t *load_cmd;
3031 int symbol_load_cmds;
3032 off_t offset;
3033 int i;
3034 int num_syms;
3035 int status;
3036 char *str_sect;
3037 struct file_info *obj_file;
3038 int prog_fd;
3039 mo_lcid_t cmd_strings = -1;
3040 symbol_info_t *main_sym = 0;
3041 int rw = (which_pass != PASS_FIRST);
3043 prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
3044 if (prog_fd < 0)
3045 fatal_perror ("open %s", prog_name);
3047 obj_file = read_file (prog_name, prog_fd, rw);
3048 obj = obj_file->start;
3050 status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);
3051 if (status != MO_HDR_CONV_SUCCESS)
3052 bad_header (status);
3055 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
3056 since the hardware will automatically swap bytes for us on loading little endian
3057 integers. */
3059 #ifndef CROSS_COMPILE
3060 if (hdr.moh_magic != MOH_MAGIC_MSB
3061 || hdr.moh_header_version != MOH_HEADER_VERSION
3062 || hdr.moh_byte_order != OUR_BYTE_ORDER
3063 || hdr.moh_data_rep_id != OUR_DATA_REP_ID
3064 || hdr.moh_cpu_type != OUR_CPU_TYPE
3065 || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE
3066 || hdr.moh_vendor_type != OUR_VENDOR_TYPE)
3068 fatal ("incompatibilities between object file & expected values");
3070 #endif
3072 if (debug)
3073 print_header (&hdr);
3075 offset = hdr.moh_first_cmd_off;
3076 load_end = load_array
3077 = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);
3079 /* Build array of load commands, calculating the offsets */
3080 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3082 load_union_t *load_hdr; /* load command header */
3084 load_cmd = load_end++;
3085 load_hdr = (load_union_t *) (obj + offset);
3087 /* If modifying the program file, copy the header. */
3088 if (rw)
3090 load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
3091 memcpy ((char *)ptr, (char *)load_hdr, load_hdr->hdr.ldci_cmd_size);
3092 load_hdr = ptr;
3094 /* null out old command map, because we will rewrite at the end. */
3095 if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
3097 cmd_strings = ptr->map.lcm_ld_cmd_strings;
3098 ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
3102 load_cmd->load = load_hdr;
3103 if (load_hdr->hdr.ldci_section_off > 0)
3104 load_cmd->section = obj + load_hdr->hdr.ldci_section_off;
3106 if (debug)
3107 print_load_command (load_hdr, offset, i);
3109 offset += load_hdr->hdr.ldci_cmd_size;
3112 /* If the last command is the load command map and is not undefined,
3113 decrement the count of load commands. */
3114 if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)
3116 load_end--;
3117 hdr.moh_n_load_cmds--;
3120 /* Go through and process each symbol table section. */
3121 symbol_load_cmds = 0;
3122 for (load_cmd = load_array; load_cmd < load_end; load_cmd++)
3124 load_union_t *load_hdr = load_cmd->load;
3126 if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
3128 symbol_load_cmds++;
3130 if (debug)
3132 const char *kind = "unknown";
3134 switch (load_hdr->sym.symc_kind)
3136 case SYMC_IMPORTS: kind = "imports"; break;
3137 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
3138 case SYMC_STABS: kind = "stabs"; break;
3141 notice ("\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
3142 symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
3145 if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
3146 continue;
3148 str_sect = load_array[load_hdr->sym.symc_strings_section].section;
3149 if (str_sect == (char *) 0)
3150 fatal ("string section missing");
3152 if (load_cmd->section == (char *) 0)
3153 fatal ("section pointer missing");
3155 num_syms = load_hdr->sym.symc_nentries;
3156 for (i = 0; i < num_syms; i++)
3158 symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
3159 char *name = sym->si_name.symbol_name + str_sect;
3161 if (name[0] != '_')
3162 continue;
3164 if (rw)
3166 char *n = name + strlen (name) - strlen (NAME__MAIN);
3168 if ((n - name) < 0 || strcmp (n, NAME__MAIN))
3169 continue;
3170 while (n != name)
3171 if (*--n != '_')
3172 continue;
3174 main_sym = sym;
3176 else
3178 switch (is_ctor_dtor (name))
3180 case 1:
3181 add_to_list (&constructors, name);
3182 break;
3184 case 2:
3185 add_to_list (&destructors, name);
3186 break;
3188 default: /* not a constructor or destructor */
3189 continue;
3193 if (debug)
3194 fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
3195 sym->si_type, sym->si_sc_type, sym->si_flags, name);
3200 if (symbol_load_cmds == 0)
3201 fatal ("no symbol table found");
3203 /* Update the program file now, rewrite header and load commands. At present,
3204 we assume that there is enough space after the last load command to insert
3205 one more. Since the first section written out is page aligned, and the
3206 number of load commands is small, this is ok for the present. */
3208 if (rw)
3210 load_union_t *load_map;
3211 size_t size;
3213 if (cmd_strings == -1)
3214 fatal ("no cmd_strings found");
3216 /* Add __main to initializer list.
3217 If we are building a program instead of a shared library, do not
3218 do anything, since in the current version, you cannot do mallocs
3219 and such in the constructors. */
3221 if (main_sym != (symbol_info_t *) 0
3222 && ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
3223 add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
3225 if (debug)
3226 notice ("\nUpdating header and load commands.\n\n");
3228 hdr.moh_n_load_cmds++;
3229 size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
3231 /* Create new load command map. */
3232 if (debug)
3233 notice ("load command map, %d cmds, new size %ld.\n",
3234 (int) hdr.moh_n_load_cmds, (long) size);
3236 load_map = (load_union_t *) xcalloc (1, size);
3237 load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
3238 load_map->map.ldc_header.ldci_cmd_size = size;
3239 load_map->map.lcm_ld_cmd_strings = cmd_strings;
3240 load_map->map.lcm_nentries = hdr.moh_n_load_cmds;
3241 load_array[hdr.moh_n_load_cmds-1].load = load_map;
3243 offset = hdr.moh_first_cmd_off;
3244 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3246 load_map->map.lcm_map[i] = offset;
3247 if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)
3248 hdr.moh_load_map_cmd_off = offset;
3250 offset += load_array[i].load->hdr.ldci_cmd_size;
3253 hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
3255 if (debug)
3256 print_header (&hdr);
3258 /* Write header */
3259 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
3260 if (status != MO_HDR_CONV_SUCCESS)
3261 bad_header (status);
3263 if (debug)
3264 notice ("writing load commands.\n\n");
3266 /* Write load commands */
3267 offset = hdr.moh_first_cmd_off;
3268 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3270 load_union_t *load_hdr = load_array[i].load;
3271 size_t size = load_hdr->hdr.ldci_cmd_size;
3273 if (debug)
3274 print_load_command (load_hdr, offset, i);
3276 bcopy ((char *) load_hdr, (char *) (obj + offset), size);
3277 offset += size;
3281 end_file (obj_file);
3283 if (close (prog_fd))
3284 fatal_perror ("close %s", prog_name);
3286 if (debug)
3287 fprintf (stderr, "\n");
3291 /* Add a function table to the load commands to call a function
3292 on initiation or termination of the process. */
3294 static void
3295 add_func_table (hdr_p, load_array, sym, type)
3296 mo_header_t *hdr_p; /* pointer to global header */
3297 load_all_t *load_array; /* array of ptrs to load cmds */
3298 symbol_info_t *sym; /* pointer to symbol entry */
3299 int type; /* fntc_type value */
3301 /* Add a new load command. */
3302 int num_cmds = ++hdr_p->moh_n_load_cmds;
3303 int load_index = num_cmds - 1;
3304 size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);
3305 load_union_t *ptr = xcalloc (1, size);
3306 load_all_t *load_cmd;
3307 int i;
3309 /* Set the unresolved address bit in the header to force the loader to be
3310 used, since kernel exec does not call the initialization functions. */
3311 hdr_p->moh_flags |= MOH_UNRESOLVED_F;
3313 load_cmd = &load_array[load_index];
3314 load_cmd->load = ptr;
3315 load_cmd->section = (char *) 0;
3317 /* Fill in func table load command. */
3318 ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
3319 ptr->func.ldc_header.ldci_cmd_size = size;
3320 ptr->func.ldc_header.ldci_section_off = 0;
3321 ptr->func.ldc_header.ldci_section_len = 0;
3322 ptr->func.fntc_type = type;
3323 ptr->func.fntc_nentries = 1;
3325 /* copy address, turn it from abs. address to (region,offset) if necessary. */
3326 /* Is the symbol already expressed as (region, offset)? */
3327 if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)
3329 ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;
3330 ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;
3333 /* If not, figure out which region it's in. */
3334 else
3336 mo_vm_addr_t addr = sym->si_value.abs_val;
3337 int found = 0;
3339 for (i = 0; i < load_index; i++)
3341 if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
3343 region_command_t *region_ptr = &load_array[i].load->region;
3345 if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0
3346 && addr >= region_ptr->regc_addr.vm_addr
3347 && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)
3349 ptr->func.fntc_entry_loc[0].adr_lcid = i;
3350 ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;
3351 found++;
3352 break;
3357 if (!found)
3358 fatal ("could not convert 0x%l.8x into a region", addr);
3361 if (debug)
3362 notice ("%s function, region %d, offset = %ld (0x%.8lx)\n",
3363 type == FNTC_INITIALIZATION ? "init" : "term",
3364 (int) ptr->func.fntc_entry_loc[i].adr_lcid,
3365 (long) ptr->func.fntc_entry_loc[i].adr_sctoff,
3366 (long) ptr->func.fntc_entry_loc[i].adr_sctoff);
3371 /* Print the global header for an OSF/rose object. */
3373 static void
3374 print_header (hdr_ptr)
3375 mo_header_t *hdr_ptr;
3377 fprintf (stderr, "\nglobal header:\n");
3378 fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic);
3379 fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version);
3380 fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version);
3381 fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version);
3382 fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size);
3383 fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order);
3384 fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id);
3385 fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type);
3386 fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype);
3387 fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type);
3388 fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);
3389 fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off);
3390 fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds);
3391 fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds);
3392 fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags);
3394 if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
3395 fprintf (stderr, ", relocatable");
3397 if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
3398 fprintf (stderr, ", linkable");
3400 if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
3401 fprintf (stderr, ", execable");
3403 if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
3404 fprintf (stderr, ", executable");
3406 if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
3407 fprintf (stderr, ", unresolved");
3409 fprintf (stderr, "\n\n");
3410 return;
3414 /* Print a short summary of a load command. */
3416 static void
3417 print_load_command (load_hdr, offset, number)
3418 load_union_t *load_hdr;
3419 size_t offset;
3420 int number;
3422 mo_long_t type = load_hdr->hdr.ldci_cmd_type;
3423 const char *type_str = (char *) 0;
3425 switch (type)
3427 case LDC_UNDEFINED: type_str = "UNDEFINED"; break;
3428 case LDC_CMD_MAP: type_str = "CMD_MAP"; break;
3429 case LDC_INTERPRETER: type_str = "INTERPRETER"; break;
3430 case LDC_STRINGS: type_str = "STRINGS"; break;
3431 case LDC_REGION: type_str = "REGION"; break;
3432 case LDC_RELOC: type_str = "RELOC"; break;
3433 case LDC_PACKAGE: type_str = "PACKAGE"; break;
3434 case LDC_SYMBOLS: type_str = "SYMBOLS"; break;
3435 case LDC_ENTRY: type_str = "ENTRY"; break;
3436 case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break;
3437 case LDC_GEN_INFO: type_str = "GEN_INFO"; break;
3440 fprintf (stderr,
3441 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3442 number,
3443 (long) load_hdr->hdr.ldci_cmd_size,
3444 (long) offset,
3445 (long) load_hdr->hdr.ldci_section_off,
3446 (long) load_hdr->hdr.ldci_section_len);
3448 if (type_str == (char *) 0)
3449 fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
3451 else if (type != LDC_REGION)
3452 fprintf (stderr, ", ty: %s\n", type_str);
3454 else
3456 const char *region = "";
3457 switch (load_hdr->region.regc_usage_type)
3459 case REG_TEXT_T: region = ", .text"; break;
3460 case REG_DATA_T: region = ", .data"; break;
3461 case REG_BSS_T: region = ", .bss"; break;
3462 case REG_GLUE_T: region = ", .glue"; break;
3463 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3464 case REG_RDATA_T: region = ", .rdata"; break;
3465 case REG_SDATA_T: region = ", .sdata"; break;
3466 case REG_SBSS_T: region = ", .sbss"; break;
3467 #endif
3470 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3471 type_str,
3472 (long) load_hdr->region.regc_vm_addr,
3473 (long) load_hdr->region.regc_vm_size,
3474 region);
3477 return;
3481 /* Fatal error when {en,de}code_mach_o_header fails. */
3483 static void
3484 bad_header (status)
3485 int status;
3487 switch (status)
3489 case MO_ERROR_BAD_MAGIC: fatal ("bad magic number");
3490 case MO_ERROR_BAD_HDR_VERS: fatal ("bad header version");
3491 case MO_ERROR_BAD_RAW_HDR_VERS: fatal ("bad raw header version");
3492 case MO_ERROR_BUF2SML: fatal ("raw header buffer too small");
3493 case MO_ERROR_OLD_RAW_HDR_FILE: fatal ("old raw header file");
3494 case MO_ERROR_UNSUPPORTED_VERS: fatal ("unsupported version");
3495 default:
3496 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
3501 /* Read a file into a memory buffer. */
3503 static struct file_info *
3504 read_file (name, fd, rw)
3505 const char *name; /* filename */
3506 int fd; /* file descriptor */
3507 int rw; /* read/write */
3509 struct stat stat_pkt;
3510 struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
3511 #ifdef USE_MMAP
3512 static int page_size;
3513 #endif
3515 if (fstat (fd, &stat_pkt) < 0)
3516 fatal_perror ("fstat %s", name);
3518 p->name = name;
3519 p->size = stat_pkt.st_size;
3520 p->rounded_size = stat_pkt.st_size;
3521 p->fd = fd;
3522 p->rw = rw;
3524 #ifdef USE_MMAP
3525 if (debug)
3526 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
3528 if (page_size == 0)
3529 page_size = sysconf (_SC_PAGE_SIZE);
3531 p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
3532 p->start = mmap ((caddr_t) 0,
3533 (rw) ? p->rounded_size : p->size,
3534 (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
3535 MAP_FILE | MAP_VARIABLE | MAP_SHARED,
3537 0L);
3539 if (p->start != (char *) 0 && p->start != (char *) -1)
3540 p->use_mmap = 1;
3542 else
3543 #endif /* USE_MMAP */
3545 long len;
3547 if (debug)
3548 fprintf (stderr, "read %s\n", name);
3550 p->use_mmap = 0;
3551 p->start = xmalloc (p->size);
3552 if (lseek (fd, 0L, SEEK_SET) < 0)
3553 fatal_perror ("lseek %s 0", name);
3555 len = read (fd, p->start, p->size);
3556 if (len < 0)
3557 fatal_perror ("read %s", name);
3559 if (len != p->size)
3560 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
3563 return p;
3566 /* Do anything necessary to write a file back from memory. */
3568 static void
3569 end_file (ptr)
3570 struct file_info *ptr; /* file information block */
3572 #ifdef USE_MMAP
3573 if (ptr->use_mmap)
3575 if (ptr->rw)
3577 if (debug)
3578 fprintf (stderr, "msync %s\n", ptr->name);
3580 if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
3581 fatal_perror ("msync %s", ptr->name);
3584 if (debug)
3585 fprintf (stderr, "munmap %s\n", ptr->name);
3587 if (munmap (ptr->start, ptr->size))
3588 fatal_perror ("munmap %s", ptr->name);
3590 else
3591 #endif /* USE_MMAP */
3593 if (ptr->rw)
3595 long len;
3597 if (debug)
3598 fprintf (stderr, "write %s\n", ptr->name);
3600 if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
3601 fatal_perror ("lseek %s 0", ptr->name);
3603 len = write (ptr->fd, ptr->start, ptr->size);
3604 if (len < 0)
3605 fatal_perror ("write %s", ptr->name);
3607 if (len != ptr->size)
3608 fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
3611 free (ptr->start);
3614 free (ptr);
3617 #endif /* OBJECT_FORMAT_ROSE */