* collect2.c (main): Still handle !do_collecting for non-AIX targets.
[official-gcc.git] / gcc / collect2.c
blob79e59b5be1d99a8a665ae8758836e257582d5155
1 /* Collect static initialization info into data structures that can be
2 traversed by C++ initialization and finalization routines.
3 Copyright (C) 1992, 93-97, 1998 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 <sys/types.h>
30 #include <stdio.h>
31 #include <ctype.h>
32 #include <errno.h>
33 #include <signal.h>
34 #include <sys/file.h>
35 #include <sys/stat.h>
37 #ifdef HAVE_STDLIB_H
38 #include <stdlib.h>
39 #endif
41 #ifdef HAVE_UNISTD_H
42 #include <unistd.h>
43 #endif
45 #ifdef HAVE_STRING_H
46 #include <string.h>
47 #else
48 #ifdef HAVE_STRINGS_H
49 #include <strings.h>
50 #endif
51 #endif
53 #define COLLECT
55 #include "demangle.h"
56 #include "obstack.h"
57 #include "gansidecl.h"
59 #ifndef errno
60 extern int errno;
61 #endif
63 #ifndef HAVE_STRERROR
64 extern char *sys_errlist[];
65 extern int sys_nerr;
66 #else
67 char *strerror();
68 #endif
70 /* Obstack allocation and deallocation routines. */
71 #define obstack_chunk_alloc xmalloc
72 #define obstack_chunk_free free
74 #ifdef USG
75 #define vfork fork
76 #endif
78 #ifndef R_OK
79 #define R_OK 4
80 #define W_OK 2
81 #define X_OK 1
82 #endif
84 #ifndef WIFSIGNALED
85 #define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
86 #endif
87 #ifndef WTERMSIG
88 #define WTERMSIG(S) ((S) & 0x7f)
89 #endif
90 #ifndef WIFEXITED
91 #define WIFEXITED(S) (((S) & 0xff) == 0)
92 #endif
93 #ifndef WEXITSTATUS
94 #define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
95 #endif
97 extern char *choose_temp_base ();
99 /* On certain systems, we have code that works by scanning the object file
100 directly. But this code uses system-specific header files and library
101 functions, so turn it off in a cross-compiler. Likewise, the names of
102 the utilities are not correct for a cross-compiler; we have to hope that
103 cross-versions are in the proper directories. */
105 #ifdef CROSS_COMPILE
106 #undef SUNOS4_SHARED_LIBRARIES
107 #undef OBJECT_FORMAT_COFF
108 #undef OBJECT_FORMAT_ROSE
109 #undef MD_EXEC_PREFIX
110 #undef REAL_LD_FILE_NAME
111 #undef REAL_NM_FILE_NAME
112 #undef REAL_STRIP_FILE_NAME
113 #endif
115 /* If we cannot use a special method, use the ordinary one:
116 run nm to find what symbols are present.
117 In a cross-compiler, this means you need a cross nm,
118 but that is not quite as unpleasant as special headers. */
120 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
121 #define OBJECT_FORMAT_NONE
122 #endif
124 #ifdef OBJECT_FORMAT_COFF
126 #include <a.out.h>
127 #include <ar.h>
129 #ifdef UMAX
130 #include <sgs.h>
131 #endif
133 /* Many versions of ldfcn.h define these. */
134 #ifdef FREAD
135 #undef FREAD
136 #undef FWRITE
137 #endif
139 #include <ldfcn.h>
141 /* Some systems have an ISCOFF macro, but others do not. In some cases
142 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
143 that either do not have an ISCOFF macro in /usr/include or for those
144 where it is wrong. */
146 #ifndef MY_ISCOFF
147 #define MY_ISCOFF(X) ISCOFF (X)
148 #endif
150 #endif /* OBJECT_FORMAT_COFF */
152 #ifdef OBJECT_FORMAT_ROSE
154 #ifdef _OSF_SOURCE
155 #define USE_MMAP
156 #endif
158 #ifdef USE_MMAP
159 #include <sys/mman.h>
160 #endif
162 #include <unistd.h>
163 #include <mach_o_format.h>
164 #include <mach_o_header.h>
165 #include <mach_o_vals.h>
166 #include <mach_o_types.h>
168 #endif /* OBJECT_FORMAT_ROSE */
170 #ifdef OBJECT_FORMAT_NONE
172 /* Default flags to pass to nm. */
173 #ifndef NM_FLAGS
174 #define NM_FLAGS "-p"
175 #endif
177 #endif /* OBJECT_FORMAT_NONE */
179 /* Some systems use __main in a way incompatible with its use in gcc, in these
180 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
181 give the same symbol without quotes for an alternative entry point. You
182 must define both, or neither. */
183 #ifndef NAME__MAIN
184 #define NAME__MAIN "__main"
185 #define SYMBOL__MAIN __main
186 #endif
188 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
189 #define SCAN_LIBRARIES
190 #endif
192 #ifdef USE_COLLECT2
193 int do_collecting = 1;
194 #else
195 int do_collecting = 0;
196 #endif
198 /* Linked lists of constructor and destructor names. */
200 struct id
202 struct id *next;
203 int sequence;
204 char name[1];
207 struct head
209 struct id *first;
210 struct id *last;
211 int number;
214 /* Enumeration giving which pass this is for scanning the program file. */
216 enum pass {
217 PASS_FIRST, /* without constructors */
218 PASS_OBJ, /* individual objects */
219 PASS_LIB, /* looking for shared libraries */
220 PASS_SECOND /* with constructors linked in */
223 #ifndef NO_SYS_SIGLIST
224 #ifndef SYS_SIGLIST_DECLARED
225 extern char *sys_siglist[];
226 #endif
227 #endif
228 extern char *version_string;
230 int vflag; /* true if -v */
231 static int rflag; /* true if -r */
232 static int strip_flag; /* true if -s */
233 #ifdef COLLECT_EXPORT_LIST
234 static int export_flag; /* true if -bE */
235 #endif
237 int debug; /* true if -debug */
239 static int shared_obj; /* true if -shared */
241 static int temp_filename_length; /* Length of temp_filename */
242 static char *temp_filename; /* Base of temp filenames */
243 static char *c_file; /* <xxx>.c for constructor/destructor list. */
244 static char *o_file; /* <xxx>.o for constructor/destructor list. */
245 #ifdef COLLECT_EXPORT_LIST
246 static char *export_file; /* <xxx>.x for AIX export list. */
247 static char *import_file; /* <xxx>.p for AIX import list. */
248 #endif
249 char *ldout; /* File for ld errors. */
250 static char *output_file; /* Output file for ld. */
251 static char *nm_file_name; /* pathname of nm */
252 static char *ldd_file_name; /* pathname of ldd (or equivalent) */
253 static char *strip_file_name; /* pathname of strip */
254 char *c_file_name; /* pathname of gcc */
255 static char *initname, *fininame; /* names of init and fini funcs */
257 static struct head constructors; /* list of constructors found */
258 static struct head destructors; /* list of destructors found */
259 #ifdef COLLECT_EXPORT_LIST
260 static struct head exports; /* list of exported symbols */
261 static struct head imports; /* list of imported symbols */
262 static struct head undefined; /* list of undefined symbols */
263 #endif
264 static struct head frame_tables; /* list of frame unwind info tables */
266 struct obstack temporary_obstack;
267 struct obstack permanent_obstack;
268 char * temporary_firstobj;
270 /* Defined in the automatically-generated underscore.c. */
271 extern int prepends_underscore;
273 extern char *getenv ();
274 extern char *mktemp ();
275 extern FILE *fdopen ();
277 /* Structure to hold all the directories in which to search for files to
278 execute. */
280 struct prefix_list
282 char *prefix; /* String to prepend to the path. */
283 struct prefix_list *next; /* Next in linked list. */
286 struct path_prefix
288 struct prefix_list *plist; /* List of prefixes to try */
289 int max_len; /* Max length of a prefix in PLIST */
290 char *name; /* Name of this list (used in config stuff) */
293 #ifdef COLLECT_EXPORT_LIST
294 /* Lists to keep libraries to be scanned for global constructors/destructors. */
295 static struct head libs; /* list of libraries */
296 static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
297 static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
298 static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
299 &libpath_lib_dirs, NULL};
300 static char *libexts[3] = {"a", "so", NULL}; /* possible library extentions */
301 #endif
303 void collect_exit PROTO((int));
304 void collect_execute PROTO((char *, char **, char *));
305 void dump_file PROTO((char *));
306 static void handler PROTO((int));
307 static int is_ctor_dtor PROTO((char *));
308 static int is_in_prefix_list PROTO((struct path_prefix *, char *, int));
309 static char *find_a_file PROTO((struct path_prefix *, char *));
310 static void add_prefix PROTO((struct path_prefix *, char *));
311 static void prefix_from_env PROTO((char *, struct path_prefix *));
312 static void prefix_from_string PROTO((char *, struct path_prefix *));
313 static void do_wait PROTO((char *));
314 static void fork_execute PROTO((char *, char **));
315 static void maybe_unlink PROTO((char *));
316 static void add_to_list PROTO((struct head *, char *));
317 static void write_list PROTO((FILE *, char *, struct id *));
318 static void dump_list PROTO((FILE *, char *, struct id *));
319 static void dump_prefix_list PROTO((FILE *, char *, struct prefix_list *));
320 static int is_in_list PROTO((char *, struct id *));
321 static void write_list_with_asm PROTO((FILE *, char *, struct id *));
322 static void write_c_file PROTO((FILE *, char *));
323 static void scan_prog_file PROTO((char *, enum pass));
324 #ifdef SCAN_LIBRARIES
325 static void scan_libraries PROTO((char *));
326 #endif
327 #ifdef COLLECT_EXPORT_LIST
328 static void write_export_file PROTO((FILE *));
329 static void write_import_file PROTO((FILE *));
330 static char *resolve_lib_name PROTO((char *));
331 static int use_import_list PROTO((char *));
332 static int ignore_library PROTO((char *));
333 #endif
335 char *xcalloc ();
336 char *xmalloc ();
338 #ifdef NEED_DECLARATION_INDEX
339 extern char *index ();
340 #endif
342 #ifdef NEED_DECLARATION_RINDEX
343 extern char *rindex ();
344 #endif
346 #ifdef NEED_DECLARATION_FREE
347 extern void free ();
348 #endif
350 #ifdef NO_DUP2
352 dup2 (oldfd, newfd)
353 int oldfd;
354 int newfd;
356 int fdtmp[256];
357 int fdx = 0;
358 int fd;
360 if (oldfd == newfd)
361 return oldfd;
362 close (newfd);
363 while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
364 fdtmp[fdx++] = fd;
365 while (fdx > 0)
366 close (fdtmp[--fdx]);
368 return fd;
370 #endif
372 char *
373 my_strerror (e)
374 int e;
377 #ifdef HAVE_STRERROR
378 return strerror (e);
380 #else
382 static char buffer[30];
383 if (!e)
384 return "";
386 if (e > 0 && e < sys_nerr)
387 return sys_errlist[e];
389 sprintf (buffer, "Unknown error %d", e);
390 return buffer;
391 #endif
394 /* Delete tempfiles and exit function. */
396 void
397 collect_exit (status)
398 int status;
400 if (c_file != 0 && c_file[0])
401 maybe_unlink (c_file);
403 if (o_file != 0 && o_file[0])
404 maybe_unlink (o_file);
406 #ifdef COLLECT_EXPORT_LIST
407 if (export_file != 0 && export_file[0])
408 maybe_unlink (export_file);
410 if (import_file != 0 && import_file[0])
411 maybe_unlink (import_file);
412 #endif
414 if (ldout != 0 && ldout[0])
416 dump_file (ldout);
417 maybe_unlink (ldout);
420 if (status != 0 && output_file != 0 && output_file[0])
421 maybe_unlink (output_file);
423 exit (status);
427 /* Die when sys call fails. */
429 void
430 fatal_perror (string, arg1, arg2, arg3)
431 char *string, *arg1, *arg2, *arg3;
433 int e = errno;
435 fprintf (stderr, "collect2: ");
436 fprintf (stderr, string, arg1, arg2, arg3);
437 fprintf (stderr, ": %s\n", my_strerror (e));
438 collect_exit (FATAL_EXIT_CODE);
441 /* Just die. */
443 void
444 fatal (string, arg1, arg2, arg3)
445 char *string, *arg1, *arg2, *arg3;
447 fprintf (stderr, "collect2: ");
448 fprintf (stderr, string, arg1, arg2, arg3);
449 fprintf (stderr, "\n");
450 collect_exit (FATAL_EXIT_CODE);
453 /* Write error message. */
455 void
456 error (string, arg1, arg2, arg3, arg4)
457 char *string, *arg1, *arg2, *arg3, *arg4;
459 fprintf (stderr, "collect2: ");
460 fprintf (stderr, string, arg1, arg2, arg3, arg4);
461 fprintf (stderr, "\n");
464 /* In case obstack is linked in, and abort is defined to fancy_abort,
465 provide a default entry. */
467 void
468 fancy_abort ()
470 fatal ("internal error");
474 static void
475 handler (signo)
476 int signo;
478 if (c_file != 0 && c_file[0])
479 maybe_unlink (c_file);
481 if (o_file != 0 && o_file[0])
482 maybe_unlink (o_file);
484 if (ldout != 0 && ldout[0])
485 maybe_unlink (ldout);
487 #ifdef COLLECT_EXPORT_LIST
488 if (export_file != 0 && export_file[0])
489 maybe_unlink (export_file);
491 if (import_file != 0 && import_file[0])
492 maybe_unlink (import_file);
493 #endif
495 signal (signo, SIG_DFL);
496 kill (getpid (), signo);
500 char *
501 xcalloc (size1, size2)
502 int size1, size2;
504 char *ptr = (char *) calloc (size1, size2);
505 if (ptr)
506 return ptr;
508 fatal ("out of memory");
509 return (char *) 0;
512 char *
513 xmalloc (size)
514 unsigned size;
516 char *ptr = (char *) malloc (size);
517 if (ptr)
518 return ptr;
520 fatal ("out of memory");
521 return (char *) 0;
524 char *
525 xrealloc (ptr, size)
526 char *ptr;
527 unsigned size;
529 register char *value = (char *) realloc (ptr, size);
530 if (value == 0)
531 fatal ("virtual memory exhausted");
532 return value;
536 file_exists (name)
537 char *name;
539 return access (name, R_OK) == 0;
542 /* Make a copy of a string INPUT with size SIZE. */
544 char *
545 savestring (input, size)
546 char *input;
547 int size;
549 char *output = (char *) xmalloc (size + 1);
550 bcopy (input, output, size);
551 output[size] = 0;
552 return output;
555 /* Parse a reasonable subset of shell quoting syntax. */
557 static char *
558 extract_string (pp)
559 char **pp;
561 char *p = *pp;
562 int backquote = 0;
563 int inside = 0;
565 for (;;)
567 char c = *p;
568 if (c == '\0')
569 break;
570 ++p;
571 if (backquote)
572 obstack_1grow (&temporary_obstack, c);
573 else if (! inside && c == ' ')
574 break;
575 else if (! inside && c == '\\')
576 backquote = 1;
577 else if (c == '\'')
578 inside = !inside;
579 else
580 obstack_1grow (&temporary_obstack, c);
583 obstack_1grow (&temporary_obstack, '\0');
584 *pp = p;
585 return obstack_finish (&temporary_obstack);
588 void
589 dump_file (name)
590 char *name;
592 FILE *stream = fopen (name, "r");
593 int no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
595 if (stream == 0)
596 return;
597 while (1)
599 int c;
600 while (c = getc (stream),
601 c != EOF && (isalnum (c) || c == '_' || c == '$' || c == '.'))
602 obstack_1grow (&temporary_obstack, c);
603 if (obstack_object_size (&temporary_obstack) > 0)
605 char *word, *p, *result;
606 obstack_1grow (&temporary_obstack, '\0');
607 word = obstack_finish (&temporary_obstack);
609 if (*word == '.')
610 ++word, putc ('.', stderr);
611 p = word;
612 if (*p == '_' && prepends_underscore)
613 ++p;
615 if (no_demangle)
616 result = 0;
617 else
618 result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI);
620 if (result)
622 int diff;
623 fputs (result, stderr);
625 diff = strlen (word) - strlen (result);
626 while (diff > 0)
627 --diff, putc (' ', stderr);
628 while (diff < 0 && c == ' ')
629 ++diff, c = getc (stream);
631 free (result);
633 else
634 fputs (word, stderr);
636 fflush (stderr);
637 obstack_free (&temporary_obstack, temporary_firstobj);
639 if (c == EOF)
640 break;
641 putc (c, stderr);
643 fclose (stream);
646 /* Decide whether the given symbol is:
647 a constructor (1), a destructor (2), or neither (0). */
649 static int
650 is_ctor_dtor (s)
651 char *s;
653 struct names { char *name; int len; int ret; int two_underscores; };
655 register struct names *p;
656 register int ch;
657 register char *orig_s = s;
659 static struct names special[] = {
660 #ifdef NO_DOLLAR_IN_LABEL
661 #ifdef NO_DOT_IN_LABEL
662 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
663 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
664 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
665 #else
666 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
667 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
668 { "GLOBAL_.F.", sizeof ("GLOBAL_.F.")-1, 5, 0 },
669 #endif
670 #else
671 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
672 { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },
673 { "GLOBAL_$F$", sizeof ("GLOBAL_$F$")-1, 5, 0 },
674 #endif
675 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
676 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
677 #ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions.
678 cfront has its own linker procedure to collect them;
679 if collect2 gets them too, they get collected twice
680 when the cfront procedure is run and the compiler used
681 for linking happens to be GCC. */
682 { "sti__", sizeof ("sti__")-1, 1, 1 },
683 { "std__", sizeof ("std__")-1, 2, 1 },
684 #endif /* CFRONT_LOSSAGE */
685 { NULL, 0, 0, 0 }
688 while ((ch = *s) == '_')
689 ++s;
691 if (s == orig_s)
692 return 0;
694 for (p = &special[0]; p->len > 0; p++)
696 if (ch == p->name[0]
697 && (!p->two_underscores || ((s - orig_s) >= 2))
698 && strncmp(s, p->name, p->len) == 0)
700 return p->ret;
703 return 0;
706 /* Routine to add variables to the environment. */
708 #ifndef HAVE_PUTENV
711 putenv (str)
712 char *str;
714 #ifndef VMS /* nor about VMS */
716 extern char **environ;
717 char **old_environ = environ;
718 char **envp;
719 int num_envs = 0;
720 int name_len = 1;
721 char *p = str;
722 int ch;
724 while ((ch = *p++) != '\0' && ch != '=')
725 name_len++;
727 if (!ch)
728 abort ();
730 /* Search for replacing an existing environment variable, and
731 count the number of total environment variables. */
732 for (envp = old_environ; *envp; envp++)
734 num_envs++;
735 if (!strncmp (str, *envp, name_len))
737 *envp = str;
738 return 0;
742 /* Add a new environment variable */
743 environ = (char **) xmalloc (sizeof (char *) * (num_envs+2));
744 *environ = str;
745 bcopy ((char *) old_environ, (char *) (environ + 1),
746 sizeof (char *) * (num_envs+1));
748 return 0;
749 #endif /* VMS */
752 #endif /* HAVE_PUTENV */
754 /* By default, colon separates directories in a path. */
755 #ifndef PATH_SEPARATOR
756 #define PATH_SEPARATOR ':'
757 #endif
759 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
760 and one from the PATH variable. */
762 static struct path_prefix cpath, path;
764 #ifdef CROSS_COMPILE
765 /* This is the name of the target machine. We use it to form the name
766 of the files to execute. */
768 static char *target_machine = TARGET_MACHINE;
769 #endif
771 /* Names under which we were executed. Never return one of those files in our
772 searches. */
774 static struct path_prefix our_file_names;
776 /* Determine if STRING is in PPREFIX.
778 This utility is currently only used to look up file names. Prefix lists
779 record directory names. This matters to us because the latter has a
780 trailing slash, so I've added a flag to handle both. */
782 static int
783 is_in_prefix_list (pprefix, string, filep)
784 struct path_prefix *pprefix;
785 char *string;
786 int filep;
788 struct prefix_list *pl;
790 if (filep)
792 int len = strlen (string);
794 for (pl = pprefix->plist; pl; pl = pl->next)
796 if (strncmp (pl->prefix, string, len) == 0
797 && strcmp (pl->prefix + len, "/") == 0)
798 return 1;
801 else
803 for (pl = pprefix->plist; pl; pl = pl->next)
805 if (strcmp (pl->prefix, string) == 0)
806 return 1;
810 return 0;
813 /* Search for NAME using prefix list PPREFIX. We only look for executable
814 files.
816 Return 0 if not found, otherwise return its name, allocated with malloc. */
818 static char *
819 find_a_file (pprefix, name)
820 struct path_prefix *pprefix;
821 char *name;
823 char *temp;
824 struct prefix_list *pl;
825 int len = pprefix->max_len + strlen (name) + 1;
827 #ifdef EXECUTABLE_SUFFIX
828 len += strlen (EXECUTABLE_SUFFIX);
829 #endif
831 temp = xmalloc (len);
833 /* Determine the filename to execute (special case for absolute paths). */
835 if (*name == '/')
837 if (access (name, X_OK) == 0)
839 strcpy (temp, name);
840 return temp;
843 else
844 for (pl = pprefix->plist; pl; pl = pl->next)
846 strcpy (temp, pl->prefix);
847 strcat (temp, name);
848 if (! is_in_prefix_list (&our_file_names, temp, 1)
849 /* This is a kludge, but there seems no way around it. */
850 && strcmp (temp, "./ld") != 0
851 && access (temp, X_OK) == 0)
852 return temp;
854 #ifdef EXECUTABLE_SUFFIX
855 /* Some systems have a suffix for executable files.
856 So try appending that. */
857 strcat (temp, EXECUTABLE_SUFFIX);
858 if (! is_in_prefix_list (&our_file_names, temp, 1)
859 && access (temp, X_OK) == 0)
860 return temp;
861 #endif
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 = savestring (prefix, len);
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 = getenv (env);
913 if (p)
914 prefix_from_string (p, pprefix);
917 static void
918 prefix_from_string (p, pprefix)
919 char *p;
920 struct path_prefix *pprefix;
922 char *startp, *endp;
923 char *nstore = (char *) xmalloc (strlen (p) + 3);
925 startp = endp = p;
926 while (1)
928 if (*endp == PATH_SEPARATOR || *endp == 0)
930 strncpy (nstore, startp, endp-startp);
931 if (endp == startp)
933 strcpy (nstore, "./");
935 else if (endp[-1] != '/')
937 nstore[endp-startp] = '/';
938 nstore[endp-startp+1] = 0;
940 else
941 nstore[endp-startp] = 0;
943 add_prefix (pprefix, nstore);
944 if (*endp == 0)
945 break;
946 endp = startp = endp + 1;
948 else
949 endp++;
953 /* Main program. */
956 main (argc, argv)
957 int argc;
958 char *argv[];
960 char *ld_suffix = "ld";
961 char *full_ld_suffix = ld_suffix;
962 char *real_ld_suffix = "real-ld";
963 #ifdef CROSS_COMPILE
964 char *full_real_ld_suffix = real_ld_suffix;
965 #endif
966 char *collect_ld_suffix = "collect-ld";
967 char *nm_suffix = "nm";
968 char *full_nm_suffix = nm_suffix;
969 char *gnm_suffix = "gnm";
970 char *full_gnm_suffix = gnm_suffix;
971 #ifdef LDD_SUFFIX
972 char *ldd_suffix = LDD_SUFFIX;
973 char *full_ldd_suffix = ldd_suffix;
974 #endif
975 char *strip_suffix = "strip";
976 char *full_strip_suffix = strip_suffix;
977 char *gstrip_suffix = "gstrip";
978 char *full_gstrip_suffix = gstrip_suffix;
979 char *arg;
980 FILE *outf;
981 #ifdef COLLECT_EXPORT_LIST
982 FILE *exportf;
983 FILE *importf;
984 #endif
985 char *ld_file_name;
986 char *collect_name;
987 char *collect_names;
988 char *p;
989 char **c_argv;
990 char **c_ptr;
991 char **ld1_argv = (char **) xcalloc (sizeof (char *), argc+3);
992 char **ld1 = ld1_argv;
993 char **ld2_argv = (char **) xcalloc (sizeof (char *), argc+6);
994 char **ld2 = ld2_argv;
995 char **object_lst = (char **) xcalloc (sizeof (char *), argc);
996 char **object = object_lst;
997 int first_file;
998 int num_c_args = argc+7;
1000 #ifdef DEBUG
1001 debug = 1;
1002 vflag = 1;
1003 #endif
1005 #ifndef DEFAULT_A_OUT_NAME
1006 output_file = "a.out";
1007 #else
1008 output_file = DEFAULT_A_OUT_NAME;
1009 #endif
1011 obstack_begin (&temporary_obstack, 0);
1012 obstack_begin (&permanent_obstack, 0);
1013 temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
1014 current_demangling_style = gnu_demangling;
1016 /* We must check that we do not call ourselves in an infinite
1017 recursion loop. We append the name used for us to the COLLECT_NAMES
1018 environment variable.
1020 In practice, collect will rarely invoke itself. This can happen now
1021 that we are no longer called gld. A perfect example is when running
1022 gcc in a build directory that has been installed. When looking for
1023 ld, we will find our installed version and believe that's the real ld. */
1025 /* We must also append COLLECT_NAME to COLLECT_NAMES to watch for the
1026 previous version of collect (the one that used COLLECT_NAME and only
1027 handled two levels of recursion). If we do not we may mutually recurse
1028 forever. This can happen (I think) when bootstrapping the old version
1029 and a new one is installed (rare, but we should handle it).
1030 ??? Hopefully references to COLLECT_NAME can be removed at some point. */
1032 collect_name = (char *) getenv ("COLLECT_NAME");
1033 collect_names = (char *) getenv ("COLLECT_NAMES");
1035 p = (char *) xmalloc (strlen ("COLLECT_NAMES=")
1036 + (collect_name ? strlen (collect_name) + 1 : 0)
1037 + (collect_names ? strlen (collect_names) + 1 : 0)
1038 + strlen (argv[0]) + 1);
1039 strcpy (p, "COLLECT_NAMES=");
1040 if (collect_name != 0)
1041 sprintf (p + strlen (p), "%s%c", collect_name, PATH_SEPARATOR);
1042 if (collect_names != 0)
1043 sprintf (p + strlen (p), "%s%c", collect_names, PATH_SEPARATOR);
1044 strcat (p, argv[0]);
1045 putenv (p);
1047 prefix_from_env ("COLLECT_NAMES", &our_file_names);
1049 /* Set environment variable COLLECT_NAME to our name so the previous version
1050 of collect will not find us. If it does we will mutually recurse forever.
1051 This can happen when bootstrapping the new version and an old version is
1052 installed.
1053 ??? Hopefully this bit of code can be removed at some point. */
1055 p = xmalloc (strlen ("COLLECT_NAME=") + strlen (argv[0]) + 1);
1056 sprintf (p, "COLLECT_NAME=%s", argv[0]);
1057 putenv (p);
1059 p = (char *) getenv ("COLLECT_GCC_OPTIONS");
1060 while (p && *p)
1062 char *q = extract_string (&p);
1063 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1064 num_c_args++;
1066 obstack_free (&temporary_obstack, temporary_firstobj);
1067 ++num_c_args;
1069 c_ptr = c_argv = (char **) xcalloc (sizeof (char *), num_c_args);
1071 if (argc < 2)
1072 fatal ("no arguments");
1074 #ifdef SIGQUIT
1075 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
1076 signal (SIGQUIT, handler);
1077 #endif
1078 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
1079 signal (SIGINT, handler);
1080 #ifdef SIGALRM
1081 if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
1082 signal (SIGALRM, handler);
1083 #endif
1084 #ifdef SIGHUP
1085 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
1086 signal (SIGHUP, handler);
1087 #endif
1088 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
1089 signal (SIGSEGV, handler);
1090 #ifdef SIGBUS
1091 if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
1092 signal (SIGBUS, handler);
1093 #endif
1095 /* Extract COMPILER_PATH and PATH into our prefix list. */
1096 prefix_from_env ("COMPILER_PATH", &cpath);
1097 prefix_from_env ("PATH", &path);
1099 #ifdef CROSS_COMPILE
1100 /* If we look for a program in the compiler directories, we just use
1101 the short name, since these directories are already system-specific.
1102 But it we look for a took in the system directories, we need to
1103 qualify the program name with the target machine. */
1105 full_ld_suffix
1106 = xcalloc (strlen (ld_suffix) + strlen (target_machine) + 2, 1);
1107 strcpy (full_ld_suffix, target_machine);
1108 strcat (full_ld_suffix, "-");
1109 strcat (full_ld_suffix, ld_suffix);
1111 full_real_ld_suffix
1112 = xcalloc (strlen (real_ld_suffix) + strlen (target_machine) + 2, 1);
1113 strcpy (full_real_ld_suffix, target_machine);
1114 strcat (full_real_ld_suffix, "-");
1115 strcat (full_real_ld_suffix, real_ld_suffix);
1117 #if 0
1118 full_gld_suffix
1119 = xcalloc (strlen (gld_suffix) + strlen (target_machine) + 2, 1);
1120 strcpy (full_gld_suffix, target_machine);
1121 strcat (full_gld_suffix, "-");
1122 strcat (full_gld_suffix, gld_suffix);
1123 #endif
1125 full_nm_suffix
1126 = xcalloc (strlen (nm_suffix) + strlen (target_machine) + 2, 1);
1127 strcpy (full_nm_suffix, target_machine);
1128 strcat (full_nm_suffix, "-");
1129 strcat (full_nm_suffix, nm_suffix);
1131 full_gnm_suffix
1132 = xcalloc (strlen (gnm_suffix) + strlen (target_machine) + 2, 1);
1133 strcpy (full_gnm_suffix, target_machine);
1134 strcat (full_gnm_suffix, "-");
1135 strcat (full_gnm_suffix, gnm_suffix);
1137 #ifdef LDD_SUFFIX
1138 full_ldd_suffix
1139 = xcalloc (strlen (ldd_suffix) + strlen (target_machine) + 2, 1);
1140 strcpy (full_ldd_suffix, target_machine);
1141 strcat (full_ldd_suffix, "-");
1142 strcat (full_ldd_suffix, ldd_suffix);
1143 #endif
1145 full_strip_suffix
1146 = xcalloc (strlen (strip_suffix) + strlen (target_machine) + 2, 1);
1147 strcpy (full_strip_suffix, target_machine);
1148 strcat (full_strip_suffix, "-");
1149 strcat (full_strip_suffix, strip_suffix);
1151 full_gstrip_suffix
1152 = xcalloc (strlen (gstrip_suffix) + strlen (target_machine) + 2, 1);
1153 strcpy (full_gstrip_suffix, target_machine);
1154 strcat (full_gstrip_suffix, "-");
1155 strcat (full_gstrip_suffix, gstrip_suffix);
1156 #endif /* CROSS_COMPILE */
1158 /* Try to discover a valid linker/nm/strip to use. */
1160 /* Maybe we know the right file to use (if not cross). */
1161 #ifdef REAL_LD_FILE_NAME
1162 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
1163 if (ld_file_name == 0)
1164 #endif
1165 /* Search the (target-specific) compiler dirs for ld'. */
1166 ld_file_name = find_a_file (&cpath, real_ld_suffix);
1167 /* Likewise for `collect-ld'. */
1168 if (ld_file_name == 0)
1169 ld_file_name = find_a_file (&cpath, collect_ld_suffix);
1170 /* Search the compiler directories for `ld'. We have protection against
1171 recursive calls in find_a_file. */
1172 if (ld_file_name == 0)
1173 ld_file_name = find_a_file (&cpath, ld_suffix);
1174 /* Search the ordinary system bin directories
1175 for `ld' (if native linking) or `TARGET-ld' (if cross). */
1176 if (ld_file_name == 0)
1177 ld_file_name = find_a_file (&path, full_ld_suffix);
1179 /* If we've invoked ourselves, try again with LD_FILE_NAME. */
1181 if (collect_names != 0)
1183 if (ld_file_name != 0)
1185 argv[0] = ld_file_name;
1186 execvp (argv[0], argv);
1188 fatal ("cannot find `ld'");
1191 #ifdef REAL_NM_FILE_NAME
1192 nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
1193 if (nm_file_name == 0)
1194 #endif
1195 nm_file_name = find_a_file (&cpath, gnm_suffix);
1196 if (nm_file_name == 0)
1197 nm_file_name = find_a_file (&path, full_gnm_suffix);
1198 if (nm_file_name == 0)
1199 nm_file_name = find_a_file (&cpath, nm_suffix);
1200 if (nm_file_name == 0)
1201 nm_file_name = find_a_file (&path, full_nm_suffix);
1203 #ifdef LDD_SUFFIX
1204 ldd_file_name = find_a_file (&cpath, ldd_suffix);
1205 if (ldd_file_name == 0)
1206 ldd_file_name = find_a_file (&path, full_ldd_suffix);
1207 #endif
1209 #ifdef REAL_STRIP_FILE_NAME
1210 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
1211 if (strip_file_name == 0)
1212 #endif
1213 strip_file_name = find_a_file (&cpath, gstrip_suffix);
1214 if (strip_file_name == 0)
1215 strip_file_name = find_a_file (&path, full_gstrip_suffix);
1216 if (strip_file_name == 0)
1217 strip_file_name = find_a_file (&cpath, strip_suffix);
1218 if (strip_file_name == 0)
1219 strip_file_name = find_a_file (&path, full_strip_suffix);
1221 /* Determine the full path name of the C compiler to use. */
1222 c_file_name = getenv ("COLLECT_GCC");
1223 if (c_file_name == 0)
1225 #ifdef CROSS_COMPILE
1226 c_file_name = xcalloc (sizeof ("gcc-") + strlen (target_machine) + 1, 1);
1227 strcpy (c_file_name, target_machine);
1228 strcat (c_file_name, "-gcc");
1229 #else
1230 c_file_name = "gcc";
1231 #endif
1234 p = find_a_file (&cpath, c_file_name);
1236 /* Here it should be safe to use the system search path since we should have
1237 already qualified the name of the compiler when it is needed. */
1238 if (p == 0)
1239 p = find_a_file (&path, c_file_name);
1241 if (p)
1242 c_file_name = p;
1244 *ld1++ = *ld2++ = ld_file_name;
1246 /* Make temp file names. */
1247 temp_filename = choose_temp_base ();
1248 temp_filename_length = strlen (temp_filename);
1249 c_file = xcalloc (temp_filename_length + sizeof (".c"), 1);
1250 o_file = xcalloc (temp_filename_length + sizeof (".o"), 1);
1251 #ifdef COLLECT_EXPORT_LIST
1252 export_file = xmalloc (temp_filename_length + sizeof (".x"));
1253 import_file = xmalloc (temp_filename_length + sizeof (".p"));
1254 #endif
1255 ldout = xmalloc (temp_filename_length + sizeof (".ld"));
1256 sprintf (ldout, "%s.ld", temp_filename);
1257 sprintf (c_file, "%s.c", temp_filename);
1258 sprintf (o_file, "%s.o", temp_filename);
1259 #ifdef COLLECT_EXPORT_LIST
1260 sprintf (export_file, "%s.x", temp_filename);
1261 sprintf (import_file, "%s.p", temp_filename);
1262 #endif
1263 *c_ptr++ = c_file_name;
1264 *c_ptr++ = "-c";
1265 *c_ptr++ = "-o";
1266 *c_ptr++ = o_file;
1268 #ifdef COLLECT_EXPORT_LIST
1269 /* Generate a list of directories from LIBPATH. */
1270 prefix_from_env ("LIBPATH", &libpath_lib_dirs);
1271 /* Add to this list also two standard directories where
1272 AIX loader always searches for libraries. */
1273 add_prefix (&libpath_lib_dirs, "/lib");
1274 add_prefix (&libpath_lib_dirs, "/usr/lib");
1275 #endif
1277 /* Get any options that the upper GCC wants to pass to the sub-GCC.
1279 AIX support needs to know if -shared has been specified before
1280 parsing commandline arguments. */
1282 p = (char *) getenv ("COLLECT_GCC_OPTIONS");
1283 while (p && *p)
1285 char *q = extract_string (&p);
1286 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1287 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1288 if (strncmp (q, "-shared", sizeof ("-shared") - 1) == 0)
1289 shared_obj = 1;
1291 obstack_free (&temporary_obstack, temporary_firstobj);
1292 *c_ptr++ = "-fno-exceptions";
1294 /* !!! When GCC calls collect2,
1295 it does not know whether it is calling collect2 or ld.
1296 So collect2 cannot meaningfully understand any options
1297 except those ld understands.
1298 If you propose to make GCC pass some other option,
1299 just imagine what will happen if ld is really ld!!! */
1301 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1302 /* After the first file, put in the c++ rt0. */
1304 first_file = 1;
1305 while ((arg = *++argv) != (char *) 0)
1307 *ld1++ = *ld2++ = arg;
1309 if (arg[0] == '-')
1311 switch (arg[1])
1313 #ifdef COLLECT_EXPORT_LIST
1314 /* We want to disable automatic exports on AIX when user
1315 explicitly puts an export list in command line */
1316 case 'b':
1317 if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
1318 export_flag = 1;
1319 break;
1320 #endif
1322 case 'd':
1323 if (!strcmp (arg, "-debug"))
1325 debug = 1;
1326 vflag = 1;
1327 ld1--;
1328 ld2--;
1330 break;
1332 case 'l':
1333 if (first_file)
1335 /* place o_file BEFORE this argument! */
1336 first_file = 0;
1337 ld2--;
1338 *ld2++ = o_file;
1339 *ld2++ = arg;
1341 #ifdef COLLECT_EXPORT_LIST
1343 /* Resolving full library name. */
1344 char *s = resolve_lib_name (arg+2);
1346 /* If we will use an import list for this library,
1347 we should exclude it from ld args. */
1348 if (use_import_list (s))
1350 ld1--;
1351 ld2--;
1354 /* Saving a full library name. */
1355 add_to_list (&libs, s);
1357 #endif
1358 break;
1360 #ifdef COLLECT_EXPORT_LIST
1361 /* Saving directories where to search for libraries. */
1362 case 'L':
1363 add_prefix (&cmdline_lib_dirs, arg+2);
1364 break;
1365 #endif
1367 case 'o':
1368 if (arg[2] == '\0')
1369 output_file = *ld1++ = *ld2++ = *++argv;
1370 else
1371 output_file = &arg[2];
1372 break;
1374 case 'r':
1375 if (arg[2] == '\0')
1376 rflag = 1;
1377 break;
1379 case 's':
1380 if (arg[2] == '\0' && do_collecting)
1382 /* We must strip after the nm run, otherwise C++ linking
1383 will not work. Thus we strip in the second ld run, or
1384 else with strip if there is no second ld run. */
1385 strip_flag = 1;
1386 ld1--;
1388 break;
1390 case 'v':
1391 if (arg[2] == '\0')
1392 vflag = 1;
1393 break;
1396 else if ((p = rindex (arg, '.')) != (char *) 0
1397 && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
1398 || strcmp (p, ".so") == 0))
1400 if (first_file)
1402 first_file = 0;
1403 if (p[1] == 'o')
1404 *ld2++ = o_file;
1405 else
1407 /* place o_file BEFORE this argument! */
1408 ld2--;
1409 *ld2++ = o_file;
1410 *ld2++ = arg;
1413 if (p[1] == 'o')
1414 *object++ = arg;
1415 #ifdef COLLECT_EXPORT_LIST
1416 /* libraries can be specified directly, i.e. without -l flag. */
1417 else
1419 /* If we will use an import list for this library,
1420 we should exclude it from ld args. */
1421 if (use_import_list (arg))
1423 ld1--;
1424 ld2--;
1427 /* Saving a full library name. */
1428 add_to_list (&libs, arg);
1430 #endif
1434 #ifdef COLLECT_EXPORT_LIST
1435 /* This is added only for debugging purposes. */
1436 if (debug)
1438 fprintf (stderr, "List of libraries:\n");
1439 dump_list (stderr, "\t", libs.first);
1442 /* The AIX linker will discard static constructors in object files if
1443 nothing else in the file is referenced, so look at them first. */
1445 char **export_object_lst = object_lst;
1446 while (export_object_lst < object)
1447 scan_prog_file (*export_object_lst++, PASS_OBJ);
1450 struct id *list = libs.first;
1451 for (; list; list = list->next)
1452 scan_prog_file (list->name, PASS_FIRST);
1455 char *buf1 = alloca (strlen (export_file) + 5);
1456 char *buf2 = alloca (strlen (import_file) + 5);
1457 sprintf (buf1, "-bE:%s", export_file);
1458 sprintf (buf2, "-bI:%s", import_file);
1459 *ld1++ = buf1;
1460 *ld2++ = buf1;
1461 *ld1++ = buf2;
1462 *ld2++ = buf2;
1463 exportf = fopen (export_file, "w");
1464 if (exportf == (FILE *) 0)
1465 fatal_perror ("%s", export_file);
1466 write_export_file (exportf);
1467 if (fclose (exportf))
1468 fatal_perror ("closing %s", export_file);
1469 importf = fopen (import_file, "w");
1470 if (importf == (FILE *) 0)
1471 fatal_perror ("%s", import_file);
1472 write_import_file (importf);
1473 if (fclose (importf))
1474 fatal_perror ("closing %s", import_file);
1476 #endif
1478 *c_ptr++ = c_file;
1479 *object = *c_ptr = *ld1 = (char *) 0;
1481 if (vflag)
1483 fprintf (stderr, "collect2 version %s", version_string);
1484 #ifdef TARGET_VERSION
1485 TARGET_VERSION;
1486 #endif
1487 fprintf (stderr, "\n");
1490 if (debug)
1492 char *ptr;
1493 fprintf (stderr, "ld_file_name = %s\n",
1494 (ld_file_name ? ld_file_name : "not found"));
1495 fprintf (stderr, "c_file_name = %s\n",
1496 (c_file_name ? c_file_name : "not found"));
1497 fprintf (stderr, "nm_file_name = %s\n",
1498 (nm_file_name ? nm_file_name : "not found"));
1499 #ifdef LDD_SUFFIX
1500 fprintf (stderr, "ldd_file_name = %s\n",
1501 (ldd_file_name ? ldd_file_name : "not found"));
1502 #endif
1503 fprintf (stderr, "strip_file_name = %s\n",
1504 (strip_file_name ? strip_file_name : "not found"));
1505 fprintf (stderr, "c_file = %s\n",
1506 (c_file ? c_file : "not found"));
1507 fprintf (stderr, "o_file = %s\n",
1508 (o_file ? o_file : "not found"));
1510 ptr = getenv ("COLLECT_NAMES");
1511 if (ptr)
1512 fprintf (stderr, "COLLECT_NAMES = %s\n", ptr);
1514 ptr = getenv ("COLLECT_GCC_OPTIONS");
1515 if (ptr)
1516 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1518 ptr = getenv ("COLLECT_GCC");
1519 if (ptr)
1520 fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
1522 ptr = getenv ("COMPILER_PATH");
1523 if (ptr)
1524 fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
1526 ptr = getenv ("LIBRARY_PATH");
1527 if (ptr)
1528 fprintf (stderr, "LIBRARY_PATH = %s\n", ptr);
1530 fprintf (stderr, "\n");
1533 /* Load the program, searching all libraries and attempting to provide
1534 undefined symbols from repository information. */
1536 /* On AIX we do this later. */
1537 #ifndef COLLECT_EXPORT_LIST
1538 do_tlink (ld1_argv, object_lst);
1539 #endif
1541 /* If -r or they will be run via some other method, do not build the
1542 constructor or destructor list, just return now. */
1543 if (rflag || ! do_collecting)
1545 /* But make sure we delete the export file we may have created. */
1546 if (export_file != 0 && export_file[0])
1547 maybe_unlink (export_file);
1548 if (import_file != 0 && import_file[0])
1549 maybe_unlink (import_file);
1550 return 0;
1553 /* Examine the namelist with nm and search it for static constructors
1554 and destructors to call.
1555 Write the constructor and destructor tables to a .s file and reload. */
1557 /* On AIX we already done scanning for global constructors/destructors. */
1558 #ifndef COLLECT_EXPORT_LIST
1559 scan_prog_file (output_file, PASS_FIRST);
1560 #endif
1562 #ifdef SCAN_LIBRARIES
1563 scan_libraries (output_file);
1564 #endif
1566 if (debug)
1568 fprintf (stderr, "%d constructor(s) found\n", constructors.number);
1569 fprintf (stderr, "%d destructor(s) found\n", destructors.number);
1572 if (constructors.number == 0 && destructors.number == 0
1573 && frame_tables.number == 0
1574 #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1575 /* If we will be running these functions ourselves, we want to emit
1576 stubs into the shared library so that we do not have to relink
1577 dependent programs when we add static objects. */
1578 && ! shared_obj
1579 #endif
1582 #ifdef COLLECT_EXPORT_LIST
1583 /* Doing tlink without additional code generation */
1584 do_tlink (ld1_argv, object_lst);
1585 #endif
1586 /* Strip now if it was requested on the command line. */
1587 if (strip_flag)
1589 char **strip_argv = (char **) xcalloc (sizeof (char *), 3);
1590 strip_argv[0] = strip_file_name;
1591 strip_argv[1] = output_file;
1592 strip_argv[2] = (char *) 0;
1593 fork_execute ("strip", strip_argv);
1596 #ifdef COLLECT_EXPORT_LIST
1597 maybe_unlink (export_file);
1598 maybe_unlink (import_file);
1599 #endif
1600 return 0;
1603 maybe_unlink(output_file);
1604 outf = fopen (c_file, "w");
1605 if (outf == (FILE *) 0)
1606 fatal_perror ("%s", c_file);
1608 write_c_file (outf, c_file);
1610 if (fclose (outf))
1611 fatal_perror ("closing %s", c_file);
1613 /* Tell the linker that we have initializer and finalizer functions. */
1614 #ifdef LD_INIT_SWITCH
1615 *ld2++ = LD_INIT_SWITCH;
1616 *ld2++ = initname;
1617 *ld2++ = LD_FINI_SWITCH;
1618 *ld2++ = fininame;
1619 #endif
1620 *ld2 = (char*) 0;
1622 #ifdef COLLECT_EXPORT_LIST
1623 if (shared_obj)
1625 add_to_list (&exports, initname);
1626 add_to_list (&exports, fininame);
1627 add_to_list (&exports, "_GLOBAL__DI");
1628 add_to_list (&exports, "_GLOBAL__DD");
1629 exportf = fopen (export_file, "w");
1630 if (exportf == (FILE *) 0)
1631 fatal_perror ("%s", export_file);
1632 write_export_file (exportf);
1633 if (fclose (exportf))
1634 fatal_perror ("closing %s", export_file);
1636 #endif
1638 if (debug)
1640 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1641 output_file, c_file);
1642 write_c_file (stderr, "stderr");
1643 fprintf (stderr, "========== end of c_file\n\n");
1644 #ifdef COLLECT_EXPORT_LIST
1645 fprintf (stderr, "\n========== export_file = %s\n", export_file);
1646 write_export_file (stderr);
1647 fprintf (stderr, "========== end of export_file\n\n");
1648 #endif
1651 /* Assemble the constructor and destructor tables.
1652 Link the tables in with the rest of the program. */
1654 fork_execute ("gcc", c_argv);
1655 #ifdef COLLECT_EXPORT_LIST
1656 /* On AIX we must call tlink because of possible templates resolution */
1657 do_tlink (ld2_argv, object_lst);
1658 #else
1659 /* Otherwise, simply call ld because tlink is already done */
1660 fork_execute ("ld", ld2_argv);
1662 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1663 constructors/destructors in shared libraries. */
1664 scan_prog_file (output_file, PASS_SECOND);
1665 #endif
1667 maybe_unlink (c_file);
1668 maybe_unlink (o_file);
1670 #ifdef COLLECT_EXPORT_LIST
1671 maybe_unlink (export_file);
1672 maybe_unlink (import_file);
1673 #endif
1675 return 0;
1679 /* Wait for a process to finish, and exit if a non-zero status is found. */
1682 collect_wait (prog)
1683 char *prog;
1685 int status;
1687 wait (&status);
1688 if (status)
1690 if (WIFSIGNALED (status))
1692 int sig = WTERMSIG (status);
1693 #ifdef NO_SYS_SIGLIST
1694 error ("%s terminated with signal %d %s",
1695 prog,
1696 sig,
1697 (status & 0200) ? ", core dumped" : "");
1698 #else
1699 error ("%s terminated with signal %d [%s]%s",
1700 prog,
1701 sig,
1702 sys_siglist[sig],
1703 (status & 0200) ? ", core dumped" : "");
1704 #endif
1706 collect_exit (FATAL_EXIT_CODE);
1709 if (WIFEXITED (status))
1710 return WEXITSTATUS (status);
1712 return 0;
1715 static void
1716 do_wait (prog)
1717 char *prog;
1719 int ret = collect_wait (prog);
1720 if (ret != 0)
1722 error ("%s returned %d exit status", prog, ret);
1723 collect_exit (ret);
1728 /* Fork and execute a program, and wait for the reply. */
1730 void
1731 collect_execute (prog, argv, redir)
1732 char *prog;
1733 char **argv;
1734 char *redir;
1736 int pid;
1738 if (vflag || debug)
1740 char **p_argv;
1741 char *str;
1743 if (argv[0])
1744 fprintf (stderr, "%s", argv[0]);
1745 else
1746 fprintf (stderr, "[cannot find %s]", prog);
1748 for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
1749 fprintf (stderr, " %s", str);
1751 fprintf (stderr, "\n");
1754 fflush (stdout);
1755 fflush (stderr);
1757 /* If we cannot find a program we need, complain error. Do this here
1758 since we might not end up needing something that we could not find. */
1760 if (argv[0] == 0)
1761 fatal ("cannot find `%s'", prog);
1763 pid = vfork ();
1764 if (pid == -1)
1766 #ifdef vfork
1767 fatal_perror ("fork");
1768 #else
1769 fatal_perror ("vfork");
1770 #endif
1773 if (pid == 0) /* child context */
1775 if (redir)
1777 unlink (redir);
1778 if (freopen (redir, "a", stdout) == NULL)
1779 fatal_perror ("redirecting stdout: %s", redir);
1780 if (freopen (redir, "a", stderr) == NULL)
1781 fatal_perror ("redirecting stderr: %s", redir);
1784 execvp (argv[0], argv);
1785 fatal_perror ("executing %s", prog);
1789 static void
1790 fork_execute (prog, argv)
1791 char *prog;
1792 char **argv;
1794 collect_execute (prog, argv, NULL);
1795 do_wait (prog);
1798 /* Unlink a file unless we are debugging. */
1800 static void
1801 maybe_unlink (file)
1802 char *file;
1804 if (!debug)
1805 unlink (file);
1806 else
1807 fprintf (stderr, "[Leaving %s]\n", file);
1811 /* Add a name to a linked list. */
1813 static void
1814 add_to_list (head_ptr, name)
1815 struct head *head_ptr;
1816 char *name;
1818 struct id *newid
1819 = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
1820 struct id *p;
1821 static long sequence_number = 0;
1822 strcpy (newid->name, name);
1824 if (head_ptr->first)
1825 head_ptr->last->next = newid;
1826 else
1827 head_ptr->first = newid;
1829 /* Check for duplicate symbols. */
1830 for (p = head_ptr->first;
1831 strcmp (name, p->name) != 0;
1832 p = p->next)
1834 if (p != newid)
1836 head_ptr->last->next = 0;
1837 free (newid);
1838 return;
1841 newid->sequence = ++sequence_number;
1842 head_ptr->last = newid;
1843 head_ptr->number++;
1846 /* Write: `prefix', the names on list LIST, `suffix'. */
1848 static void
1849 write_list (stream, prefix, list)
1850 FILE *stream;
1851 char *prefix;
1852 struct id *list;
1854 while (list)
1856 fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1857 list = list->next;
1861 /* This function is really used only on AIX, but may be useful. */
1862 static int
1863 is_in_list (prefix, list)
1864 char *prefix;
1865 struct id *list;
1867 while (list)
1869 if (!strcmp (prefix, list->name)) return 1;
1870 list = list->next;
1872 return 0;
1875 /* Added for debugging purpose. */
1876 static void
1877 dump_list (stream, prefix, list)
1878 FILE *stream;
1879 char *prefix;
1880 struct id *list;
1882 while (list)
1884 fprintf (stream, "%s%s,\n", prefix, list->name);
1885 list = list->next;
1889 static void
1890 dump_prefix_list (stream, prefix, list)
1891 FILE *stream;
1892 char *prefix;
1893 struct prefix_list *list;
1895 while (list)
1897 fprintf (stream, "%s%s,\n", prefix, list->prefix);
1898 list = list->next;
1902 static void
1903 write_list_with_asm (stream, prefix, list)
1904 FILE *stream;
1905 char *prefix;
1906 struct id *list;
1908 while (list)
1910 fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1911 prefix, list->sequence, list->name);
1912 list = list->next;
1916 /* Write out the constructor and destructor tables statically (for a shared
1917 object), along with the functions to execute them. */
1919 static void
1920 write_c_file_stat (stream, name)
1921 FILE *stream;
1922 char *name;
1924 char *prefix, *p, *q;
1925 int frames = (frame_tables.number > 0);
1927 /* Figure out name of output_file, stripping off .so version. */
1928 p = rindex (output_file, '/');
1929 if (p == 0)
1930 p = (char *) output_file;
1931 else
1932 p++;
1933 q = p;
1934 while (q)
1936 q = index (q,'.');
1937 if (q == 0)
1939 q = p + strlen (p);
1940 break;
1942 else
1944 if (strncmp (q, ".so", 3) == 0)
1946 q += 3;
1947 break;
1949 else
1950 q++;
1953 /* q points to null at end of the string (or . of the .so version) */
1954 prefix = xmalloc (q - p + 1);
1955 strncpy (prefix, p, q - p);
1956 prefix[q - p] = 0;
1957 for (q = prefix; *q; q++)
1958 if (!isalnum (*q))
1959 *q = '_';
1960 if (debug)
1961 fprintf (stderr, "\nwrite_c_file - output name is %s, prefix is %s\n",
1962 output_file, prefix);
1964 #define INIT_NAME_FORMAT "_GLOBAL__FI_%s"
1965 initname = xmalloc (strlen (prefix) + sizeof (INIT_NAME_FORMAT) - 2);
1966 sprintf (initname, INIT_NAME_FORMAT, prefix);
1968 #define FINI_NAME_FORMAT "_GLOBAL__FD_%s"
1969 fininame = xmalloc (strlen (prefix) + sizeof (FINI_NAME_FORMAT) - 2);
1970 sprintf (fininame, FINI_NAME_FORMAT, prefix);
1972 free (prefix);
1974 /* Write the tables as C code */
1976 fprintf (stream, "static int count;\n");
1977 fprintf (stream, "typedef void entry_pt();\n");
1978 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1980 if (frames)
1982 write_list_with_asm (stream, "extern void *", frame_tables.first);
1984 fprintf (stream, "\tstatic void *frame_table[] = {\n");
1985 write_list (stream, "\t\t&", frame_tables.first);
1986 fprintf (stream, "\t0\n};\n");
1988 /* This must match what's in frame.h. */
1989 fprintf (stream, "struct object {\n");
1990 fprintf (stream, " void *pc_begin;\n");
1991 fprintf (stream, " void *pc_end;\n");
1992 fprintf (stream, " void *fde_begin;\n");
1993 fprintf (stream, " void *fde_array;\n");
1994 fprintf (stream, " __SIZE_TYPE__ count;\n");
1995 fprintf (stream, " struct object *next;\n");
1996 fprintf (stream, "};\n");
1998 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
1999 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
2001 fprintf (stream, "static void reg_frame () {\n");
2002 fprintf (stream, "\tstatic struct object ob;\n");
2003 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
2004 fprintf (stream, "\t}\n");
2006 fprintf (stream, "static void dereg_frame () {\n");
2007 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
2008 fprintf (stream, "\t}\n");
2011 fprintf (stream, "void %s() {\n", initname);
2012 if (constructors.number > 0 || frames)
2014 fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
2015 write_list (stream, "\t\t", constructors.first);
2016 if (frames)
2017 fprintf (stream, "\treg_frame,\n");
2018 fprintf (stream, "\t};\n");
2019 fprintf (stream, "\tentry_pt **p;\n");
2020 fprintf (stream, "\tif (count++ != 0) return;\n");
2021 fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
2022 fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
2024 else
2025 fprintf (stream, "\t++count;\n");
2026 fprintf (stream, "}\n");
2027 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
2028 fprintf (stream, "void %s() {\n", fininame);
2029 if (destructors.number > 0 || frames)
2031 fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
2032 write_list (stream, "\t\t", destructors.first);
2033 if (frames)
2034 fprintf (stream, "\tdereg_frame,\n");
2035 fprintf (stream, "\t};\n");
2036 fprintf (stream, "\tentry_pt **p;\n");
2037 fprintf (stream, "\tif (--count != 0) return;\n");
2038 fprintf (stream, "\tp = dtors;\n");
2039 fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
2040 destructors.number + frames);
2042 fprintf (stream, "}\n");
2044 if (shared_obj)
2046 fprintf (stream, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname);
2047 fprintf (stream, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame);
2051 /* Write the constructor/destructor tables. */
2053 static void
2054 write_c_file_glob (stream, name)
2055 FILE *stream;
2056 char *name;
2058 /* Write the tables as C code */
2060 int frames = (frame_tables.number > 0);
2062 fprintf (stream, "typedef void entry_pt();\n\n");
2064 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
2066 if (frames)
2068 write_list_with_asm (stream, "extern void *", frame_tables.first);
2070 fprintf (stream, "\tstatic void *frame_table[] = {\n");
2071 write_list (stream, "\t\t&", frame_tables.first);
2072 fprintf (stream, "\t0\n};\n");
2074 /* This must match what's in frame.h. */
2075 fprintf (stream, "struct object {\n");
2076 fprintf (stream, " void *pc_begin;\n");
2077 fprintf (stream, " void *pc_end;\n");
2078 fprintf (stream, " void *fde_begin;\n");
2079 fprintf (stream, " void *fde_array;\n");
2080 fprintf (stream, " __SIZE_TYPE__ count;\n");
2081 fprintf (stream, " struct object *next;\n");
2082 fprintf (stream, "};\n");
2084 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
2085 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
2087 fprintf (stream, "static void reg_frame () {\n");
2088 fprintf (stream, "\tstatic struct object ob;\n");
2089 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
2090 fprintf (stream, "\t}\n");
2092 fprintf (stream, "static void dereg_frame () {\n");
2093 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
2094 fprintf (stream, "\t}\n");
2097 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
2098 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
2099 write_list (stream, "\t", constructors.first);
2100 if (frames)
2101 fprintf (stream, "\treg_frame,\n");
2102 fprintf (stream, "\t0\n};\n\n");
2104 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
2106 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
2107 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
2108 write_list (stream, "\t", destructors.first);
2109 if (frames)
2110 fprintf (stream, "\tdereg_frame,\n");
2111 fprintf (stream, "\t0\n};\n\n");
2113 fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
2114 fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
2117 static void
2118 write_c_file (stream, name)
2119 FILE *stream;
2120 char *name;
2122 fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
2123 #ifndef LD_INIT_SWITCH
2124 if (! shared_obj)
2125 write_c_file_glob (stream, name);
2126 else
2127 #endif
2128 write_c_file_stat (stream, name);
2129 fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
2132 #ifdef COLLECT_EXPORT_LIST
2133 static void
2134 write_export_file (stream)
2135 FILE *stream;
2137 struct id *list = exports.first;
2138 for (; list; list = list->next)
2139 fprintf (stream, "%s\n", list->name);
2142 static void
2143 write_import_file (stream)
2144 FILE *stream;
2146 struct id *list = imports.first;
2147 fprintf (stream, "%s\n", "#! .");
2148 for (; list; list = list->next)
2149 fprintf (stream, "%s\n", list->name);
2151 #endif
2153 #ifdef OBJECT_FORMAT_NONE
2155 /* Generic version to scan the name list of the loaded program for
2156 the symbols g++ uses for static constructors and destructors.
2158 The constructor table begins at __CTOR_LIST__ and contains a count
2159 of the number of pointers (or -1 if the constructors are built in a
2160 separate section by the linker), followed by the pointers to the
2161 constructor functions, terminated with a null pointer. The
2162 destructor table has the same format, and begins at __DTOR_LIST__. */
2164 static void
2165 scan_prog_file (prog_name, which_pass)
2166 char *prog_name;
2167 enum pass which_pass;
2169 void (*int_handler) ();
2170 void (*quit_handler) ();
2171 char *nm_argv[4];
2172 int pid;
2173 int argc = 0;
2174 int pipe_fd[2];
2175 char *p, buf[1024];
2176 FILE *inf;
2178 if (which_pass == PASS_SECOND)
2179 return;
2181 /* If we do not have an `nm', complain. */
2182 if (nm_file_name == 0)
2183 fatal ("cannot find `nm'");
2185 nm_argv[argc++] = nm_file_name;
2186 if (NM_FLAGS[0] != '\0')
2187 nm_argv[argc++] = NM_FLAGS;
2189 nm_argv[argc++] = prog_name;
2190 nm_argv[argc++] = (char *) 0;
2192 if (pipe (pipe_fd) < 0)
2193 fatal_perror ("pipe");
2195 inf = fdopen (pipe_fd[0], "r");
2196 if (inf == (FILE *) 0)
2197 fatal_perror ("fdopen");
2199 /* Trace if needed. */
2200 if (vflag)
2202 char **p_argv;
2203 char *str;
2205 for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2206 fprintf (stderr, " %s", str);
2208 fprintf (stderr, "\n");
2211 fflush (stdout);
2212 fflush (stderr);
2214 /* Spawn child nm on pipe */
2215 pid = vfork ();
2216 if (pid == -1)
2218 #ifdef vfork
2219 fatal_perror ("fork");
2220 #else
2221 fatal_perror ("vfork");
2222 #endif
2225 if (pid == 0) /* child context */
2227 /* setup stdout */
2228 if (dup2 (pipe_fd[1], 1) < 0)
2229 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
2231 if (close (pipe_fd[0]) < 0)
2232 fatal_perror ("close (%d)", pipe_fd[0]);
2234 if (close (pipe_fd[1]) < 0)
2235 fatal_perror ("close (%d)", pipe_fd[1]);
2237 execv (nm_file_name, nm_argv);
2238 fatal_perror ("executing %s", nm_file_name);
2241 /* Parent context from here on. */
2242 int_handler = (void (*) ())signal (SIGINT, SIG_IGN);
2243 #ifdef SIGQUIT
2244 quit_handler = (void (*) ())signal (SIGQUIT, SIG_IGN);
2245 #endif
2247 if (close (pipe_fd[1]) < 0)
2248 fatal_perror ("close (%d)", pipe_fd[1]);
2250 if (debug)
2251 fprintf (stderr, "\nnm output with constructors/destructors.\n");
2253 /* Read each line of nm output. */
2254 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2256 int ch, ch2;
2257 char *name, *end;
2259 /* If it contains a constructor or destructor name, add the name
2260 to the appropriate list. */
2262 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
2263 if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
2264 break;
2266 if (ch != '_')
2267 continue;
2269 name = p;
2270 /* Find the end of the symbol name.
2271 Do not include `|', because Encore nm can tack that on the end. */
2272 for (end = p; (ch2 = *end) != '\0' && !isspace (ch2) && ch2 != '|';
2273 end++)
2274 continue;
2277 *end = '\0';
2278 switch (is_ctor_dtor (name))
2280 case 1:
2281 if (which_pass != PASS_LIB)
2282 add_to_list (&constructors, name);
2283 break;
2285 case 2:
2286 if (which_pass != PASS_LIB)
2287 add_to_list (&destructors, name);
2288 break;
2290 case 3:
2291 if (which_pass != PASS_LIB)
2292 fatal ("init function found in object %s", prog_name);
2293 #ifndef LD_INIT_SWITCH
2294 add_to_list (&constructors, name);
2295 #endif
2296 break;
2298 case 4:
2299 if (which_pass != PASS_LIB)
2300 fatal ("fini function found in object %s", prog_name);
2301 #ifndef LD_FINI_SWITCH
2302 add_to_list (&destructors, name);
2303 #endif
2304 break;
2306 case 5:
2307 if (which_pass != PASS_LIB)
2308 add_to_list (&frame_tables, name);
2310 default: /* not a constructor or destructor */
2311 continue;
2314 if (debug)
2315 fprintf (stderr, "\t%s\n", buf);
2318 if (debug)
2319 fprintf (stderr, "\n");
2321 if (fclose (inf) != 0)
2322 fatal_perror ("fclose of pipe");
2324 do_wait (nm_file_name);
2326 signal (SIGINT, int_handler);
2327 #ifdef SIGQUIT
2328 signal (SIGQUIT, quit_handler);
2329 #endif
2332 #if SUNOS4_SHARED_LIBRARIES
2334 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2335 that the output file depends upon and their initialization/finalization
2336 routines, if any. */
2338 #include <a.out.h>
2339 #include <fcntl.h>
2340 #include <link.h>
2341 #include <sys/mman.h>
2342 #include <sys/param.h>
2343 #include <unistd.h>
2344 #include <sys/dir.h>
2346 /* pointers to the object file */
2347 unsigned object; /* address of memory mapped file */
2348 unsigned objsize; /* size of memory mapped to file */
2349 char * code; /* pointer to code segment */
2350 char * data; /* pointer to data segment */
2351 struct nlist *symtab; /* pointer to symbol table */
2352 struct link_dynamic *ld;
2353 struct link_dynamic_2 *ld_2;
2354 struct head libraries;
2356 /* Map the file indicated by NAME into memory and store its address. */
2358 static void
2359 mapfile (name)
2360 char *name;
2362 int fp;
2363 struct stat s;
2364 if ((fp = open (name, O_RDONLY)) == -1)
2365 fatal ("unable to open file '%s'", name);
2366 if (fstat (fp, &s) == -1)
2367 fatal ("unable to stat file '%s'", name);
2369 objsize = s.st_size;
2370 object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE,
2371 fp, 0);
2372 if (object == -1)
2373 fatal ("unable to mmap file '%s'", name);
2375 close (fp);
2378 /* Helpers for locatelib. */
2380 static char *libname;
2382 static int
2383 libselect (d)
2384 struct direct *d;
2386 return (strncmp (libname, d->d_name, strlen (libname)) == 0);
2389 /* If one file has an additional numeric extension past LIBNAME, then put
2390 that one first in the sort. If both files have additional numeric
2391 extensions, then put the one with the higher number first in the sort.
2393 We must verify that the extension is numeric, because Sun saves the
2394 original versions of patched libraries with a .FCS extension. Files with
2395 invalid extensions must go last in the sort, so that they will not be used. */
2397 static int
2398 libcompare (d1, d2)
2399 struct direct **d1, **d2;
2401 int i1, i2 = strlen (libname);
2402 char *e1 = (*d1)->d_name + i2;
2403 char *e2 = (*d2)->d_name + i2;
2405 while (*e1 && *e2 && *e1 == '.' && *e2 == '.'
2406 && e1[1] && isdigit (e1[1]) && e2[1] && isdigit (e2[1]))
2408 ++e1;
2409 ++e2;
2410 i1 = strtol (e1, &e1, 10);
2411 i2 = strtol (e2, &e2, 10);
2412 if (i1 != i2)
2413 return i1 - i2;
2416 if (*e1)
2418 /* It has a valid numeric extension, prefer this one. */
2419 if (*e1 == '.' && e1[1] && isdigit (e1[1]))
2420 return 1;
2421 /* It has a invalid numeric extension, must prefer the other one. */
2422 else
2423 return -1;
2425 else if (*e2)
2427 /* It has a valid numeric extension, prefer this one. */
2428 if (*e2 == '.' && e2[1] && isdigit (e2[1]))
2429 return -1;
2430 /* It has a invalid numeric extension, must prefer the other one. */
2431 else
2432 return 1;
2434 else
2435 return 0;
2438 /* Given the name NAME of a dynamic dependency, find its pathname and add
2439 it to the list of libraries. */
2441 static void
2442 locatelib (name)
2443 char *name;
2445 static char **l;
2446 static int cnt;
2447 char buf[MAXPATHLEN];
2448 char *p, *q;
2449 char **pp;
2451 if (l == 0)
2453 char *ld_rules;
2454 char *ldr = 0;
2455 /* counting elements in array, need 1 extra for null */
2456 cnt = 1;
2457 ld_rules = (char *) (ld_2->ld_rules + code);
2458 if (ld_rules)
2460 cnt++;
2461 for (; *ld_rules != 0; ld_rules++)
2462 if (*ld_rules == ':')
2463 cnt++;
2464 ld_rules = (char *) (ld_2->ld_rules + code);
2465 ldr = (char *) malloc (strlen (ld_rules) + 1);
2466 strcpy (ldr, ld_rules);
2468 p = getenv ("LD_LIBRARY_PATH");
2469 q = 0;
2470 if (p)
2472 cnt++;
2473 for (q = p ; *q != 0; q++)
2474 if (*q == ':')
2475 cnt++;
2476 q = (char *) malloc (strlen (p) + 1);
2477 strcpy (q, p);
2479 l = (char **) malloc ((cnt + 3) * sizeof (char *));
2480 pp = l;
2481 if (ldr)
2483 *pp++ = ldr;
2484 for (; *ldr != 0; ldr++)
2485 if (*ldr == ':')
2487 *ldr++ = 0;
2488 *pp++ = ldr;
2491 if (q)
2493 *pp++ = q;
2494 for (; *q != 0; q++)
2495 if (*q == ':')
2497 *q++ = 0;
2498 *pp++ = q;
2501 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2502 *pp++ = "/lib";
2503 *pp++ = "/usr/lib";
2504 *pp++ = "/usr/local/lib";
2505 *pp = 0;
2507 libname = name;
2508 for (pp = l; *pp != 0 ; pp++)
2510 struct direct **namelist;
2511 int entries;
2512 if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0)
2514 sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name);
2515 add_to_list (&libraries, buf);
2516 if (debug)
2517 fprintf (stderr, "%s\n", buf);
2518 break;
2521 if (*pp == 0)
2523 if (debug)
2524 fprintf (stderr, "not found\n");
2525 else
2526 fatal ("dynamic dependency %s not found", name);
2530 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2531 that it depends upon and any constructors or destructors they contain. */
2533 static void
2534 scan_libraries (prog_name)
2535 char *prog_name;
2537 struct exec *header;
2538 char *base;
2539 struct link_object *lo;
2540 char buff[MAXPATHLEN];
2541 struct id *list;
2543 mapfile (prog_name);
2544 header = (struct exec *)object;
2545 if (N_BADMAG (*header))
2546 fatal ("bad magic number in file '%s'", prog_name);
2547 if (header->a_dynamic == 0)
2548 return;
2550 code = (char *) (N_TXTOFF (*header) + (long) header);
2551 data = (char *) (N_DATOFF (*header) + (long) header);
2552 symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header);
2554 if (header->a_magic == ZMAGIC && header->a_entry == 0x20)
2556 /* shared object */
2557 ld = (struct link_dynamic *) (symtab->n_value + code);
2558 base = code;
2560 else
2562 /* executable */
2563 ld = (struct link_dynamic *) data;
2564 base = code-PAGSIZ;
2567 if (debug)
2568 fprintf (stderr, "dynamic dependencies.\n");
2570 ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);
2571 for (lo = (struct link_object *) ld_2->ld_need; lo;
2572 lo = (struct link_object *) lo->lo_next)
2574 char *name;
2575 lo = (struct link_object *) ((long) lo + code);
2576 name = (char *) (code + lo->lo_name);
2577 if (lo->lo_library)
2579 if (debug)
2580 fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major);
2581 sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor);
2582 locatelib (buff);
2584 else
2586 if (debug)
2587 fprintf (stderr, "\t%s\n", name);
2588 add_to_list (&libraries, name);
2592 if (debug)
2593 fprintf (stderr, "\n");
2595 /* now iterate through the library list adding their symbols to
2596 the list. */
2597 for (list = libraries.first; list; list = list->next)
2598 scan_prog_file (list->name, PASS_LIB);
2601 #else /* SUNOS4_SHARED_LIBRARIES */
2602 #ifdef LDD_SUFFIX
2604 /* Use the List Dynamic Dependencies program to find shared libraries that
2605 the output file depends upon and their initialization/finalization
2606 routines, if any. */
2608 static void
2609 scan_libraries (prog_name)
2610 char *prog_name;
2612 static struct head libraries; /* list of shared libraries found */
2613 struct id *list;
2614 void (*int_handler) ();
2615 void (*quit_handler) ();
2616 char *ldd_argv[4];
2617 int pid;
2618 int argc = 0;
2619 int pipe_fd[2];
2620 char buf[1024];
2621 FILE *inf;
2623 /* If we do not have an `ldd', complain. */
2624 if (ldd_file_name == 0)
2626 error ("cannot find `ldd'");
2627 return;
2630 ldd_argv[argc++] = ldd_file_name;
2631 ldd_argv[argc++] = prog_name;
2632 ldd_argv[argc++] = (char *) 0;
2634 if (pipe (pipe_fd) < 0)
2635 fatal_perror ("pipe");
2637 inf = fdopen (pipe_fd[0], "r");
2638 if (inf == (FILE *) 0)
2639 fatal_perror ("fdopen");
2641 /* Trace if needed. */
2642 if (vflag)
2644 char **p_argv;
2645 char *str;
2647 for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2648 fprintf (stderr, " %s", str);
2650 fprintf (stderr, "\n");
2653 fflush (stdout);
2654 fflush (stderr);
2656 /* Spawn child ldd on pipe */
2657 pid = vfork ();
2658 if (pid == -1)
2660 #ifdef vfork
2661 fatal_perror ("fork");
2662 #else
2663 fatal_perror ("vfork");
2664 #endif
2667 if (pid == 0) /* child context */
2669 /* setup stdout */
2670 if (dup2 (pipe_fd[1], 1) < 0)
2671 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
2673 if (close (pipe_fd[0]) < 0)
2674 fatal_perror ("close (%d)", pipe_fd[0]);
2676 if (close (pipe_fd[1]) < 0)
2677 fatal_perror ("close (%d)", pipe_fd[1]);
2679 execv (ldd_file_name, ldd_argv);
2680 fatal_perror ("executing %s", ldd_file_name);
2683 /* Parent context from here on. */
2684 int_handler = (void (*) ()) signal (SIGINT, SIG_IGN);
2685 #ifdef SIGQUIT
2686 quit_handler = (void (*) ()) signal (SIGQUIT, SIG_IGN);
2687 #endif
2689 if (close (pipe_fd[1]) < 0)
2690 fatal_perror ("close (%d)", pipe_fd[1]);
2692 if (debug)
2693 fprintf (stderr, "\nldd output with constructors/destructors.\n");
2695 /* Read each line of ldd output. */
2696 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2698 int ch, ch2;
2699 char *name, *end, *p = buf;
2701 /* Extract names of libraries and add to list. */
2702 PARSE_LDD_OUTPUT (p);
2703 if (p == 0)
2704 continue;
2706 name = p;
2707 if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
2708 fatal ("dynamic dependency %s not found", buf);
2710 /* Find the end of the symbol name. */
2711 for (end = p;
2712 (ch2 = *end) != '\0' && ch2 != '\n' && !isspace (ch2) && ch2 != '|';
2713 end++)
2714 continue;
2715 *end = '\0';
2717 if (access (name, R_OK) == 0)
2718 add_to_list (&libraries, name);
2719 else
2720 fatal ("unable to open dynamic dependency '%s'", buf);
2722 if (debug)
2723 fprintf (stderr, "\t%s\n", buf);
2725 if (debug)
2726 fprintf (stderr, "\n");
2728 if (fclose (inf) != 0)
2729 fatal_perror ("fclose of pipe");
2731 do_wait (ldd_file_name);
2733 signal (SIGINT, int_handler);
2734 #ifdef SIGQUIT
2735 signal (SIGQUIT, quit_handler);
2736 #endif
2738 /* now iterate through the library list adding their symbols to
2739 the list. */
2740 for (list = libraries.first; list; list = list->next)
2741 scan_prog_file (list->name, PASS_LIB);
2744 #endif /* LDD_SUFFIX */
2745 #endif /* SUNOS4_SHARED_LIBRARIES */
2747 #endif /* OBJECT_FORMAT_NONE */
2751 * COFF specific stuff.
2754 #ifdef OBJECT_FORMAT_COFF
2756 #if defined(EXTENDED_COFF)
2757 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2758 # define GCC_SYMENT SYMR
2759 # define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
2760 # define GCC_SYMINC(X) (1)
2761 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2762 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2763 #else
2764 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2765 # define GCC_SYMENT SYMENT
2766 # define GCC_OK_SYMBOL(X) \
2767 (((X).n_sclass == C_EXT) && \
2768 ((X).n_scnum > N_UNDEF) && \
2769 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
2770 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
2771 # define GCC_UNDEF_SYMBOL(X) \
2772 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2773 # define GCC_SYMINC(X) ((X).n_numaux+1)
2774 # define GCC_SYMZERO(X) 0
2775 # define GCC_CHECK_HDR(X) (1)
2776 #endif
2778 extern char *ldgetname ();
2780 /* COFF version to scan the name list of the loaded program for
2781 the symbols g++ uses for static constructors and destructors.
2783 The constructor table begins at __CTOR_LIST__ and contains a count
2784 of the number of pointers (or -1 if the constructors are built in a
2785 separate section by the linker), followed by the pointers to the
2786 constructor functions, terminated with a null pointer. The
2787 destructor table has the same format, and begins at __DTOR_LIST__. */
2789 static void
2790 scan_prog_file (prog_name, which_pass)
2791 char *prog_name;
2792 enum pass which_pass;
2794 LDFILE *ldptr = NULL;
2795 int sym_index, sym_count;
2796 int is_shared = 0;
2797 #ifdef COLLECT_EXPORT_LIST
2798 /* Should we generate an import list for given prog_name? */
2799 int import_flag = (which_pass == PASS_OBJ ? 0 : use_import_list (prog_name));
2800 #endif
2802 if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2803 return;
2805 #ifdef COLLECT_EXPORT_LIST
2806 /* We do not need scanning for some standard C libraries. */
2807 if (which_pass == PASS_FIRST && ignore_library (prog_name))
2808 return;
2810 /* On AIX we have a loop, because there is not much difference
2811 between an object and an archive. This trick allows us to
2812 eliminate scan_libraries() function. */
2815 #endif
2816 if ((ldptr = ldopen (prog_name, ldptr)) != NULL)
2819 if (!MY_ISCOFF (HEADER (ldptr).f_magic))
2820 fatal ("%s: not a COFF file", prog_name);
2822 #ifdef COLLECT_EXPORT_LIST
2823 /* Is current archive member a shared object? */
2824 is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
2825 #endif
2826 if (GCC_CHECK_HDR (ldptr))
2828 sym_count = GCC_SYMBOLS (ldptr);
2829 sym_index = GCC_SYMZERO (ldptr);
2830 while (sym_index < sym_count)
2832 GCC_SYMENT symbol;
2834 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2835 break;
2836 sym_index += GCC_SYMINC (symbol);
2838 if (GCC_OK_SYMBOL (symbol))
2840 char *name;
2842 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2843 continue; /* should never happen */
2845 #ifdef XCOFF_DEBUGGING_INFO
2846 /* All AIX function names have a duplicate entry
2847 beginning with a dot. */
2848 if (*name == '.')
2849 ++name;
2850 #endif
2852 switch (is_ctor_dtor (name))
2854 case 1:
2855 if (! is_shared) add_to_list (&constructors, name);
2856 if (which_pass == PASS_OBJ)
2857 add_to_list (&exports, name);
2858 #ifdef COLLECT_EXPORT_LIST
2859 /* If this symbol was undefined and we are building
2860 an import list, we should add a symbol to this
2861 list. */
2862 else
2863 if (import_flag
2864 && is_in_list (name, undefined.first))
2865 add_to_list (&imports, name);
2866 #endif
2867 break;
2869 case 2:
2870 if (! is_shared) add_to_list (&destructors, name);
2871 if (which_pass == PASS_OBJ)
2872 add_to_list (&exports, name);
2873 #ifdef COLLECT_EXPORT_LIST
2874 /* If this symbol was undefined and we are building
2875 an import list, we should add a symbol to this
2876 list. */
2877 else
2878 if (import_flag
2879 && is_in_list (name, undefined.first))
2880 add_to_list (&imports, name);
2881 #endif
2882 break;
2884 #ifdef COLLECT_EXPORT_LIST
2885 case 3:
2886 if (is_shared)
2887 add_to_list (&constructors, name);
2888 break;
2890 case 4:
2891 if (is_shared)
2892 add_to_list (&destructors, name);
2893 break;
2894 #endif
2896 default: /* not a constructor or destructor */
2897 #ifdef COLLECT_EXPORT_LIST
2898 /* If we are building a shared object on AIX we need
2899 to explicitly export all global symbols or add
2900 them to import list. */
2901 if (shared_obj)
2902 if (which_pass == PASS_OBJ && (! export_flag))
2903 add_to_list (&exports, name);
2904 else if (! is_shared && which_pass == PASS_FIRST
2905 && import_flag
2906 && is_in_list(name, undefined.first))
2907 add_to_list (&imports, name);
2908 #endif
2909 continue;
2912 #if !defined(EXTENDED_COFF)
2913 if (debug)
2914 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
2915 symbol.n_scnum, symbol.n_sclass,
2916 (symbol.n_type ? "0" : ""), symbol.n_type,
2917 name);
2918 #else
2919 if (debug)
2920 fprintf (stderr,
2921 "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
2922 symbol.iss, symbol.value, symbol.index, name);
2923 #endif
2925 #ifdef COLLECT_EXPORT_LIST
2926 /* If we are building a shared object we should collect
2927 information about undefined symbols for later
2928 import list generation. */
2929 else if (shared_obj && GCC_UNDEF_SYMBOL (symbol))
2931 char *name;
2933 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2934 continue; /* should never happen */
2936 /* All AIX function names have a duplicate entry
2937 beginning with a dot. */
2938 if (*name == '.')
2939 ++name;
2940 add_to_list (&undefined, name);
2942 #endif
2946 else
2948 fatal ("%s: cannot open as COFF file", prog_name);
2950 #ifdef COLLECT_EXPORT_LIST
2951 /* On AIX loop continues while there are more members in archive. */
2953 while (ldclose (ldptr) == FAILURE);
2954 #else
2955 /* Otherwise we simply close ldptr. */
2956 (void) ldclose(ldptr);
2957 #endif
2961 #ifdef COLLECT_EXPORT_LIST
2963 /* This new function is used to decide whether we should
2964 generate import list for an object or to use it directly. */
2965 static int
2966 use_import_list (prog_name)
2967 char *prog_name;
2969 char *p;
2971 /* If we do not build a shared object then import list should not be used. */
2972 if (! shared_obj) return 0;
2974 /* Currently we check only for libgcc, but this can be changed in future. */
2975 p = strstr (prog_name, "libgcc.a");
2976 if (p != 0 && (strlen (p) == sizeof ("libgcc.a") - 1))
2977 return 1;
2978 return 0;
2981 /* Given a library name without "lib" prefix, this function
2982 returns a full library name including a path. */
2983 static char *
2984 resolve_lib_name (name)
2985 char *name;
2987 char *lib_buf;
2988 int i, j, l = 0;
2990 for (i = 0; libpaths[i]; i++)
2991 if (libpaths[i]->max_len > l)
2992 l = libpaths[i]->max_len;
2994 lib_buf = xmalloc (l + strlen(name) + 10);
2996 for (i = 0; libpaths[i]; i++)
2998 struct prefix_list *list = libpaths[i]->plist;
2999 for (; list; list = list->next)
3001 for (j = 0; libexts[j]; j++)
3003 /* The following lines are needed because path_prefix list
3004 may contain directories both with trailing '/' and
3005 without it. */
3006 char *p = "";
3007 if (list->prefix[strlen(list->prefix)-1] != '/')
3008 p = "/";
3009 sprintf (lib_buf, "%s%slib%s.%s",
3010 list->prefix, p, name, libexts[j]);
3011 if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
3012 if (file_exists (lib_buf))
3014 if (debug) fprintf (stderr, "found: %s\n", lib_buf);
3015 return (lib_buf);
3020 if (debug)
3021 fprintf (stderr, "not found\n");
3022 else
3023 fatal ("Library lib%s not found", name);
3024 return (NULL);
3027 /* Array of standard AIX libraries which should not
3028 be scanned for ctors/dtors. */
3029 static char* aix_std_libs[] = {
3030 "/unix",
3031 "/lib/libc.a",
3032 "/lib/libc_r.a",
3033 "/usr/lib/libc.a",
3034 "/usr/lib/libc_r.a",
3035 "/usr/lib/threads/libc.a",
3036 "/usr/ccs/lib/libc.a",
3037 "/usr/ccs/lib/libc_r.a",
3038 NULL
3041 /* This function checks the filename and returns 1
3042 if this name matches the location of a standard AIX library. */
3043 static int
3044 ignore_library (name)
3045 char *name;
3047 char **p = &aix_std_libs[0];
3048 while (*p++ != NULL)
3049 if (! strcmp (name, *p)) return 1;
3050 return 0;
3053 #endif
3055 #endif /* OBJECT_FORMAT_COFF */
3059 * OSF/rose specific stuff.
3062 #ifdef OBJECT_FORMAT_ROSE
3064 /* Union of the various load commands */
3066 typedef union load_union
3068 ldc_header_t hdr; /* common header */
3069 load_cmd_map_command_t map; /* map indexing other load cmds */
3070 interpreter_command_t iprtr; /* interpreter pathname */
3071 strings_command_t str; /* load commands strings section */
3072 region_command_t region; /* region load command */
3073 reloc_command_t reloc; /* relocation section */
3074 package_command_t pkg; /* package load command */
3075 symbols_command_t sym; /* symbol sections */
3076 entry_command_t ent; /* program start section */
3077 gen_info_command_t info; /* object information */
3078 func_table_command_t func; /* function constructors/destructors */
3079 } load_union_t;
3081 /* Structure to point to load command and data section in memory. */
3083 typedef struct load_all
3085 load_union_t *load; /* load command */
3086 char *section; /* pointer to section */
3087 } load_all_t;
3089 /* Structure to contain information about a file mapped into memory. */
3091 struct file_info
3093 char *start; /* start of map */
3094 char *name; /* filename */
3095 long size; /* size of the file */
3096 long rounded_size; /* size rounded to page boundary */
3097 int fd; /* file descriptor */
3098 int rw; /* != 0 if opened read/write */
3099 int use_mmap; /* != 0 if mmap'ed */
3102 extern int decode_mach_o_hdr ();
3103 extern int encode_mach_o_hdr ();
3105 static void add_func_table PROTO((mo_header_t *, load_all_t *,
3106 symbol_info_t *, int));
3107 static void print_header PROTO((mo_header_t *));
3108 static void print_load_command PROTO((load_union_t *, size_t, int));
3109 static void bad_header PROTO((int));
3110 static struct file_info *read_file PROTO((char *, int, int));
3111 static void end_file PROTO((struct file_info *));
3113 /* OSF/rose specific version to scan the name list of the loaded
3114 program for the symbols g++ uses for static constructors and
3115 destructors.
3117 The constructor table begins at __CTOR_LIST__ and contains a count
3118 of the number of pointers (or -1 if the constructors are built in a
3119 separate section by the linker), followed by the pointers to the
3120 constructor functions, terminated with a null pointer. The
3121 destructor table has the same format, and begins at __DTOR_LIST__. */
3123 static void
3124 scan_prog_file (prog_name, which_pass)
3125 char *prog_name;
3126 enum pass which_pass;
3128 char *obj;
3129 mo_header_t hdr;
3130 load_all_t *load_array;
3131 load_all_t *load_end;
3132 load_all_t *load_cmd;
3133 int symbol_load_cmds;
3134 off_t offset;
3135 int i;
3136 int num_syms;
3137 int status;
3138 char *str_sect;
3139 struct file_info *obj_file;
3140 int prog_fd;
3141 mo_lcid_t cmd_strings = -1;
3142 symbol_info_t *main_sym = 0;
3143 int rw = (which_pass != PASS_FIRST);
3145 prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
3146 if (prog_fd < 0)
3147 fatal_perror ("cannot read %s", prog_name);
3149 obj_file = read_file (prog_name, prog_fd, rw);
3150 obj = obj_file->start;
3152 status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);
3153 if (status != MO_HDR_CONV_SUCCESS)
3154 bad_header (status);
3157 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
3158 since the hardware will automatically swap bytes for us on loading little endian
3159 integers. */
3161 #ifndef CROSS_COMPILE
3162 if (hdr.moh_magic != MOH_MAGIC_MSB
3163 || hdr.moh_header_version != MOH_HEADER_VERSION
3164 || hdr.moh_byte_order != OUR_BYTE_ORDER
3165 || hdr.moh_data_rep_id != OUR_DATA_REP_ID
3166 || hdr.moh_cpu_type != OUR_CPU_TYPE
3167 || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE
3168 || hdr.moh_vendor_type != OUR_VENDOR_TYPE)
3170 fatal ("incompatibilities between object file & expected values");
3172 #endif
3174 if (debug)
3175 print_header (&hdr);
3177 offset = hdr.moh_first_cmd_off;
3178 load_end = load_array
3179 = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);
3181 /* Build array of load commands, calculating the offsets */
3182 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3184 load_union_t *load_hdr; /* load command header */
3186 load_cmd = load_end++;
3187 load_hdr = (load_union_t *) (obj + offset);
3189 /* If modifying the program file, copy the header. */
3190 if (rw)
3192 load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
3193 bcopy ((char *)load_hdr, (char *)ptr, load_hdr->hdr.ldci_cmd_size);
3194 load_hdr = ptr;
3196 /* null out old command map, because we will rewrite at the end. */
3197 if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
3199 cmd_strings = ptr->map.lcm_ld_cmd_strings;
3200 ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
3204 load_cmd->load = load_hdr;
3205 if (load_hdr->hdr.ldci_section_off > 0)
3206 load_cmd->section = obj + load_hdr->hdr.ldci_section_off;
3208 if (debug)
3209 print_load_command (load_hdr, offset, i);
3211 offset += load_hdr->hdr.ldci_cmd_size;
3214 /* If the last command is the load command map and is not undefined,
3215 decrement the count of load commands. */
3216 if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)
3218 load_end--;
3219 hdr.moh_n_load_cmds--;
3222 /* Go through and process each symbol table section. */
3223 symbol_load_cmds = 0;
3224 for (load_cmd = load_array; load_cmd < load_end; load_cmd++)
3226 load_union_t *load_hdr = load_cmd->load;
3228 if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
3230 symbol_load_cmds++;
3232 if (debug)
3234 char *kind = "unknown";
3236 switch (load_hdr->sym.symc_kind)
3238 case SYMC_IMPORTS: kind = "imports"; break;
3239 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
3240 case SYMC_STABS: kind = "stabs"; break;
3243 fprintf (stderr, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
3244 symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
3247 if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
3248 continue;
3250 str_sect = load_array[load_hdr->sym.symc_strings_section].section;
3251 if (str_sect == (char *) 0)
3252 fatal ("string section missing");
3254 if (load_cmd->section == (char *) 0)
3255 fatal ("section pointer missing");
3257 num_syms = load_hdr->sym.symc_nentries;
3258 for (i = 0; i < num_syms; i++)
3260 symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
3261 char *name = sym->si_name.symbol_name + str_sect;
3263 if (name[0] != '_')
3264 continue;
3266 if (rw)
3268 char *n = name + strlen (name) - strlen (NAME__MAIN);
3270 if ((n - name) < 0 || strcmp (n, NAME__MAIN))
3271 continue;
3272 while (n != name)
3273 if (*--n != '_')
3274 continue;
3276 main_sym = sym;
3278 else
3280 switch (is_ctor_dtor (name))
3282 case 1:
3283 add_to_list (&constructors, name);
3284 break;
3286 case 2:
3287 add_to_list (&destructors, name);
3288 break;
3290 default: /* not a constructor or destructor */
3291 continue;
3295 if (debug)
3296 fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
3297 sym->si_type, sym->si_sc_type, sym->si_flags, name);
3302 if (symbol_load_cmds == 0)
3303 fatal ("no symbol table found");
3305 /* Update the program file now, rewrite header and load commands. At present,
3306 we assume that there is enough space after the last load command to insert
3307 one more. Since the first section written out is page aligned, and the
3308 number of load commands is small, this is ok for the present. */
3310 if (rw)
3312 load_union_t *load_map;
3313 size_t size;
3315 if (cmd_strings == -1)
3316 fatal ("no cmd_strings found");
3318 /* Add __main to initializer list.
3319 If we are building a program instead of a shared library, do not
3320 do anything, since in the current version, you cannot do mallocs
3321 and such in the constructors. */
3323 if (main_sym != (symbol_info_t *) 0
3324 && ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
3325 add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
3327 if (debug)
3328 fprintf (stderr, "\nUpdating header and load commands.\n\n");
3330 hdr.moh_n_load_cmds++;
3331 size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
3333 /* Create new load command map. */
3334 if (debug)
3335 fprintf (stderr, "load command map, %d cmds, new size %ld.\n",
3336 (int)hdr.moh_n_load_cmds, (long)size);
3338 load_map = (load_union_t *) xcalloc (1, size);
3339 load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
3340 load_map->map.ldc_header.ldci_cmd_size = size;
3341 load_map->map.lcm_ld_cmd_strings = cmd_strings;
3342 load_map->map.lcm_nentries = hdr.moh_n_load_cmds;
3343 load_array[hdr.moh_n_load_cmds-1].load = load_map;
3345 offset = hdr.moh_first_cmd_off;
3346 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3348 load_map->map.lcm_map[i] = offset;
3349 if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)
3350 hdr.moh_load_map_cmd_off = offset;
3352 offset += load_array[i].load->hdr.ldci_cmd_size;
3355 hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
3357 if (debug)
3358 print_header (&hdr);
3360 /* Write header */
3361 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
3362 if (status != MO_HDR_CONV_SUCCESS)
3363 bad_header (status);
3365 if (debug)
3366 fprintf (stderr, "writing load commands.\n\n");
3368 /* Write load commands */
3369 offset = hdr.moh_first_cmd_off;
3370 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3372 load_union_t *load_hdr = load_array[i].load;
3373 size_t size = load_hdr->hdr.ldci_cmd_size;
3375 if (debug)
3376 print_load_command (load_hdr, offset, i);
3378 bcopy ((char *) load_hdr, (char *) (obj + offset), size);
3379 offset += size;
3383 end_file (obj_file);
3385 if (close (prog_fd))
3386 fatal_perror ("closing %s", prog_name);
3388 if (debug)
3389 fprintf (stderr, "\n");
3393 /* Add a function table to the load commands to call a function
3394 on initiation or termination of the process. */
3396 static void
3397 add_func_table (hdr_p, load_array, sym, type)
3398 mo_header_t *hdr_p; /* pointer to global header */
3399 load_all_t *load_array; /* array of ptrs to load cmds */
3400 symbol_info_t *sym; /* pointer to symbol entry */
3401 int type; /* fntc_type value */
3403 /* Add a new load command. */
3404 int num_cmds = ++hdr_p->moh_n_load_cmds;
3405 int load_index = num_cmds - 1;
3406 size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);
3407 load_union_t *ptr = xcalloc (1, size);
3408 load_all_t *load_cmd;
3409 int i;
3411 /* Set the unresolved address bit in the header to force the loader to be
3412 used, since kernel exec does not call the initialization functions. */
3413 hdr_p->moh_flags |= MOH_UNRESOLVED_F;
3415 load_cmd = &load_array[load_index];
3416 load_cmd->load = ptr;
3417 load_cmd->section = (char *) 0;
3419 /* Fill in func table load command. */
3420 ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
3421 ptr->func.ldc_header.ldci_cmd_size = size;
3422 ptr->func.ldc_header.ldci_section_off = 0;
3423 ptr->func.ldc_header.ldci_section_len = 0;
3424 ptr->func.fntc_type = type;
3425 ptr->func.fntc_nentries = 1;
3427 /* copy address, turn it from abs. address to (region,offset) if necessary. */
3428 /* Is the symbol already expressed as (region, offset)? */
3429 if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)
3431 ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;
3432 ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;
3435 /* If not, figure out which region it's in. */
3436 else
3438 mo_vm_addr_t addr = sym->si_value.abs_val;
3439 int found = 0;
3441 for (i = 0; i < load_index; i++)
3443 if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
3445 region_command_t *region_ptr = &load_array[i].load->region;
3447 if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0
3448 && addr >= region_ptr->regc_addr.vm_addr
3449 && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)
3451 ptr->func.fntc_entry_loc[0].adr_lcid = i;
3452 ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;
3453 found++;
3454 break;
3459 if (!found)
3460 fatal ("could not convert 0x%l.8x into a region", addr);
3463 if (debug)
3464 fprintf (stderr,
3465 "%s function, region %d, offset = %ld (0x%.8lx)\n",
3466 (type == FNTC_INITIALIZATION) ? "init" : "term",
3467 (int)ptr->func.fntc_entry_loc[i].adr_lcid,
3468 (long)ptr->func.fntc_entry_loc[i].adr_sctoff,
3469 (long)ptr->func.fntc_entry_loc[i].adr_sctoff);
3474 /* Print the global header for an OSF/rose object. */
3476 static void
3477 print_header (hdr_ptr)
3478 mo_header_t *hdr_ptr;
3480 fprintf (stderr, "\nglobal header:\n");
3481 fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic);
3482 fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version);
3483 fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version);
3484 fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version);
3485 fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size);
3486 fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order);
3487 fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id);
3488 fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type);
3489 fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype);
3490 fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type);
3491 fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);
3492 fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off);
3493 fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds);
3494 fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds);
3495 fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags);
3497 if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
3498 fprintf (stderr, ", relocatable");
3500 if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
3501 fprintf (stderr, ", linkable");
3503 if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
3504 fprintf (stderr, ", execable");
3506 if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
3507 fprintf (stderr, ", executable");
3509 if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
3510 fprintf (stderr, ", unresolved");
3512 fprintf (stderr, "\n\n");
3513 return;
3517 /* Print a short summary of a load command. */
3519 static void
3520 print_load_command (load_hdr, offset, number)
3521 load_union_t *load_hdr;
3522 size_t offset;
3523 int number;
3525 mo_long_t type = load_hdr->hdr.ldci_cmd_type;
3526 char *type_str = (char *) 0;
3528 switch (type)
3530 case LDC_UNDEFINED: type_str = "UNDEFINED"; break;
3531 case LDC_CMD_MAP: type_str = "CMD_MAP"; break;
3532 case LDC_INTERPRETER: type_str = "INTERPRETER"; break;
3533 case LDC_STRINGS: type_str = "STRINGS"; break;
3534 case LDC_REGION: type_str = "REGION"; break;
3535 case LDC_RELOC: type_str = "RELOC"; break;
3536 case LDC_PACKAGE: type_str = "PACKAGE"; break;
3537 case LDC_SYMBOLS: type_str = "SYMBOLS"; break;
3538 case LDC_ENTRY: type_str = "ENTRY"; break;
3539 case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break;
3540 case LDC_GEN_INFO: type_str = "GEN_INFO"; break;
3543 fprintf (stderr,
3544 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3545 number,
3546 (long) load_hdr->hdr.ldci_cmd_size,
3547 (long) offset,
3548 (long) load_hdr->hdr.ldci_section_off,
3549 (long) load_hdr->hdr.ldci_section_len);
3551 if (type_str == (char *) 0)
3552 fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
3554 else if (type != LDC_REGION)
3555 fprintf (stderr, ", ty: %s\n", type_str);
3557 else
3559 char *region = "";
3560 switch (load_hdr->region.regc_usage_type)
3562 case REG_TEXT_T: region = ", .text"; break;
3563 case REG_DATA_T: region = ", .data"; break;
3564 case REG_BSS_T: region = ", .bss"; break;
3565 case REG_GLUE_T: region = ", .glue"; break;
3566 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3567 case REG_RDATA_T: region = ", .rdata"; break;
3568 case REG_SDATA_T: region = ", .sdata"; break;
3569 case REG_SBSS_T: region = ", .sbss"; break;
3570 #endif
3573 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3574 type_str,
3575 (long) load_hdr->region.regc_vm_addr,
3576 (long) load_hdr->region.regc_vm_size,
3577 region);
3580 return;
3584 /* Fatal error when {en,de}code_mach_o_header fails. */
3586 static void
3587 bad_header (status)
3588 int status;
3590 char *msg = (char *) 0;
3592 switch (status)
3594 case MO_ERROR_BAD_MAGIC: msg = "bad magic number"; break;
3595 case MO_ERROR_BAD_HDR_VERS: msg = "bad header version"; break;
3596 case MO_ERROR_BAD_RAW_HDR_VERS: msg = "bad raw header version"; break;
3597 case MO_ERROR_BUF2SML: msg = "raw header buffer too small"; break;
3598 case MO_ERROR_OLD_RAW_HDR_FILE: msg = "old raw header file"; break;
3599 case MO_ERROR_UNSUPPORTED_VERS: msg = "unsupported version"; break;
3602 if (msg == (char *) 0)
3603 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
3604 else
3605 fatal ("%s", msg);
3609 /* Read a file into a memory buffer. */
3611 static struct file_info *
3612 read_file (name, fd, rw)
3613 char *name; /* filename */
3614 int fd; /* file descriptor */
3615 int rw; /* read/write */
3617 struct stat stat_pkt;
3618 struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
3619 #ifdef USE_MMAP
3620 static int page_size;
3621 #endif
3623 if (fstat (fd, &stat_pkt) < 0)
3624 fatal_perror ("fstat %s", name);
3626 p->name = name;
3627 p->size = stat_pkt.st_size;
3628 p->rounded_size = stat_pkt.st_size;
3629 p->fd = fd;
3630 p->rw = rw;
3632 #ifdef USE_MMAP
3633 if (debug)
3634 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
3636 if (page_size == 0)
3637 page_size = sysconf (_SC_PAGE_SIZE);
3639 p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
3640 p->start = mmap ((caddr_t) 0,
3641 (rw) ? p->rounded_size : p->size,
3642 (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
3643 MAP_FILE | MAP_VARIABLE | MAP_SHARED,
3645 0L);
3647 if (p->start != (char *) 0 && p->start != (char *) -1)
3648 p->use_mmap = 1;
3650 else
3651 #endif /* USE_MMAP */
3653 long len;
3655 if (debug)
3656 fprintf (stderr, "read %s\n", name);
3658 p->use_mmap = 0;
3659 p->start = xmalloc (p->size);
3660 if (lseek (fd, 0L, SEEK_SET) < 0)
3661 fatal_perror ("lseek to 0 on %s", name);
3663 len = read (fd, p->start, p->size);
3664 if (len < 0)
3665 fatal_perror ("read %s", name);
3667 if (len != p->size)
3668 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
3671 return p;
3674 /* Do anything necessary to write a file back from memory. */
3676 static void
3677 end_file (ptr)
3678 struct file_info *ptr; /* file information block */
3680 #ifdef USE_MMAP
3681 if (ptr->use_mmap)
3683 if (ptr->rw)
3685 if (debug)
3686 fprintf (stderr, "msync %s\n", ptr->name);
3688 if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
3689 fatal_perror ("msync %s", ptr->name);
3692 if (debug)
3693 fprintf (stderr, "munmap %s\n", ptr->name);
3695 if (munmap (ptr->start, ptr->size))
3696 fatal_perror ("munmap %s", ptr->name);
3698 else
3699 #endif /* USE_MMAP */
3701 if (ptr->rw)
3703 long len;
3705 if (debug)
3706 fprintf (stderr, "write %s\n", ptr->name);
3708 if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
3709 fatal_perror ("lseek to 0 on %s", ptr->name);
3711 len = write (ptr->fd, ptr->start, ptr->size);
3712 if (len < 0)
3713 fatal_perror ("write %s", ptr->name);
3715 if (len != ptr->size)
3716 fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
3719 free (ptr->start);
3722 free (ptr);
3725 #endif /* OBJECT_FORMAT_ROSE */