* Makefile.in (jcf-parse.o): Depend on $(PARSE_H).
[official-gcc.git] / gcc / collect2.c
blobe51ce71d39d63048e434b74943da4b91c12813cd
1 /* Collect static initialization info into data structures that can be
2 traversed by C++ initialization and finalization routines.
3 Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
4 Contributed by Chris Smith (csmith@convex.com).
5 Heavily modified by Michael Meissner (meissner@cygnus.com),
6 Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
8 This file is part of GNU CC.
10 GNU CC is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
15 GNU CC is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GNU CC; see the file COPYING. If not, write to
22 the Free Software Foundation, 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
26 /* Build tables of static constructors and destructors and run ld. */
28 #include "config.h"
29 #include "system.h"
30 #include <signal.h>
32 #ifdef vfork /* Autoconf may define this to fork for us. */
33 # define VFORK_STRING "fork"
34 #else
35 # define VFORK_STRING "vfork"
36 #endif
37 #ifdef HAVE_VFORK_H
38 #include <vfork.h>
39 #endif
40 #ifdef VMS
41 #define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
42 lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
43 #endif /* VMS */
45 #define COLLECT
47 #include "collect2.h"
48 #include "demangle.h"
49 #include "obstack.h"
50 #include "intl.h"
52 /* Obstack allocation and deallocation routines. */
53 #define obstack_chunk_alloc xmalloc
54 #define obstack_chunk_free free
56 extern char *make_temp_file PROTO ((char *));
58 /* On certain systems, we have code that works by scanning the object file
59 directly. But this code uses system-specific header files and library
60 functions, so turn it off in a cross-compiler. Likewise, the names of
61 the utilities are not correct for a cross-compiler; we have to hope that
62 cross-versions are in the proper directories. */
64 #ifdef CROSS_COMPILE
65 #undef SUNOS4_SHARED_LIBRARIES
66 #undef OBJECT_FORMAT_COFF
67 #undef OBJECT_FORMAT_ROSE
68 #undef MD_EXEC_PREFIX
69 #undef REAL_LD_FILE_NAME
70 #undef REAL_NM_FILE_NAME
71 #undef REAL_STRIP_FILE_NAME
72 #endif
74 /* If we cannot use a special method, use the ordinary one:
75 run nm to find what symbols are present.
76 In a cross-compiler, this means you need a cross nm,
77 but that is not quite as unpleasant as special headers. */
79 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
80 #define OBJECT_FORMAT_NONE
81 #endif
83 #ifdef OBJECT_FORMAT_COFF
85 #include <a.out.h>
86 #include <ar.h>
88 #ifdef UMAX
89 #include <sgs.h>
90 #endif
92 /* Many versions of ldfcn.h define these. */
93 #ifdef FREAD
94 #undef FREAD
95 #undef FWRITE
96 #endif
98 #include <ldfcn.h>
100 /* Some systems have an ISCOFF macro, but others do not. In some cases
101 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
102 that either do not have an ISCOFF macro in /usr/include or for those
103 where it is wrong. */
105 #ifndef MY_ISCOFF
106 #define MY_ISCOFF(X) ISCOFF (X)
107 #endif
109 #endif /* OBJECT_FORMAT_COFF */
111 #ifdef OBJECT_FORMAT_ROSE
113 #ifdef _OSF_SOURCE
114 #define USE_MMAP
115 #endif
117 #ifdef USE_MMAP
118 #include <sys/mman.h>
119 #endif
121 #include <unistd.h>
122 #include <mach_o_format.h>
123 #include <mach_o_header.h>
124 #include <mach_o_vals.h>
125 #include <mach_o_types.h>
127 #endif /* OBJECT_FORMAT_ROSE */
129 #ifdef OBJECT_FORMAT_NONE
131 /* Default flags to pass to nm. */
132 #ifndef NM_FLAGS
133 #define NM_FLAGS "-n"
134 #endif
136 #endif /* OBJECT_FORMAT_NONE */
138 /* Some systems use __main in a way incompatible with its use in gcc, in these
139 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
140 give the same symbol without quotes for an alternative entry point. You
141 must define both, or neither. */
142 #ifndef NAME__MAIN
143 #define NAME__MAIN "__main"
144 #define SYMBOL__MAIN __main
145 #endif
147 /* This must match tree.h. */
148 #define DEFAULT_INIT_PRIORITY 65535
150 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
151 #define SCAN_LIBRARIES
152 #endif
154 #ifdef USE_COLLECT2
155 int do_collecting = 1;
156 #else
157 int do_collecting = 0;
158 #endif
160 /* Linked lists of constructor and destructor names. */
162 struct id
164 struct id *next;
165 int sequence;
166 char name[1];
169 struct head
171 struct id *first;
172 struct id *last;
173 int number;
176 /* Enumeration giving which pass this is for scanning the program file. */
178 enum pass {
179 PASS_FIRST, /* without constructors */
180 PASS_OBJ, /* individual objects */
181 PASS_LIB, /* looking for shared libraries */
182 PASS_SECOND /* with constructors linked in */
185 extern char *version_string;
187 int vflag; /* true if -v */
188 static int rflag; /* true if -r */
189 static int strip_flag; /* true if -s */
190 #ifdef COLLECT_EXPORT_LIST
191 static int export_flag; /* true if -bE */
192 static int aix64_flag; /* true if -b64 */
193 #endif
195 int debug; /* true if -debug */
197 static int shared_obj; /* true if -shared */
199 static char *c_file; /* <xxx>.c for constructor/destructor list. */
200 static char *o_file; /* <xxx>.o for constructor/destructor list. */
201 #ifdef COLLECT_EXPORT_LIST
202 static char *export_file; /* <xxx>.x for AIX export list. */
203 static char *import_file; /* <xxx>.p for AIX import list. */
204 #endif
205 char *ldout; /* File for ld errors. */
206 static char *output_file; /* Output file for ld. */
207 static char *nm_file_name; /* pathname of nm */
208 #ifdef LDD_SUFFIX
209 static char *ldd_file_name; /* pathname of ldd (or equivalent) */
210 #endif
211 static char *strip_file_name; /* pathname of strip */
212 char *c_file_name; /* pathname of gcc */
213 static char *initname, *fininame; /* names of init and fini funcs */
215 static struct head constructors; /* list of constructors found */
216 static struct head destructors; /* list of destructors found */
217 #ifdef COLLECT_EXPORT_LIST
218 static struct head exports; /* list of exported symbols */
219 static struct head imports; /* list of imported symbols */
220 static struct head undefined; /* list of undefined symbols */
221 #endif
222 static struct head frame_tables; /* list of frame unwind info tables */
224 struct obstack temporary_obstack;
225 struct obstack permanent_obstack;
226 char * temporary_firstobj;
228 /* Defined in the automatically-generated underscore.c. */
229 extern int prepends_underscore;
231 extern FILE *fdopen ();
233 #ifndef GET_ENV_PATH_LIST
234 #define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
235 #endif
237 /* Structure to hold all the directories in which to search for files to
238 execute. */
240 struct prefix_list
242 char *prefix; /* String to prepend to the path. */
243 struct prefix_list *next; /* Next in linked list. */
246 struct path_prefix
248 struct prefix_list *plist; /* List of prefixes to try */
249 int max_len; /* Max length of a prefix in PLIST */
250 char *name; /* Name of this list (used in config stuff) */
253 #ifdef COLLECT_EXPORT_LIST
254 /* Lists to keep libraries to be scanned for global constructors/destructors. */
255 static struct head libs; /* list of libraries */
256 static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
257 static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
258 static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
259 &libpath_lib_dirs, NULL};
260 static char *libexts[3] = {"a", "so", NULL}; /* possible library extentions */
261 #endif
263 void error PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
264 void fatal PVPROTO((const char *, ...))
265 ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
266 void fatal_perror PVPROTO((const char *, ...))
267 ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
268 static char *my_strerror PROTO((int));
269 static const char *my_strsignal PROTO((int));
270 static void handler PROTO((int));
271 static int is_ctor_dtor PROTO((char *));
272 static char *find_a_file PROTO((struct path_prefix *, char *));
273 static void add_prefix PROTO((struct path_prefix *, char *));
274 static void prefix_from_env PROTO((char *, struct path_prefix *));
275 static void prefix_from_string PROTO((char *, struct path_prefix *));
276 static void do_wait PROTO((char *));
277 static void fork_execute PROTO((char *, char **));
278 static void maybe_unlink PROTO((char *));
279 static void add_to_list PROTO((struct head *, char *));
280 static int extract_init_priority PROTO((char *));
281 static void sort_ids PROTO((struct head *));
282 static void write_list PROTO((FILE *, char *, struct id *));
283 #ifdef COLLECT_EXPORT_LIST
284 static void dump_list PROTO((FILE *, char *, struct id *));
285 #endif
286 #if 0
287 static void dump_prefix_list PROTO((FILE *, char *, struct prefix_list *));
288 #endif
289 static void write_list_with_asm PROTO((FILE *, char *, struct id *));
290 static void write_c_file PROTO((FILE *, char *));
291 static void scan_prog_file PROTO((char *, enum pass));
292 #ifdef SCAN_LIBRARIES
293 static void scan_libraries PROTO((char *));
294 #endif
295 #ifdef COLLECT_EXPORT_LIST
296 static int is_in_list PROTO((char *, struct id *));
297 static void write_export_file PROTO((FILE *));
298 static void write_import_file PROTO((FILE *));
299 static char *resolve_lib_name PROTO((char *));
300 static int use_import_list PROTO((char *));
301 static int ignore_library PROTO((char *));
302 #endif
304 #ifdef NO_DUP2
306 dup2 (oldfd, newfd)
307 int oldfd;
308 int newfd;
310 int fdtmp[256];
311 int fdx = 0;
312 int fd;
314 if (oldfd == newfd)
315 return oldfd;
316 close (newfd);
317 while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
318 fdtmp[fdx++] = fd;
319 while (fdx > 0)
320 close (fdtmp[--fdx]);
322 return fd;
324 #endif
326 static char *
327 my_strerror (e)
328 int e;
331 #ifdef HAVE_STRERROR
332 return strerror (e);
334 #else
336 if (!e)
337 return "";
339 if (e > 0 && e < sys_nerr)
340 return sys_errlist[e];
342 return "errno = ?";
343 #endif
346 static const char *
347 my_strsignal (s)
348 int s;
350 #ifdef HAVE_STRSIGNAL
351 return strsignal (s);
352 #else
353 if (s >= 0 && s < NSIG)
355 # ifdef NO_SYS_SIGLIST
356 static char buffer[30];
358 sprintf (buffer, "Unknown signal %d", s);
359 return buffer;
360 # else
361 return sys_siglist[s];
362 # endif
364 else
365 return NULL;
366 #endif /* HAVE_STRSIGNAL */
369 /* Delete tempfiles and exit function. */
371 void
372 collect_exit (status)
373 int status;
375 if (c_file != 0 && c_file[0])
376 maybe_unlink (c_file);
378 if (o_file != 0 && o_file[0])
379 maybe_unlink (o_file);
381 #ifdef COLLECT_EXPORT_LIST
382 if (export_file != 0 && export_file[0])
383 maybe_unlink (export_file);
385 if (import_file != 0 && import_file[0])
386 maybe_unlink (import_file);
387 #endif
389 if (ldout != 0 && ldout[0])
391 dump_file (ldout);
392 maybe_unlink (ldout);
395 if (status != 0 && output_file != 0 && output_file[0])
396 maybe_unlink (output_file);
398 exit (status);
402 /* Notify user of a non-error. */
403 void
404 notice VPROTO((char *msgid, ...))
406 #ifndef ANSI_PROTOTYPES
407 char *msgid;
408 #endif
409 va_list ap;
411 VA_START (ap, msgid);
413 #ifndef ANSI_PROTOTYPES
414 msgid = va_arg (ap, char *);
415 #endif
417 vfprintf (stderr, _(msgid), ap);
418 va_end (ap);
421 /* Die when sys call fails. */
423 void
424 fatal_perror VPROTO((const char * msgid, ...))
426 #ifndef ANSI_PROTOTYPES
427 const char *msgid;
428 #endif
429 int e = errno;
430 va_list ap;
432 VA_START (ap, msgid);
434 #ifndef ANSI_PROTOTYPES
435 msgid = va_arg (ap, const char *);
436 #endif
438 fprintf (stderr, "collect2: ");
439 vfprintf (stderr, _(msgid), ap);
440 fprintf (stderr, ": %s\n", my_strerror (e));
441 va_end (ap);
443 collect_exit (FATAL_EXIT_CODE);
446 /* Just die. */
448 void
449 fatal VPROTO((const char * msgid, ...))
451 #ifndef ANSI_PROTOTYPES
452 const char *msgid;
453 #endif
454 va_list ap;
456 VA_START (ap, msgid);
458 #ifndef ANSI_PROTOTYPES
459 msgid = va_arg (ap, const char *);
460 #endif
462 fprintf (stderr, "collect2: ");
463 vfprintf (stderr, _(msgid), ap);
464 fprintf (stderr, "\n");
465 va_end (ap);
467 collect_exit (FATAL_EXIT_CODE);
470 /* Write error message. */
472 void
473 error VPROTO((const char * msgid, ...))
475 #ifndef ANSI_PROTOTYPES
476 const char * msgid;
477 #endif
478 va_list ap;
480 VA_START (ap, msgid);
482 #ifndef ANSI_PROTOTYPES
483 msgid = va_arg (ap, const char *);
484 #endif
486 fprintf (stderr, "collect2: ");
487 vfprintf (stderr, _(msgid), ap);
488 fprintf (stderr, "\n");
489 va_end(ap);
492 /* In case obstack is linked in, and abort is defined to fancy_abort,
493 provide a default entry. */
495 void
496 fancy_abort ()
498 fatal ("internal error");
501 static void
502 handler (signo)
503 int signo;
505 if (c_file != 0 && c_file[0])
506 maybe_unlink (c_file);
508 if (o_file != 0 && o_file[0])
509 maybe_unlink (o_file);
511 if (ldout != 0 && ldout[0])
512 maybe_unlink (ldout);
514 #ifdef COLLECT_EXPORT_LIST
515 if (export_file != 0 && export_file[0])
516 maybe_unlink (export_file);
518 if (import_file != 0 && import_file[0])
519 maybe_unlink (import_file);
520 #endif
522 signal (signo, SIG_DFL);
523 kill (getpid (), signo);
528 xcalloc (size1, size2)
529 size_t size1, size2;
531 PTR ptr = (PTR) calloc (size1, size2);
532 if (!ptr)
533 fatal ("out of memory");
534 return ptr;
538 xmalloc (size)
539 size_t size;
541 PTR ptr = (PTR) malloc (size);
542 if (!ptr)
543 fatal ("out of memory");
544 return ptr;
548 xrealloc (old, size)
549 PTR old;
550 size_t size;
552 register PTR ptr;
553 if (old)
554 ptr = (PTR) realloc (old, size);
555 else
556 ptr = (PTR) malloc (size);
557 if (ptr == 0)
558 fatal ("virtual memory exhausted");
559 return ptr;
563 file_exists (name)
564 char *name;
566 return access (name, R_OK) == 0;
569 /* Make a copy of a string INPUT with size SIZE. */
571 char *
572 xstrdup (input)
573 const char *input;
575 register size_t len = strlen (input) + 1;
576 register char *output = xmalloc (len);
577 memcpy (output, input, len);
578 return output;
581 /* Parse a reasonable subset of shell quoting syntax. */
583 static char *
584 extract_string (pp)
585 char **pp;
587 char *p = *pp;
588 int backquote = 0;
589 int inside = 0;
591 for (;;)
593 char c = *p;
594 if (c == '\0')
595 break;
596 ++p;
597 if (backquote)
598 obstack_1grow (&temporary_obstack, c);
599 else if (! inside && c == ' ')
600 break;
601 else if (! inside && c == '\\')
602 backquote = 1;
603 else if (c == '\'')
604 inside = !inside;
605 else
606 obstack_1grow (&temporary_obstack, c);
609 obstack_1grow (&temporary_obstack, '\0');
610 *pp = p;
611 return obstack_finish (&temporary_obstack);
614 void
615 dump_file (name)
616 char *name;
618 FILE *stream = fopen (name, "r");
619 int no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
621 if (stream == 0)
622 return;
623 while (1)
625 int c;
626 while (c = getc (stream),
627 c != EOF && (ISALNUM (c) || c == '_' || c == '$' || c == '.'))
628 obstack_1grow (&temporary_obstack, c);
629 if (obstack_object_size (&temporary_obstack) > 0)
631 char *word, *p, *result;
632 obstack_1grow (&temporary_obstack, '\0');
633 word = obstack_finish (&temporary_obstack);
635 if (*word == '.')
636 ++word, putc ('.', stderr);
637 p = word;
638 if (*p == '_' && prepends_underscore)
639 ++p;
641 if (no_demangle)
642 result = 0;
643 else
644 result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI);
646 if (result)
648 int diff;
649 fputs (result, stderr);
651 diff = strlen (word) - strlen (result);
652 while (diff > 0)
653 --diff, putc (' ', stderr);
654 while (diff < 0 && c == ' ')
655 ++diff, c = getc (stream);
657 free (result);
659 else
660 fputs (word, stderr);
662 fflush (stderr);
663 obstack_free (&temporary_obstack, temporary_firstobj);
665 if (c == EOF)
666 break;
667 putc (c, stderr);
669 fclose (stream);
672 /* Decide whether the given symbol is:
673 a constructor (1), a destructor (2), or neither (0). */
675 static int
676 is_ctor_dtor (s)
677 char *s;
679 struct names { char *name; int len; int ret; int two_underscores; };
681 register struct names *p;
682 register int ch;
683 register char *orig_s = s;
685 static struct names special[] = {
686 #ifdef NO_DOLLAR_IN_LABEL
687 #ifdef NO_DOT_IN_LABEL
688 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
689 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
690 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
691 #else
692 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
693 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
694 { "GLOBAL_.F.", sizeof ("GLOBAL_.F.")-1, 5, 0 },
695 #endif
696 #else
697 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
698 { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },
699 { "GLOBAL_$F$", sizeof ("GLOBAL_$F$")-1, 5, 0 },
700 #endif
701 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
702 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
703 #ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions.
704 cfront has its own linker procedure to collect them;
705 if collect2 gets them too, they get collected twice
706 when the cfront procedure is run and the compiler used
707 for linking happens to be GCC. */
708 { "sti__", sizeof ("sti__")-1, 1, 1 },
709 { "std__", sizeof ("std__")-1, 2, 1 },
710 #endif /* CFRONT_LOSSAGE */
711 { NULL, 0, 0, 0 }
714 while ((ch = *s) == '_')
715 ++s;
717 if (s == orig_s)
718 return 0;
720 for (p = &special[0]; p->len > 0; p++)
722 if (ch == p->name[0]
723 && (!p->two_underscores || ((s - orig_s) >= 2))
724 && strncmp(s, p->name, p->len) == 0)
726 return p->ret;
729 return 0;
732 /* Routine to add variables to the environment. */
734 #ifndef HAVE_PUTENV
737 putenv (str)
738 char *str;
740 #ifndef VMS /* nor about VMS */
742 extern char **environ;
743 char **old_environ = environ;
744 char **envp;
745 int num_envs = 0;
746 int name_len = 1;
747 char *p = str;
748 int ch;
750 while ((ch = *p++) != '\0' && ch != '=')
751 name_len++;
753 if (!ch)
754 abort ();
756 /* Search for replacing an existing environment variable, and
757 count the number of total environment variables. */
758 for (envp = old_environ; *envp; envp++)
760 num_envs++;
761 if (!strncmp (str, *envp, name_len))
763 *envp = str;
764 return 0;
768 /* Add a new environment variable */
769 environ = (char **) xmalloc (sizeof (char *) * (num_envs+2));
770 *environ = str;
771 bcopy ((char *) old_environ, (char *) (environ + 1),
772 sizeof (char *) * (num_envs+1));
774 return 0;
775 #endif /* VMS */
778 #endif /* HAVE_PUTENV */
780 /* By default, colon separates directories in a path. */
781 #ifndef PATH_SEPARATOR
782 #define PATH_SEPARATOR ':'
783 #endif
785 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
786 and one from the PATH variable. */
788 static struct path_prefix cpath, path;
790 #ifdef CROSS_COMPILE
791 /* This is the name of the target machine. We use it to form the name
792 of the files to execute. */
794 static char *target_machine = TARGET_MACHINE;
795 #endif
797 /* Search for NAME using prefix list PPREFIX. We only look for executable
798 files.
800 Return 0 if not found, otherwise return its name, allocated with malloc. */
802 static char *
803 find_a_file (pprefix, name)
804 struct path_prefix *pprefix;
805 char *name;
807 char *temp;
808 struct prefix_list *pl;
809 int len = pprefix->max_len + strlen (name) + 1;
811 if (debug)
812 fprintf (stderr, "Looking for '%s'\n", name);
814 #ifdef EXECUTABLE_SUFFIX
815 len += strlen (EXECUTABLE_SUFFIX);
816 #endif
818 temp = xmalloc (len);
820 /* Determine the filename to execute (special case for absolute paths). */
822 if (*name == '/'
823 #ifdef DIR_SEPARATOR
824 || (DIR_SEPARATOR == '\\' && name[1] == ':'
825 && (name[2] == DIR_SEPARATOR || name[2] == '/'))
826 #endif
829 if (access (name, X_OK) == 0)
831 strcpy (temp, name);
833 if (debug)
834 fprintf (stderr, " - found: absolute path\n");
836 return temp;
839 if (debug)
840 fprintf (stderr, " - failed to locate using absolute path\n");
842 else
843 for (pl = pprefix->plist; pl; pl = pl->next)
845 strcpy (temp, pl->prefix);
846 strcat (temp, name);
848 if (access (temp, X_OK) == 0)
849 return temp;
851 #ifdef EXECUTABLE_SUFFIX
852 /* Some systems have a suffix for executable files.
853 So try appending that. */
854 strcat (temp, EXECUTABLE_SUFFIX);
856 if (access (temp, X_OK) == 0)
857 return temp;
858 #endif
861 if (debug && pprefix->plist == NULL)
862 fprintf (stderr, " - failed: no entries in prefix list\n");
864 free (temp);
865 return 0;
868 /* Add an entry for PREFIX to prefix list PPREFIX. */
870 static void
871 add_prefix (pprefix, prefix)
872 struct path_prefix *pprefix;
873 char *prefix;
875 struct prefix_list *pl, **prev;
876 int len;
878 if (pprefix->plist)
880 for (pl = pprefix->plist; pl->next; pl = pl->next)
882 prev = &pl->next;
884 else
885 prev = &pprefix->plist;
887 /* Keep track of the longest prefix */
889 len = strlen (prefix);
890 if (len > pprefix->max_len)
891 pprefix->max_len = len;
893 pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
894 pl->prefix = xstrdup (prefix);
896 if (*prev)
897 pl->next = *prev;
898 else
899 pl->next = (struct prefix_list *) 0;
900 *prev = pl;
903 /* Take the value of the environment variable ENV, break it into a path, and
904 add of the entries to PPREFIX. */
906 static void
907 prefix_from_env (env, pprefix)
908 char *env;
909 struct path_prefix *pprefix;
911 char *p;
912 GET_ENV_PATH_LIST (p, env);
914 if (p)
915 prefix_from_string (p, pprefix);
918 static void
919 prefix_from_string (p, pprefix)
920 char *p;
921 struct path_prefix *pprefix;
923 char *startp, *endp;
924 char *nstore = (char *) xmalloc (strlen (p) + 3);
926 if (debug)
927 fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
929 startp = endp = p;
930 while (1)
932 if (*endp == PATH_SEPARATOR || *endp == 0)
934 strncpy (nstore, startp, endp-startp);
935 if (endp == startp)
937 strcpy (nstore, "./");
939 else if (endp[-1] != '/')
941 nstore[endp-startp] = '/';
942 nstore[endp-startp+1] = 0;
944 else
945 nstore[endp-startp] = 0;
947 if (debug)
948 fprintf (stderr, " - add prefix: %s\n", nstore);
950 add_prefix (pprefix, nstore);
951 if (*endp == 0)
952 break;
953 endp = startp = endp + 1;
955 else
956 endp++;
960 /* Main program. */
963 main (argc, argv)
964 int argc;
965 char *argv[];
967 char *ld_suffix = "ld";
968 char *full_ld_suffix = ld_suffix;
969 char *real_ld_suffix = "real-ld";
970 char *collect_ld_suffix = "collect-ld";
971 char *nm_suffix = "nm";
972 char *full_nm_suffix = nm_suffix;
973 char *gnm_suffix = "gnm";
974 char *full_gnm_suffix = gnm_suffix;
975 #ifdef LDD_SUFFIX
976 char *ldd_suffix = LDD_SUFFIX;
977 char *full_ldd_suffix = ldd_suffix;
978 #endif
979 char *strip_suffix = "strip";
980 char *full_strip_suffix = strip_suffix;
981 char *gstrip_suffix = "gstrip";
982 char *full_gstrip_suffix = gstrip_suffix;
983 char *arg;
984 FILE *outf;
985 #ifdef COLLECT_EXPORT_LIST
986 FILE *exportf;
987 FILE *importf;
988 #endif
989 char *ld_file_name;
990 char *p;
991 char **c_argv;
992 char **c_ptr;
993 char **ld1_argv;
994 char **ld1;
995 char **ld2_argv;
996 char **ld2;
997 char **object_lst;
998 char **object;
999 int first_file;
1000 int num_c_args = argc+9;
1002 #ifdef HAVE_LC_MESSAGES
1003 setlocale (LC_MESSAGES, "");
1004 #endif
1005 bindtextdomain (PACKAGE, localedir);
1006 textdomain (PACKAGE);
1008 /* Do not invoke xcalloc before this point, since locale needs to be
1009 set first, in case a diagnostic is issued. */
1011 ld1 = ld1_argv = (char **) xcalloc (sizeof (char *), argc+3);
1012 ld2 = ld2_argv = (char **) xcalloc (sizeof (char *), argc+6);
1013 object = object_lst = (char **) xcalloc (sizeof (char *), argc);
1015 #ifdef DEBUG
1016 debug = 1;
1017 #endif
1019 /* Parse command line early for instances of -debug. This allows
1020 the debug flag to be set before functions like find_a_file()
1021 are called. */
1023 int i;
1025 for (i = 1; argv[i] != NULL; i ++)
1026 if (! strcmp (argv[i], "-debug"))
1027 debug = 1;
1028 vflag = debug;
1031 #ifndef DEFAULT_A_OUT_NAME
1032 output_file = "a.out";
1033 #else
1034 output_file = DEFAULT_A_OUT_NAME;
1035 #endif
1037 obstack_begin (&temporary_obstack, 0);
1038 obstack_begin (&permanent_obstack, 0);
1039 temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
1041 current_demangling_style = gnu_demangling;
1042 p = getenv ("COLLECT_GCC_OPTIONS");
1043 while (p && *p)
1045 char *q = extract_string (&p);
1046 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1047 num_c_args++;
1049 obstack_free (&temporary_obstack, temporary_firstobj);
1050 ++num_c_args;
1052 c_ptr = c_argv = (char **) xcalloc (sizeof (char *), num_c_args);
1054 if (argc < 2)
1055 fatal ("no arguments");
1057 #ifdef SIGQUIT
1058 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
1059 signal (SIGQUIT, handler);
1060 #endif
1061 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
1062 signal (SIGINT, handler);
1063 #ifdef SIGALRM
1064 if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
1065 signal (SIGALRM, handler);
1066 #endif
1067 #ifdef SIGHUP
1068 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
1069 signal (SIGHUP, handler);
1070 #endif
1071 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
1072 signal (SIGSEGV, handler);
1073 #ifdef SIGBUS
1074 if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
1075 signal (SIGBUS, handler);
1076 #endif
1078 /* Extract COMPILER_PATH and PATH into our prefix list. */
1079 prefix_from_env ("COMPILER_PATH", &cpath);
1080 prefix_from_env ("PATH", &path);
1082 #ifdef CROSS_COMPILE
1083 /* If we look for a program in the compiler directories, we just use
1084 the short name, since these directories are already system-specific.
1085 But it we look for a program in the system directories, we need to
1086 qualify the program name with the target machine. */
1088 full_ld_suffix
1089 = xcalloc (strlen (ld_suffix) + strlen (target_machine) + 2, 1);
1090 strcpy (full_ld_suffix, target_machine);
1091 strcat (full_ld_suffix, "-");
1092 strcat (full_ld_suffix, ld_suffix);
1094 #if 0
1095 full_gld_suffix
1096 = xcalloc (strlen (gld_suffix) + strlen (target_machine) + 2, 1);
1097 strcpy (full_gld_suffix, target_machine);
1098 strcat (full_gld_suffix, "-");
1099 strcat (full_gld_suffix, gld_suffix);
1100 #endif
1102 full_nm_suffix
1103 = xcalloc (strlen (nm_suffix) + strlen (target_machine) + 2, 1);
1104 strcpy (full_nm_suffix, target_machine);
1105 strcat (full_nm_suffix, "-");
1106 strcat (full_nm_suffix, nm_suffix);
1108 full_gnm_suffix
1109 = xcalloc (strlen (gnm_suffix) + strlen (target_machine) + 2, 1);
1110 strcpy (full_gnm_suffix, target_machine);
1111 strcat (full_gnm_suffix, "-");
1112 strcat (full_gnm_suffix, gnm_suffix);
1114 #ifdef LDD_SUFFIX
1115 full_ldd_suffix
1116 = xcalloc (strlen (ldd_suffix) + strlen (target_machine) + 2, 1);
1117 strcpy (full_ldd_suffix, target_machine);
1118 strcat (full_ldd_suffix, "-");
1119 strcat (full_ldd_suffix, ldd_suffix);
1120 #endif
1122 full_strip_suffix
1123 = xcalloc (strlen (strip_suffix) + strlen (target_machine) + 2, 1);
1124 strcpy (full_strip_suffix, target_machine);
1125 strcat (full_strip_suffix, "-");
1126 strcat (full_strip_suffix, strip_suffix);
1128 full_gstrip_suffix
1129 = xcalloc (strlen (gstrip_suffix) + strlen (target_machine) + 2, 1);
1130 strcpy (full_gstrip_suffix, target_machine);
1131 strcat (full_gstrip_suffix, "-");
1132 strcat (full_gstrip_suffix, gstrip_suffix);
1133 #endif /* CROSS_COMPILE */
1135 /* Try to discover a valid linker/nm/strip to use. */
1137 /* Maybe we know the right file to use (if not cross). */
1138 ld_file_name = 0;
1139 #ifdef DEFAULT_LINKER
1140 if (access (DEFAULT_LINKER, X_OK) == 0)
1141 ld_file_name = DEFAULT_LINKER;
1142 if (ld_file_name == 0)
1143 #endif
1144 #ifdef REAL_LD_FILE_NAME
1145 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
1146 if (ld_file_name == 0)
1147 #endif
1148 /* Search the (target-specific) compiler dirs for ld'. */
1149 ld_file_name = find_a_file (&cpath, real_ld_suffix);
1150 /* Likewise for `collect-ld'. */
1151 if (ld_file_name == 0)
1152 ld_file_name = find_a_file (&cpath, collect_ld_suffix);
1153 /* Search the compiler directories for `ld'. We have protection against
1154 recursive calls in find_a_file. */
1155 if (ld_file_name == 0)
1156 ld_file_name = find_a_file (&cpath, ld_suffix);
1157 /* Search the ordinary system bin directories
1158 for `ld' (if native linking) or `TARGET-ld' (if cross). */
1159 if (ld_file_name == 0)
1160 ld_file_name = find_a_file (&path, full_ld_suffix);
1162 #ifdef REAL_NM_FILE_NAME
1163 nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
1164 if (nm_file_name == 0)
1165 #endif
1166 nm_file_name = find_a_file (&cpath, gnm_suffix);
1167 if (nm_file_name == 0)
1168 nm_file_name = find_a_file (&path, full_gnm_suffix);
1169 if (nm_file_name == 0)
1170 nm_file_name = find_a_file (&cpath, nm_suffix);
1171 if (nm_file_name == 0)
1172 nm_file_name = find_a_file (&path, full_nm_suffix);
1174 #ifdef LDD_SUFFIX
1175 ldd_file_name = find_a_file (&cpath, ldd_suffix);
1176 if (ldd_file_name == 0)
1177 ldd_file_name = find_a_file (&path, full_ldd_suffix);
1178 #endif
1180 #ifdef REAL_STRIP_FILE_NAME
1181 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
1182 if (strip_file_name == 0)
1183 #endif
1184 strip_file_name = find_a_file (&cpath, gstrip_suffix);
1185 if (strip_file_name == 0)
1186 strip_file_name = find_a_file (&path, full_gstrip_suffix);
1187 if (strip_file_name == 0)
1188 strip_file_name = find_a_file (&cpath, strip_suffix);
1189 if (strip_file_name == 0)
1190 strip_file_name = find_a_file (&path, full_strip_suffix);
1192 /* Determine the full path name of the C compiler to use. */
1193 c_file_name = getenv ("COLLECT_GCC");
1194 if (c_file_name == 0)
1196 #ifdef CROSS_COMPILE
1197 c_file_name = xcalloc (sizeof ("gcc-") + strlen (target_machine) + 1, 1);
1198 strcpy (c_file_name, target_machine);
1199 strcat (c_file_name, "-gcc");
1200 #else
1201 c_file_name = "gcc";
1202 #endif
1205 p = find_a_file (&cpath, c_file_name);
1207 /* Here it should be safe to use the system search path since we should have
1208 already qualified the name of the compiler when it is needed. */
1209 if (p == 0)
1210 p = find_a_file (&path, c_file_name);
1212 if (p)
1213 c_file_name = p;
1215 *ld1++ = *ld2++ = ld_file_name;
1217 /* Make temp file names. */
1218 c_file = make_temp_file (".c");
1219 o_file = make_temp_file (".o");
1220 #ifdef COLLECT_EXPORT_LIST
1221 export_file = make_temp_file (".x");
1222 import_file = make_temp_file (".p");
1223 #endif
1224 ldout = make_temp_file (".ld");
1225 *c_ptr++ = c_file_name;
1226 *c_ptr++ = "-x";
1227 *c_ptr++ = "c";
1228 *c_ptr++ = "-c";
1229 *c_ptr++ = "-o";
1230 *c_ptr++ = o_file;
1232 #ifdef COLLECT_EXPORT_LIST
1233 /* Generate a list of directories from LIBPATH. */
1234 prefix_from_env ("LIBPATH", &libpath_lib_dirs);
1235 /* Add to this list also two standard directories where
1236 AIX loader always searches for libraries. */
1237 add_prefix (&libpath_lib_dirs, "/lib");
1238 add_prefix (&libpath_lib_dirs, "/usr/lib");
1239 #endif
1241 /* Get any options that the upper GCC wants to pass to the sub-GCC.
1243 AIX support needs to know if -shared has been specified before
1244 parsing commandline arguments. */
1246 p = getenv ("COLLECT_GCC_OPTIONS");
1247 while (p && *p)
1249 char *q = extract_string (&p);
1250 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1251 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1252 if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0)
1253 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1254 if (strncmp (q, "-shared", sizeof ("-shared") - 1) == 0)
1255 shared_obj = 1;
1257 obstack_free (&temporary_obstack, temporary_firstobj);
1258 *c_ptr++ = "-fno-exceptions";
1260 /* !!! When GCC calls collect2,
1261 it does not know whether it is calling collect2 or ld.
1262 So collect2 cannot meaningfully understand any options
1263 except those ld understands.
1264 If you propose to make GCC pass some other option,
1265 just imagine what will happen if ld is really ld!!! */
1267 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1268 /* After the first file, put in the c++ rt0. */
1270 first_file = 1;
1271 while ((arg = *++argv) != (char *) 0)
1273 *ld1++ = *ld2++ = arg;
1275 if (arg[0] == '-')
1277 switch (arg[1])
1279 #ifdef COLLECT_EXPORT_LIST
1280 /* We want to disable automatic exports on AIX when user
1281 explicitly puts an export list in command line */
1282 case 'b':
1283 if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
1284 export_flag = 1;
1285 else if (arg[2] == '6' && arg[3] == '4')
1286 aix64_flag = 1;
1287 break;
1288 #endif
1290 case 'd':
1291 if (!strcmp (arg, "-debug"))
1293 /* Already parsed. */
1294 ld1--;
1295 ld2--;
1297 break;
1299 case 'l':
1300 if (first_file)
1302 /* place o_file BEFORE this argument! */
1303 first_file = 0;
1304 ld2--;
1305 *ld2++ = o_file;
1306 *ld2++ = arg;
1308 #ifdef COLLECT_EXPORT_LIST
1310 /* Resolving full library name. */
1311 char *s = resolve_lib_name (arg+2);
1313 /* If we will use an import list for this library,
1314 we should exclude it from ld args. */
1315 if (use_import_list (s))
1317 ld1--;
1318 ld2--;
1321 /* Saving a full library name. */
1322 add_to_list (&libs, s);
1324 #endif
1325 break;
1327 #ifdef COLLECT_EXPORT_LIST
1328 /* Saving directories where to search for libraries. */
1329 case 'L':
1330 add_prefix (&cmdline_lib_dirs, arg+2);
1331 break;
1332 #endif
1334 case 'o':
1335 if (arg[2] == '\0')
1336 output_file = *ld1++ = *ld2++ = *++argv;
1337 else
1338 output_file = &arg[2];
1339 break;
1341 case 'r':
1342 if (arg[2] == '\0')
1343 rflag = 1;
1344 break;
1346 case 's':
1347 if (arg[2] == '\0' && do_collecting)
1349 /* We must strip after the nm run, otherwise C++ linking
1350 will not work. Thus we strip in the second ld run, or
1351 else with strip if there is no second ld run. */
1352 strip_flag = 1;
1353 ld1--;
1355 break;
1357 case 'v':
1358 if (arg[2] == '\0')
1359 vflag = 1;
1360 break;
1363 else if ((p = rindex (arg, '.')) != (char *) 0
1364 && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
1365 || strcmp (p, ".so") == 0))
1367 if (first_file)
1369 first_file = 0;
1370 if (p[1] == 'o')
1371 *ld2++ = o_file;
1372 else
1374 /* place o_file BEFORE this argument! */
1375 ld2--;
1376 *ld2++ = o_file;
1377 *ld2++ = arg;
1380 if (p[1] == 'o')
1381 *object++ = arg;
1382 #ifdef COLLECT_EXPORT_LIST
1383 /* libraries can be specified directly, i.e. without -l flag. */
1384 else
1386 /* If we will use an import list for this library,
1387 we should exclude it from ld args. */
1388 if (use_import_list (arg))
1390 ld1--;
1391 ld2--;
1394 /* Saving a full library name. */
1395 add_to_list (&libs, arg);
1397 #endif
1401 #ifdef COLLECT_EXPORT_LIST
1402 /* This is added only for debugging purposes. */
1403 if (debug)
1405 fprintf (stderr, "List of libraries:\n");
1406 dump_list (stderr, "\t", libs.first);
1409 /* The AIX linker will discard static constructors in object files if
1410 nothing else in the file is referenced, so look at them first. */
1412 char **export_object_lst = object_lst;
1413 while (export_object_lst < object)
1414 scan_prog_file (*export_object_lst++, PASS_OBJ);
1417 struct id *list = libs.first;
1418 for (; list; list = list->next)
1419 scan_prog_file (list->name, PASS_FIRST);
1422 char *buf1 = alloca (strlen (export_file) + 5);
1423 char *buf2 = alloca (strlen (import_file) + 5);
1424 sprintf (buf1, "-bE:%s", export_file);
1425 sprintf (buf2, "-bI:%s", import_file);
1426 *ld1++ = buf1;
1427 *ld2++ = buf1;
1428 *ld1++ = buf2;
1429 *ld2++ = buf2;
1430 exportf = fopen (export_file, "w");
1431 if (exportf == (FILE *) 0)
1432 fatal_perror ("fopen %s", export_file);
1433 write_export_file (exportf);
1434 if (fclose (exportf))
1435 fatal_perror ("fclose %s", export_file);
1436 importf = fopen (import_file, "w");
1437 if (importf == (FILE *) 0)
1438 fatal_perror ("%s", import_file);
1439 write_import_file (importf);
1440 if (fclose (importf))
1441 fatal_perror ("fclose %s", import_file);
1443 #endif
1445 *c_ptr++ = c_file;
1446 *object = *c_ptr = *ld1 = (char *) 0;
1448 if (vflag)
1450 notice ("collect2 version %s", version_string);
1451 #ifdef TARGET_VERSION
1452 TARGET_VERSION;
1453 #endif
1454 fprintf (stderr, "\n");
1457 if (debug)
1459 char *ptr;
1460 fprintf (stderr, "ld_file_name = %s\n",
1461 (ld_file_name ? ld_file_name : "not found"));
1462 fprintf (stderr, "c_file_name = %s\n",
1463 (c_file_name ? c_file_name : "not found"));
1464 fprintf (stderr, "nm_file_name = %s\n",
1465 (nm_file_name ? nm_file_name : "not found"));
1466 #ifdef LDD_SUFFIX
1467 fprintf (stderr, "ldd_file_name = %s\n",
1468 (ldd_file_name ? ldd_file_name : "not found"));
1469 #endif
1470 fprintf (stderr, "strip_file_name = %s\n",
1471 (strip_file_name ? strip_file_name : "not found"));
1472 fprintf (stderr, "c_file = %s\n",
1473 (c_file ? c_file : "not found"));
1474 fprintf (stderr, "o_file = %s\n",
1475 (o_file ? o_file : "not found"));
1477 ptr = getenv ("COLLECT_GCC_OPTIONS");
1478 if (ptr)
1479 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1481 ptr = getenv ("COLLECT_GCC");
1482 if (ptr)
1483 fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
1485 ptr = getenv ("COMPILER_PATH");
1486 if (ptr)
1487 fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
1489 ptr = getenv ("LIBRARY_PATH");
1490 if (ptr)
1491 fprintf (stderr, "LIBRARY_PATH = %s\n", ptr);
1493 fprintf (stderr, "\n");
1496 /* Load the program, searching all libraries and attempting to provide
1497 undefined symbols from repository information. */
1499 /* On AIX we do this later. */
1500 #ifndef COLLECT_EXPORT_LIST
1501 do_tlink (ld1_argv, object_lst);
1502 #endif
1504 /* If -r or they will be run via some other method, do not build the
1505 constructor or destructor list, just return now. */
1506 if (rflag
1507 #ifndef COLLECT_EXPORT_LIST
1508 || ! do_collecting
1509 #endif
1512 #ifdef COLLECT_EXPORT_LIST
1513 /* But make sure we delete the export file we may have created. */
1514 if (export_file != 0 && export_file[0])
1515 maybe_unlink (export_file);
1516 if (import_file != 0 && import_file[0])
1517 maybe_unlink (import_file);
1518 #endif
1519 maybe_unlink (c_file);
1520 maybe_unlink (o_file);
1521 return 0;
1524 /* Examine the namelist with nm and search it for static constructors
1525 and destructors to call.
1526 Write the constructor and destructor tables to a .s file and reload. */
1528 /* On AIX we already done scanning for global constructors/destructors. */
1529 #ifndef COLLECT_EXPORT_LIST
1530 scan_prog_file (output_file, PASS_FIRST);
1531 #endif
1533 #ifdef SCAN_LIBRARIES
1534 scan_libraries (output_file);
1535 #endif
1537 if (debug)
1539 notice ("%d constructor(s) found\n", constructors.number);
1540 notice ("%d destructor(s) found\n", destructors.number);
1543 if (constructors.number == 0 && destructors.number == 0
1544 && frame_tables.number == 0
1545 #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1546 /* If we will be running these functions ourselves, we want to emit
1547 stubs into the shared library so that we do not have to relink
1548 dependent programs when we add static objects. */
1549 && ! shared_obj
1550 #endif
1553 #ifdef COLLECT_EXPORT_LIST
1554 /* Doing tlink without additional code generation */
1555 do_tlink (ld1_argv, object_lst);
1556 #endif
1557 /* Strip now if it was requested on the command line. */
1558 if (strip_flag)
1560 char **strip_argv = (char **) xcalloc (sizeof (char *), 3);
1561 strip_argv[0] = strip_file_name;
1562 strip_argv[1] = output_file;
1563 strip_argv[2] = (char *) 0;
1564 fork_execute ("strip", strip_argv);
1567 #ifdef COLLECT_EXPORT_LIST
1568 maybe_unlink (export_file);
1569 maybe_unlink (import_file);
1570 #endif
1571 maybe_unlink (c_file);
1572 maybe_unlink (o_file);
1573 return 0;
1576 /* Sort ctor and dtor lists by priority. */
1577 sort_ids (&constructors);
1578 sort_ids (&destructors);
1580 maybe_unlink(output_file);
1581 outf = fopen (c_file, "w");
1582 if (outf == (FILE *) 0)
1583 fatal_perror ("fopen %s", c_file);
1585 write_c_file (outf, c_file);
1587 if (fclose (outf))
1588 fatal_perror ("fclose %s", c_file);
1590 /* Tell the linker that we have initializer and finalizer functions. */
1591 #ifdef LD_INIT_SWITCH
1592 *ld2++ = LD_INIT_SWITCH;
1593 *ld2++ = initname;
1594 *ld2++ = LD_FINI_SWITCH;
1595 *ld2++ = fininame;
1596 #endif
1597 *ld2 = (char*) 0;
1599 #ifdef COLLECT_EXPORT_LIST
1600 if (shared_obj)
1602 add_to_list (&exports, initname);
1603 add_to_list (&exports, fininame);
1604 add_to_list (&exports, "_GLOBAL__DI");
1605 add_to_list (&exports, "_GLOBAL__DD");
1606 exportf = fopen (export_file, "w");
1607 if (exportf == (FILE *) 0)
1608 fatal_perror ("fopen %s", export_file);
1609 write_export_file (exportf);
1610 if (fclose (exportf))
1611 fatal_perror ("fclose %s", export_file);
1613 #endif
1615 if (debug)
1617 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1618 output_file, c_file);
1619 write_c_file (stderr, "stderr");
1620 fprintf (stderr, "========== end of c_file\n\n");
1621 #ifdef COLLECT_EXPORT_LIST
1622 fprintf (stderr, "\n========== export_file = %s\n", export_file);
1623 write_export_file (stderr);
1624 fprintf (stderr, "========== end of export_file\n\n");
1625 #endif
1628 /* Assemble the constructor and destructor tables.
1629 Link the tables in with the rest of the program. */
1631 fork_execute ("gcc", c_argv);
1632 #ifdef COLLECT_EXPORT_LIST
1633 /* On AIX we must call tlink because of possible templates resolution */
1634 do_tlink (ld2_argv, object_lst);
1635 #else
1636 /* Otherwise, simply call ld because tlink is already done */
1637 fork_execute ("ld", ld2_argv);
1639 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1640 constructors/destructors in shared libraries. */
1641 scan_prog_file (output_file, PASS_SECOND);
1642 #endif
1644 maybe_unlink (c_file);
1645 maybe_unlink (o_file);
1647 #ifdef COLLECT_EXPORT_LIST
1648 maybe_unlink (export_file);
1649 maybe_unlink (import_file);
1650 #endif
1652 return 0;
1656 /* Wait for a process to finish, and exit if a non-zero status is found. */
1659 collect_wait (prog)
1660 char *prog;
1662 int status;
1664 wait (&status);
1665 if (status)
1667 if (WIFSIGNALED (status))
1669 int sig = WTERMSIG (status);
1670 error ((status & 0200
1671 ? "%s terminated with signal %d [%s]"
1672 : "%s terminated with signal %d [%s], core dumped"),
1673 prog,
1674 sig,
1675 my_strsignal(sig));
1676 collect_exit (FATAL_EXIT_CODE);
1679 if (WIFEXITED (status))
1680 return WEXITSTATUS (status);
1682 return 0;
1685 static void
1686 do_wait (prog)
1687 char *prog;
1689 int ret = collect_wait (prog);
1690 if (ret != 0)
1692 error ("%s returned %d exit status", prog, ret);
1693 collect_exit (ret);
1698 /* Fork and execute a program, and wait for the reply. */
1700 void
1701 collect_execute (prog, argv, redir)
1702 char *prog;
1703 char **argv;
1704 char *redir;
1706 int pid;
1708 if (vflag || debug)
1710 char **p_argv;
1711 char *str;
1713 if (argv[0])
1714 fprintf (stderr, "%s", argv[0]);
1715 else
1716 notice ("[cannot find %s]", prog);
1718 for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
1719 fprintf (stderr, " %s", str);
1721 fprintf (stderr, "\n");
1724 fflush (stdout);
1725 fflush (stderr);
1727 /* If we cannot find a program we need, complain error. Do this here
1728 since we might not end up needing something that we could not find. */
1730 if (argv[0] == 0)
1731 fatal ("cannot find `%s'", prog);
1733 pid = vfork ();
1734 if (pid == -1)
1735 fatal_perror (VFORK_STRING);
1737 if (pid == 0) /* child context */
1739 if (redir)
1741 unlink (redir);
1742 if (freopen (redir, "a", stdout) == NULL)
1743 fatal_perror ("freopen stdout %s", redir);
1744 if (freopen (redir, "a", stderr) == NULL)
1745 fatal_perror ("freopen stderr %s", redir);
1748 execvp (argv[0], argv);
1749 fatal_perror ("execvp %s", prog);
1753 static void
1754 fork_execute (prog, argv)
1755 char *prog;
1756 char **argv;
1758 collect_execute (prog, argv, NULL);
1759 do_wait (prog);
1762 /* Unlink a file unless we are debugging. */
1764 static void
1765 maybe_unlink (file)
1766 char *file;
1768 if (!debug)
1769 unlink (file);
1770 else
1771 notice ("[Leaving %s]\n", file);
1775 static long sequence_number = 0;
1777 /* Add a name to a linked list. */
1779 static void
1780 add_to_list (head_ptr, name)
1781 struct head *head_ptr;
1782 char *name;
1784 struct id *newid
1785 = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
1786 struct id *p;
1787 strcpy (newid->name, name);
1789 if (head_ptr->first)
1790 head_ptr->last->next = newid;
1791 else
1792 head_ptr->first = newid;
1794 /* Check for duplicate symbols. */
1795 for (p = head_ptr->first;
1796 strcmp (name, p->name) != 0;
1797 p = p->next)
1799 if (p != newid)
1801 head_ptr->last->next = 0;
1802 free (newid);
1803 return;
1806 newid->sequence = ++sequence_number;
1807 head_ptr->last = newid;
1808 head_ptr->number++;
1811 /* Grab the init priority number from an init function name that
1812 looks like "_GLOBAL_.I.12345.foo". */
1814 static int
1815 extract_init_priority (name)
1816 char *name;
1818 int pos = 0, pri;
1820 while (name[pos] == '_')
1821 ++pos;
1822 pos += 10; /* strlen ("GLOBAL__X_") */
1824 /* Extract init_p number from ctor/dtor name. */
1825 pri = atoi (name + pos);
1826 return pri ? pri : DEFAULT_INIT_PRIORITY;
1829 /* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
1830 ctors will be run from right to left, dtors from left to right. */
1832 static void
1833 sort_ids (head_ptr)
1834 struct head *head_ptr;
1836 /* id holds the current element to insert. id_next holds the next
1837 element to insert. id_ptr iterates through the already sorted elements
1838 looking for the place to insert id. */
1839 struct id *id, *id_next, **id_ptr;
1841 id = head_ptr->first;
1843 /* We don't have any sorted elements yet. */
1844 head_ptr->first = NULL;
1846 for (; id; id = id_next)
1848 id_next = id->next;
1849 id->sequence = extract_init_priority (id->name);
1851 for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next))
1852 if (*id_ptr == NULL
1853 /* If the sequence numbers are the same, we put the id from the
1854 file later on the command line later in the list. */
1855 || id->sequence > (*id_ptr)->sequence
1856 /* Hack: do lexical compare, too.
1857 || (id->sequence == (*id_ptr)->sequence
1858 && strcmp (id->name, (*id_ptr)->name) > 0) */
1861 id->next = *id_ptr;
1862 *id_ptr = id;
1863 break;
1867 /* Now set the sequence numbers properly so write_c_file works. */
1868 for (id = head_ptr->first; id; id = id->next)
1869 id->sequence = ++sequence_number;
1872 /* Write: `prefix', the names on list LIST, `suffix'. */
1874 static void
1875 write_list (stream, prefix, list)
1876 FILE *stream;
1877 char *prefix;
1878 struct id *list;
1880 while (list)
1882 fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1883 list = list->next;
1887 #ifdef COLLECT_EXPORT_LIST
1888 /* This function is really used only on AIX, but may be useful. */
1889 static int
1890 is_in_list (prefix, list)
1891 char *prefix;
1892 struct id *list;
1894 while (list)
1896 if (!strcmp (prefix, list->name)) return 1;
1897 list = list->next;
1899 return 0;
1901 #endif
1903 /* Added for debugging purpose. */
1904 #ifdef COLLECT_EXPORT_LIST
1905 static void
1906 dump_list (stream, prefix, list)
1907 FILE *stream;
1908 char *prefix;
1909 struct id *list;
1911 while (list)
1913 fprintf (stream, "%s%s,\n", prefix, list->name);
1914 list = list->next;
1917 #endif
1919 #if 0
1920 static void
1921 dump_prefix_list (stream, prefix, list)
1922 FILE *stream;
1923 char *prefix;
1924 struct prefix_list *list;
1926 while (list)
1928 fprintf (stream, "%s%s,\n", prefix, list->prefix);
1929 list = list->next;
1932 #endif
1934 static void
1935 write_list_with_asm (stream, prefix, list)
1936 FILE *stream;
1937 char *prefix;
1938 struct id *list;
1940 while (list)
1942 fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1943 prefix, list->sequence, list->name);
1944 list = list->next;
1948 /* Write out the constructor and destructor tables statically (for a shared
1949 object), along with the functions to execute them. */
1951 static void
1952 write_c_file_stat (stream, name)
1953 FILE *stream;
1954 char *name;
1956 char *prefix, *p, *q;
1957 int frames = (frame_tables.number > 0);
1959 /* Figure out name of output_file, stripping off .so version. */
1960 p = rindex (output_file, '/');
1961 if (p == 0)
1962 p = (char *) output_file;
1963 else
1964 p++;
1965 q = p;
1966 while (q)
1968 q = index (q,'.');
1969 if (q == 0)
1971 q = p + strlen (p);
1972 break;
1974 else
1976 if (strncmp (q, ".so", 3) == 0)
1978 q += 3;
1979 break;
1981 else
1982 q++;
1985 /* q points to null at end of the string (or . of the .so version) */
1986 prefix = xmalloc (q - p + 1);
1987 strncpy (prefix, p, q - p);
1988 prefix[q - p] = 0;
1989 for (q = prefix; *q; q++)
1990 if (!ISALNUM ((unsigned char)*q))
1991 *q = '_';
1992 if (debug)
1993 notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
1994 output_file, prefix);
1996 #define INIT_NAME_FORMAT "_GLOBAL__FI_%s"
1997 initname = xmalloc (strlen (prefix) + sizeof (INIT_NAME_FORMAT) - 2);
1998 sprintf (initname, INIT_NAME_FORMAT, prefix);
2000 #define FINI_NAME_FORMAT "_GLOBAL__FD_%s"
2001 fininame = xmalloc (strlen (prefix) + sizeof (FINI_NAME_FORMAT) - 2);
2002 sprintf (fininame, FINI_NAME_FORMAT, prefix);
2004 free (prefix);
2006 /* Write the tables as C code */
2008 fprintf (stream, "static int count;\n");
2009 fprintf (stream, "typedef void entry_pt();\n");
2010 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
2012 if (frames)
2014 write_list_with_asm (stream, "extern void *", frame_tables.first);
2016 fprintf (stream, "\tstatic void *frame_table[] = {\n");
2017 write_list (stream, "\t\t&", frame_tables.first);
2018 fprintf (stream, "\t0\n};\n");
2020 /* This must match what's in frame.h. */
2021 fprintf (stream, "struct object {\n");
2022 fprintf (stream, " void *pc_begin;\n");
2023 fprintf (stream, " void *pc_end;\n");
2024 fprintf (stream, " void *fde_begin;\n");
2025 fprintf (stream, " void *fde_array;\n");
2026 fprintf (stream, " __SIZE_TYPE__ count;\n");
2027 fprintf (stream, " struct object *next;\n");
2028 fprintf (stream, "};\n");
2030 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
2031 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
2033 fprintf (stream, "static void reg_frame () {\n");
2034 fprintf (stream, "\tstatic struct object ob;\n");
2035 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
2036 fprintf (stream, "\t}\n");
2038 fprintf (stream, "static void dereg_frame () {\n");
2039 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
2040 fprintf (stream, "\t}\n");
2043 fprintf (stream, "void %s() {\n", initname);
2044 if (constructors.number > 0 || frames)
2046 fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
2047 write_list (stream, "\t\t", constructors.first);
2048 if (frames)
2049 fprintf (stream, "\treg_frame,\n");
2050 fprintf (stream, "\t};\n");
2051 fprintf (stream, "\tentry_pt **p;\n");
2052 fprintf (stream, "\tif (count++ != 0) return;\n");
2053 fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
2054 fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
2056 else
2057 fprintf (stream, "\t++count;\n");
2058 fprintf (stream, "}\n");
2059 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
2060 fprintf (stream, "void %s() {\n", fininame);
2061 if (destructors.number > 0 || frames)
2063 fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
2064 write_list (stream, "\t\t", destructors.first);
2065 if (frames)
2066 fprintf (stream, "\tdereg_frame,\n");
2067 fprintf (stream, "\t};\n");
2068 fprintf (stream, "\tentry_pt **p;\n");
2069 fprintf (stream, "\tif (--count != 0) return;\n");
2070 fprintf (stream, "\tp = dtors;\n");
2071 fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
2072 destructors.number + frames);
2074 fprintf (stream, "}\n");
2076 if (shared_obj)
2078 fprintf (stream, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname);
2079 fprintf (stream, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame);
2083 /* Write the constructor/destructor tables. */
2085 #ifndef LD_INIT_SWITCH
2086 static void
2087 write_c_file_glob (stream, name)
2088 FILE *stream;
2089 char *name;
2091 /* Write the tables as C code */
2093 int frames = (frame_tables.number > 0);
2095 fprintf (stream, "typedef void entry_pt();\n\n");
2097 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
2099 if (frames)
2101 write_list_with_asm (stream, "extern void *", frame_tables.first);
2103 fprintf (stream, "\tstatic void *frame_table[] = {\n");
2104 write_list (stream, "\t\t&", frame_tables.first);
2105 fprintf (stream, "\t0\n};\n");
2107 /* This must match what's in frame.h. */
2108 fprintf (stream, "struct object {\n");
2109 fprintf (stream, " void *pc_begin;\n");
2110 fprintf (stream, " void *pc_end;\n");
2111 fprintf (stream, " void *fde_begin;\n");
2112 fprintf (stream, " void *fde_array;\n");
2113 fprintf (stream, " __SIZE_TYPE__ count;\n");
2114 fprintf (stream, " struct object *next;\n");
2115 fprintf (stream, "};\n");
2117 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
2118 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
2120 fprintf (stream, "static void reg_frame () {\n");
2121 fprintf (stream, "\tstatic struct object ob;\n");
2122 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
2123 fprintf (stream, "\t}\n");
2125 fprintf (stream, "static void dereg_frame () {\n");
2126 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
2127 fprintf (stream, "\t}\n");
2130 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
2131 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
2132 write_list (stream, "\t", constructors.first);
2133 if (frames)
2134 fprintf (stream, "\treg_frame,\n");
2135 fprintf (stream, "\t0\n};\n\n");
2137 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
2139 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
2140 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
2141 write_list (stream, "\t", destructors.first);
2142 if (frames)
2143 fprintf (stream, "\tdereg_frame,\n");
2144 fprintf (stream, "\t0\n};\n\n");
2146 fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
2147 fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
2149 #endif /* ! LD_INIT_SWITCH */
2151 static void
2152 write_c_file (stream, name)
2153 FILE *stream;
2154 char *name;
2156 fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
2157 #ifndef LD_INIT_SWITCH
2158 if (! shared_obj)
2159 write_c_file_glob (stream, name);
2160 else
2161 #endif
2162 write_c_file_stat (stream, name);
2163 fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
2166 #ifdef COLLECT_EXPORT_LIST
2167 static void
2168 write_export_file (stream)
2169 FILE *stream;
2171 struct id *list = exports.first;
2172 for (; list; list = list->next)
2173 fprintf (stream, "%s\n", list->name);
2176 static void
2177 write_import_file (stream)
2178 FILE *stream;
2180 struct id *list = imports.first;
2181 fprintf (stream, "%s\n", "#! .");
2182 for (; list; list = list->next)
2183 fprintf (stream, "%s\n", list->name);
2185 #endif
2187 #ifdef OBJECT_FORMAT_NONE
2189 /* Generic version to scan the name list of the loaded program for
2190 the symbols g++ uses for static constructors and destructors.
2192 The constructor table begins at __CTOR_LIST__ and contains a count
2193 of the number of pointers (or -1 if the constructors are built in a
2194 separate section by the linker), followed by the pointers to the
2195 constructor functions, terminated with a null pointer. The
2196 destructor table has the same format, and begins at __DTOR_LIST__. */
2198 static void
2199 scan_prog_file (prog_name, which_pass)
2200 char *prog_name;
2201 enum pass which_pass;
2203 void (*int_handler) ();
2204 void (*quit_handler) ();
2205 char *nm_argv[4];
2206 int pid;
2207 int argc = 0;
2208 int pipe_fd[2];
2209 char *p, buf[1024];
2210 FILE *inf;
2212 if (which_pass == PASS_SECOND)
2213 return;
2215 /* If we do not have an `nm', complain. */
2216 if (nm_file_name == 0)
2217 fatal ("cannot find `nm'");
2219 nm_argv[argc++] = nm_file_name;
2220 if (NM_FLAGS[0] != '\0')
2221 nm_argv[argc++] = NM_FLAGS;
2223 nm_argv[argc++] = prog_name;
2224 nm_argv[argc++] = (char *) 0;
2226 if (pipe (pipe_fd) < 0)
2227 fatal_perror ("pipe");
2229 inf = fdopen (pipe_fd[0], "r");
2230 if (inf == (FILE *) 0)
2231 fatal_perror ("fdopen");
2233 /* Trace if needed. */
2234 if (vflag)
2236 char **p_argv;
2237 char *str;
2239 for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2240 fprintf (stderr, " %s", str);
2242 fprintf (stderr, "\n");
2245 fflush (stdout);
2246 fflush (stderr);
2248 /* Spawn child nm on pipe */
2249 pid = vfork ();
2250 if (pid == -1)
2251 fatal_perror (VFORK_STRING);
2253 if (pid == 0) /* child context */
2255 /* setup stdout */
2256 if (dup2 (pipe_fd[1], 1) < 0)
2257 fatal_perror ("dup2 %d 1", pipe_fd[1]);
2259 if (close (pipe_fd[0]) < 0)
2260 fatal_perror ("close %d", pipe_fd[0]);
2262 if (close (pipe_fd[1]) < 0)
2263 fatal_perror ("close %d", pipe_fd[1]);
2265 execv (nm_file_name, nm_argv);
2266 fatal_perror ("execvp %s", nm_file_name);
2269 /* Parent context from here on. */
2270 int_handler = (void (*) ())signal (SIGINT, SIG_IGN);
2271 #ifdef SIGQUIT
2272 quit_handler = (void (*) ())signal (SIGQUIT, SIG_IGN);
2273 #endif
2275 if (close (pipe_fd[1]) < 0)
2276 fatal_perror ("close %d", pipe_fd[1]);
2278 if (debug)
2279 fprintf (stderr, "\nnm output with constructors/destructors.\n");
2281 /* Read each line of nm output. */
2282 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2284 int ch, ch2;
2285 char *name, *end;
2287 /* If it contains a constructor or destructor name, add the name
2288 to the appropriate list. */
2290 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
2291 if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
2292 break;
2294 if (ch != '_')
2295 continue;
2297 name = p;
2298 /* Find the end of the symbol name.
2299 Do not include `|', because Encore nm can tack that on the end. */
2300 for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|';
2301 end++)
2302 continue;
2305 *end = '\0';
2306 switch (is_ctor_dtor (name))
2308 case 1:
2309 if (which_pass != PASS_LIB)
2310 add_to_list (&constructors, name);
2311 break;
2313 case 2:
2314 if (which_pass != PASS_LIB)
2315 add_to_list (&destructors, name);
2316 break;
2318 case 3:
2319 if (which_pass != PASS_LIB)
2320 fatal ("init function found in object %s", prog_name);
2321 #ifndef LD_INIT_SWITCH
2322 add_to_list (&constructors, name);
2323 #endif
2324 break;
2326 case 4:
2327 if (which_pass != PASS_LIB)
2328 fatal ("fini function found in object %s", prog_name);
2329 #ifndef LD_FINI_SWITCH
2330 add_to_list (&destructors, name);
2331 #endif
2332 break;
2334 case 5:
2335 if (which_pass != PASS_LIB)
2336 add_to_list (&frame_tables, name);
2338 default: /* not a constructor or destructor */
2339 continue;
2342 if (debug)
2343 fprintf (stderr, "\t%s\n", buf);
2346 if (debug)
2347 fprintf (stderr, "\n");
2349 if (fclose (inf) != 0)
2350 fatal_perror ("fclose");
2352 do_wait (nm_file_name);
2354 signal (SIGINT, int_handler);
2355 #ifdef SIGQUIT
2356 signal (SIGQUIT, quit_handler);
2357 #endif
2360 #if SUNOS4_SHARED_LIBRARIES
2362 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2363 that the output file depends upon and their initialization/finalization
2364 routines, if any. */
2366 #include <a.out.h>
2367 #include <fcntl.h>
2368 #include <link.h>
2369 #include <sys/mman.h>
2370 #include <sys/param.h>
2371 #include <unistd.h>
2372 #include <sys/dir.h>
2374 /* pointers to the object file */
2375 unsigned object; /* address of memory mapped file */
2376 unsigned objsize; /* size of memory mapped to file */
2377 char * code; /* pointer to code segment */
2378 char * data; /* pointer to data segment */
2379 struct nlist *symtab; /* pointer to symbol table */
2380 struct link_dynamic *ld;
2381 struct link_dynamic_2 *ld_2;
2382 struct head libraries;
2384 /* Map the file indicated by NAME into memory and store its address. */
2386 static void
2387 mapfile (name)
2388 char *name;
2390 int fp;
2391 struct stat s;
2392 if ((fp = open (name, O_RDONLY)) == -1)
2393 fatal ("unable to open file '%s'", name);
2394 if (fstat (fp, &s) == -1)
2395 fatal ("unable to stat file '%s'", name);
2397 objsize = s.st_size;
2398 object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE,
2399 fp, 0);
2400 if (object == -1)
2401 fatal ("unable to mmap file '%s'", name);
2403 close (fp);
2406 /* Helpers for locatelib. */
2408 static char *libname;
2410 static int
2411 libselect (d)
2412 struct direct *d;
2414 return (strncmp (libname, d->d_name, strlen (libname)) == 0);
2417 /* If one file has an additional numeric extension past LIBNAME, then put
2418 that one first in the sort. If both files have additional numeric
2419 extensions, then put the one with the higher number first in the sort.
2421 We must verify that the extension is numeric, because Sun saves the
2422 original versions of patched libraries with a .FCS extension. Files with
2423 invalid extensions must go last in the sort, so that they will not be used. */
2425 static int
2426 libcompare (d1, d2)
2427 struct direct **d1, **d2;
2429 int i1, i2 = strlen (libname);
2430 char *e1 = (*d1)->d_name + i2;
2431 char *e2 = (*d2)->d_name + i2;
2433 while (*e1 && *e2 && *e1 == '.' && *e2 == '.'
2434 && e1[1] && ISDIGIT (e1[1]) && e2[1] && ISDIGIT (e2[1]))
2436 ++e1;
2437 ++e2;
2438 i1 = strtol (e1, &e1, 10);
2439 i2 = strtol (e2, &e2, 10);
2440 if (i1 != i2)
2441 return i1 - i2;
2444 if (*e1)
2446 /* It has a valid numeric extension, prefer this one. */
2447 if (*e1 == '.' && e1[1] && ISDIGIT (e1[1]))
2448 return 1;
2449 /* It has a invalid numeric extension, must prefer the other one. */
2450 else
2451 return -1;
2453 else if (*e2)
2455 /* It has a valid numeric extension, prefer this one. */
2456 if (*e2 == '.' && e2[1] && ISDIGIT (e2[1]))
2457 return -1;
2458 /* It has a invalid numeric extension, must prefer the other one. */
2459 else
2460 return 1;
2462 else
2463 return 0;
2466 /* Given the name NAME of a dynamic dependency, find its pathname and add
2467 it to the list of libraries. */
2469 static void
2470 locatelib (name)
2471 char *name;
2473 static char **l;
2474 static int cnt;
2475 char buf[MAXPATHLEN];
2476 char *p, *q;
2477 char **pp;
2479 if (l == 0)
2481 char *ld_rules;
2482 char *ldr = 0;
2483 /* counting elements in array, need 1 extra for null */
2484 cnt = 1;
2485 ld_rules = (char *) (ld_2->ld_rules + code);
2486 if (ld_rules)
2488 cnt++;
2489 for (; *ld_rules != 0; ld_rules++)
2490 if (*ld_rules == ':')
2491 cnt++;
2492 ld_rules = (char *) (ld_2->ld_rules + code);
2493 ldr = (char *) malloc (strlen (ld_rules) + 1);
2494 strcpy (ldr, ld_rules);
2496 p = getenv ("LD_LIBRARY_PATH");
2497 q = 0;
2498 if (p)
2500 cnt++;
2501 for (q = p ; *q != 0; q++)
2502 if (*q == ':')
2503 cnt++;
2504 q = (char *) malloc (strlen (p) + 1);
2505 strcpy (q, p);
2507 l = (char **) malloc ((cnt + 3) * sizeof (char *));
2508 pp = l;
2509 if (ldr)
2511 *pp++ = ldr;
2512 for (; *ldr != 0; ldr++)
2513 if (*ldr == ':')
2515 *ldr++ = 0;
2516 *pp++ = ldr;
2519 if (q)
2521 *pp++ = q;
2522 for (; *q != 0; q++)
2523 if (*q == ':')
2525 *q++ = 0;
2526 *pp++ = q;
2529 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2530 *pp++ = "/lib";
2531 *pp++ = "/usr/lib";
2532 *pp++ = "/usr/local/lib";
2533 *pp = 0;
2535 libname = name;
2536 for (pp = l; *pp != 0 ; pp++)
2538 struct direct **namelist;
2539 int entries;
2540 if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0)
2542 sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name);
2543 add_to_list (&libraries, buf);
2544 if (debug)
2545 fprintf (stderr, "%s\n", buf);
2546 break;
2549 if (*pp == 0)
2551 if (debug)
2552 notice ("not found\n");
2553 else
2554 fatal ("dynamic dependency %s not found", name);
2558 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2559 that it depends upon and any constructors or destructors they contain. */
2561 static void
2562 scan_libraries (prog_name)
2563 char *prog_name;
2565 struct exec *header;
2566 char *base;
2567 struct link_object *lo;
2568 char buff[MAXPATHLEN];
2569 struct id *list;
2571 mapfile (prog_name);
2572 header = (struct exec *)object;
2573 if (N_BADMAG (*header))
2574 fatal ("bad magic number in file '%s'", prog_name);
2575 if (header->a_dynamic == 0)
2576 return;
2578 code = (char *) (N_TXTOFF (*header) + (long) header);
2579 data = (char *) (N_DATOFF (*header) + (long) header);
2580 symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header);
2582 if (header->a_magic == ZMAGIC && header->a_entry == 0x20)
2584 /* shared object */
2585 ld = (struct link_dynamic *) (symtab->n_value + code);
2586 base = code;
2588 else
2590 /* executable */
2591 ld = (struct link_dynamic *) data;
2592 base = code-PAGSIZ;
2595 if (debug)
2596 notice ("dynamic dependencies.\n");
2598 ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);
2599 for (lo = (struct link_object *) ld_2->ld_need; lo;
2600 lo = (struct link_object *) lo->lo_next)
2602 char *name;
2603 lo = (struct link_object *) ((long) lo + code);
2604 name = (char *) (code + lo->lo_name);
2605 if (lo->lo_library)
2607 if (debug)
2608 fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major);
2609 sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor);
2610 locatelib (buff);
2612 else
2614 if (debug)
2615 fprintf (stderr, "\t%s\n", name);
2616 add_to_list (&libraries, name);
2620 if (debug)
2621 fprintf (stderr, "\n");
2623 /* now iterate through the library list adding their symbols to
2624 the list. */
2625 for (list = libraries.first; list; list = list->next)
2626 scan_prog_file (list->name, PASS_LIB);
2629 #else /* SUNOS4_SHARED_LIBRARIES */
2630 #ifdef LDD_SUFFIX
2632 /* Use the List Dynamic Dependencies program to find shared libraries that
2633 the output file depends upon and their initialization/finalization
2634 routines, if any. */
2636 static void
2637 scan_libraries (prog_name)
2638 char *prog_name;
2640 static struct head libraries; /* list of shared libraries found */
2641 struct id *list;
2642 void (*int_handler) ();
2643 void (*quit_handler) ();
2644 char *ldd_argv[4];
2645 int pid;
2646 int argc = 0;
2647 int pipe_fd[2];
2648 char buf[1024];
2649 FILE *inf;
2651 /* If we do not have an `ldd', complain. */
2652 if (ldd_file_name == 0)
2654 error ("cannot find `ldd'");
2655 return;
2658 ldd_argv[argc++] = ldd_file_name;
2659 ldd_argv[argc++] = prog_name;
2660 ldd_argv[argc++] = (char *) 0;
2662 if (pipe (pipe_fd) < 0)
2663 fatal_perror ("pipe");
2665 inf = fdopen (pipe_fd[0], "r");
2666 if (inf == (FILE *) 0)
2667 fatal_perror ("fdopen");
2669 /* Trace if needed. */
2670 if (vflag)
2672 char **p_argv;
2673 char *str;
2675 for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2676 fprintf (stderr, " %s", str);
2678 fprintf (stderr, "\n");
2681 fflush (stdout);
2682 fflush (stderr);
2684 /* Spawn child ldd on pipe */
2685 pid = vfork ();
2686 if (pid == -1)
2687 fatal_perror (VFORK_STRING);
2689 if (pid == 0) /* child context */
2691 /* setup stdout */
2692 if (dup2 (pipe_fd[1], 1) < 0)
2693 fatal_perror ("dup2 %d 1", pipe_fd[1]);
2695 if (close (pipe_fd[0]) < 0)
2696 fatal_perror ("close %d", pipe_fd[0]);
2698 if (close (pipe_fd[1]) < 0)
2699 fatal_perror ("close %d", pipe_fd[1]);
2701 execv (ldd_file_name, ldd_argv);
2702 fatal_perror ("execv %s", ldd_file_name);
2705 /* Parent context from here on. */
2706 int_handler = (void (*) ()) signal (SIGINT, SIG_IGN);
2707 #ifdef SIGQUIT
2708 quit_handler = (void (*) ()) signal (SIGQUIT, SIG_IGN);
2709 #endif
2711 if (close (pipe_fd[1]) < 0)
2712 fatal_perror ("close %d", pipe_fd[1]);
2714 if (debug)
2715 notice ("\nldd output with constructors/destructors.\n");
2717 /* Read each line of ldd output. */
2718 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2720 int ch, ch2;
2721 char *name, *end, *p = buf;
2723 /* Extract names of libraries and add to list. */
2724 PARSE_LDD_OUTPUT (p);
2725 if (p == 0)
2726 continue;
2728 name = p;
2729 if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
2730 fatal ("dynamic dependency %s not found", buf);
2732 /* Find the end of the symbol name. */
2733 for (end = p;
2734 (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|';
2735 end++)
2736 continue;
2737 *end = '\0';
2739 if (access (name, R_OK) == 0)
2740 add_to_list (&libraries, name);
2741 else
2742 fatal ("unable to open dynamic dependency '%s'", buf);
2744 if (debug)
2745 fprintf (stderr, "\t%s\n", buf);
2747 if (debug)
2748 fprintf (stderr, "\n");
2750 if (fclose (inf) != 0)
2751 fatal_perror ("fclose");
2753 do_wait (ldd_file_name);
2755 signal (SIGINT, int_handler);
2756 #ifdef SIGQUIT
2757 signal (SIGQUIT, quit_handler);
2758 #endif
2760 /* now iterate through the library list adding their symbols to
2761 the list. */
2762 for (list = libraries.first; list; list = list->next)
2763 scan_prog_file (list->name, PASS_LIB);
2766 #endif /* LDD_SUFFIX */
2767 #endif /* SUNOS4_SHARED_LIBRARIES */
2769 #endif /* OBJECT_FORMAT_NONE */
2773 * COFF specific stuff.
2776 #ifdef OBJECT_FORMAT_COFF
2778 #if defined(EXTENDED_COFF)
2779 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2780 # define GCC_SYMENT SYMR
2781 # define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
2782 # define GCC_SYMINC(X) (1)
2783 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2784 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2785 #else
2786 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2787 # define GCC_SYMENT SYMENT
2788 # define GCC_OK_SYMBOL(X) \
2789 (((X).n_sclass == C_EXT) && \
2790 ((X).n_scnum > N_UNDEF) && \
2791 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
2792 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
2793 # define GCC_UNDEF_SYMBOL(X) \
2794 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2795 # define GCC_SYMINC(X) ((X).n_numaux+1)
2796 # define GCC_SYMZERO(X) 0
2797 # define GCC_CHECK_HDR(X) \
2798 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2799 || (HEADER (X).f_magic == 0757 && aix64_flag))
2800 #endif
2802 extern char *ldgetname ();
2804 /* COFF version to scan the name list of the loaded program for
2805 the symbols g++ uses for static constructors and destructors.
2807 The constructor table begins at __CTOR_LIST__ and contains a count
2808 of the number of pointers (or -1 if the constructors are built in a
2809 separate section by the linker), followed by the pointers to the
2810 constructor functions, terminated with a null pointer. The
2811 destructor table has the same format, and begins at __DTOR_LIST__. */
2813 static void
2814 scan_prog_file (prog_name, which_pass)
2815 char *prog_name;
2816 enum pass which_pass;
2818 LDFILE *ldptr = NULL;
2819 int sym_index, sym_count;
2820 int is_shared = 0;
2821 #ifdef COLLECT_EXPORT_LIST
2822 /* Should we generate an import list for given prog_name? */
2823 int import_flag = (which_pass == PASS_OBJ ? 0 : use_import_list (prog_name));
2824 #endif
2826 if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2827 return;
2829 #ifdef COLLECT_EXPORT_LIST
2830 /* We do not need scanning for some standard C libraries. */
2831 if (which_pass == PASS_FIRST && ignore_library (prog_name))
2832 return;
2834 /* On AIX we have a loop, because there is not much difference
2835 between an object and an archive. This trick allows us to
2836 eliminate scan_libraries() function. */
2839 #endif
2840 if ((ldptr = ldopen (prog_name, ldptr)) != NULL)
2842 if (! MY_ISCOFF (HEADER (ldptr).f_magic))
2843 fatal ("%s: not a COFF file", prog_name);
2845 if (GCC_CHECK_HDR (ldptr))
2847 sym_count = GCC_SYMBOLS (ldptr);
2848 sym_index = GCC_SYMZERO (ldptr);
2850 #ifdef COLLECT_EXPORT_LIST
2851 /* Is current archive member a shared object? */
2852 is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
2853 #endif
2855 while (sym_index < sym_count)
2857 GCC_SYMENT symbol;
2859 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2860 break;
2861 sym_index += GCC_SYMINC (symbol);
2863 if (GCC_OK_SYMBOL (symbol))
2865 char *name;
2867 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2868 continue; /* should never happen */
2870 #ifdef XCOFF_DEBUGGING_INFO
2871 /* All AIX function names have a duplicate entry
2872 beginning with a dot. */
2873 if (*name == '.')
2874 ++name;
2875 #endif
2877 switch (is_ctor_dtor (name))
2879 case 1:
2880 if (! is_shared) add_to_list (&constructors, name);
2881 #ifdef COLLECT_EXPORT_LIST
2882 if (which_pass == PASS_OBJ)
2883 add_to_list (&exports, name);
2884 /* If this symbol was undefined and we are building
2885 an import list, we should add a symbol to this
2886 list. */
2887 else
2888 if (import_flag
2889 && is_in_list (name, undefined.first))
2890 add_to_list (&imports, name);
2891 #endif
2892 break;
2894 case 2:
2895 if (! is_shared) add_to_list (&destructors, name);
2896 #ifdef COLLECT_EXPORT_LIST
2897 if (which_pass == PASS_OBJ)
2898 add_to_list (&exports, name);
2899 /* If this symbol was undefined and we are building
2900 an import list, we should add a symbol to this
2901 list. */
2902 else
2903 if (import_flag
2904 && is_in_list (name, undefined.first))
2905 add_to_list (&imports, name);
2906 #endif
2907 break;
2909 #ifdef COLLECT_EXPORT_LIST
2910 case 3:
2911 if (is_shared)
2912 add_to_list (&constructors, name);
2913 break;
2915 case 4:
2916 if (is_shared)
2917 add_to_list (&destructors, name);
2918 break;
2919 #endif
2921 default: /* not a constructor or destructor */
2922 #ifdef COLLECT_EXPORT_LIST
2923 /* If we are building a shared object on AIX we need
2924 to explicitly export all global symbols or add
2925 them to import list. */
2926 if (shared_obj)
2928 if (which_pass == PASS_OBJ && (! export_flag))
2929 add_to_list (&exports, name);
2930 else if (! is_shared && which_pass == PASS_FIRST
2931 && import_flag
2932 && is_in_list(name, undefined.first))
2933 add_to_list (&imports, name);
2935 #endif
2936 continue;
2939 #if !defined(EXTENDED_COFF)
2940 if (debug)
2941 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
2942 symbol.n_scnum, symbol.n_sclass,
2943 (symbol.n_type ? "0" : ""), symbol.n_type,
2944 name);
2945 #else
2946 if (debug)
2947 fprintf (stderr,
2948 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
2949 symbol.iss, (long) symbol.value, symbol.index, name);
2950 #endif
2952 #ifdef COLLECT_EXPORT_LIST
2953 /* If we are building a shared object we should collect
2954 information about undefined symbols for later
2955 import list generation. */
2956 else if (shared_obj && GCC_UNDEF_SYMBOL (symbol))
2958 char *name;
2960 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2961 continue; /* should never happen */
2963 /* All AIX function names have a duplicate entry
2964 beginning with a dot. */
2965 if (*name == '.')
2966 ++name;
2967 add_to_list (&undefined, name);
2969 #endif
2972 #ifdef COLLECT_EXPORT_LIST
2973 else
2975 /* If archive contains both 32-bit and 64-bit objects,
2976 we want to skip objects in other mode so mismatch normal. */
2977 if (debug)
2978 fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n",
2979 prog_name, HEADER (ldptr).f_magic, aix64_flag);
2981 #endif
2983 else
2985 fatal ("%s: cannot open as COFF file", prog_name);
2987 #ifdef COLLECT_EXPORT_LIST
2988 /* On AIX loop continues while there are more members in archive. */
2990 while (ldclose (ldptr) == FAILURE);
2991 #else
2992 /* Otherwise we simply close ldptr. */
2993 (void) ldclose(ldptr);
2994 #endif
2998 #ifdef COLLECT_EXPORT_LIST
3000 /* This new function is used to decide whether we should
3001 generate import list for an object or to use it directly. */
3002 static int
3003 use_import_list (prog_name)
3004 char *prog_name;
3006 char *p;
3008 /* If we do not build a shared object then import list should not be used. */
3009 if (! shared_obj) return 0;
3011 /* Currently we check only for libgcc, but this can be changed in future. */
3012 p = strstr (prog_name, "libgcc.a");
3013 if (p != 0 && (strlen (p) == sizeof ("libgcc.a") - 1))
3014 return 1;
3015 return 0;
3018 /* Given a library name without "lib" prefix, this function
3019 returns a full library name including a path. */
3020 static char *
3021 resolve_lib_name (name)
3022 char *name;
3024 char *lib_buf;
3025 int i, j, l = 0;
3027 for (i = 0; libpaths[i]; i++)
3028 if (libpaths[i]->max_len > l)
3029 l = libpaths[i]->max_len;
3031 lib_buf = xmalloc (l + strlen(name) + 10);
3033 for (i = 0; libpaths[i]; i++)
3035 struct prefix_list *list = libpaths[i]->plist;
3036 for (; list; list = list->next)
3038 for (j = 0; libexts[j]; j++)
3040 /* The following lines are needed because path_prefix list
3041 may contain directories both with trailing '/' and
3042 without it. */
3043 char *p = "";
3044 if (list->prefix[strlen(list->prefix)-1] != '/')
3045 p = "/";
3046 sprintf (lib_buf, "%s%slib%s.%s",
3047 list->prefix, p, name, libexts[j]);
3048 if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
3049 if (file_exists (lib_buf))
3051 if (debug) fprintf (stderr, "found: %s\n", lib_buf);
3052 return (lib_buf);
3057 if (debug)
3058 fprintf (stderr, "not found\n");
3059 else
3060 fatal ("Library lib%s not found", name);
3061 return (NULL);
3064 /* Array of standard AIX libraries which should not
3065 be scanned for ctors/dtors. */
3066 static char* aix_std_libs[] = {
3067 "/unix",
3068 "/lib/libc.a",
3069 "/lib/libc_r.a",
3070 "/usr/lib/libc.a",
3071 "/usr/lib/libc_r.a",
3072 "/usr/lib/threads/libc.a",
3073 "/usr/ccs/lib/libc.a",
3074 "/usr/ccs/lib/libc_r.a",
3075 NULL
3078 /* This function checks the filename and returns 1
3079 if this name matches the location of a standard AIX library. */
3080 static int
3081 ignore_library (name)
3082 char *name;
3084 char **p = &aix_std_libs[0];
3085 while (*p++ != NULL)
3086 if (! strcmp (name, *p)) return 1;
3087 return 0;
3090 #endif
3092 #endif /* OBJECT_FORMAT_COFF */
3096 * OSF/rose specific stuff.
3099 #ifdef OBJECT_FORMAT_ROSE
3101 /* Union of the various load commands */
3103 typedef union load_union
3105 ldc_header_t hdr; /* common header */
3106 load_cmd_map_command_t map; /* map indexing other load cmds */
3107 interpreter_command_t iprtr; /* interpreter pathname */
3108 strings_command_t str; /* load commands strings section */
3109 region_command_t region; /* region load command */
3110 reloc_command_t reloc; /* relocation section */
3111 package_command_t pkg; /* package load command */
3112 symbols_command_t sym; /* symbol sections */
3113 entry_command_t ent; /* program start section */
3114 gen_info_command_t info; /* object information */
3115 func_table_command_t func; /* function constructors/destructors */
3116 } load_union_t;
3118 /* Structure to point to load command and data section in memory. */
3120 typedef struct load_all
3122 load_union_t *load; /* load command */
3123 char *section; /* pointer to section */
3124 } load_all_t;
3126 /* Structure to contain information about a file mapped into memory. */
3128 struct file_info
3130 char *start; /* start of map */
3131 char *name; /* filename */
3132 long size; /* size of the file */
3133 long rounded_size; /* size rounded to page boundary */
3134 int fd; /* file descriptor */
3135 int rw; /* != 0 if opened read/write */
3136 int use_mmap; /* != 0 if mmap'ed */
3139 extern int decode_mach_o_hdr ();
3140 extern int encode_mach_o_hdr ();
3142 static void add_func_table PROTO((mo_header_t *, load_all_t *,
3143 symbol_info_t *, int));
3144 static void print_header PROTO((mo_header_t *));
3145 static void print_load_command PROTO((load_union_t *, size_t, int));
3146 static void bad_header PROTO((int));
3147 static struct file_info *read_file PROTO((char *, int, int));
3148 static void end_file PROTO((struct file_info *));
3150 /* OSF/rose specific version to scan the name list of the loaded
3151 program for the symbols g++ uses for static constructors and
3152 destructors.
3154 The constructor table begins at __CTOR_LIST__ and contains a count
3155 of the number of pointers (or -1 if the constructors are built in a
3156 separate section by the linker), followed by the pointers to the
3157 constructor functions, terminated with a null pointer. The
3158 destructor table has the same format, and begins at __DTOR_LIST__. */
3160 static void
3161 scan_prog_file (prog_name, which_pass)
3162 char *prog_name;
3163 enum pass which_pass;
3165 char *obj;
3166 mo_header_t hdr;
3167 load_all_t *load_array;
3168 load_all_t *load_end;
3169 load_all_t *load_cmd;
3170 int symbol_load_cmds;
3171 off_t offset;
3172 int i;
3173 int num_syms;
3174 int status;
3175 char *str_sect;
3176 struct file_info *obj_file;
3177 int prog_fd;
3178 mo_lcid_t cmd_strings = -1;
3179 symbol_info_t *main_sym = 0;
3180 int rw = (which_pass != PASS_FIRST);
3182 prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
3183 if (prog_fd < 0)
3184 fatal_perror ("open %s", prog_name);
3186 obj_file = read_file (prog_name, prog_fd, rw);
3187 obj = obj_file->start;
3189 status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);
3190 if (status != MO_HDR_CONV_SUCCESS)
3191 bad_header (status);
3194 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
3195 since the hardware will automatically swap bytes for us on loading little endian
3196 integers. */
3198 #ifndef CROSS_COMPILE
3199 if (hdr.moh_magic != MOH_MAGIC_MSB
3200 || hdr.moh_header_version != MOH_HEADER_VERSION
3201 || hdr.moh_byte_order != OUR_BYTE_ORDER
3202 || hdr.moh_data_rep_id != OUR_DATA_REP_ID
3203 || hdr.moh_cpu_type != OUR_CPU_TYPE
3204 || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE
3205 || hdr.moh_vendor_type != OUR_VENDOR_TYPE)
3207 fatal ("incompatibilities between object file & expected values");
3209 #endif
3211 if (debug)
3212 print_header (&hdr);
3214 offset = hdr.moh_first_cmd_off;
3215 load_end = load_array
3216 = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);
3218 /* Build array of load commands, calculating the offsets */
3219 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3221 load_union_t *load_hdr; /* load command header */
3223 load_cmd = load_end++;
3224 load_hdr = (load_union_t *) (obj + offset);
3226 /* If modifying the program file, copy the header. */
3227 if (rw)
3229 load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
3230 bcopy ((char *)load_hdr, (char *)ptr, load_hdr->hdr.ldci_cmd_size);
3231 load_hdr = ptr;
3233 /* null out old command map, because we will rewrite at the end. */
3234 if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
3236 cmd_strings = ptr->map.lcm_ld_cmd_strings;
3237 ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
3241 load_cmd->load = load_hdr;
3242 if (load_hdr->hdr.ldci_section_off > 0)
3243 load_cmd->section = obj + load_hdr->hdr.ldci_section_off;
3245 if (debug)
3246 print_load_command (load_hdr, offset, i);
3248 offset += load_hdr->hdr.ldci_cmd_size;
3251 /* If the last command is the load command map and is not undefined,
3252 decrement the count of load commands. */
3253 if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)
3255 load_end--;
3256 hdr.moh_n_load_cmds--;
3259 /* Go through and process each symbol table section. */
3260 symbol_load_cmds = 0;
3261 for (load_cmd = load_array; load_cmd < load_end; load_cmd++)
3263 load_union_t *load_hdr = load_cmd->load;
3265 if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
3267 symbol_load_cmds++;
3269 if (debug)
3271 char *kind = "unknown";
3273 switch (load_hdr->sym.symc_kind)
3275 case SYMC_IMPORTS: kind = "imports"; break;
3276 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
3277 case SYMC_STABS: kind = "stabs"; break;
3280 notice ("\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
3281 symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
3284 if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
3285 continue;
3287 str_sect = load_array[load_hdr->sym.symc_strings_section].section;
3288 if (str_sect == (char *) 0)
3289 fatal ("string section missing");
3291 if (load_cmd->section == (char *) 0)
3292 fatal ("section pointer missing");
3294 num_syms = load_hdr->sym.symc_nentries;
3295 for (i = 0; i < num_syms; i++)
3297 symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
3298 char *name = sym->si_name.symbol_name + str_sect;
3300 if (name[0] != '_')
3301 continue;
3303 if (rw)
3305 char *n = name + strlen (name) - strlen (NAME__MAIN);
3307 if ((n - name) < 0 || strcmp (n, NAME__MAIN))
3308 continue;
3309 while (n != name)
3310 if (*--n != '_')
3311 continue;
3313 main_sym = sym;
3315 else
3317 switch (is_ctor_dtor (name))
3319 case 1:
3320 add_to_list (&constructors, name);
3321 break;
3323 case 2:
3324 add_to_list (&destructors, name);
3325 break;
3327 default: /* not a constructor or destructor */
3328 continue;
3332 if (debug)
3333 fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
3334 sym->si_type, sym->si_sc_type, sym->si_flags, name);
3339 if (symbol_load_cmds == 0)
3340 fatal ("no symbol table found");
3342 /* Update the program file now, rewrite header and load commands. At present,
3343 we assume that there is enough space after the last load command to insert
3344 one more. Since the first section written out is page aligned, and the
3345 number of load commands is small, this is ok for the present. */
3347 if (rw)
3349 load_union_t *load_map;
3350 size_t size;
3352 if (cmd_strings == -1)
3353 fatal ("no cmd_strings found");
3355 /* Add __main to initializer list.
3356 If we are building a program instead of a shared library, do not
3357 do anything, since in the current version, you cannot do mallocs
3358 and such in the constructors. */
3360 if (main_sym != (symbol_info_t *) 0
3361 && ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
3362 add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
3364 if (debug)
3365 notice ("\nUpdating header and load commands.\n\n");
3367 hdr.moh_n_load_cmds++;
3368 size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
3370 /* Create new load command map. */
3371 if (debug)
3372 notice ("load command map, %d cmds, new size %ld.\n",
3373 (int) hdr.moh_n_load_cmds, (long) size);
3375 load_map = (load_union_t *) xcalloc (1, size);
3376 load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
3377 load_map->map.ldc_header.ldci_cmd_size = size;
3378 load_map->map.lcm_ld_cmd_strings = cmd_strings;
3379 load_map->map.lcm_nentries = hdr.moh_n_load_cmds;
3380 load_array[hdr.moh_n_load_cmds-1].load = load_map;
3382 offset = hdr.moh_first_cmd_off;
3383 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3385 load_map->map.lcm_map[i] = offset;
3386 if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)
3387 hdr.moh_load_map_cmd_off = offset;
3389 offset += load_array[i].load->hdr.ldci_cmd_size;
3392 hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
3394 if (debug)
3395 print_header (&hdr);
3397 /* Write header */
3398 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
3399 if (status != MO_HDR_CONV_SUCCESS)
3400 bad_header (status);
3402 if (debug)
3403 notice ("writing load commands.\n\n");
3405 /* Write load commands */
3406 offset = hdr.moh_first_cmd_off;
3407 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3409 load_union_t *load_hdr = load_array[i].load;
3410 size_t size = load_hdr->hdr.ldci_cmd_size;
3412 if (debug)
3413 print_load_command (load_hdr, offset, i);
3415 bcopy ((char *) load_hdr, (char *) (obj + offset), size);
3416 offset += size;
3420 end_file (obj_file);
3422 if (close (prog_fd))
3423 fatal_perror ("close %s", prog_name);
3425 if (debug)
3426 fprintf (stderr, "\n");
3430 /* Add a function table to the load commands to call a function
3431 on initiation or termination of the process. */
3433 static void
3434 add_func_table (hdr_p, load_array, sym, type)
3435 mo_header_t *hdr_p; /* pointer to global header */
3436 load_all_t *load_array; /* array of ptrs to load cmds */
3437 symbol_info_t *sym; /* pointer to symbol entry */
3438 int type; /* fntc_type value */
3440 /* Add a new load command. */
3441 int num_cmds = ++hdr_p->moh_n_load_cmds;
3442 int load_index = num_cmds - 1;
3443 size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);
3444 load_union_t *ptr = xcalloc (1, size);
3445 load_all_t *load_cmd;
3446 int i;
3448 /* Set the unresolved address bit in the header to force the loader to be
3449 used, since kernel exec does not call the initialization functions. */
3450 hdr_p->moh_flags |= MOH_UNRESOLVED_F;
3452 load_cmd = &load_array[load_index];
3453 load_cmd->load = ptr;
3454 load_cmd->section = (char *) 0;
3456 /* Fill in func table load command. */
3457 ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
3458 ptr->func.ldc_header.ldci_cmd_size = size;
3459 ptr->func.ldc_header.ldci_section_off = 0;
3460 ptr->func.ldc_header.ldci_section_len = 0;
3461 ptr->func.fntc_type = type;
3462 ptr->func.fntc_nentries = 1;
3464 /* copy address, turn it from abs. address to (region,offset) if necessary. */
3465 /* Is the symbol already expressed as (region, offset)? */
3466 if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)
3468 ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;
3469 ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;
3472 /* If not, figure out which region it's in. */
3473 else
3475 mo_vm_addr_t addr = sym->si_value.abs_val;
3476 int found = 0;
3478 for (i = 0; i < load_index; i++)
3480 if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
3482 region_command_t *region_ptr = &load_array[i].load->region;
3484 if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0
3485 && addr >= region_ptr->regc_addr.vm_addr
3486 && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)
3488 ptr->func.fntc_entry_loc[0].adr_lcid = i;
3489 ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;
3490 found++;
3491 break;
3496 if (!found)
3497 fatal ("could not convert 0x%l.8x into a region", addr);
3500 if (debug)
3501 notice ("%s function, region %d, offset = %ld (0x%.8lx)\n",
3502 type == FNTC_INITIALIZATION ? "init" : "term",
3503 (int) ptr->func.fntc_entry_loc[i].adr_lcid,
3504 (long) ptr->func.fntc_entry_loc[i].adr_sctoff,
3505 (long) ptr->func.fntc_entry_loc[i].adr_sctoff);
3510 /* Print the global header for an OSF/rose object. */
3512 static void
3513 print_header (hdr_ptr)
3514 mo_header_t *hdr_ptr;
3516 fprintf (stderr, "\nglobal header:\n");
3517 fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic);
3518 fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version);
3519 fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version);
3520 fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version);
3521 fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size);
3522 fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order);
3523 fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id);
3524 fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type);
3525 fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype);
3526 fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type);
3527 fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);
3528 fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off);
3529 fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds);
3530 fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds);
3531 fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags);
3533 if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
3534 fprintf (stderr, ", relocatable");
3536 if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
3537 fprintf (stderr, ", linkable");
3539 if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
3540 fprintf (stderr, ", execable");
3542 if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
3543 fprintf (stderr, ", executable");
3545 if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
3546 fprintf (stderr, ", unresolved");
3548 fprintf (stderr, "\n\n");
3549 return;
3553 /* Print a short summary of a load command. */
3555 static void
3556 print_load_command (load_hdr, offset, number)
3557 load_union_t *load_hdr;
3558 size_t offset;
3559 int number;
3561 mo_long_t type = load_hdr->hdr.ldci_cmd_type;
3562 char *type_str = (char *) 0;
3564 switch (type)
3566 case LDC_UNDEFINED: type_str = "UNDEFINED"; break;
3567 case LDC_CMD_MAP: type_str = "CMD_MAP"; break;
3568 case LDC_INTERPRETER: type_str = "INTERPRETER"; break;
3569 case LDC_STRINGS: type_str = "STRINGS"; break;
3570 case LDC_REGION: type_str = "REGION"; break;
3571 case LDC_RELOC: type_str = "RELOC"; break;
3572 case LDC_PACKAGE: type_str = "PACKAGE"; break;
3573 case LDC_SYMBOLS: type_str = "SYMBOLS"; break;
3574 case LDC_ENTRY: type_str = "ENTRY"; break;
3575 case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break;
3576 case LDC_GEN_INFO: type_str = "GEN_INFO"; break;
3579 fprintf (stderr,
3580 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3581 number,
3582 (long) load_hdr->hdr.ldci_cmd_size,
3583 (long) offset,
3584 (long) load_hdr->hdr.ldci_section_off,
3585 (long) load_hdr->hdr.ldci_section_len);
3587 if (type_str == (char *) 0)
3588 fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
3590 else if (type != LDC_REGION)
3591 fprintf (stderr, ", ty: %s\n", type_str);
3593 else
3595 char *region = "";
3596 switch (load_hdr->region.regc_usage_type)
3598 case REG_TEXT_T: region = ", .text"; break;
3599 case REG_DATA_T: region = ", .data"; break;
3600 case REG_BSS_T: region = ", .bss"; break;
3601 case REG_GLUE_T: region = ", .glue"; break;
3602 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3603 case REG_RDATA_T: region = ", .rdata"; break;
3604 case REG_SDATA_T: region = ", .sdata"; break;
3605 case REG_SBSS_T: region = ", .sbss"; break;
3606 #endif
3609 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3610 type_str,
3611 (long) load_hdr->region.regc_vm_addr,
3612 (long) load_hdr->region.regc_vm_size,
3613 region);
3616 return;
3620 /* Fatal error when {en,de}code_mach_o_header fails. */
3622 static void
3623 bad_header (status)
3624 int status;
3626 switch (status)
3628 case MO_ERROR_BAD_MAGIC: fatal ("bad magic number");
3629 case MO_ERROR_BAD_HDR_VERS: fatal ("bad header version");
3630 case MO_ERROR_BAD_RAW_HDR_VERS: fatal ("bad raw header version");
3631 case MO_ERROR_BUF2SML: fatal ("raw header buffer too small");
3632 case MO_ERROR_OLD_RAW_HDR_FILE: fatal ("old raw header file");
3633 case MO_ERROR_UNSUPPORTED_VERS: fatal ("unsupported version");
3634 default:
3635 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
3640 /* Read a file into a memory buffer. */
3642 static struct file_info *
3643 read_file (name, fd, rw)
3644 char *name; /* filename */
3645 int fd; /* file descriptor */
3646 int rw; /* read/write */
3648 struct stat stat_pkt;
3649 struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
3650 #ifdef USE_MMAP
3651 static int page_size;
3652 #endif
3654 if (fstat (fd, &stat_pkt) < 0)
3655 fatal_perror ("fstat %s", name);
3657 p->name = name;
3658 p->size = stat_pkt.st_size;
3659 p->rounded_size = stat_pkt.st_size;
3660 p->fd = fd;
3661 p->rw = rw;
3663 #ifdef USE_MMAP
3664 if (debug)
3665 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
3667 if (page_size == 0)
3668 page_size = sysconf (_SC_PAGE_SIZE);
3670 p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
3671 p->start = mmap ((caddr_t) 0,
3672 (rw) ? p->rounded_size : p->size,
3673 (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
3674 MAP_FILE | MAP_VARIABLE | MAP_SHARED,
3676 0L);
3678 if (p->start != (char *) 0 && p->start != (char *) -1)
3679 p->use_mmap = 1;
3681 else
3682 #endif /* USE_MMAP */
3684 long len;
3686 if (debug)
3687 fprintf (stderr, "read %s\n", name);
3689 p->use_mmap = 0;
3690 p->start = xmalloc (p->size);
3691 if (lseek (fd, 0L, SEEK_SET) < 0)
3692 fatal_perror ("lseek %s 0", name);
3694 len = read (fd, p->start, p->size);
3695 if (len < 0)
3696 fatal_perror ("read %s", name);
3698 if (len != p->size)
3699 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
3702 return p;
3705 /* Do anything necessary to write a file back from memory. */
3707 static void
3708 end_file (ptr)
3709 struct file_info *ptr; /* file information block */
3711 #ifdef USE_MMAP
3712 if (ptr->use_mmap)
3714 if (ptr->rw)
3716 if (debug)
3717 fprintf (stderr, "msync %s\n", ptr->name);
3719 if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
3720 fatal_perror ("msync %s", ptr->name);
3723 if (debug)
3724 fprintf (stderr, "munmap %s\n", ptr->name);
3726 if (munmap (ptr->start, ptr->size))
3727 fatal_perror ("munmap %s", ptr->name);
3729 else
3730 #endif /* USE_MMAP */
3732 if (ptr->rw)
3734 long len;
3736 if (debug)
3737 fprintf (stderr, "write %s\n", ptr->name);
3739 if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
3740 fatal_perror ("lseek %s 0", ptr->name);
3742 len = write (ptr->fd, ptr->start, ptr->size);
3743 if (len < 0)
3744 fatal_perror ("write %s", ptr->name);
3746 if (len != ptr->size)
3747 fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
3750 free (ptr->start);
3753 free (ptr);
3756 #endif /* OBJECT_FORMAT_ROSE */