Use MODE_BASE_REG_CLASS in legitimize macros.
[official-gcc.git] / gcc / collect2.c
blob23e4606a1fddcf0757d0e485b1bfcf146ab5e380
1 /* Collect static initialization info into data structures that can be
2 traversed by C++ initialization and finalization routines.
3 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
4 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
5 Contributed by Chris Smith (csmith@convex.com).
6 Heavily modified by Michael Meissner (meissner@cygnus.com),
7 Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
9 This file is part of GCC.
11 GCC is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 2, or (at your option) any later
14 version.
16 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 for more details.
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING. If not, write to the Free
23 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
24 02111-1307, USA. */
27 /* Build tables of static constructors and destructors and run ld. */
29 #include "config.h"
30 #include "system.h"
31 #include <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 #ifndef COLLECT_SHARED_INIT_FUNC
158 #define COLLECT_SHARED_INIT_FUNC(STREAM, FUNC) \
159 fprintf ((STREAM), "void _GLOBAL__DI() {\n\t%s();\n}\n", (FUNC))
160 #endif
161 #ifndef COLLECT_SHARED_FINI_FUNC
162 #define COLLECT_SHARED_FINI_FUNC(STREAM, FUNC) \
163 fprintf ((STREAM), "void _GLOBAL__DD() {\n\t%s();\n}\n", (FUNC))
164 #endif
166 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
167 #define SCAN_LIBRARIES
168 #endif
170 #ifdef USE_COLLECT2
171 int do_collecting = 1;
172 #else
173 int do_collecting = 0;
174 #endif
176 /* Nonzero if we should suppress the automatic demangling of identifiers
177 in linker error messages. Set from COLLECT_NO_DEMANGLE. */
178 int no_demangle;
180 /* Linked lists of constructor and destructor names. */
182 struct id
184 struct id *next;
185 int sequence;
186 char name[1];
189 struct head
191 struct id *first;
192 struct id *last;
193 int number;
196 /* Enumeration giving which pass this is for scanning the program file. */
198 enum pass {
199 PASS_FIRST, /* without constructors */
200 PASS_OBJ, /* individual objects */
201 PASS_LIB, /* looking for shared libraries */
202 PASS_SECOND /* with constructors linked in */
205 int vflag; /* true if -v */
206 static int rflag; /* true if -r */
207 static int strip_flag; /* true if -s */
208 #ifdef COLLECT_EXPORT_LIST
209 static int export_flag; /* true if -bE */
210 static int aix64_flag; /* true if -b64 */
211 #endif
213 int debug; /* true if -debug */
215 static int shared_obj; /* true if -shared */
217 static const char *c_file; /* <xxx>.c for constructor/destructor list. */
218 static const char *o_file; /* <xxx>.o for constructor/destructor list. */
219 #ifdef COLLECT_EXPORT_LIST
220 static const char *export_file; /* <xxx>.x for AIX export list. */
221 #endif
222 const char *ldout; /* File for ld errors. */
223 static const char *output_file; /* Output file for ld. */
224 static const char *nm_file_name; /* pathname of nm */
225 #ifdef LDD_SUFFIX
226 static const char *ldd_file_name; /* pathname of ldd (or equivalent) */
227 #endif
228 static const char *strip_file_name; /* pathname of strip */
229 const char *c_file_name; /* pathname of gcc */
230 static char *initname, *fininame; /* names of init and fini funcs */
232 static struct head constructors; /* list of constructors found */
233 static struct head destructors; /* list of destructors found */
234 #ifdef COLLECT_EXPORT_LIST
235 static struct head exports; /* list of exported symbols */
236 #endif
237 static struct head frame_tables; /* list of frame unwind info tables */
239 struct obstack temporary_obstack;
240 struct obstack permanent_obstack;
241 char * temporary_firstobj;
243 /* Holds the return value of pexecute. */
244 int pexecute_pid;
246 /* Defined in the automatically-generated underscore.c. */
247 extern int prepends_underscore;
249 #ifndef GET_ENV_PATH_LIST
250 #define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
251 #endif
253 /* Structure to hold all the directories in which to search for files to
254 execute. */
256 struct prefix_list
258 const char *prefix; /* String to prepend to the path. */
259 struct prefix_list *next; /* Next in linked list. */
262 struct path_prefix
264 struct prefix_list *plist; /* List of prefixes to try */
265 int max_len; /* Max length of a prefix in PLIST */
266 const char *name; /* Name of this list (used in config stuff) */
269 #ifdef COLLECT_EXPORT_LIST
270 /* Lists to keep libraries to be scanned for global constructors/destructors. */
271 static struct head libs; /* list of libraries */
272 static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
273 static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
274 static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
275 &libpath_lib_dirs, NULL};
276 static const char *const libexts[3] = {"a", "so", NULL}; /* possible library extensions */
277 #endif
279 static void handler PARAMS ((int));
280 static int is_ctor_dtor PARAMS ((const char *));
281 static char *find_a_file PARAMS ((struct path_prefix *, const char *));
282 static void add_prefix PARAMS ((struct path_prefix *, const char *));
283 static void prefix_from_env PARAMS ((const char *, struct path_prefix *));
284 static void prefix_from_string PARAMS ((const char *, struct path_prefix *));
285 static void do_wait PARAMS ((const char *));
286 static void fork_execute PARAMS ((const char *, char **));
287 static void maybe_unlink PARAMS ((const char *));
288 static void add_to_list PARAMS ((struct head *, const char *));
289 static int extract_init_priority PARAMS ((const char *));
290 static void sort_ids PARAMS ((struct head *));
291 static void write_list PARAMS ((FILE *, const char *, struct id *));
292 #ifdef COLLECT_EXPORT_LIST
293 static void dump_list PARAMS ((FILE *, const char *, struct id *));
294 #endif
295 #if 0
296 static void dump_prefix_list PARAMS ((FILE *, const char *, struct prefix_list *));
297 #endif
298 static void write_list_with_asm PARAMS ((FILE *, const char *, struct id *));
299 static void write_c_file PARAMS ((FILE *, const char *));
300 static void write_c_file_stat PARAMS ((FILE *, const char *));
301 #ifndef LD_INIT_SWITCH
302 static void write_c_file_glob PARAMS ((FILE *, const char *));
303 #endif
304 static void scan_prog_file PARAMS ((const char *, enum pass));
305 #ifdef SCAN_LIBRARIES
306 static void scan_libraries PARAMS ((const char *));
307 #endif
308 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
309 static int is_in_args PARAMS ((const char *, const char **, const char **));
310 #endif
311 #ifdef COLLECT_EXPORT_LIST
312 #if 0
313 static int is_in_list PARAMS ((const char *, struct id *));
314 #endif
315 static void write_aix_file PARAMS ((FILE *, struct id *));
316 static char *resolve_lib_name PARAMS ((const char *));
317 static int ignore_library PARAMS ((const char *));
318 #endif
319 static char *extract_string PARAMS ((const char **));
321 #ifndef HAVE_DUP2
322 static int dup2 PARAMS ((int, int));
323 static int
324 dup2 (oldfd, newfd)
325 int oldfd;
326 int newfd;
328 int fdtmp[256];
329 int fdx = 0;
330 int fd;
332 if (oldfd == newfd)
333 return oldfd;
334 close (newfd);
335 while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
336 fdtmp[fdx++] = fd;
337 while (fdx > 0)
338 close (fdtmp[--fdx]);
340 return fd;
342 #endif /* ! HAVE_DUP2 */
344 /* Delete tempfiles and exit function. */
346 void
347 collect_exit (status)
348 int status;
350 if (c_file != 0 && c_file[0])
351 maybe_unlink (c_file);
353 if (o_file != 0 && o_file[0])
354 maybe_unlink (o_file);
356 #ifdef COLLECT_EXPORT_LIST
357 if (export_file != 0 && export_file[0])
358 maybe_unlink (export_file);
359 #endif
361 if (ldout != 0 && ldout[0])
363 dump_file (ldout);
364 maybe_unlink (ldout);
367 if (status != 0 && output_file != 0 && output_file[0])
368 maybe_unlink (output_file);
370 exit (status);
374 /* Notify user of a non-error. */
375 void
376 notice VPARAMS ((const char *msgid, ...))
378 VA_OPEN (ap, msgid);
379 VA_FIXEDARG (ap, const char *, msgid);
381 vfprintf (stderr, _(msgid), ap);
382 VA_CLOSE (ap);
385 /* Die when sys call fails. */
387 void
388 fatal_perror VPARAMS ((const char * msgid, ...))
390 int e = errno;
392 VA_OPEN (ap, msgid);
393 VA_FIXEDARG (ap, const char *, msgid);
395 fprintf (stderr, "collect2: ");
396 vfprintf (stderr, _(msgid), ap);
397 fprintf (stderr, ": %s\n", xstrerror (e));
398 VA_CLOSE (ap);
400 collect_exit (FATAL_EXIT_CODE);
403 /* Just die. */
405 void
406 fatal VPARAMS ((const char * msgid, ...))
408 VA_OPEN (ap, msgid);
409 VA_FIXEDARG (ap, const char *, msgid);
411 fprintf (stderr, "collect2: ");
412 vfprintf (stderr, _(msgid), ap);
413 fprintf (stderr, "\n");
414 VA_CLOSE (ap);
416 collect_exit (FATAL_EXIT_CODE);
419 /* Write error message. */
421 void
422 error VPARAMS ((const char * msgid, ...))
424 VA_OPEN (ap, msgid);
425 VA_FIXEDARG (ap, const char *, msgid);
427 fprintf (stderr, "collect2: ");
428 vfprintf (stderr, _(msgid), ap);
429 fprintf (stderr, "\n");
430 VA_CLOSE(ap);
433 /* In case obstack is linked in, and abort is defined to fancy_abort,
434 provide a default entry. */
436 void
437 fancy_abort ()
439 fatal ("internal error");
442 static void
443 handler (signo)
444 int signo;
446 if (c_file != 0 && c_file[0])
447 maybe_unlink (c_file);
449 if (o_file != 0 && o_file[0])
450 maybe_unlink (o_file);
452 if (ldout != 0 && ldout[0])
453 maybe_unlink (ldout);
455 #ifdef COLLECT_EXPORT_LIST
456 if (export_file != 0 && export_file[0])
457 maybe_unlink (export_file);
458 #endif
460 signal (signo, SIG_DFL);
461 kill (getpid (), signo);
466 file_exists (name)
467 const char *name;
469 return access (name, R_OK) == 0;
472 /* Parse a reasonable subset of shell quoting syntax. */
474 static char *
475 extract_string (pp)
476 const char **pp;
478 const char *p = *pp;
479 int backquote = 0;
480 int inside = 0;
482 for (;;)
484 char c = *p;
485 if (c == '\0')
486 break;
487 ++p;
488 if (backquote)
489 obstack_1grow (&temporary_obstack, c);
490 else if (! inside && c == ' ')
491 break;
492 else if (! inside && c == '\\')
493 backquote = 1;
494 else if (c == '\'')
495 inside = !inside;
496 else
497 obstack_1grow (&temporary_obstack, c);
500 obstack_1grow (&temporary_obstack, '\0');
501 *pp = p;
502 return obstack_finish (&temporary_obstack);
505 void
506 dump_file (name)
507 const char *name;
509 FILE *stream = fopen (name, "r");
511 if (stream == 0)
512 return;
513 while (1)
515 int c;
516 while (c = getc (stream),
517 c != EOF && (ISIDNUM (c) || c == '$' || c == '.'))
518 obstack_1grow (&temporary_obstack, c);
519 if (obstack_object_size (&temporary_obstack) > 0)
521 const char *word, *p;
522 char *result;
523 obstack_1grow (&temporary_obstack, '\0');
524 word = obstack_finish (&temporary_obstack);
526 if (*word == '.')
527 ++word, putc ('.', stderr);
528 p = word;
529 if (*p == '_' && prepends_underscore)
530 ++p;
532 if (no_demangle)
533 result = 0;
534 else
535 result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI);
537 if (result)
539 int diff;
540 fputs (result, stderr);
542 diff = strlen (word) - strlen (result);
543 while (diff > 0 && c == ' ')
544 --diff, putc (' ', stderr);
545 while (diff < 0 && c == ' ')
546 ++diff, c = getc (stream);
548 free (result);
550 else
551 fputs (word, stderr);
553 fflush (stderr);
554 obstack_free (&temporary_obstack, temporary_firstobj);
556 if (c == EOF)
557 break;
558 putc (c, stderr);
560 fclose (stream);
563 /* Decide whether the given symbol is: a constructor (1), a destructor
564 (2), a routine in a shared object that calls all the constructors
565 (3) or destructors (4), a DWARF exception-handling table (5), or
566 nothing special (0). */
568 static int
569 is_ctor_dtor (s)
570 const char *s;
572 struct names { const char *const name; const int len; const int ret;
573 const int two_underscores; };
575 const struct names *p;
576 int ch;
577 const char *orig_s = s;
579 static const struct names special[] = {
580 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
581 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
582 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
583 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
584 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
585 #ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions.
586 cfront has its own linker procedure to collect them;
587 if collect2 gets them too, they get collected twice
588 when the cfront procedure is run and the compiler used
589 for linking happens to be GCC. */
590 { "sti__", sizeof ("sti__")-1, 1, 1 },
591 { "std__", sizeof ("std__")-1, 2, 1 },
592 #endif /* CFRONT_LOSSAGE */
593 { NULL, 0, 0, 0 }
596 while ((ch = *s) == '_')
597 ++s;
599 if (s == orig_s)
600 return 0;
602 for (p = &special[0]; p->len > 0; p++)
604 if (ch == p->name[0]
605 && (!p->two_underscores || ((s - orig_s) >= 2))
606 && strncmp(s, p->name, p->len) == 0)
608 return p->ret;
611 return 0;
614 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
615 and one from the PATH variable. */
617 static struct path_prefix cpath, path;
619 #ifdef CROSS_COMPILE
620 /* This is the name of the target machine. We use it to form the name
621 of the files to execute. */
623 static const char *const target_machine = TARGET_MACHINE;
624 #endif
626 /* Search for NAME using prefix list PPREFIX. We only look for executable
627 files.
629 Return 0 if not found, otherwise return its name, allocated with malloc. */
631 static char *
632 find_a_file (pprefix, name)
633 struct path_prefix *pprefix;
634 const char *name;
636 char *temp;
637 struct prefix_list *pl;
638 int len = pprefix->max_len + strlen (name) + 1;
640 if (debug)
641 fprintf (stderr, "Looking for '%s'\n", name);
643 #ifdef HOST_EXECUTABLE_SUFFIX
644 len += strlen (HOST_EXECUTABLE_SUFFIX);
645 #endif
647 temp = xmalloc (len);
649 /* Determine the filename to execute (special case for absolute paths). */
651 if (*name == '/'
652 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
653 || (*name && name[1] == ':')
654 #endif
657 if (access (name, X_OK) == 0)
659 strcpy (temp, name);
661 if (debug)
662 fprintf (stderr, " - found: absolute path\n");
664 return temp;
667 #ifdef HOST_EXECUTABLE_SUFFIX
668 /* Some systems have a suffix for executable files.
669 So try appending that. */
670 strcpy (temp, name);
671 strcat (temp, HOST_EXECUTABLE_SUFFIX);
673 if (access (temp, X_OK) == 0)
674 return temp;
675 #endif
677 if (debug)
678 fprintf (stderr, " - failed to locate using absolute path\n");
680 else
681 for (pl = pprefix->plist; pl; pl = pl->next)
683 struct stat st;
685 strcpy (temp, pl->prefix);
686 strcat (temp, name);
688 if (stat (temp, &st) >= 0
689 && ! S_ISDIR (st.st_mode)
690 && access (temp, X_OK) == 0)
691 return temp;
693 #ifdef HOST_EXECUTABLE_SUFFIX
694 /* Some systems have a suffix for executable files.
695 So try appending that. */
696 strcat (temp, HOST_EXECUTABLE_SUFFIX);
698 if (stat (temp, &st) >= 0
699 && ! S_ISDIR (st.st_mode)
700 && access (temp, X_OK) == 0)
701 return temp;
702 #endif
705 if (debug && pprefix->plist == NULL)
706 fprintf (stderr, " - failed: no entries in prefix list\n");
708 free (temp);
709 return 0;
712 /* Add an entry for PREFIX to prefix list PPREFIX. */
714 static void
715 add_prefix (pprefix, prefix)
716 struct path_prefix *pprefix;
717 const char *prefix;
719 struct prefix_list *pl, **prev;
720 int len;
722 if (pprefix->plist)
724 for (pl = pprefix->plist; pl->next; pl = pl->next)
726 prev = &pl->next;
728 else
729 prev = &pprefix->plist;
731 /* Keep track of the longest prefix */
733 len = strlen (prefix);
734 if (len > pprefix->max_len)
735 pprefix->max_len = len;
737 pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
738 pl->prefix = xstrdup (prefix);
740 if (*prev)
741 pl->next = *prev;
742 else
743 pl->next = (struct prefix_list *) 0;
744 *prev = pl;
747 /* Take the value of the environment variable ENV, break it into a path, and
748 add of the entries to PPREFIX. */
750 static void
751 prefix_from_env (env, pprefix)
752 const char *env;
753 struct path_prefix *pprefix;
755 const char *p;
756 GET_ENV_PATH_LIST (p, env);
758 if (p)
759 prefix_from_string (p, pprefix);
762 static void
763 prefix_from_string (p, pprefix)
764 const char *p;
765 struct path_prefix *pprefix;
767 const char *startp, *endp;
768 char *nstore = (char *) xmalloc (strlen (p) + 3);
770 if (debug)
771 fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
773 startp = endp = p;
774 while (1)
776 if (*endp == PATH_SEPARATOR || *endp == 0)
778 strncpy (nstore, startp, endp-startp);
779 if (endp == startp)
781 strcpy (nstore, "./");
783 else if (! IS_DIR_SEPARATOR (endp[-1]))
785 nstore[endp-startp] = DIR_SEPARATOR;
786 nstore[endp-startp+1] = 0;
788 else
789 nstore[endp-startp] = 0;
791 if (debug)
792 fprintf (stderr, " - add prefix: %s\n", nstore);
794 add_prefix (pprefix, nstore);
795 if (*endp == 0)
796 break;
797 endp = startp = endp + 1;
799 else
800 endp++;
804 /* Main program. */
806 int main PARAMS ((int, char *[]));
808 main (argc, argv)
809 int argc;
810 char *argv[];
812 static const char *const ld_suffix = "ld";
813 static const char *const real_ld_suffix = "real-ld";
814 static const char *const collect_ld_suffix = "collect-ld";
815 static const char *const nm_suffix = "nm";
816 static const char *const gnm_suffix = "gnm";
817 #ifdef LDD_SUFFIX
818 static const char *const ldd_suffix = LDD_SUFFIX;
819 #endif
820 static const char *const strip_suffix = "strip";
821 static const char *const gstrip_suffix = "gstrip";
823 #ifdef CROSS_COMPILE
824 /* If we look for a program in the compiler directories, we just use
825 the short name, since these directories are already system-specific.
826 But it we look for a program in the system directories, we need to
827 qualify the program name with the target machine. */
829 const char *const full_ld_suffix =
830 concat(target_machine, "-", ld_suffix, NULL);
831 const char *const full_nm_suffix =
832 concat (target_machine, "-", nm_suffix, NULL);
833 const char *const full_gnm_suffix =
834 concat (target_machine, "-", gnm_suffix, NULL);
835 #ifdef LDD_SUFFIX
836 const char *const full_ldd_suffix =
837 concat (target_machine, "-", ldd_suffix, NULL);
838 #endif
839 const char *const full_strip_suffix =
840 concat (target_machine, "-", strip_suffix, NULL);
841 const char *const full_gstrip_suffix =
842 concat (target_machine, "-", gstrip_suffix, NULL);
843 #else
844 const char *const full_ld_suffix = ld_suffix;
845 const char *const full_nm_suffix = nm_suffix;
846 const char *const full_gnm_suffix = gnm_suffix;
847 #ifdef LDD_SUFFIX
848 const char *const full_ldd_suffix = ldd_suffix;
849 #endif
850 const char *const full_strip_suffix = strip_suffix;
851 const char *const full_gstrip_suffix = gstrip_suffix;
852 #endif /* CROSS_COMPILE */
854 const char *arg;
855 FILE *outf;
856 #ifdef COLLECT_EXPORT_LIST
857 FILE *exportf;
858 #endif
859 const char *ld_file_name;
860 const char *p;
861 char **c_argv;
862 const char **c_ptr;
863 char **ld1_argv;
864 const char **ld1;
865 char **ld2_argv;
866 const char **ld2;
867 char **object_lst;
868 const char **object;
869 int first_file;
870 int num_c_args = argc+9;
872 no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
874 /* Suppress demangling by the real linker, which may be broken. */
875 putenv (xstrdup ("COLLECT_NO_DEMANGLE="));
877 #if defined (COLLECT2_HOST_INITIALIZATION)
878 /* Perform system dependent initialization, if necessary. */
879 COLLECT2_HOST_INITIALIZATION;
880 #endif
882 #ifdef SIGCHLD
883 /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
884 receive the signal. A different setting is inheritable */
885 signal (SIGCHLD, SIG_DFL);
886 #endif
888 gcc_init_libintl ();
890 /* Do not invoke xcalloc before this point, since locale needs to be
891 set first, in case a diagnostic is issued. */
893 ld1 = (const char **)(ld1_argv = (char **) xcalloc(sizeof (char *), argc+3));
894 ld2 = (const char **)(ld2_argv = (char **) xcalloc(sizeof (char *), argc+10));
895 object = (const char **)(object_lst = (char **) xcalloc(sizeof (char *), argc));
897 #ifdef DEBUG
898 debug = 1;
899 #endif
901 /* Parse command line early for instances of -debug. This allows
902 the debug flag to be set before functions like find_a_file()
903 are called. */
905 int i;
907 for (i = 1; argv[i] != NULL; i ++)
908 if (! strcmp (argv[i], "-debug"))
909 debug = 1;
910 vflag = debug;
913 #ifndef DEFAULT_A_OUT_NAME
914 output_file = "a.out";
915 #else
916 output_file = DEFAULT_A_OUT_NAME;
917 #endif
919 obstack_begin (&temporary_obstack, 0);
920 obstack_begin (&permanent_obstack, 0);
921 temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
923 current_demangling_style = auto_demangling;
924 p = getenv ("COLLECT_GCC_OPTIONS");
925 while (p && *p)
927 const char *q = extract_string (&p);
928 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
929 num_c_args++;
931 obstack_free (&temporary_obstack, temporary_firstobj);
933 /* -fno-exceptions -w */
934 num_c_args += 2;
936 c_ptr = (const char **)
937 (c_argv = (char **) xcalloc (sizeof (char *), num_c_args));
939 if (argc < 2)
940 fatal ("no arguments");
942 #ifdef SIGQUIT
943 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
944 signal (SIGQUIT, handler);
945 #endif
946 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
947 signal (SIGINT, handler);
948 #ifdef SIGALRM
949 if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
950 signal (SIGALRM, handler);
951 #endif
952 #ifdef SIGHUP
953 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
954 signal (SIGHUP, handler);
955 #endif
956 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
957 signal (SIGSEGV, handler);
958 #ifdef SIGBUS
959 if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
960 signal (SIGBUS, handler);
961 #endif
963 /* Extract COMPILER_PATH and PATH into our prefix list. */
964 prefix_from_env ("COMPILER_PATH", &cpath);
965 prefix_from_env ("PATH", &path);
967 /* Try to discover a valid linker/nm/strip to use. */
969 /* Maybe we know the right file to use (if not cross). */
970 ld_file_name = 0;
971 #ifdef DEFAULT_LINKER
972 if (access (DEFAULT_LINKER, X_OK) == 0)
973 ld_file_name = DEFAULT_LINKER;
974 if (ld_file_name == 0)
975 #endif
976 #ifdef REAL_LD_FILE_NAME
977 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
978 if (ld_file_name == 0)
979 #endif
980 /* Search the (target-specific) compiler dirs for ld'. */
981 ld_file_name = find_a_file (&cpath, real_ld_suffix);
982 /* Likewise for `collect-ld'. */
983 if (ld_file_name == 0)
984 ld_file_name = find_a_file (&cpath, collect_ld_suffix);
985 /* Search the compiler directories for `ld'. We have protection against
986 recursive calls in find_a_file. */
987 if (ld_file_name == 0)
988 ld_file_name = find_a_file (&cpath, ld_suffix);
989 /* Search the ordinary system bin directories
990 for `ld' (if native linking) or `TARGET-ld' (if cross). */
991 if (ld_file_name == 0)
992 ld_file_name = find_a_file (&path, full_ld_suffix);
994 #ifdef REAL_NM_FILE_NAME
995 nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
996 if (nm_file_name == 0)
997 #endif
998 nm_file_name = find_a_file (&cpath, gnm_suffix);
999 if (nm_file_name == 0)
1000 nm_file_name = find_a_file (&path, full_gnm_suffix);
1001 if (nm_file_name == 0)
1002 nm_file_name = find_a_file (&cpath, nm_suffix);
1003 if (nm_file_name == 0)
1004 nm_file_name = find_a_file (&path, full_nm_suffix);
1006 #ifdef LDD_SUFFIX
1007 ldd_file_name = find_a_file (&cpath, ldd_suffix);
1008 if (ldd_file_name == 0)
1009 ldd_file_name = find_a_file (&path, full_ldd_suffix);
1010 #endif
1012 #ifdef REAL_STRIP_FILE_NAME
1013 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
1014 if (strip_file_name == 0)
1015 #endif
1016 strip_file_name = find_a_file (&cpath, gstrip_suffix);
1017 if (strip_file_name == 0)
1018 strip_file_name = find_a_file (&path, full_gstrip_suffix);
1019 if (strip_file_name == 0)
1020 strip_file_name = find_a_file (&cpath, strip_suffix);
1021 if (strip_file_name == 0)
1022 strip_file_name = find_a_file (&path, full_strip_suffix);
1024 /* Determine the full path name of the C compiler to use. */
1025 c_file_name = getenv ("COLLECT_GCC");
1026 if (c_file_name == 0)
1028 #ifdef CROSS_COMPILE
1029 c_file_name = concat (target_machine, "-gcc", NULL);
1030 #else
1031 c_file_name = "gcc";
1032 #endif
1035 p = find_a_file (&cpath, c_file_name);
1037 /* Here it should be safe to use the system search path since we should have
1038 already qualified the name of the compiler when it is needed. */
1039 if (p == 0)
1040 p = find_a_file (&path, c_file_name);
1042 if (p)
1043 c_file_name = p;
1045 *ld1++ = *ld2++ = ld_file_name;
1047 /* Make temp file names. */
1048 c_file = make_temp_file (".c");
1049 o_file = make_temp_file (".o");
1050 #ifdef COLLECT_EXPORT_LIST
1051 export_file = make_temp_file (".x");
1052 #endif
1053 ldout = make_temp_file (".ld");
1054 *c_ptr++ = c_file_name;
1055 *c_ptr++ = "-x";
1056 *c_ptr++ = "c";
1057 *c_ptr++ = "-c";
1058 *c_ptr++ = "-o";
1059 *c_ptr++ = o_file;
1061 #ifdef COLLECT_EXPORT_LIST
1062 /* Generate a list of directories from LIBPATH. */
1063 prefix_from_env ("LIBPATH", &libpath_lib_dirs);
1064 /* Add to this list also two standard directories where
1065 AIX loader always searches for libraries. */
1066 add_prefix (&libpath_lib_dirs, "/lib");
1067 add_prefix (&libpath_lib_dirs, "/usr/lib");
1068 #endif
1070 /* Get any options that the upper GCC wants to pass to the sub-GCC.
1072 AIX support needs to know if -shared has been specified before
1073 parsing commandline arguments. */
1075 p = getenv ("COLLECT_GCC_OPTIONS");
1076 while (p && *p)
1078 const char *q = extract_string (&p);
1079 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1080 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1081 if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0)
1082 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1083 if (strcmp (q, "-shared") == 0)
1084 shared_obj = 1;
1085 if (*q == '-' && q[1] == 'B')
1087 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1088 if (q[2] == 0)
1090 q = extract_string (&p);
1091 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1095 obstack_free (&temporary_obstack, temporary_firstobj);
1096 *c_ptr++ = "-fno-exceptions";
1097 *c_ptr++ = "-w";
1099 /* !!! When GCC calls collect2,
1100 it does not know whether it is calling collect2 or ld.
1101 So collect2 cannot meaningfully understand any options
1102 except those ld understands.
1103 If you propose to make GCC pass some other option,
1104 just imagine what will happen if ld is really ld!!! */
1106 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1107 /* After the first file, put in the c++ rt0. */
1109 first_file = 1;
1110 while ((arg = *++argv) != (char *) 0)
1112 *ld1++ = *ld2++ = arg;
1114 if (arg[0] == '-')
1116 switch (arg[1])
1118 #ifdef COLLECT_EXPORT_LIST
1119 /* We want to disable automatic exports on AIX when user
1120 explicitly puts an export list in command line */
1121 case 'b':
1122 if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
1123 export_flag = 1;
1124 else if (arg[2] == '6' && arg[3] == '4')
1125 aix64_flag = 1;
1126 break;
1127 #endif
1129 case 'd':
1130 if (!strcmp (arg, "-debug"))
1132 /* Already parsed. */
1133 ld1--;
1134 ld2--;
1136 break;
1138 case 'l':
1139 if (first_file)
1141 /* place o_file BEFORE this argument! */
1142 first_file = 0;
1143 ld2--;
1144 *ld2++ = o_file;
1145 *ld2++ = arg;
1147 #ifdef COLLECT_EXPORT_LIST
1149 /* Resolving full library name. */
1150 const char *s = resolve_lib_name (arg+2);
1152 /* Saving a full library name. */
1153 add_to_list (&libs, s);
1155 #endif
1156 break;
1158 #ifdef COLLECT_EXPORT_LIST
1159 /* Saving directories where to search for libraries. */
1160 case 'L':
1161 add_prefix (&cmdline_lib_dirs, arg+2);
1162 break;
1163 #else
1164 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1165 case 'L':
1166 if (is_in_args (arg, (const char **) ld1_argv, ld1-1))
1167 --ld1;
1168 break;
1169 #endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1170 #endif
1172 case 'o':
1173 if (arg[2] == '\0')
1174 output_file = *ld1++ = *ld2++ = *++argv;
1175 else if (1
1176 #ifdef SWITCHES_NEED_SPACES
1177 && ! strchr (SWITCHES_NEED_SPACES, arg[1])
1178 #endif
1181 output_file = &arg[2];
1182 break;
1184 case 'r':
1185 if (arg[2] == '\0')
1186 rflag = 1;
1187 break;
1189 case 's':
1190 if (arg[2] == '\0' && do_collecting)
1192 /* We must strip after the nm run, otherwise C++ linking
1193 will not work. Thus we strip in the second ld run, or
1194 else with strip if there is no second ld run. */
1195 strip_flag = 1;
1196 ld1--;
1198 break;
1200 case 'v':
1201 if (arg[2] == '\0')
1202 vflag = 1;
1203 break;
1206 else if ((p = strrchr (arg, '.')) != (char *) 0
1207 && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
1208 || strcmp (p, ".so") == 0 || strcmp (p, ".lo") == 0
1209 || strcmp (p, ".obj") == 0))
1211 if (first_file)
1213 first_file = 0;
1214 if (p[1] == 'o')
1215 *ld2++ = o_file;
1216 else
1218 /* place o_file BEFORE this argument! */
1219 ld2--;
1220 *ld2++ = o_file;
1221 *ld2++ = arg;
1224 if (p[1] == 'o' || p[1] == 'l')
1225 *object++ = arg;
1226 #ifdef COLLECT_EXPORT_LIST
1227 /* libraries can be specified directly, i.e. without -l flag. */
1228 else
1230 /* Saving a full library name. */
1231 add_to_list (&libs, arg);
1233 #endif
1237 #ifdef COLLECT_EXPORT_LIST
1238 /* This is added only for debugging purposes. */
1239 if (debug)
1241 fprintf (stderr, "List of libraries:\n");
1242 dump_list (stderr, "\t", libs.first);
1245 /* The AIX linker will discard static constructors in object files if
1246 nothing else in the file is referenced, so look at them first. */
1248 const char **export_object_lst = (const char **)object_lst;
1250 while (export_object_lst < object)
1251 scan_prog_file (*export_object_lst++, PASS_OBJ);
1254 struct id *list = libs.first;
1256 for (; list; list = list->next)
1257 scan_prog_file (list->name, PASS_FIRST);
1260 if (exports.first)
1262 char *buf = concat ("-bE:", export_file, NULL);
1264 *ld1++ = buf;
1265 *ld2++ = buf;
1267 exportf = fopen (export_file, "w");
1268 if (exportf == (FILE *) 0)
1269 fatal_perror ("fopen %s", export_file);
1270 write_aix_file (exportf, exports.first);
1271 if (fclose (exportf))
1272 fatal_perror ("fclose %s", export_file);
1274 #endif
1276 *c_ptr++ = c_file;
1277 *c_ptr = *ld1 = *object = (char *) 0;
1279 if (vflag)
1281 notice ("collect2 version %s", version_string);
1282 #ifdef TARGET_VERSION
1283 TARGET_VERSION;
1284 #endif
1285 fprintf (stderr, "\n");
1288 if (debug)
1290 const char *ptr;
1291 fprintf (stderr, "ld_file_name = %s\n",
1292 (ld_file_name ? ld_file_name : "not found"));
1293 fprintf (stderr, "c_file_name = %s\n",
1294 (c_file_name ? c_file_name : "not found"));
1295 fprintf (stderr, "nm_file_name = %s\n",
1296 (nm_file_name ? nm_file_name : "not found"));
1297 #ifdef LDD_SUFFIX
1298 fprintf (stderr, "ldd_file_name = %s\n",
1299 (ldd_file_name ? ldd_file_name : "not found"));
1300 #endif
1301 fprintf (stderr, "strip_file_name = %s\n",
1302 (strip_file_name ? strip_file_name : "not found"));
1303 fprintf (stderr, "c_file = %s\n",
1304 (c_file ? c_file : "not found"));
1305 fprintf (stderr, "o_file = %s\n",
1306 (o_file ? o_file : "not found"));
1308 ptr = getenv ("COLLECT_GCC_OPTIONS");
1309 if (ptr)
1310 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1312 ptr = getenv ("COLLECT_GCC");
1313 if (ptr)
1314 fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
1316 ptr = getenv ("COMPILER_PATH");
1317 if (ptr)
1318 fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
1320 ptr = getenv (LIBRARY_PATH_ENV);
1321 if (ptr)
1322 fprintf (stderr, "%-20s= %s\n", LIBRARY_PATH_ENV, ptr);
1324 fprintf (stderr, "\n");
1327 /* Load the program, searching all libraries and attempting to provide
1328 undefined symbols from repository information. */
1330 /* On AIX we do this later. */
1331 #ifndef COLLECT_EXPORT_LIST
1332 do_tlink (ld1_argv, object_lst);
1333 #endif
1335 /* If -r or they will be run via some other method, do not build the
1336 constructor or destructor list, just return now. */
1337 if (rflag
1338 #ifndef COLLECT_EXPORT_LIST
1339 || ! do_collecting
1340 #endif
1343 #ifdef COLLECT_EXPORT_LIST
1344 /* Do the link we avoided above if we are exiting. */
1345 do_tlink (ld1_argv, object_lst);
1347 /* But make sure we delete the export file we may have created. */
1348 if (export_file != 0 && export_file[0])
1349 maybe_unlink (export_file);
1350 #endif
1351 maybe_unlink (c_file);
1352 maybe_unlink (o_file);
1353 return 0;
1356 /* Examine the namelist with nm and search it for static constructors
1357 and destructors to call.
1358 Write the constructor and destructor tables to a .s file and reload. */
1360 /* On AIX we already scanned for global constructors/destructors. */
1361 #ifndef COLLECT_EXPORT_LIST
1362 scan_prog_file (output_file, PASS_FIRST);
1363 #endif
1365 #ifdef SCAN_LIBRARIES
1366 scan_libraries (output_file);
1367 #endif
1369 if (debug)
1371 notice ("%d constructor(s) found\n", constructors.number);
1372 notice ("%d destructor(s) found\n", destructors.number);
1373 notice ("%d frame table(s) found\n", frame_tables.number);
1376 if (constructors.number == 0 && destructors.number == 0
1377 && frame_tables.number == 0
1378 #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1379 /* If we will be running these functions ourselves, we want to emit
1380 stubs into the shared library so that we do not have to relink
1381 dependent programs when we add static objects. */
1382 && ! shared_obj
1383 #endif
1386 #ifdef COLLECT_EXPORT_LIST
1387 /* Do tlink without additional code generation */
1388 do_tlink (ld1_argv, object_lst);
1389 #endif
1390 /* Strip now if it was requested on the command line. */
1391 if (strip_flag)
1393 char **real_strip_argv = (char **) xcalloc (sizeof (char *), 3);
1394 const char ** strip_argv = (const char **) real_strip_argv;
1396 strip_argv[0] = strip_file_name;
1397 strip_argv[1] = output_file;
1398 strip_argv[2] = (char *) 0;
1399 fork_execute ("strip", real_strip_argv);
1402 #ifdef COLLECT_EXPORT_LIST
1403 maybe_unlink (export_file);
1404 #endif
1405 maybe_unlink (c_file);
1406 maybe_unlink (o_file);
1407 return 0;
1410 /* Sort ctor and dtor lists by priority. */
1411 sort_ids (&constructors);
1412 sort_ids (&destructors);
1414 maybe_unlink(output_file);
1415 outf = fopen (c_file, "w");
1416 if (outf == (FILE *) 0)
1417 fatal_perror ("fopen %s", c_file);
1419 write_c_file (outf, c_file);
1421 if (fclose (outf))
1422 fatal_perror ("fclose %s", c_file);
1424 /* Tell the linker that we have initializer and finalizer functions. */
1425 #ifdef LD_INIT_SWITCH
1426 #ifdef COLLECT_EXPORT_LIST
1427 *ld2++ = concat (LD_INIT_SWITCH, ":", initname, ":", fininame, NULL);
1428 #else
1429 *ld2++ = LD_INIT_SWITCH;
1430 *ld2++ = initname;
1431 *ld2++ = LD_FINI_SWITCH;
1432 *ld2++ = fininame;
1433 #endif
1434 #endif
1436 #ifdef COLLECT_EXPORT_LIST
1437 if (shared_obj)
1439 /* If we did not add export flag to link arguments before, add it to
1440 second link phase now. No new exports should have been added. */
1441 if (! exports.first)
1442 *ld2++ = concat ("-bE:", export_file, NULL);
1444 add_to_list (&exports, initname);
1445 add_to_list (&exports, fininame);
1446 add_to_list (&exports, "_GLOBAL__DI");
1447 add_to_list (&exports, "_GLOBAL__DD");
1448 exportf = fopen (export_file, "w");
1449 if (exportf == (FILE *) 0)
1450 fatal_perror ("fopen %s", export_file);
1451 write_aix_file (exportf, exports.first);
1452 if (fclose (exportf))
1453 fatal_perror ("fclose %s", export_file);
1455 #endif
1457 /* End of arguments to second link phase. */
1458 *ld2 = (char*) 0;
1460 if (debug)
1462 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1463 output_file, c_file);
1464 write_c_file (stderr, "stderr");
1465 fprintf (stderr, "========== end of c_file\n\n");
1466 #ifdef COLLECT_EXPORT_LIST
1467 fprintf (stderr, "\n========== export_file = %s\n", export_file);
1468 write_aix_file (stderr, exports.first);
1469 fprintf (stderr, "========== end of export_file\n\n");
1470 #endif
1473 /* Assemble the constructor and destructor tables.
1474 Link the tables in with the rest of the program. */
1476 fork_execute ("gcc", c_argv);
1477 #ifdef COLLECT_EXPORT_LIST
1478 /* On AIX we must call tlink because of possible templates resolution */
1479 do_tlink (ld2_argv, object_lst);
1480 #else
1481 /* Otherwise, simply call ld because tlink is already done */
1482 fork_execute ("ld", ld2_argv);
1484 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1485 constructors/destructors in shared libraries. */
1486 scan_prog_file (output_file, PASS_SECOND);
1487 #endif
1489 maybe_unlink (c_file);
1490 maybe_unlink (o_file);
1492 #ifdef COLLECT_EXPORT_LIST
1493 maybe_unlink (export_file);
1494 #endif
1496 return 0;
1500 /* Wait for a process to finish, and exit if a non-zero status is found. */
1503 collect_wait (prog)
1504 const char *prog;
1506 int status;
1508 pwait (pexecute_pid, &status, 0);
1509 if (status)
1511 if (WIFSIGNALED (status))
1513 int sig = WTERMSIG (status);
1514 error ("%s terminated with signal %d [%s]%s",
1515 prog, sig, strsignal(sig),
1516 status & 0200 ? "" : ", core dumped");
1517 collect_exit (FATAL_EXIT_CODE);
1520 if (WIFEXITED (status))
1521 return WEXITSTATUS (status);
1523 return 0;
1526 static void
1527 do_wait (prog)
1528 const char *prog;
1530 int ret = collect_wait (prog);
1531 if (ret != 0)
1533 error ("%s returned %d exit status", prog, ret);
1534 collect_exit (ret);
1539 /* Execute a program, and wait for the reply. */
1541 void
1542 collect_execute (prog, argv, redir)
1543 const char *prog;
1544 char **argv;
1545 const char *redir;
1547 char *errmsg_fmt;
1548 char *errmsg_arg;
1549 int redir_handle = -1;
1550 int stdout_save = -1;
1551 int stderr_save = -1;
1553 if (vflag || debug)
1555 char **p_argv;
1556 const char *str;
1558 if (argv[0])
1559 fprintf (stderr, "%s", argv[0]);
1560 else
1561 notice ("[cannot find %s]", prog);
1563 for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
1564 fprintf (stderr, " %s", str);
1566 fprintf (stderr, "\n");
1569 fflush (stdout);
1570 fflush (stderr);
1572 /* If we cannot find a program we need, complain error. Do this here
1573 since we might not end up needing something that we could not find. */
1575 if (argv[0] == 0)
1576 fatal ("cannot find `%s'", prog);
1578 if (redir)
1580 /* Open response file. */
1581 redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT);
1583 /* Duplicate the stdout and stderr file handles
1584 so they can be restored later. */
1585 stdout_save = dup (STDOUT_FILENO);
1586 if (stdout_save == -1)
1587 fatal_perror ("redirecting stdout: %s", redir);
1588 stderr_save = dup (STDERR_FILENO);
1589 if (stderr_save == -1)
1590 fatal_perror ("redirecting stdout: %s", redir);
1592 /* Redirect stdout & stderr to our response file. */
1593 dup2 (redir_handle, STDOUT_FILENO);
1594 dup2 (redir_handle, STDERR_FILENO);
1597 pexecute_pid = pexecute (argv[0], argv, argv[0], NULL,
1598 &errmsg_fmt, &errmsg_arg,
1599 (PEXECUTE_FIRST | PEXECUTE_LAST | PEXECUTE_SEARCH));
1601 if (redir)
1603 /* Restore stdout and stderr to their previous settings. */
1604 dup2 (stdout_save, STDOUT_FILENO);
1605 dup2 (stderr_save, STDERR_FILENO);
1607 /* Close response file. */
1608 close (redir_handle);
1611 if (pexecute_pid == -1)
1612 fatal_perror (errmsg_fmt, errmsg_arg);
1615 static void
1616 fork_execute (prog, argv)
1617 const char *prog;
1618 char **argv;
1620 collect_execute (prog, argv, NULL);
1621 do_wait (prog);
1624 /* Unlink a file unless we are debugging. */
1626 static void
1627 maybe_unlink (file)
1628 const char *file;
1630 if (!debug)
1631 unlink (file);
1632 else
1633 notice ("[Leaving %s]\n", file);
1637 static long sequence_number = 0;
1639 /* Add a name to a linked list. */
1641 static void
1642 add_to_list (head_ptr, name)
1643 struct head *head_ptr;
1644 const char *name;
1646 struct id *newid
1647 = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
1648 struct id *p;
1649 strcpy (newid->name, name);
1651 if (head_ptr->first)
1652 head_ptr->last->next = newid;
1653 else
1654 head_ptr->first = newid;
1656 /* Check for duplicate symbols. */
1657 for (p = head_ptr->first;
1658 strcmp (name, p->name) != 0;
1659 p = p->next)
1661 if (p != newid)
1663 head_ptr->last->next = 0;
1664 free (newid);
1665 return;
1668 newid->sequence = ++sequence_number;
1669 head_ptr->last = newid;
1670 head_ptr->number++;
1673 /* Grab the init priority number from an init function name that
1674 looks like "_GLOBAL_.I.12345.foo". */
1676 static int
1677 extract_init_priority (name)
1678 const char *name;
1680 int pos = 0, pri;
1682 while (name[pos] == '_')
1683 ++pos;
1684 pos += 10; /* strlen ("GLOBAL__X_") */
1686 /* Extract init_p number from ctor/dtor name. */
1687 pri = atoi (name + pos);
1688 return pri ? pri : DEFAULT_INIT_PRIORITY;
1691 /* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
1692 ctors will be run from right to left, dtors from left to right. */
1694 static void
1695 sort_ids (head_ptr)
1696 struct head *head_ptr;
1698 /* id holds the current element to insert. id_next holds the next
1699 element to insert. id_ptr iterates through the already sorted elements
1700 looking for the place to insert id. */
1701 struct id *id, *id_next, **id_ptr;
1703 id = head_ptr->first;
1705 /* We don't have any sorted elements yet. */
1706 head_ptr->first = NULL;
1708 for (; id; id = id_next)
1710 id_next = id->next;
1711 id->sequence = extract_init_priority (id->name);
1713 for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next))
1714 if (*id_ptr == NULL
1715 /* If the sequence numbers are the same, we put the id from the
1716 file later on the command line later in the list. */
1717 || id->sequence > (*id_ptr)->sequence
1718 /* Hack: do lexical compare, too.
1719 || (id->sequence == (*id_ptr)->sequence
1720 && strcmp (id->name, (*id_ptr)->name) > 0) */
1723 id->next = *id_ptr;
1724 *id_ptr = id;
1725 break;
1729 /* Now set the sequence numbers properly so write_c_file works. */
1730 for (id = head_ptr->first; id; id = id->next)
1731 id->sequence = ++sequence_number;
1734 /* Write: `prefix', the names on list LIST, `suffix'. */
1736 static void
1737 write_list (stream, prefix, list)
1738 FILE *stream;
1739 const char *prefix;
1740 struct id *list;
1742 while (list)
1744 fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1745 list = list->next;
1749 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1750 /* Given a STRING, return nonzero if it occurs in the list in range
1751 [ARGS_BEGIN,ARGS_END). */
1753 static int
1754 is_in_args (string, args_begin, args_end)
1755 const char *string;
1756 const char **args_begin;
1757 const char **args_end;
1759 const char **args_pointer;
1760 for (args_pointer = args_begin; args_pointer != args_end; ++args_pointer)
1761 if (strcmp (string, *args_pointer) == 0)
1762 return 1;
1763 return 0;
1765 #endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1767 #ifdef COLLECT_EXPORT_LIST
1768 /* This function is really used only on AIX, but may be useful. */
1769 #if 0
1770 static int
1771 is_in_list (prefix, list)
1772 const char *prefix;
1773 struct id *list;
1775 while (list)
1777 if (!strcmp (prefix, list->name)) return 1;
1778 list = list->next;
1780 return 0;
1782 #endif
1783 #endif /* COLLECT_EXPORT_LIST */
1785 /* Added for debugging purpose. */
1786 #ifdef COLLECT_EXPORT_LIST
1787 static void
1788 dump_list (stream, prefix, list)
1789 FILE *stream;
1790 const char *prefix;
1791 struct id *list;
1793 while (list)
1795 fprintf (stream, "%s%s,\n", prefix, list->name);
1796 list = list->next;
1799 #endif
1801 #if 0
1802 static void
1803 dump_prefix_list (stream, prefix, list)
1804 FILE *stream;
1805 const char *prefix;
1806 struct prefix_list *list;
1808 while (list)
1810 fprintf (stream, "%s%s,\n", prefix, list->prefix);
1811 list = list->next;
1814 #endif
1816 static void
1817 write_list_with_asm (stream, prefix, list)
1818 FILE *stream;
1819 const char *prefix;
1820 struct id *list;
1822 while (list)
1824 fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1825 prefix, list->sequence, list->name);
1826 list = list->next;
1830 /* Write out the constructor and destructor tables statically (for a shared
1831 object), along with the functions to execute them. */
1833 static void
1834 write_c_file_stat (stream, name)
1835 FILE *stream;
1836 const char *name ATTRIBUTE_UNUSED;
1838 const char *p, *q;
1839 char *prefix, *r;
1840 int frames = (frame_tables.number > 0);
1842 /* Figure out name of output_file, stripping off .so version. */
1843 p = strrchr (output_file, '/');
1844 if (p == 0)
1845 p = output_file;
1846 else
1847 p++;
1848 q = p;
1849 while (q)
1851 q = strchr (q,'.');
1852 if (q == 0)
1854 q = p + strlen (p);
1855 break;
1857 else
1859 if (strncmp (q, ".so", 3) == 0)
1861 q += 3;
1862 break;
1864 else
1865 q++;
1868 /* q points to null at end of the string (or . of the .so version) */
1869 prefix = xmalloc (q - p + 1);
1870 strncpy (prefix, p, q - p);
1871 prefix[q - p] = 0;
1872 for (r = prefix; *r; r++)
1873 if (!ISALNUM ((unsigned char)*r))
1874 *r = '_';
1875 if (debug)
1876 notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
1877 output_file, prefix);
1879 initname = concat ("_GLOBAL__FI_", prefix, NULL);
1880 fininame = concat ("_GLOBAL__FD_", prefix, NULL);
1882 free (prefix);
1884 /* Write the tables as C code */
1886 fprintf (stream, "static int count;\n");
1887 fprintf (stream, "typedef void entry_pt();\n");
1888 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1890 if (frames)
1892 write_list_with_asm (stream, "extern void *", frame_tables.first);
1894 fprintf (stream, "\tstatic void *frame_table[] = {\n");
1895 write_list (stream, "\t\t&", frame_tables.first);
1896 fprintf (stream, "\t0\n};\n");
1898 /* This must match what's in frame.h. */
1899 fprintf (stream, "struct object {\n");
1900 fprintf (stream, " void *pc_begin;\n");
1901 fprintf (stream, " void *pc_end;\n");
1902 fprintf (stream, " void *fde_begin;\n");
1903 fprintf (stream, " void *fde_array;\n");
1904 fprintf (stream, " __SIZE_TYPE__ count;\n");
1905 fprintf (stream, " struct object *next;\n");
1906 fprintf (stream, "};\n");
1908 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
1909 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
1911 fprintf (stream, "static void reg_frame () {\n");
1912 fprintf (stream, "\tstatic struct object ob;\n");
1913 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
1914 fprintf (stream, "\t}\n");
1916 fprintf (stream, "static void dereg_frame () {\n");
1917 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
1918 fprintf (stream, "\t}\n");
1921 fprintf (stream, "void %s() {\n", initname);
1922 if (constructors.number > 0 || frames)
1924 fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
1925 write_list (stream, "\t\t", constructors.first);
1926 if (frames)
1927 fprintf (stream, "\treg_frame,\n");
1928 fprintf (stream, "\t};\n");
1929 fprintf (stream, "\tentry_pt **p;\n");
1930 fprintf (stream, "\tif (count++ != 0) return;\n");
1931 fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
1932 fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
1934 else
1935 fprintf (stream, "\t++count;\n");
1936 fprintf (stream, "}\n");
1937 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1938 fprintf (stream, "void %s() {\n", fininame);
1939 if (destructors.number > 0 || frames)
1941 fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
1942 write_list (stream, "\t\t", destructors.first);
1943 if (frames)
1944 fprintf (stream, "\tdereg_frame,\n");
1945 fprintf (stream, "\t};\n");
1946 fprintf (stream, "\tentry_pt **p;\n");
1947 fprintf (stream, "\tif (--count != 0) return;\n");
1948 fprintf (stream, "\tp = dtors;\n");
1949 fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
1950 destructors.number + frames);
1952 fprintf (stream, "}\n");
1954 if (shared_obj)
1956 COLLECT_SHARED_INIT_FUNC(stream, initname);
1957 COLLECT_SHARED_FINI_FUNC(stream, fininame);
1961 /* Write the constructor/destructor tables. */
1963 #ifndef LD_INIT_SWITCH
1964 static void
1965 write_c_file_glob (stream, name)
1966 FILE *stream;
1967 const char *name ATTRIBUTE_UNUSED;
1969 /* Write the tables as C code */
1971 int frames = (frame_tables.number > 0);
1973 fprintf (stream, "typedef void entry_pt();\n\n");
1975 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1977 if (frames)
1979 write_list_with_asm (stream, "extern void *", frame_tables.first);
1981 fprintf (stream, "\tstatic void *frame_table[] = {\n");
1982 write_list (stream, "\t\t&", frame_tables.first);
1983 fprintf (stream, "\t0\n};\n");
1985 /* This must match what's in frame.h. */
1986 fprintf (stream, "struct object {\n");
1987 fprintf (stream, " void *pc_begin;\n");
1988 fprintf (stream, " void *pc_end;\n");
1989 fprintf (stream, " void *fde_begin;\n");
1990 fprintf (stream, " void *fde_array;\n");
1991 fprintf (stream, " __SIZE_TYPE__ count;\n");
1992 fprintf (stream, " struct object *next;\n");
1993 fprintf (stream, "};\n");
1995 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
1996 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
1998 fprintf (stream, "static void reg_frame () {\n");
1999 fprintf (stream, "\tstatic struct object ob;\n");
2000 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
2001 fprintf (stream, "\t}\n");
2003 fprintf (stream, "static void dereg_frame () {\n");
2004 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
2005 fprintf (stream, "\t}\n");
2008 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
2009 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
2010 write_list (stream, "\t", constructors.first);
2011 if (frames)
2012 fprintf (stream, "\treg_frame,\n");
2013 fprintf (stream, "\t0\n};\n\n");
2015 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
2017 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
2018 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
2019 write_list (stream, "\t", destructors.first);
2020 if (frames)
2021 fprintf (stream, "\tdereg_frame,\n");
2022 fprintf (stream, "\t0\n};\n\n");
2024 fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
2025 fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
2027 #endif /* ! LD_INIT_SWITCH */
2029 static void
2030 write_c_file (stream, name)
2031 FILE *stream;
2032 const char *name;
2034 fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
2035 #ifndef LD_INIT_SWITCH
2036 if (! shared_obj)
2037 write_c_file_glob (stream, name);
2038 else
2039 #endif
2040 write_c_file_stat (stream, name);
2041 fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
2044 #ifdef COLLECT_EXPORT_LIST
2045 static void
2046 write_aix_file (stream, list)
2047 FILE *stream;
2048 struct id *list;
2050 for (; list; list = list->next)
2052 fputs (list->name, stream);
2053 putc ('\n', stream);
2056 #endif
2058 #ifdef OBJECT_FORMAT_NONE
2060 /* Generic version to scan the name list of the loaded program for
2061 the symbols g++ uses for static constructors and destructors.
2063 The constructor table begins at __CTOR_LIST__ and contains a count
2064 of the number of pointers (or -1 if the constructors are built in a
2065 separate section by the linker), followed by the pointers to the
2066 constructor functions, terminated with a null pointer. The
2067 destructor table has the same format, and begins at __DTOR_LIST__. */
2069 static void
2070 scan_prog_file (prog_name, which_pass)
2071 const char *prog_name;
2072 enum pass which_pass;
2074 void (*int_handler) PARAMS ((int));
2075 void (*quit_handler) PARAMS ((int));
2076 char *real_nm_argv[4];
2077 const char **nm_argv = (const char **) real_nm_argv;
2078 int pid;
2079 int argc = 0;
2080 int pipe_fd[2];
2081 char *p, buf[1024];
2082 FILE *inf;
2084 if (which_pass == PASS_SECOND)
2085 return;
2087 /* If we do not have an `nm', complain. */
2088 if (nm_file_name == 0)
2089 fatal ("cannot find `nm'");
2091 nm_argv[argc++] = nm_file_name;
2092 if (NM_FLAGS[0] != '\0')
2093 nm_argv[argc++] = NM_FLAGS;
2095 nm_argv[argc++] = prog_name;
2096 nm_argv[argc++] = (char *) 0;
2098 if (pipe (pipe_fd) < 0)
2099 fatal_perror ("pipe");
2101 inf = fdopen (pipe_fd[0], "r");
2102 if (inf == (FILE *) 0)
2103 fatal_perror ("fdopen");
2105 /* Trace if needed. */
2106 if (vflag)
2108 const char **p_argv;
2109 const char *str;
2111 for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2112 fprintf (stderr, " %s", str);
2114 fprintf (stderr, "\n");
2117 fflush (stdout);
2118 fflush (stderr);
2120 /* Spawn child nm on pipe */
2121 pid = vfork ();
2122 if (pid == -1)
2123 fatal_perror (VFORK_STRING);
2125 if (pid == 0) /* child context */
2127 /* setup stdout */
2128 if (dup2 (pipe_fd[1], 1) < 0)
2129 fatal_perror ("dup2 %d 1", pipe_fd[1]);
2131 if (close (pipe_fd[0]) < 0)
2132 fatal_perror ("close %d", pipe_fd[0]);
2134 if (close (pipe_fd[1]) < 0)
2135 fatal_perror ("close %d", pipe_fd[1]);
2137 execv (nm_file_name, real_nm_argv);
2138 fatal_perror ("execvp %s", nm_file_name);
2141 /* Parent context from here on. */
2142 int_handler = (void (*) PARAMS ((int))) signal (SIGINT, SIG_IGN);
2143 #ifdef SIGQUIT
2144 quit_handler = (void (*) PARAMS ((int))) signal (SIGQUIT, SIG_IGN);
2145 #endif
2147 if (close (pipe_fd[1]) < 0)
2148 fatal_perror ("close %d", pipe_fd[1]);
2150 if (debug)
2151 fprintf (stderr, "\nnm output with constructors/destructors.\n");
2153 /* Read each line of nm output. */
2154 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2156 int ch, ch2;
2157 char *name, *end;
2159 /* If it contains a constructor or destructor name, add the name
2160 to the appropriate list. */
2162 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
2163 if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
2164 break;
2166 if (ch != '_')
2167 continue;
2169 name = p;
2170 /* Find the end of the symbol name.
2171 Do not include `|', because Encore nm can tack that on the end. */
2172 for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|';
2173 end++)
2174 continue;
2177 *end = '\0';
2178 switch (is_ctor_dtor (name))
2180 case 1:
2181 if (which_pass != PASS_LIB)
2182 add_to_list (&constructors, name);
2183 break;
2185 case 2:
2186 if (which_pass != PASS_LIB)
2187 add_to_list (&destructors, name);
2188 break;
2190 case 3:
2191 if (which_pass != PASS_LIB)
2192 fatal ("init function found in object %s", prog_name);
2193 #ifndef LD_INIT_SWITCH
2194 add_to_list (&constructors, name);
2195 #endif
2196 break;
2198 case 4:
2199 if (which_pass != PASS_LIB)
2200 fatal ("fini function found in object %s", prog_name);
2201 #ifndef LD_FINI_SWITCH
2202 add_to_list (&destructors, name);
2203 #endif
2204 break;
2206 case 5:
2207 if (which_pass != PASS_LIB)
2208 add_to_list (&frame_tables, name);
2209 break;
2211 default: /* not a constructor or destructor */
2212 continue;
2215 if (debug)
2216 fprintf (stderr, "\t%s\n", buf);
2219 if (debug)
2220 fprintf (stderr, "\n");
2222 if (fclose (inf) != 0)
2223 fatal_perror ("fclose");
2225 do_wait (nm_file_name);
2227 signal (SIGINT, int_handler);
2228 #ifdef SIGQUIT
2229 signal (SIGQUIT, quit_handler);
2230 #endif
2233 #if SUNOS4_SHARED_LIBRARIES
2235 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2236 that the output file depends upon and their initialization/finalization
2237 routines, if any. */
2239 #include <a.out.h>
2240 #include <fcntl.h>
2241 #include <link.h>
2242 #include <sys/mman.h>
2243 #include <sys/param.h>
2244 #include <unistd.h>
2245 #include <sys/dir.h>
2247 /* pointers to the object file */
2248 unsigned object; /* address of memory mapped file */
2249 unsigned objsize; /* size of memory mapped to file */
2250 char * code; /* pointer to code segment */
2251 char * data; /* pointer to data segment */
2252 struct nlist *symtab; /* pointer to symbol table */
2253 struct link_dynamic *ld;
2254 struct link_dynamic_2 *ld_2;
2255 struct head libraries;
2257 /* Map the file indicated by NAME into memory and store its address. */
2259 static void mapfile PARAMS ((const char *));
2261 static void
2262 mapfile (name)
2263 const char *name;
2265 int fp;
2266 struct stat s;
2267 if ((fp = open (name, O_RDONLY)) == -1)
2268 fatal ("unable to open file '%s'", name);
2269 if (fstat (fp, &s) == -1)
2270 fatal ("unable to stat file '%s'", name);
2272 objsize = s.st_size;
2273 object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE,
2274 fp, 0);
2275 if (object == (unsigned)-1)
2276 fatal ("unable to mmap file '%s'", name);
2278 close (fp);
2281 /* Helpers for locatelib. */
2283 static const char *libname;
2285 static int libselect PARAMS ((struct direct *));
2287 static int
2288 libselect (d)
2289 struct direct *d;
2291 return (strncmp (libname, d->d_name, strlen (libname)) == 0);
2294 /* If one file has an additional numeric extension past LIBNAME, then put
2295 that one first in the sort. If both files have additional numeric
2296 extensions, then put the one with the higher number first in the sort.
2298 We must verify that the extension is numeric, because Sun saves the
2299 original versions of patched libraries with a .FCS extension. Files with
2300 invalid extensions must go last in the sort, so that they will not be used. */
2301 static int libcompare PARAMS ((struct direct **, struct direct **));
2303 static int
2304 libcompare (d1, d2)
2305 struct direct **d1, **d2;
2307 int i1, i2 = strlen (libname);
2308 char *e1 = (*d1)->d_name + i2;
2309 char *e2 = (*d2)->d_name + i2;
2311 while (*e1 && *e2 && *e1 == '.' && *e2 == '.'
2312 && e1[1] && ISDIGIT (e1[1]) && e2[1] && ISDIGIT (e2[1]))
2314 ++e1;
2315 ++e2;
2316 i1 = strtol (e1, &e1, 10);
2317 i2 = strtol (e2, &e2, 10);
2318 if (i1 != i2)
2319 return i1 - i2;
2322 if (*e1)
2324 /* It has a valid numeric extension, prefer this one. */
2325 if (*e1 == '.' && e1[1] && ISDIGIT (e1[1]))
2326 return 1;
2327 /* It has an invalid numeric extension, must prefer the other one. */
2328 else
2329 return -1;
2331 else if (*e2)
2333 /* It has a valid numeric extension, prefer this one. */
2334 if (*e2 == '.' && e2[1] && ISDIGIT (e2[1]))
2335 return -1;
2336 /* It has an invalid numeric extension, must prefer the other one. */
2337 else
2338 return 1;
2340 else
2341 return 0;
2344 /* Given the name NAME of a dynamic dependency, find its pathname and add
2345 it to the list of libraries. */
2346 static void locatelib PARAMS ((const char *));
2348 static void
2349 locatelib (name)
2350 const char *name;
2352 static const char **l;
2353 static int cnt;
2354 char buf[MAXPATHLEN];
2355 char *p, *q;
2356 const char **pp;
2358 if (l == 0)
2360 char *ld_rules;
2361 char *ldr = 0;
2362 /* counting elements in array, need 1 extra for null */
2363 cnt = 1;
2364 ld_rules = (char *) (ld_2->ld_rules + code);
2365 if (ld_rules)
2367 cnt++;
2368 for (; *ld_rules != 0; ld_rules++)
2369 if (*ld_rules == ':')
2370 cnt++;
2371 ld_rules = (char *) (ld_2->ld_rules + code);
2372 ldr = xstrdup (ld_rules);
2374 p = getenv ("LD_LIBRARY_PATH");
2375 q = 0;
2376 if (p)
2378 cnt++;
2379 for (q = p ; *q != 0; q++)
2380 if (*q == ':')
2381 cnt++;
2382 q = xstrdup (p);
2384 l = (const char **) xmalloc ((cnt + 3) * sizeof (char *));
2385 pp = l;
2386 if (ldr)
2388 *pp++ = ldr;
2389 for (; *ldr != 0; ldr++)
2390 if (*ldr == ':')
2392 *ldr++ = 0;
2393 *pp++ = ldr;
2396 if (q)
2398 *pp++ = q;
2399 for (; *q != 0; q++)
2400 if (*q == ':')
2402 *q++ = 0;
2403 *pp++ = q;
2406 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2407 *pp++ = "/lib";
2408 *pp++ = "/usr/lib";
2409 *pp++ = "/usr/local/lib";
2410 *pp = 0;
2412 libname = name;
2413 for (pp = l; *pp != 0 ; pp++)
2415 struct direct **namelist;
2416 int entries;
2417 if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0)
2419 sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name);
2420 add_to_list (&libraries, buf);
2421 if (debug)
2422 fprintf (stderr, "%s\n", buf);
2423 break;
2426 if (*pp == 0)
2428 if (debug)
2429 notice ("not found\n");
2430 else
2431 fatal ("dynamic dependency %s not found", name);
2435 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2436 that it depends upon and any constructors or destructors they contain. */
2438 static void
2439 scan_libraries (prog_name)
2440 const char *prog_name;
2442 struct exec *header;
2443 char *base;
2444 struct link_object *lo;
2445 char buff[MAXPATHLEN];
2446 struct id *list;
2448 mapfile (prog_name);
2449 header = (struct exec *)object;
2450 if (N_BADMAG (*header))
2451 fatal ("bad magic number in file '%s'", prog_name);
2452 if (header->a_dynamic == 0)
2453 return;
2455 code = (char *) (N_TXTOFF (*header) + (long) header);
2456 data = (char *) (N_DATOFF (*header) + (long) header);
2457 symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header);
2459 if (header->a_magic == ZMAGIC && header->a_entry == 0x20)
2461 /* shared object */
2462 ld = (struct link_dynamic *) (symtab->n_value + code);
2463 base = code;
2465 else
2467 /* executable */
2468 ld = (struct link_dynamic *) data;
2469 base = code-PAGSIZ;
2472 if (debug)
2473 notice ("dynamic dependencies.\n");
2475 ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);
2476 for (lo = (struct link_object *) ld_2->ld_need; lo;
2477 lo = (struct link_object *) lo->lo_next)
2479 char *name;
2480 lo = (struct link_object *) ((long) lo + code);
2481 name = (char *) (code + lo->lo_name);
2482 if (lo->lo_library)
2484 if (debug)
2485 fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major);
2486 sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor);
2487 locatelib (buff);
2489 else
2491 if (debug)
2492 fprintf (stderr, "\t%s\n", name);
2493 add_to_list (&libraries, name);
2497 if (debug)
2498 fprintf (stderr, "\n");
2500 /* now iterate through the library list adding their symbols to
2501 the list. */
2502 for (list = libraries.first; list; list = list->next)
2503 scan_prog_file (list->name, PASS_LIB);
2506 #else /* SUNOS4_SHARED_LIBRARIES */
2507 #ifdef LDD_SUFFIX
2509 /* Use the List Dynamic Dependencies program to find shared libraries that
2510 the output file depends upon and their initialization/finalization
2511 routines, if any. */
2513 static void
2514 scan_libraries (prog_name)
2515 const char *prog_name;
2517 static struct head libraries; /* list of shared libraries found */
2518 struct id *list;
2519 void (*int_handler) PARAMS ((int));
2520 void (*quit_handler) PARAMS ((int));
2521 char *real_ldd_argv[4];
2522 const char **ldd_argv = (const char **) real_ldd_argv;
2523 int pid;
2524 int argc = 0;
2525 int pipe_fd[2];
2526 char buf[1024];
2527 FILE *inf;
2529 /* If we do not have an `ldd', complain. */
2530 if (ldd_file_name == 0)
2532 error ("cannot find `ldd'");
2533 return;
2536 ldd_argv[argc++] = ldd_file_name;
2537 ldd_argv[argc++] = prog_name;
2538 ldd_argv[argc++] = (char *) 0;
2540 if (pipe (pipe_fd) < 0)
2541 fatal_perror ("pipe");
2543 inf = fdopen (pipe_fd[0], "r");
2544 if (inf == (FILE *) 0)
2545 fatal_perror ("fdopen");
2547 /* Trace if needed. */
2548 if (vflag)
2550 const char **p_argv;
2551 const char *str;
2553 for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2554 fprintf (stderr, " %s", str);
2556 fprintf (stderr, "\n");
2559 fflush (stdout);
2560 fflush (stderr);
2562 /* Spawn child ldd on pipe */
2563 pid = vfork ();
2564 if (pid == -1)
2565 fatal_perror (VFORK_STRING);
2567 if (pid == 0) /* child context */
2569 /* setup stdout */
2570 if (dup2 (pipe_fd[1], 1) < 0)
2571 fatal_perror ("dup2 %d 1", pipe_fd[1]);
2573 if (close (pipe_fd[0]) < 0)
2574 fatal_perror ("close %d", pipe_fd[0]);
2576 if (close (pipe_fd[1]) < 0)
2577 fatal_perror ("close %d", pipe_fd[1]);
2579 execv (ldd_file_name, real_ldd_argv);
2580 fatal_perror ("execv %s", ldd_file_name);
2583 /* Parent context from here on. */
2584 int_handler = (void (*) PARAMS ((int))) signal (SIGINT, SIG_IGN);
2585 #ifdef SIGQUIT
2586 quit_handler = (void (*) PARAMS ((int))) signal (SIGQUIT, SIG_IGN);
2587 #endif
2589 if (close (pipe_fd[1]) < 0)
2590 fatal_perror ("close %d", pipe_fd[1]);
2592 if (debug)
2593 notice ("\nldd output with constructors/destructors.\n");
2595 /* Read each line of ldd output. */
2596 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2598 int ch2;
2599 char *name, *end, *p = buf;
2601 /* Extract names of libraries and add to list. */
2602 PARSE_LDD_OUTPUT (p);
2603 if (p == 0)
2604 continue;
2606 name = p;
2607 if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
2608 fatal ("dynamic dependency %s not found", buf);
2610 /* Find the end of the symbol name. */
2611 for (end = p;
2612 (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|';
2613 end++)
2614 continue;
2615 *end = '\0';
2617 if (access (name, R_OK) == 0)
2618 add_to_list (&libraries, name);
2619 else
2620 fatal ("unable to open dynamic dependency '%s'", buf);
2622 if (debug)
2623 fprintf (stderr, "\t%s\n", buf);
2625 if (debug)
2626 fprintf (stderr, "\n");
2628 if (fclose (inf) != 0)
2629 fatal_perror ("fclose");
2631 do_wait (ldd_file_name);
2633 signal (SIGINT, int_handler);
2634 #ifdef SIGQUIT
2635 signal (SIGQUIT, quit_handler);
2636 #endif
2638 /* now iterate through the library list adding their symbols to
2639 the list. */
2640 for (list = libraries.first; list; list = list->next)
2641 scan_prog_file (list->name, PASS_LIB);
2644 #endif /* LDD_SUFFIX */
2645 #endif /* SUNOS4_SHARED_LIBRARIES */
2647 #endif /* OBJECT_FORMAT_NONE */
2651 * COFF specific stuff.
2654 #ifdef OBJECT_FORMAT_COFF
2656 #if defined(EXTENDED_COFF)
2658 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2659 # define GCC_SYMENT SYMR
2660 # define GCC_OK_SYMBOL(X) ((X).st == stProc || (X).st == stGlobal)
2661 # define GCC_SYMINC(X) (1)
2662 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2663 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2665 #else
2667 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2668 # define GCC_SYMENT SYMENT
2669 # define GCC_OK_SYMBOL(X) \
2670 (((X).n_sclass == C_EXT) && \
2671 ((X).n_scnum > N_UNDEF) && \
2672 (aix64_flag \
2673 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2674 || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2675 # define GCC_UNDEF_SYMBOL(X) \
2676 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2677 # define GCC_SYMINC(X) ((X).n_numaux+1)
2678 # define GCC_SYMZERO(X) 0
2680 /* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
2681 #ifdef _AIX51
2682 # define GCC_CHECK_HDR(X) \
2683 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2684 || (HEADER (X).f_magic == 0767 && aix64_flag))
2685 #else
2686 # define GCC_CHECK_HDR(X) \
2687 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2688 || (HEADER (X).f_magic == 0757 && aix64_flag))
2689 #endif
2691 #endif
2693 extern char *ldgetname ();
2695 /* COFF version to scan the name list of the loaded program for
2696 the symbols g++ uses for static constructors and destructors.
2698 The constructor table begins at __CTOR_LIST__ and contains a count
2699 of the number of pointers (or -1 if the constructors are built in a
2700 separate section by the linker), followed by the pointers to the
2701 constructor functions, terminated with a null pointer. The
2702 destructor table has the same format, and begins at __DTOR_LIST__. */
2704 static void
2705 scan_prog_file (prog_name, which_pass)
2706 const char *prog_name;
2707 enum pass which_pass;
2709 LDFILE *ldptr = NULL;
2710 int sym_index, sym_count;
2711 int is_shared = 0;
2713 if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2714 return;
2716 #ifdef COLLECT_EXPORT_LIST
2717 /* We do not need scanning for some standard C libraries. */
2718 if (which_pass == PASS_FIRST && ignore_library (prog_name))
2719 return;
2721 /* On AIX we have a loop, because there is not much difference
2722 between an object and an archive. This trick allows us to
2723 eliminate scan_libraries() function. */
2726 #endif
2727 /* Some platforms (e.g. OSF4) declare ldopen as taking a
2728 non-const char * filename parameter, even though it will not
2729 modify that string. So we must cast away const-ness here,
2730 which will cause -Wcast-qual to burp. */
2731 if ((ldptr = ldopen ((char *)prog_name, ldptr)) != NULL)
2733 if (! MY_ISCOFF (HEADER (ldptr).f_magic))
2734 fatal ("%s: not a COFF file", prog_name);
2736 if (GCC_CHECK_HDR (ldptr))
2738 sym_count = GCC_SYMBOLS (ldptr);
2739 sym_index = GCC_SYMZERO (ldptr);
2741 #ifdef COLLECT_EXPORT_LIST
2742 /* Is current archive member a shared object? */
2743 is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
2744 #endif
2746 while (sym_index < sym_count)
2748 GCC_SYMENT symbol;
2750 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2751 break;
2752 sym_index += GCC_SYMINC (symbol);
2754 if (GCC_OK_SYMBOL (symbol))
2756 char *name;
2758 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2759 continue; /* should never happen */
2761 #ifdef XCOFF_DEBUGGING_INFO
2762 /* All AIX function names have a duplicate entry
2763 beginning with a dot. */
2764 if (*name == '.')
2765 ++name;
2766 #endif
2768 switch (is_ctor_dtor (name))
2770 case 1:
2771 if (! is_shared)
2772 add_to_list (&constructors, name);
2773 #ifdef COLLECT_EXPORT_LIST
2774 if (which_pass == PASS_OBJ)
2775 add_to_list (&exports, name);
2776 #endif
2777 break;
2779 case 2:
2780 if (! is_shared)
2781 add_to_list (&destructors, name);
2782 #ifdef COLLECT_EXPORT_LIST
2783 if (which_pass == PASS_OBJ)
2784 add_to_list (&exports, name);
2785 #endif
2786 break;
2788 #ifdef COLLECT_EXPORT_LIST
2789 case 3:
2790 #ifndef LD_INIT_SWITCH
2791 if (is_shared)
2792 add_to_list (&constructors, name);
2793 #endif
2794 break;
2796 case 4:
2797 #ifndef LD_INIT_SWITCH
2798 if (is_shared)
2799 add_to_list (&destructors, name);
2800 #endif
2801 break;
2802 #endif
2804 case 5:
2805 if (! is_shared)
2806 add_to_list (&frame_tables, name);
2807 #ifdef COLLECT_EXPORT_LIST
2808 if (which_pass == PASS_OBJ)
2809 add_to_list (&exports, name);
2810 #endif
2811 break;
2813 default: /* not a constructor or destructor */
2814 #ifdef COLLECT_EXPORT_LIST
2815 /* If we are building a shared object on AIX we need
2816 to explicitly export all global symbols. */
2817 if (shared_obj)
2819 if (which_pass == PASS_OBJ && (! export_flag))
2820 add_to_list (&exports, name);
2822 #endif
2823 continue;
2826 if (debug)
2827 #if !defined(EXTENDED_COFF)
2828 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
2829 symbol.n_scnum, symbol.n_sclass,
2830 (symbol.n_type ? "0" : ""), symbol.n_type,
2831 name);
2832 #else
2833 fprintf (stderr,
2834 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
2835 symbol.iss, (long) symbol.value, symbol.index, name);
2836 #endif
2840 #ifdef COLLECT_EXPORT_LIST
2841 else
2843 /* If archive contains both 32-bit and 64-bit objects,
2844 we want to skip objects in other mode so mismatch normal. */
2845 if (debug)
2846 fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n",
2847 prog_name, HEADER (ldptr).f_magic, aix64_flag);
2849 #endif
2851 else
2853 fatal ("%s: cannot open as COFF file", prog_name);
2855 #ifdef COLLECT_EXPORT_LIST
2856 /* On AIX loop continues while there are more members in archive. */
2858 while (ldclose (ldptr) == FAILURE);
2859 #else
2860 /* Otherwise we simply close ldptr. */
2861 (void) ldclose(ldptr);
2862 #endif
2866 #ifdef COLLECT_EXPORT_LIST
2867 /* Given a library name without "lib" prefix, this function
2868 returns a full library name including a path. */
2869 static char *
2870 resolve_lib_name (name)
2871 const char *name;
2873 char *lib_buf;
2874 int i, j, l = 0;
2876 for (i = 0; libpaths[i]; i++)
2877 if (libpaths[i]->max_len > l)
2878 l = libpaths[i]->max_len;
2880 lib_buf = xmalloc (l + strlen(name) + 10);
2882 for (i = 0; libpaths[i]; i++)
2884 struct prefix_list *list = libpaths[i]->plist;
2885 for (; list; list = list->next)
2887 /* The following lines are needed because path_prefix list
2888 may contain directories both with trailing '/' and
2889 without it. */
2890 const char *p = "";
2891 if (list->prefix[strlen(list->prefix)-1] != '/')
2892 p = "/";
2893 for (j = 0; libexts[j]; j++)
2895 sprintf (lib_buf, "%s%slib%s.%s",
2896 list->prefix, p, name, libexts[j]);
2897 if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
2898 if (file_exists (lib_buf))
2900 if (debug) fprintf (stderr, "found: %s\n", lib_buf);
2901 return (lib_buf);
2906 if (debug)
2907 fprintf (stderr, "not found\n");
2908 else
2909 fatal ("library lib%s not found", name);
2910 return (NULL);
2913 /* Array of standard AIX libraries which should not
2914 be scanned for ctors/dtors. */
2915 static const char *const aix_std_libs[] = {
2916 "/unix",
2917 "/lib/libc.a",
2918 "/lib/libm.a",
2919 "/lib/libc_r.a",
2920 "/lib/libm_r.a",
2921 "/usr/lib/libc.a",
2922 "/usr/lib/libm.a",
2923 "/usr/lib/libc_r.a",
2924 "/usr/lib/libm_r.a",
2925 "/usr/lib/threads/libc.a",
2926 "/usr/ccs/lib/libc.a",
2927 "/usr/ccs/lib/libm.a",
2928 "/usr/ccs/lib/libc_r.a",
2929 "/usr/ccs/lib/libm_r.a",
2930 NULL
2933 /* This function checks the filename and returns 1
2934 if this name matches the location of a standard AIX library. */
2935 static int
2936 ignore_library (name)
2937 const char *name;
2939 const char *const *p = &aix_std_libs[0];
2940 while (*p++ != NULL)
2941 if (! strcmp (name, *p)) return 1;
2942 return 0;
2944 #endif
2946 #endif /* OBJECT_FORMAT_COFF */
2950 * OSF/rose specific stuff.
2953 #ifdef OBJECT_FORMAT_ROSE
2955 /* Union of the various load commands */
2957 typedef union load_union
2959 ldc_header_t hdr; /* common header */
2960 load_cmd_map_command_t map; /* map indexing other load cmds */
2961 interpreter_command_t iprtr; /* interpreter pathname */
2962 strings_command_t str; /* load commands strings section */
2963 region_command_t region; /* region load command */
2964 reloc_command_t reloc; /* relocation section */
2965 package_command_t pkg; /* package load command */
2966 symbols_command_t sym; /* symbol sections */
2967 entry_command_t ent; /* program start section */
2968 gen_info_command_t info; /* object information */
2969 func_table_command_t func; /* function constructors/destructors */
2970 } load_union_t;
2972 /* Structure to point to load command and data section in memory. */
2974 typedef struct load_all
2976 load_union_t *load; /* load command */
2977 char *section; /* pointer to section */
2978 } load_all_t;
2980 /* Structure to contain information about a file mapped into memory. */
2982 struct file_info
2984 char *start; /* start of map */
2985 char *name; /* filename */
2986 long size; /* size of the file */
2987 long rounded_size; /* size rounded to page boundary */
2988 int fd; /* file descriptor */
2989 int rw; /* != 0 if opened read/write */
2990 int use_mmap; /* != 0 if mmap'ed */
2993 extern int decode_mach_o_hdr ();
2994 extern int encode_mach_o_hdr ();
2996 static void add_func_table PARAMS ((mo_header_t *, load_all_t *,
2997 symbol_info_t *, int));
2998 static void print_header PARAMS ((mo_header_t *));
2999 static void print_load_command PARAMS ((load_union_t *, size_t, int));
3000 static void bad_header PARAMS ((int));
3001 static struct file_info *read_file PARAMS ((const char *, int, int));
3002 static void end_file PARAMS ((struct file_info *));
3004 /* OSF/rose specific version to scan the name list of the loaded
3005 program for the symbols g++ uses for static constructors and
3006 destructors.
3008 The constructor table begins at __CTOR_LIST__ and contains a count
3009 of the number of pointers (or -1 if the constructors are built in a
3010 separate section by the linker), followed by the pointers to the
3011 constructor functions, terminated with a null pointer. The
3012 destructor table has the same format, and begins at __DTOR_LIST__. */
3014 static void
3015 scan_prog_file (prog_name, which_pass)
3016 const char *prog_name;
3017 enum pass which_pass;
3019 char *obj;
3020 mo_header_t hdr;
3021 load_all_t *load_array;
3022 load_all_t *load_end;
3023 load_all_t *load_cmd;
3024 int symbol_load_cmds;
3025 off_t offset;
3026 int i;
3027 int num_syms;
3028 int status;
3029 char *str_sect;
3030 struct file_info *obj_file;
3031 int prog_fd;
3032 mo_lcid_t cmd_strings = -1;
3033 symbol_info_t *main_sym = 0;
3034 int rw = (which_pass != PASS_FIRST);
3036 prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
3037 if (prog_fd < 0)
3038 fatal_perror ("open %s", prog_name);
3040 obj_file = read_file (prog_name, prog_fd, rw);
3041 obj = obj_file->start;
3043 status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);
3044 if (status != MO_HDR_CONV_SUCCESS)
3045 bad_header (status);
3048 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
3049 since the hardware will automatically swap bytes for us on loading little endian
3050 integers. */
3052 #ifndef CROSS_COMPILE
3053 if (hdr.moh_magic != MOH_MAGIC_MSB
3054 || hdr.moh_header_version != MOH_HEADER_VERSION
3055 || hdr.moh_byte_order != OUR_BYTE_ORDER
3056 || hdr.moh_data_rep_id != OUR_DATA_REP_ID
3057 || hdr.moh_cpu_type != OUR_CPU_TYPE
3058 || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE
3059 || hdr.moh_vendor_type != OUR_VENDOR_TYPE)
3061 fatal ("incompatibilities between object file & expected values");
3063 #endif
3065 if (debug)
3066 print_header (&hdr);
3068 offset = hdr.moh_first_cmd_off;
3069 load_end = load_array
3070 = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);
3072 /* Build array of load commands, calculating the offsets */
3073 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3075 load_union_t *load_hdr; /* load command header */
3077 load_cmd = load_end++;
3078 load_hdr = (load_union_t *) (obj + offset);
3080 /* If modifying the program file, copy the header. */
3081 if (rw)
3083 load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
3084 memcpy ((char *)ptr, (char *)load_hdr, load_hdr->hdr.ldci_cmd_size);
3085 load_hdr = ptr;
3087 /* null out old command map, because we will rewrite at the end. */
3088 if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
3090 cmd_strings = ptr->map.lcm_ld_cmd_strings;
3091 ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
3095 load_cmd->load = load_hdr;
3096 if (load_hdr->hdr.ldci_section_off > 0)
3097 load_cmd->section = obj + load_hdr->hdr.ldci_section_off;
3099 if (debug)
3100 print_load_command (load_hdr, offset, i);
3102 offset += load_hdr->hdr.ldci_cmd_size;
3105 /* If the last command is the load command map and is not undefined,
3106 decrement the count of load commands. */
3107 if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)
3109 load_end--;
3110 hdr.moh_n_load_cmds--;
3113 /* Go through and process each symbol table section. */
3114 symbol_load_cmds = 0;
3115 for (load_cmd = load_array; load_cmd < load_end; load_cmd++)
3117 load_union_t *load_hdr = load_cmd->load;
3119 if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
3121 symbol_load_cmds++;
3123 if (debug)
3125 const char *kind = "unknown";
3127 switch (load_hdr->sym.symc_kind)
3129 case SYMC_IMPORTS: kind = "imports"; break;
3130 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
3131 case SYMC_STABS: kind = "stabs"; break;
3134 notice ("\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
3135 symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
3138 if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
3139 continue;
3141 str_sect = load_array[load_hdr->sym.symc_strings_section].section;
3142 if (str_sect == (char *) 0)
3143 fatal ("string section missing");
3145 if (load_cmd->section == (char *) 0)
3146 fatal ("section pointer missing");
3148 num_syms = load_hdr->sym.symc_nentries;
3149 for (i = 0; i < num_syms; i++)
3151 symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
3152 char *name = sym->si_name.symbol_name + str_sect;
3154 if (name[0] != '_')
3155 continue;
3157 if (rw)
3159 char *n = name + strlen (name) - strlen (NAME__MAIN);
3161 if ((n - name) < 0 || strcmp (n, NAME__MAIN))
3162 continue;
3163 while (n != name)
3164 if (*--n != '_')
3165 continue;
3167 main_sym = sym;
3169 else
3171 switch (is_ctor_dtor (name))
3173 case 1:
3174 add_to_list (&constructors, name);
3175 break;
3177 case 2:
3178 add_to_list (&destructors, name);
3179 break;
3181 default: /* not a constructor or destructor */
3182 continue;
3186 if (debug)
3187 fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
3188 sym->si_type, sym->si_sc_type, sym->si_flags, name);
3193 if (symbol_load_cmds == 0)
3194 fatal ("no symbol table found");
3196 /* Update the program file now, rewrite header and load commands. At present,
3197 we assume that there is enough space after the last load command to insert
3198 one more. Since the first section written out is page aligned, and the
3199 number of load commands is small, this is ok for the present. */
3201 if (rw)
3203 load_union_t *load_map;
3204 size_t size;
3206 if (cmd_strings == -1)
3207 fatal ("no cmd_strings found");
3209 /* Add __main to initializer list.
3210 If we are building a program instead of a shared library, do not
3211 do anything, since in the current version, you cannot do mallocs
3212 and such in the constructors. */
3214 if (main_sym != (symbol_info_t *) 0
3215 && ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
3216 add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
3218 if (debug)
3219 notice ("\nUpdating header and load commands.\n\n");
3221 hdr.moh_n_load_cmds++;
3222 size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
3224 /* Create new load command map. */
3225 if (debug)
3226 notice ("load command map, %d cmds, new size %ld.\n",
3227 (int) hdr.moh_n_load_cmds, (long) size);
3229 load_map = (load_union_t *) xcalloc (1, size);
3230 load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
3231 load_map->map.ldc_header.ldci_cmd_size = size;
3232 load_map->map.lcm_ld_cmd_strings = cmd_strings;
3233 load_map->map.lcm_nentries = hdr.moh_n_load_cmds;
3234 load_array[hdr.moh_n_load_cmds-1].load = load_map;
3236 offset = hdr.moh_first_cmd_off;
3237 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3239 load_map->map.lcm_map[i] = offset;
3240 if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)
3241 hdr.moh_load_map_cmd_off = offset;
3243 offset += load_array[i].load->hdr.ldci_cmd_size;
3246 hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
3248 if (debug)
3249 print_header (&hdr);
3251 /* Write header */
3252 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
3253 if (status != MO_HDR_CONV_SUCCESS)
3254 bad_header (status);
3256 if (debug)
3257 notice ("writing load commands.\n\n");
3259 /* Write load commands */
3260 offset = hdr.moh_first_cmd_off;
3261 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3263 load_union_t *load_hdr = load_array[i].load;
3264 size_t size = load_hdr->hdr.ldci_cmd_size;
3266 if (debug)
3267 print_load_command (load_hdr, offset, i);
3269 bcopy ((char *) load_hdr, (char *) (obj + offset), size);
3270 offset += size;
3274 end_file (obj_file);
3276 if (close (prog_fd))
3277 fatal_perror ("close %s", prog_name);
3279 if (debug)
3280 fprintf (stderr, "\n");
3284 /* Add a function table to the load commands to call a function
3285 on initiation or termination of the process. */
3287 static void
3288 add_func_table (hdr_p, load_array, sym, type)
3289 mo_header_t *hdr_p; /* pointer to global header */
3290 load_all_t *load_array; /* array of ptrs to load cmds */
3291 symbol_info_t *sym; /* pointer to symbol entry */
3292 int type; /* fntc_type value */
3294 /* Add a new load command. */
3295 int num_cmds = ++hdr_p->moh_n_load_cmds;
3296 int load_index = num_cmds - 1;
3297 size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);
3298 load_union_t *ptr = xcalloc (1, size);
3299 load_all_t *load_cmd;
3300 int i;
3302 /* Set the unresolved address bit in the header to force the loader to be
3303 used, since kernel exec does not call the initialization functions. */
3304 hdr_p->moh_flags |= MOH_UNRESOLVED_F;
3306 load_cmd = &load_array[load_index];
3307 load_cmd->load = ptr;
3308 load_cmd->section = (char *) 0;
3310 /* Fill in func table load command. */
3311 ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
3312 ptr->func.ldc_header.ldci_cmd_size = size;
3313 ptr->func.ldc_header.ldci_section_off = 0;
3314 ptr->func.ldc_header.ldci_section_len = 0;
3315 ptr->func.fntc_type = type;
3316 ptr->func.fntc_nentries = 1;
3318 /* copy address, turn it from abs. address to (region,offset) if necessary. */
3319 /* Is the symbol already expressed as (region, offset)? */
3320 if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)
3322 ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;
3323 ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;
3326 /* If not, figure out which region it's in. */
3327 else
3329 mo_vm_addr_t addr = sym->si_value.abs_val;
3330 int found = 0;
3332 for (i = 0; i < load_index; i++)
3334 if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
3336 region_command_t *region_ptr = &load_array[i].load->region;
3338 if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0
3339 && addr >= region_ptr->regc_addr.vm_addr
3340 && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)
3342 ptr->func.fntc_entry_loc[0].adr_lcid = i;
3343 ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;
3344 found++;
3345 break;
3350 if (!found)
3351 fatal ("could not convert 0x%l.8x into a region", addr);
3354 if (debug)
3355 notice ("%s function, region %d, offset = %ld (0x%.8lx)\n",
3356 type == FNTC_INITIALIZATION ? "init" : "term",
3357 (int) ptr->func.fntc_entry_loc[i].adr_lcid,
3358 (long) ptr->func.fntc_entry_loc[i].adr_sctoff,
3359 (long) ptr->func.fntc_entry_loc[i].adr_sctoff);
3364 /* Print the global header for an OSF/rose object. */
3366 static void
3367 print_header (hdr_ptr)
3368 mo_header_t *hdr_ptr;
3370 fprintf (stderr, "\nglobal header:\n");
3371 fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic);
3372 fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version);
3373 fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version);
3374 fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version);
3375 fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size);
3376 fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order);
3377 fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id);
3378 fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type);
3379 fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype);
3380 fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type);
3381 fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);
3382 fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off);
3383 fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds);
3384 fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds);
3385 fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags);
3387 if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
3388 fprintf (stderr, ", relocatable");
3390 if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
3391 fprintf (stderr, ", linkable");
3393 if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
3394 fprintf (stderr, ", execable");
3396 if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
3397 fprintf (stderr, ", executable");
3399 if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
3400 fprintf (stderr, ", unresolved");
3402 fprintf (stderr, "\n\n");
3403 return;
3407 /* Print a short summary of a load command. */
3409 static void
3410 print_load_command (load_hdr, offset, number)
3411 load_union_t *load_hdr;
3412 size_t offset;
3413 int number;
3415 mo_long_t type = load_hdr->hdr.ldci_cmd_type;
3416 const char *type_str = (char *) 0;
3418 switch (type)
3420 case LDC_UNDEFINED: type_str = "UNDEFINED"; break;
3421 case LDC_CMD_MAP: type_str = "CMD_MAP"; break;
3422 case LDC_INTERPRETER: type_str = "INTERPRETER"; break;
3423 case LDC_STRINGS: type_str = "STRINGS"; break;
3424 case LDC_REGION: type_str = "REGION"; break;
3425 case LDC_RELOC: type_str = "RELOC"; break;
3426 case LDC_PACKAGE: type_str = "PACKAGE"; break;
3427 case LDC_SYMBOLS: type_str = "SYMBOLS"; break;
3428 case LDC_ENTRY: type_str = "ENTRY"; break;
3429 case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break;
3430 case LDC_GEN_INFO: type_str = "GEN_INFO"; break;
3433 fprintf (stderr,
3434 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3435 number,
3436 (long) load_hdr->hdr.ldci_cmd_size,
3437 (long) offset,
3438 (long) load_hdr->hdr.ldci_section_off,
3439 (long) load_hdr->hdr.ldci_section_len);
3441 if (type_str == (char *) 0)
3442 fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
3444 else if (type != LDC_REGION)
3445 fprintf (stderr, ", ty: %s\n", type_str);
3447 else
3449 const char *region = "";
3450 switch (load_hdr->region.regc_usage_type)
3452 case REG_TEXT_T: region = ", .text"; break;
3453 case REG_DATA_T: region = ", .data"; break;
3454 case REG_BSS_T: region = ", .bss"; break;
3455 case REG_GLUE_T: region = ", .glue"; break;
3456 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3457 case REG_RDATA_T: region = ", .rdata"; break;
3458 case REG_SDATA_T: region = ", .sdata"; break;
3459 case REG_SBSS_T: region = ", .sbss"; break;
3460 #endif
3463 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3464 type_str,
3465 (long) load_hdr->region.regc_vm_addr,
3466 (long) load_hdr->region.regc_vm_size,
3467 region);
3470 return;
3474 /* Fatal error when {en,de}code_mach_o_header fails. */
3476 static void
3477 bad_header (status)
3478 int status;
3480 switch (status)
3482 case MO_ERROR_BAD_MAGIC: fatal ("bad magic number");
3483 case MO_ERROR_BAD_HDR_VERS: fatal ("bad header version");
3484 case MO_ERROR_BAD_RAW_HDR_VERS: fatal ("bad raw header version");
3485 case MO_ERROR_BUF2SML: fatal ("raw header buffer too small");
3486 case MO_ERROR_OLD_RAW_HDR_FILE: fatal ("old raw header file");
3487 case MO_ERROR_UNSUPPORTED_VERS: fatal ("unsupported version");
3488 default:
3489 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
3494 /* Read a file into a memory buffer. */
3496 static struct file_info *
3497 read_file (name, fd, rw)
3498 const char *name; /* filename */
3499 int fd; /* file descriptor */
3500 int rw; /* read/write */
3502 struct stat stat_pkt;
3503 struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
3504 #ifdef USE_MMAP
3505 static int page_size;
3506 #endif
3508 if (fstat (fd, &stat_pkt) < 0)
3509 fatal_perror ("fstat %s", name);
3511 p->name = name;
3512 p->size = stat_pkt.st_size;
3513 p->rounded_size = stat_pkt.st_size;
3514 p->fd = fd;
3515 p->rw = rw;
3517 #ifdef USE_MMAP
3518 if (debug)
3519 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
3521 if (page_size == 0)
3522 page_size = sysconf (_SC_PAGE_SIZE);
3524 p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
3525 p->start = mmap ((caddr_t) 0,
3526 (rw) ? p->rounded_size : p->size,
3527 (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
3528 MAP_FILE | MAP_VARIABLE | MAP_SHARED,
3530 0L);
3532 if (p->start != (char *) 0 && p->start != (char *) -1)
3533 p->use_mmap = 1;
3535 else
3536 #endif /* USE_MMAP */
3538 long len;
3540 if (debug)
3541 fprintf (stderr, "read %s\n", name);
3543 p->use_mmap = 0;
3544 p->start = xmalloc (p->size);
3545 if (lseek (fd, 0L, SEEK_SET) < 0)
3546 fatal_perror ("lseek %s 0", name);
3548 len = read (fd, p->start, p->size);
3549 if (len < 0)
3550 fatal_perror ("read %s", name);
3552 if (len != p->size)
3553 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
3556 return p;
3559 /* Do anything necessary to write a file back from memory. */
3561 static void
3562 end_file (ptr)
3563 struct file_info *ptr; /* file information block */
3565 #ifdef USE_MMAP
3566 if (ptr->use_mmap)
3568 if (ptr->rw)
3570 if (debug)
3571 fprintf (stderr, "msync %s\n", ptr->name);
3573 if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
3574 fatal_perror ("msync %s", ptr->name);
3577 if (debug)
3578 fprintf (stderr, "munmap %s\n", ptr->name);
3580 if (munmap (ptr->start, ptr->size))
3581 fatal_perror ("munmap %s", ptr->name);
3583 else
3584 #endif /* USE_MMAP */
3586 if (ptr->rw)
3588 long len;
3590 if (debug)
3591 fprintf (stderr, "write %s\n", ptr->name);
3593 if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
3594 fatal_perror ("lseek %s 0", ptr->name);
3596 len = write (ptr->fd, ptr->start, ptr->size);
3597 if (len < 0)
3598 fatal_perror ("write %s", ptr->name);
3600 if (len != ptr->size)
3601 fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
3604 free (ptr->start);
3607 free (ptr);
3610 #endif /* OBJECT_FORMAT_ROSE */