(decl_function_context): Handle QUAL_UNION_TYPE.
[official-gcc.git] / gcc / collect2.c
blob452ac9943ef4624b3e83fdd657abd28409a18d72
1 /* Collect static initialization info into data structures that can be
2 traversed by C++ initialization and finalization routines.
3 Copyright (C) 1992, 1993, 1994, 1995, 1996 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 #define COLLECT
39 #include "demangle.h"
40 #include "obstack.h"
41 #include "gansidecl.h"
43 #ifndef errno
44 extern int errno;
45 #endif
47 #ifndef HAVE_STRERROR
48 #if defined(bsd4_4)
49 extern const char *const sys_errlist[];
50 #else
51 extern char *sys_errlist[];
52 #endif
53 extern int sys_nerr;
54 #else
55 char *strerror();
56 #endif
58 /* Obstack allocation and deallocation routines. */
59 #define obstack_chunk_alloc xmalloc
60 #define obstack_chunk_free free
62 #ifdef USG
63 #define vfork fork
64 #endif
66 #ifndef R_OK
67 #define R_OK 4
68 #define W_OK 2
69 #define X_OK 1
70 #endif
72 #ifndef WIFSIGNALED
73 #define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
74 #endif
75 #ifndef WTERMSIG
76 #define WTERMSIG(S) ((S) & 0x7f)
77 #endif
78 #ifndef WIFEXITED
79 #define WIFEXITED(S) (((S) & 0xff) == 0)
80 #endif
81 #ifndef WEXITSTATUS
82 #define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
83 #endif
85 extern char *choose_temp_base ();
87 /* On certain systems, we have code that works by scanning the object file
88 directly. But this code uses system-specific header files and library
89 functions, so turn it off in a cross-compiler. Likewise, the names of
90 the utilities aren't correct for a cross-compiler; we have to hope that
91 cross-versions are in the proper directories. */
93 #ifdef CROSS_COMPILE
94 #undef SUNOS4_SHARED_LIBRARIES
95 #undef OBJECT_FORMAT_COFF
96 #undef OBJECT_FORMAT_ROSE
97 #undef MD_EXEC_PREFIX
98 #undef REAL_LD_FILE_NAME
99 #undef REAL_NM_FILE_NAME
100 #undef REAL_STRIP_FILE_NAME
101 #endif
103 /* If we can't use a special method, use the ordinary one:
104 run nm to find what symbols are present.
105 In a cross-compiler, this means you need a cross nm,
106 but that isn't quite as unpleasant as special headers. */
108 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
109 #define OBJECT_FORMAT_NONE
110 #endif
112 #ifdef OBJECT_FORMAT_COFF
114 #include <a.out.h>
115 #include <ar.h>
117 #ifdef UMAX
118 #include <sgs.h>
119 #endif
121 /* Many versions of ldfcn.h define these. */
122 #ifdef FREAD
123 #undef FREAD
124 #undef FWRITE
125 #endif
127 #include <ldfcn.h>
129 /* Some systems have an ISCOFF macro, but others do not. In some cases
130 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
131 that either do not have an ISCOFF macro in /usr/include or for those
132 where it is wrong. */
134 #ifndef MY_ISCOFF
135 #define MY_ISCOFF(X) ISCOFF (X)
136 #endif
138 #ifdef XCOFF_DEBUGGING_INFO
139 #define XCOFF_SCAN_LIBS
140 #endif
142 #endif /* OBJECT_FORMAT_COFF */
144 #ifdef OBJECT_FORMAT_ROSE
146 #ifdef _OSF_SOURCE
147 #define USE_MMAP
148 #endif
150 #ifdef USE_MMAP
151 #include <sys/mman.h>
152 #endif
154 #include <unistd.h>
155 #include <mach_o_format.h>
156 #include <mach_o_header.h>
157 #include <mach_o_vals.h>
158 #include <mach_o_types.h>
160 #endif /* OBJECT_FORMAT_ROSE */
162 #ifdef OBJECT_FORMAT_NONE
164 /* Default flags to pass to nm. */
165 #ifndef NM_FLAGS
166 #define NM_FLAGS "-p"
167 #endif
169 #endif /* OBJECT_FORMAT_NONE */
171 /* Some systems use __main in a way incompatible with its use in gcc, in these
172 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
173 give the same symbol without quotes for an alternative entry point. You
174 must define both, or neither. */
175 #ifndef NAME__MAIN
176 #define NAME__MAIN "__main"
177 #define SYMBOL__MAIN __main
178 #endif
180 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES || defined(XCOFF_SCAN_LIBS)
181 #define SCAN_LIBRARIES
182 #endif
184 #ifdef USE_COLLECT2
185 int do_collecting = 1;
186 #else
187 int do_collecting = 0;
188 #endif
190 /* Linked lists of constructor and destructor names. */
192 struct id
194 struct id *next;
195 int sequence;
196 char name[1];
199 struct head
201 struct id *first;
202 struct id *last;
203 int number;
206 /* Enumeration giving which pass this is for scanning the program file. */
208 enum pass {
209 PASS_FIRST, /* without constructors */
210 PASS_OBJ, /* individual objects */
211 PASS_LIB, /* looking for shared libraries */
212 PASS_SECOND /* with constructors linked in */
215 #ifndef NO_SYS_SIGLIST
216 #ifndef DONT_DECLARE_SYS_SIGLIST
217 extern char *sys_siglist[];
218 #endif
219 #endif
220 extern char *version_string;
222 int vflag; /* true if -v */
223 static int rflag; /* true if -r */
224 static int strip_flag; /* true if -s */
226 int debug; /* true if -debug */
228 static int shared_obj; /* true if -shared */
230 static int temp_filename_length; /* Length of temp_filename */
231 static char *temp_filename; /* Base of temp filenames */
232 static char *c_file; /* <xxx>.c for constructor/destructor list. */
233 static char *o_file; /* <xxx>.o for constructor/destructor list. */
234 static char *export_file; /* <xxx>.x for AIX export list. */
235 char *ldout; /* File for ld errors. */
236 static char *output_file; /* Output file for ld. */
237 static char *nm_file_name; /* pathname of nm */
238 static char *ldd_file_name; /* pathname of ldd (or equivalent) */
239 static char *strip_file_name; /* pathname of strip */
240 char *c_file_name; /* pathname of gcc */
241 static char *initname, *fininame; /* names of init and fini funcs */
243 static struct head constructors; /* list of constructors found */
244 static struct head destructors; /* list of destructors found */
245 static struct head exports; /* list of exported symbols */
247 struct obstack temporary_obstack;
248 struct obstack permanent_obstack;
249 char * temporary_firstobj;
251 /* Defined in the automatically-generated underscore.c. */
252 extern int prepends_underscore;
254 extern char *getenv ();
255 extern char *mktemp ();
256 extern FILE *fdopen ();
258 /* Structure to hold all the directories in which to search for files to
259 execute. */
261 struct prefix_list
263 char *prefix; /* String to prepend to the path. */
264 struct prefix_list *next; /* Next in linked list. */
267 struct path_prefix
269 struct prefix_list *plist; /* List of prefixes to try */
270 int max_len; /* Max length of a prefix in PLIST */
271 char *name; /* Name of this list (used in config stuff) */
274 void collect_exit PROTO((int));
275 void collect_execute PROTO((char *, char **, char *));
276 void dump_file PROTO((char *));
277 static void handler PROTO((int));
278 static int is_ctor_dtor PROTO((char *));
279 static int is_in_prefix_list PROTO((struct path_prefix *, char *, int));
280 static char *find_a_file PROTO((struct path_prefix *, char *));
281 static void add_prefix PROTO((struct path_prefix *, char *));
282 static void prefix_from_env PROTO((char *, struct path_prefix *));
283 static void prefix_from_string PROTO((char *, struct path_prefix *));
284 static void do_wait PROTO((char *));
285 static void fork_execute PROTO((char *, char **));
286 static void maybe_unlink PROTO((char *));
287 static void add_to_list PROTO((struct head *, char *));
288 static void write_list PROTO((FILE *, char *, struct id *));
289 static void write_list_with_asm PROTO((FILE *, char *, struct id *));
290 static void write_c_file PROTO((FILE *, char *));
291 static void write_export_file PROTO((FILE *));
292 static void scan_prog_file PROTO((char *, enum pass));
293 static void scan_libraries PROTO((char *));
295 char *xcalloc ();
296 char *xmalloc ();
298 extern char *index ();
299 extern char *rindex ();
300 extern void free ();
302 #ifdef NO_DUP2
304 dup2 (oldfd, newfd)
305 int oldfd;
306 int newfd;
308 int fdtmp[256];
309 int fdx = 0;
310 int fd;
312 if (oldfd == newfd)
313 return oldfd;
314 close (newfd);
315 while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
316 fdtmp[fdx++] = fd;
317 while (fdx > 0)
318 close (fdtmp[--fdx]);
320 return fd;
322 #endif
324 char *
325 my_strerror (e)
326 int e;
329 #ifdef HAVE_STRERROR
330 return strerror (e);
332 #else
334 static char buffer[30];
335 if (!e)
336 return "";
338 if (e > 0 && e < sys_nerr)
339 return sys_errlist[e];
341 sprintf (buffer, "Unknown error %d", e);
342 return buffer;
343 #endif
346 /* Delete tempfiles and exit function. */
348 void
349 collect_exit (status)
350 int status;
352 if (c_file != 0 && c_file[0])
353 maybe_unlink (c_file);
355 if (o_file != 0 && o_file[0])
356 maybe_unlink (o_file);
358 if (export_file != 0 && export_file[0])
359 maybe_unlink (export_file);
361 if (ldout != 0 && ldout[0])
363 dump_file (ldout);
364 maybe_unlink (ldout);
367 if (status != 0 && output_file != 0 && output_file[0])
368 maybe_unlink (output_file);
370 exit (status);
374 /* Die when sys call fails. */
376 void
377 fatal_perror (string, arg1, arg2, arg3)
378 char *string, *arg1, *arg2, *arg3;
380 int e = errno;
382 fprintf (stderr, "collect2: ");
383 fprintf (stderr, string, arg1, arg2, arg3);
384 fprintf (stderr, ": %s\n", my_strerror (e));
385 collect_exit (1);
388 /* Just die. */
390 void
391 fatal (string, arg1, arg2, arg3)
392 char *string, *arg1, *arg2, *arg3;
394 fprintf (stderr, "collect2: ");
395 fprintf (stderr, string, arg1, arg2, arg3);
396 fprintf (stderr, "\n");
397 collect_exit (1);
400 /* Write error message. */
402 void
403 error (string, arg1, arg2, arg3, arg4)
404 char *string, *arg1, *arg2, *arg3, *arg4;
406 fprintf (stderr, "collect2: ");
407 fprintf (stderr, string, arg1, arg2, arg3, arg4);
408 fprintf (stderr, "\n");
411 /* In case obstack is linked in, and abort is defined to fancy_abort,
412 provide a default entry. */
414 void
415 fancy_abort ()
417 fatal ("internal error");
421 static void
422 handler (signo)
423 int signo;
425 if (c_file != 0 && c_file[0])
426 maybe_unlink (c_file);
428 if (o_file != 0 && o_file[0])
429 maybe_unlink (o_file);
431 if (ldout != 0 && ldout[0])
432 maybe_unlink (ldout);
434 if (export_file != 0 && export_file[0])
435 maybe_unlink (export_file);
437 signal (signo, SIG_DFL);
438 kill (getpid (), signo);
442 char *
443 xcalloc (size1, size2)
444 int size1, size2;
446 char *ptr = (char *) calloc (size1, size2);
447 if (ptr)
448 return ptr;
450 fatal ("out of memory");
451 return (char *) 0;
454 char *
455 xmalloc (size)
456 unsigned size;
458 char *ptr = (char *) malloc (size);
459 if (ptr)
460 return ptr;
462 fatal ("out of memory");
463 return (char *) 0;
466 char *
467 xrealloc (ptr, size)
468 char *ptr;
469 unsigned size;
471 register char *value = (char *) realloc (ptr, size);
472 if (value == 0)
473 fatal ("virtual memory exhausted");
474 return value;
478 file_exists (name)
479 char *name;
481 return access (name, R_OK) == 0;
484 /* Make a copy of a string INPUT with size SIZE. */
486 char *
487 savestring (input, size)
488 char *input;
489 int size;
491 char *output = (char *) xmalloc (size + 1);
492 bcopy (input, output, size);
493 output[size] = 0;
494 return output;
497 void
498 dump_file (name)
499 char *name;
501 FILE *stream = fopen (name, "r");
502 int no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
504 if (stream == 0)
505 return;
506 while (1)
508 int c;
509 while (c = getc (stream),
510 c != EOF && (isalnum (c) || c == '_' || c == '$' || c == '.'))
511 obstack_1grow (&temporary_obstack, c);
512 if (obstack_object_size (&temporary_obstack) > 0)
514 char *word, *p, *result;
515 obstack_1grow (&temporary_obstack, '\0');
516 word = obstack_finish (&temporary_obstack);
518 if (*word == '.')
519 ++word, putc ('.', stderr);
520 p = word;
521 if (*p == '_' && prepends_underscore)
522 ++p;
524 if (no_demangle)
525 result = 0;
526 else
527 result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI);
529 if (result)
531 int diff;
532 fputs (result, stderr);
534 diff = strlen (word) - strlen (result);
535 while (diff > 0)
536 --diff, putc (' ', stderr);
537 while (diff < 0 && c == ' ')
538 ++diff, c = getc (stream);
540 free (result);
542 else
543 fputs (word, stderr);
545 fflush (stderr);
546 obstack_free (&temporary_obstack, temporary_firstobj);
548 if (c == EOF)
549 break;
550 putc (c, stderr);
552 fclose (stream);
555 /* Decide whether the given symbol is:
556 a constructor (1), a destructor (2), or neither (0). */
558 static int
559 is_ctor_dtor (s)
560 char *s;
562 struct names { char *name; int len; int ret; int two_underscores; };
564 register struct names *p;
565 register int ch;
566 register char *orig_s = s;
568 static struct names special[] = {
569 #ifdef NO_DOLLAR_IN_LABEL
570 #ifdef NO_DOT_IN_LABEL
571 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
572 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
573 #else
574 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
575 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
576 #endif
577 #else
578 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
579 { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },
580 #endif
581 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
582 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
583 #ifdef CFRONT_LOSSAGE /* Don't collect cfront initialization functions.
584 cfront has its own linker procedure to collect them;
585 if collect2 gets them too, they get collected twice
586 when the cfront procedure is run and the compiler used
587 for linking happens to be GCC. */
588 { "sti__", sizeof ("sti__")-1, 1, 1 },
589 { "std__", sizeof ("std__")-1, 2, 1 },
590 #endif /* CFRONT_LOSSAGE */
591 { NULL, 0, 0, 0 }
594 while ((ch = *s) == '_')
595 ++s;
597 if (s == orig_s)
598 return 0;
600 for (p = &special[0]; p->len > 0; p++)
602 if (ch == p->name[0]
603 && (!p->two_underscores || ((s - orig_s) >= 2))
604 && strncmp(s, p->name, p->len) == 0)
606 return p->ret;
609 return 0;
612 /* Routine to add variables to the environment. */
614 #ifndef HAVE_PUTENV
617 putenv (str)
618 char *str;
620 #ifndef VMS /* nor about VMS */
622 extern char **environ;
623 char **old_environ = environ;
624 char **envp;
625 int num_envs = 0;
626 int name_len = 1;
627 char *p = str;
628 int ch;
630 while ((ch = *p++) != '\0' && ch != '=')
631 name_len++;
633 if (!ch)
634 abort ();
636 /* Search for replacing an existing environment variable, and
637 count the number of total environment variables. */
638 for (envp = old_environ; *envp; envp++)
640 num_envs++;
641 if (!strncmp (str, *envp, name_len))
643 *envp = str;
644 return 0;
648 /* Add a new environment variable */
649 environ = (char **) xmalloc (sizeof (char *) * (num_envs+2));
650 *environ = str;
651 bcopy ((char *) old_environ, (char *) (environ + 1),
652 sizeof (char *) * (num_envs+1));
654 return 0;
655 #endif /* VMS */
658 #endif /* HAVE_PUTENV */
660 /* By default, colon separates directories in a path. */
661 #ifndef PATH_SEPARATOR
662 #define PATH_SEPARATOR ':'
663 #endif
665 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
666 and one from the PATH variable. */
668 static struct path_prefix cpath, path;
670 #ifdef CROSS_COMPILE
671 /* This is the name of the target machine. We use it to form the name
672 of the files to execute. */
674 static char *target_machine = TARGET_MACHINE;
675 #endif
677 /* Names under which we were executed. Never return one of those files in our
678 searches. */
680 static struct path_prefix our_file_names;
682 /* Determine if STRING is in PPREFIX.
684 This utility is currently only used to look up file names. Prefix lists
685 record directory names. This matters to us because the latter has a
686 trailing slash, so I've added a flag to handle both. */
688 static int
689 is_in_prefix_list (pprefix, string, filep)
690 struct path_prefix *pprefix;
691 char *string;
692 int filep;
694 struct prefix_list *pl;
696 if (filep)
698 int len = strlen (string);
700 for (pl = pprefix->plist; pl; pl = pl->next)
702 if (strncmp (pl->prefix, string, len) == 0
703 && strcmp (pl->prefix + len, "/") == 0)
704 return 1;
707 else
709 for (pl = pprefix->plist; pl; pl = pl->next)
711 if (strcmp (pl->prefix, string) == 0)
712 return 1;
716 return 0;
719 /* Search for NAME using prefix list PPREFIX. We only look for executable
720 files.
722 Return 0 if not found, otherwise return its name, allocated with malloc. */
724 static char *
725 find_a_file (pprefix, name)
726 struct path_prefix *pprefix;
727 char *name;
729 char *temp;
730 struct prefix_list *pl;
731 int len = pprefix->max_len + strlen (name) + 1;
733 #ifdef EXECUTABLE_SUFFIX
734 len += strlen (EXECUTABLE_SUFFIX);
735 #endif
737 temp = xmalloc (len);
739 /* Determine the filename to execute (special case for absolute paths). */
741 if (*name == '/')
743 if (access (name, X_OK) == 0)
745 strcpy (temp, name);
746 return temp;
749 else
750 for (pl = pprefix->plist; pl; pl = pl->next)
752 strcpy (temp, pl->prefix);
753 strcat (temp, name);
754 if (! is_in_prefix_list (&our_file_names, temp, 1)
755 /* This is a kludge, but there seems no way around it. */
756 && strcmp (temp, "./ld") != 0
757 && access (temp, X_OK) == 0)
758 return temp;
760 #ifdef EXECUTABLE_SUFFIX
761 /* Some systems have a suffix for executable files.
762 So try appending that. */
763 strcat (temp, EXECUTABLE_SUFFIX);
764 if (! is_in_prefix_list (&our_file_names, temp, 1)
765 && access (temp, X_OK) == 0)
766 return temp;
767 #endif
770 free (temp);
771 return 0;
774 /* Add an entry for PREFIX to prefix list PPREFIX. */
776 static void
777 add_prefix (pprefix, prefix)
778 struct path_prefix *pprefix;
779 char *prefix;
781 struct prefix_list *pl, **prev;
782 int len;
784 if (pprefix->plist)
786 for (pl = pprefix->plist; pl->next; pl = pl->next)
788 prev = &pl->next;
790 else
791 prev = &pprefix->plist;
793 /* Keep track of the longest prefix */
795 len = strlen (prefix);
796 if (len > pprefix->max_len)
797 pprefix->max_len = len;
799 pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
800 pl->prefix = savestring (prefix, len);
802 if (*prev)
803 pl->next = *prev;
804 else
805 pl->next = (struct prefix_list *) 0;
806 *prev = pl;
809 /* Take the value of the environment variable ENV, break it into a path, and
810 add of the entries to PPREFIX. */
812 static void
813 prefix_from_env (env, pprefix)
814 char *env;
815 struct path_prefix *pprefix;
817 char *p = getenv (env);
819 if (p)
820 prefix_from_string (p, pprefix);
823 static void
824 prefix_from_string (p, pprefix)
825 char *p;
826 struct path_prefix *pprefix;
828 char *startp, *endp;
829 char *nstore = (char *) xmalloc (strlen (p) + 3);
831 startp = endp = p;
832 while (1)
834 if (*endp == PATH_SEPARATOR || *endp == 0)
836 strncpy (nstore, startp, endp-startp);
837 if (endp == startp)
839 strcpy (nstore, "./");
841 else if (endp[-1] != '/')
843 nstore[endp-startp] = '/';
844 nstore[endp-startp+1] = 0;
846 else
847 nstore[endp-startp] = 0;
849 add_prefix (pprefix, nstore);
850 if (*endp == 0)
851 break;
852 endp = startp = endp + 1;
854 else
855 endp++;
859 /* Main program. */
862 main (argc, argv)
863 int argc;
864 char *argv[];
866 char *ld_suffix = "ld";
867 char *full_ld_suffix = ld_suffix;
868 char *real_ld_suffix = "real-ld";
869 char *full_real_ld_suffix = real_ld_suffix;
870 char *collect_ld_suffix = "collect-ld";
871 char *nm_suffix = "nm";
872 char *full_nm_suffix = nm_suffix;
873 char *gnm_suffix = "gnm";
874 char *full_gnm_suffix = gnm_suffix;
875 #ifdef LDD_SUFFIX
876 char *ldd_suffix = LDD_SUFFIX;
877 char *full_ldd_suffix = ldd_suffix;
878 #endif
879 char *strip_suffix = "strip";
880 char *full_strip_suffix = strip_suffix;
881 char *gstrip_suffix = "gstrip";
882 char *full_gstrip_suffix = gstrip_suffix;
883 char *arg;
884 FILE *outf, *exportf;
885 char *ld_file_name;
886 char *collect_name;
887 char *collect_names;
888 char *p;
889 char **c_argv;
890 char **c_ptr;
891 char **ld1_argv = (char **) xcalloc (sizeof (char *), argc+3);
892 char **ld1 = ld1_argv;
893 char **ld2_argv = (char **) xcalloc (sizeof (char *), argc+6);
894 char **ld2 = ld2_argv;
895 char **object_lst = (char **) xcalloc (sizeof (char *), argc);
896 char **object = object_lst;
897 int first_file;
898 int num_c_args = argc+7;
900 #ifdef DEBUG
901 debug = 1;
902 vflag = 1;
903 #endif
905 #ifndef DEFAULT_A_OUT_NAME
906 output_file = "a.out";
907 #else
908 output_file = DEFAULT_A_OUT_NAME;
909 #endif
911 obstack_begin (&temporary_obstack, 0);
912 obstack_begin (&permanent_obstack, 0);
913 temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
914 current_demangling_style = gnu_demangling;
916 /* We must check that we do not call ourselves in an infinite
917 recursion loop. We append the name used for us to the COLLECT_NAMES
918 environment variable.
920 In practice, collect will rarely invoke itself. This can happen now
921 that we are no longer called gld. A perfect example is when running
922 gcc in a build directory that has been installed. When looking for
923 ld's, we'll find our installed version and believe that's the real ld. */
925 /* We must also append COLLECT_NAME to COLLECT_NAMES to watch for the
926 previous version of collect (the one that used COLLECT_NAME and only
927 handled two levels of recursion). If we don't we may mutually recurse
928 forever. This can happen (I think) when bootstrapping the old version
929 and a new one is installed (rare, but we should handle it).
930 ??? Hopefully references to COLLECT_NAME can be removed at some point. */
932 collect_name = (char *) getenv ("COLLECT_NAME");
933 collect_names = (char *) getenv ("COLLECT_NAMES");
935 p = (char *) xmalloc (strlen ("COLLECT_NAMES=")
936 + (collect_name ? strlen (collect_name) + 1 : 0)
937 + (collect_names ? strlen (collect_names) + 1 : 0)
938 + strlen (argv[0]) + 1);
939 strcpy (p, "COLLECT_NAMES=");
940 if (collect_name != 0)
941 sprintf (p + strlen (p), "%s%c", collect_name, PATH_SEPARATOR);
942 if (collect_names != 0)
943 sprintf (p + strlen (p), "%s%c", collect_names, PATH_SEPARATOR);
944 strcat (p, argv[0]);
945 putenv (p);
947 prefix_from_env ("COLLECT_NAMES", &our_file_names);
949 /* Set environment variable COLLECT_NAME to our name so the previous version
950 of collect won't find us. If it does we'll mutually recurse forever.
951 This can happen when bootstrapping the new version and an old version is
952 installed.
953 ??? Hopefully this bit of code can be removed at some point. */
955 p = xmalloc (strlen ("COLLECT_NAME=") + strlen (argv[0]) + 1);
956 sprintf (p, "COLLECT_NAME=%s", argv[0]);
957 putenv (p);
959 p = (char *) getenv ("COLLECT_GCC_OPTIONS");
960 if (p)
961 while (*p)
963 char *q = p;
964 while (*q && *q != ' ') q++;
965 if (*p == '-' && p[1] == 'm')
966 num_c_args++;
968 if (*q) q++;
969 p = q;
972 c_ptr = c_argv = (char **) xcalloc (sizeof (char *), num_c_args);
974 if (argc < 2)
975 fatal ("no arguments");
977 #ifdef SIGQUIT
978 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
979 signal (SIGQUIT, handler);
980 #endif
981 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
982 signal (SIGINT, handler);
983 #ifdef SIGALRM
984 if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
985 signal (SIGALRM, handler);
986 #endif
987 #ifdef SIGHUP
988 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
989 signal (SIGHUP, handler);
990 #endif
991 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
992 signal (SIGSEGV, handler);
993 #ifdef SIGBUS
994 if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
995 signal (SIGBUS, handler);
996 #endif
998 /* Extract COMPILER_PATH and PATH into our prefix list. */
999 prefix_from_env ("COMPILER_PATH", &cpath);
1000 prefix_from_env ("PATH", &path);
1002 #ifdef CROSS_COMPILE
1003 /* If we look for a program in the compiler directories, we just use
1004 the short name, since these directories are already system-specific.
1005 But it we look for a took in the system directories, we need to
1006 qualify the program name with the target machine. */
1008 full_ld_suffix
1009 = xcalloc (strlen (ld_suffix) + strlen (target_machine) + 2, 1);
1010 strcpy (full_ld_suffix, target_machine);
1011 strcat (full_ld_suffix, "-");
1012 strcat (full_ld_suffix, ld_suffix);
1014 full_real_ld_suffix
1015 = xcalloc (strlen (real_ld_suffix) + strlen (target_machine) + 2, 1);
1016 strcpy (full_real_ld_suffix, target_machine);
1017 strcat (full_real_ld_suffix, "-");
1018 strcat (full_real_ld_suffix, real_ld_suffix);
1020 #if 0
1021 full_gld_suffix
1022 = xcalloc (strlen (gld_suffix) + strlen (target_machine) + 2, 1);
1023 strcpy (full_gld_suffix, target_machine);
1024 strcat (full_gld_suffix, "-");
1025 strcat (full_gld_suffix, gld_suffix);
1026 #endif
1028 full_nm_suffix
1029 = xcalloc (strlen (nm_suffix) + strlen (target_machine) + 2, 1);
1030 strcpy (full_nm_suffix, target_machine);
1031 strcat (full_nm_suffix, "-");
1032 strcat (full_nm_suffix, nm_suffix);
1034 full_gnm_suffix
1035 = xcalloc (strlen (gnm_suffix) + strlen (target_machine) + 2, 1);
1036 strcpy (full_gnm_suffix, target_machine);
1037 strcat (full_gnm_suffix, "-");
1038 strcat (full_gnm_suffix, gnm_suffix);
1040 #ifdef LDD_SUFFIX
1041 full_ldd_suffix
1042 = xcalloc (strlen (ldd_suffix) + strlen (target_machine) + 2, 1);
1043 strcpy (full_ldd_suffix, target_machine);
1044 strcat (full_ldd_suffix, "-");
1045 strcat (full_ldd_suffix, ldd_suffix);
1046 #endif
1048 full_strip_suffix
1049 = xcalloc (strlen (strip_suffix) + strlen (target_machine) + 2, 1);
1050 strcpy (full_strip_suffix, target_machine);
1051 strcat (full_strip_suffix, "-");
1052 strcat (full_strip_suffix, strip_suffix);
1054 full_gstrip_suffix
1055 = xcalloc (strlen (gstrip_suffix) + strlen (target_machine) + 2, 1);
1056 strcpy (full_gstrip_suffix, target_machine);
1057 strcat (full_gstrip_suffix, "-");
1058 strcat (full_gstrip_suffix, gstrip_suffix);
1059 #endif /* CROSS_COMPILE */
1061 /* Try to discover a valid linker/nm/strip to use. */
1063 /* Maybe we know the right file to use (if not cross). */
1064 #ifdef REAL_LD_FILE_NAME
1065 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
1066 if (ld_file_name == 0)
1067 #endif
1068 /* Search the (target-specific) compiler dirs for ld'. */
1069 ld_file_name = find_a_file (&cpath, real_ld_suffix);
1070 /* Likewise for `collect-ld'. */
1071 if (ld_file_name == 0)
1072 ld_file_name = find_a_file (&cpath, collect_ld_suffix);
1073 /* Search the compiler directories for `ld'. We have protection against
1074 recursive calls in find_a_file. */
1075 if (ld_file_name == 0)
1076 ld_file_name = find_a_file (&cpath, ld_suffix);
1077 /* Search the ordinary system bin directories
1078 for `ld' (if native linking) or `TARGET-ld' (if cross). */
1079 if (ld_file_name == 0)
1080 ld_file_name = find_a_file (&path, full_ld_suffix);
1082 /* If we've invoked ourselves, try again with LD_FILE_NAME. */
1084 if (collect_names != 0)
1086 if (ld_file_name != 0)
1088 argv[0] = ld_file_name;
1089 execvp (argv[0], argv);
1091 fatal ("cannot find `ld'");
1094 #ifdef REAL_NM_FILE_NAME
1095 nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
1096 if (nm_file_name == 0)
1097 #endif
1098 nm_file_name = find_a_file (&cpath, gnm_suffix);
1099 if (nm_file_name == 0)
1100 nm_file_name = find_a_file (&path, full_gnm_suffix);
1101 if (nm_file_name == 0)
1102 nm_file_name = find_a_file (&cpath, nm_suffix);
1103 if (nm_file_name == 0)
1104 nm_file_name = find_a_file (&path, full_nm_suffix);
1106 #ifdef LDD_SUFFIX
1107 ldd_file_name = find_a_file (&cpath, ldd_suffix);
1108 if (ldd_file_name == 0)
1109 ldd_file_name = find_a_file (&path, full_ldd_suffix);
1110 #endif
1112 #ifdef REAL_STRIP_FILE_NAME
1113 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
1114 if (strip_file_name == 0)
1115 #endif
1116 strip_file_name = find_a_file (&cpath, gstrip_suffix);
1117 if (strip_file_name == 0)
1118 strip_file_name = find_a_file (&path, full_gstrip_suffix);
1119 if (strip_file_name == 0)
1120 strip_file_name = find_a_file (&cpath, strip_suffix);
1121 if (strip_file_name == 0)
1122 strip_file_name = find_a_file (&path, full_strip_suffix);
1124 /* Determine the full path name of the C compiler to use. */
1125 c_file_name = getenv ("COLLECT_GCC");
1126 if (c_file_name == 0)
1128 #ifdef CROSS_COMPILE
1129 c_file_name = xcalloc (sizeof ("gcc-") + strlen (target_machine) + 1, 1);
1130 strcpy (c_file_name, target_machine);
1131 strcat (c_file_name, "-gcc");
1132 #else
1133 c_file_name = "gcc";
1134 #endif
1137 p = find_a_file (&cpath, c_file_name);
1139 /* Here it should be safe to use the system search path since we should have
1140 already qualified the name of the compiler when it is needed. */
1141 if (p == 0)
1142 p = find_a_file (&path, c_file_name);
1144 if (p)
1145 c_file_name = p;
1147 *ld1++ = *ld2++ = ld_file_name;
1149 /* Make temp file names. */
1150 temp_filename = choose_temp_base ();
1151 temp_filename_length = strlen (temp_filename);
1152 c_file = xcalloc (temp_filename_length + sizeof (".c"), 1);
1153 o_file = xcalloc (temp_filename_length + sizeof (".o"), 1);
1154 export_file = xmalloc (temp_filename_length + sizeof (".x"));
1155 ldout = xmalloc (temp_filename_length + sizeof (".ld"));
1156 sprintf (ldout, "%s.ld", temp_filename);
1157 sprintf (c_file, "%s.c", temp_filename);
1158 sprintf (o_file, "%s.o", temp_filename);
1159 sprintf (export_file, "%s.x", temp_filename);
1160 *c_ptr++ = c_file_name;
1161 *c_ptr++ = "-c";
1162 *c_ptr++ = "-o";
1163 *c_ptr++ = o_file;
1165 /* !!! When GCC calls collect2,
1166 it does not know whether it is calling collect2 or ld.
1167 So collect2 cannot meaningfully understand any options
1168 except those ld understands.
1169 If you propose to make GCC pass some other option,
1170 just imagine what will happen if ld is really ld!!! */
1172 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1173 /* After the first file, put in the c++ rt0. */
1175 first_file = 1;
1176 while ((arg = *++argv) != (char *) 0)
1178 *ld1++ = *ld2++ = arg;
1180 if (arg[0] == '-')
1182 switch (arg[1])
1184 case 'd':
1185 if (!strcmp (arg, "-debug"))
1187 debug = 1;
1188 vflag = 1;
1189 ld1--;
1190 ld2--;
1192 break;
1194 case 'l':
1195 if (first_file)
1197 /* place o_file BEFORE this argument! */
1198 first_file = 0;
1199 ld2--;
1200 *ld2++ = o_file;
1201 *ld2++ = arg;
1203 break;
1205 case 'o':
1206 if (arg[2] == '\0')
1207 output_file = *ld1++ = *ld2++ = *++argv;
1208 else
1209 output_file = &arg[2];
1210 break;
1212 case 'r':
1213 if (arg[2] == '\0')
1214 rflag = 1;
1215 break;
1217 case 's':
1218 if (arg[2] == '\0' && do_collecting)
1220 /* We must strip after the nm run, otherwise C++ linking
1221 won't work. Thus we strip in the second ld run, or
1222 else with strip if there is no second ld run. */
1223 strip_flag = 1;
1224 ld1--;
1226 break;
1228 case 'v':
1229 if (arg[2] == '\0')
1230 vflag = 1;
1231 break;
1234 else if ((p = rindex (arg, '.')) != (char *) 0
1235 && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0))
1237 if (first_file)
1239 first_file = 0;
1240 if (p[1] == 'o')
1241 *ld2++ = o_file;
1242 else
1244 /* place o_file BEFORE this argument! */
1245 ld2--;
1246 *ld2++ = o_file;
1247 *ld2++ = arg;
1250 if (p[1] == 'o')
1251 *object++ = arg;
1255 /* Get any options that the upper GCC wants to pass to the sub-GCC. */
1256 p = (char *) getenv ("COLLECT_GCC_OPTIONS");
1257 if (p)
1258 while (*p)
1260 char *q = p;
1261 while (*q && *q != ' ') q++;
1262 if (*p == '-' && (p[1] == 'm' || p[1] == 'f'))
1263 *c_ptr++ = savestring (p, q - p);
1264 if (strncmp (p, "-shared", sizeof ("shared") - 1) == 0)
1265 shared_obj = 1;
1267 if (*q) q++;
1268 p = q;
1271 #ifdef COLLECT_EXPORT_LIST
1272 /* The AIX linker will discard static constructors in object files if
1273 nothing else in the file is referenced, so look at them first. */
1274 while (object_lst < object)
1275 scan_prog_file (*object_lst++, PASS_OBJ);
1278 char *buf = alloca (strlen (export_file) + 5);
1279 sprintf (buf, "-bE:%s", export_file);
1280 *ld1++ = buf;
1281 *ld2++ = buf;
1282 exportf = fopen (export_file, "w");
1283 if (exportf == (FILE *) 0)
1284 fatal_perror ("%s", export_file);
1285 write_export_file (exportf);
1286 if (fclose (exportf))
1287 fatal_perror ("closing %s", export_file);
1289 #endif
1291 *c_ptr++ = c_file;
1292 *object = *c_ptr = *ld1 = (char *) 0;
1294 if (vflag)
1296 fprintf (stderr, "collect2 version %s", version_string);
1297 #ifdef TARGET_VERSION
1298 TARGET_VERSION;
1299 #endif
1300 fprintf (stderr, "\n");
1303 if (debug)
1305 char *ptr;
1306 fprintf (stderr, "ld_file_name = %s\n",
1307 (ld_file_name ? ld_file_name : "not found"));
1308 fprintf (stderr, "c_file_name = %s\n",
1309 (c_file_name ? c_file_name : "not found"));
1310 fprintf (stderr, "nm_file_name = %s\n",
1311 (nm_file_name ? nm_file_name : "not found"));
1312 #ifdef LDD_SUFFIX
1313 fprintf (stderr, "ldd_file_name = %s\n",
1314 (ldd_file_name ? ldd_file_name : "not found"));
1315 #endif
1316 fprintf (stderr, "strip_file_name = %s\n",
1317 (strip_file_name ? strip_file_name : "not found"));
1318 fprintf (stderr, "c_file = %s\n",
1319 (c_file ? c_file : "not found"));
1320 fprintf (stderr, "o_file = %s\n",
1321 (o_file ? o_file : "not found"));
1323 ptr = getenv ("COLLECT_NAMES");
1324 if (ptr)
1325 fprintf (stderr, "COLLECT_NAMES = %s\n", ptr);
1327 ptr = getenv ("COLLECT_GCC_OPTIONS");
1328 if (ptr)
1329 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1331 ptr = getenv ("COLLECT_GCC");
1332 if (ptr)
1333 fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
1335 ptr = getenv ("COMPILER_PATH");
1336 if (ptr)
1337 fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
1339 ptr = getenv ("LIBRARY_PATH");
1340 if (ptr)
1341 fprintf (stderr, "LIBRARY_PATH = %s\n", ptr);
1343 fprintf (stderr, "\n");
1346 /* Load the program, searching all libraries. */
1348 collect_execute ("ld", ld1_argv, ldout);
1349 do_wait ("ld");
1350 dump_file (ldout);
1351 unlink (ldout);
1353 /* If -r or they'll be run via some other method, don't build the
1354 constructor or destructor list, just return now. */
1355 if (rflag || ! do_collecting)
1356 return 0;
1358 /* Examine the namelist with nm and search it for static constructors
1359 and destructors to call.
1360 Write the constructor and destructor tables to a .s file and reload. */
1362 scan_prog_file (output_file, PASS_FIRST);
1364 #ifdef SCAN_LIBRARIES
1365 scan_libraries (output_file);
1366 #endif
1368 if (debug)
1370 fprintf (stderr, "%d constructor(s) found\n", constructors.number);
1371 fprintf (stderr, "%d destructor(s) found\n", destructors.number);
1374 if (constructors.number == 0 && destructors.number == 0
1375 #ifdef LDD_SUFFIX
1376 /* If we will be running these functions ourselves, we want to emit
1377 stubs into the shared library so that we don't have to relink
1378 dependent programs when we add static objects. */
1379 && ! shared_obj
1380 #endif
1383 /* Strip now if it was requested on the command line. */
1384 if (strip_flag)
1386 char **strip_argv = (char **) xcalloc (sizeof (char *), 3);
1387 strip_argv[0] = strip_file_name;
1388 strip_argv[1] = output_file;
1389 strip_argv[2] = (char *) 0;
1390 fork_execute ("strip", strip_argv);
1393 #ifdef COLLECT_EXPORT_LIST
1394 maybe_unlink (export_file);
1395 #endif
1396 return 0;
1399 maybe_unlink(output_file);
1400 outf = fopen (c_file, "w");
1401 if (outf == (FILE *) 0)
1402 fatal_perror ("%s", c_file);
1404 write_c_file (outf, c_file);
1406 if (fclose (outf))
1407 fatal_perror ("closing %s", c_file);
1409 /* Tell the linker that we have initializer and finalizer functions. */
1410 #ifdef LD_INIT_SWITCH
1411 *ld2++ = LD_INIT_SWITCH;
1412 *ld2++ = initname;
1413 *ld2++ = LD_FINI_SWITCH;
1414 *ld2++ = fininame;
1415 #endif
1416 *ld2 = (char*) 0;
1418 #ifdef COLLECT_EXPORT_LIST
1419 if (shared_obj)
1421 add_to_list (&exports, initname);
1422 add_to_list (&exports, fininame);
1423 add_to_list (&exports, "_GLOBAL__DI");
1424 add_to_list (&exports, "_GLOBAL__DD");
1425 exportf = fopen (export_file, "w");
1426 if (exportf == (FILE *) 0)
1427 fatal_perror ("%s", export_file);
1428 write_export_file (exportf);
1429 if (fclose (exportf))
1430 fatal_perror ("closing %s", export_file);
1432 #endif
1434 if (debug)
1436 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1437 output_file, c_file);
1438 write_c_file (stderr, "stderr");
1439 fprintf (stderr, "========== end of c_file\n\n");
1440 #ifdef COLLECT_EXPORT_LIST
1441 fprintf (stderr, "\n========== export_file = %s\n", export_file);
1442 write_export_file (stderr);
1443 fprintf (stderr, "========== end of export_file\n\n");
1444 #endif
1447 /* Assemble the constructor and destructor tables.
1448 Link the tables in with the rest of the program. */
1450 fork_execute ("gcc", c_argv);
1451 fork_execute ("ld", ld2_argv);
1453 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1454 constructors/destructors in shared libraries. */
1455 scan_prog_file (output_file, PASS_SECOND);
1457 maybe_unlink (c_file);
1458 maybe_unlink (o_file);
1459 maybe_unlink (export_file);
1460 return 0;
1464 /* Wait for a process to finish, and exit if a non-zero status is found. */
1467 collect_wait (prog)
1468 char *prog;
1470 int status;
1472 wait (&status);
1473 if (status)
1475 if (WIFSIGNALED (status))
1477 int sig = WTERMSIG (status);
1478 #ifdef NO_SYS_SIGLIST
1479 error ("%s terminated with signal %d %s",
1480 prog,
1481 sig,
1482 (status & 0200) ? ", core dumped" : "");
1483 #else
1484 error ("%s terminated with signal %d [%s]%s",
1485 prog,
1486 sig,
1487 sys_siglist[sig],
1488 (status & 0200) ? ", core dumped" : "");
1489 #endif
1491 collect_exit (127);
1494 if (WIFEXITED (status))
1495 return WEXITSTATUS (status);
1497 return 0;
1500 static void
1501 do_wait (prog)
1502 char *prog;
1504 int ret = collect_wait (prog);
1505 if (ret != 0)
1507 error ("%s returned %d exit status", prog, ret);
1508 collect_exit (ret);
1513 /* Fork and execute a program, and wait for the reply. */
1515 void
1516 collect_execute (prog, argv, redir)
1517 char *prog;
1518 char **argv;
1519 char *redir;
1521 int pid;
1523 if (vflag || debug)
1525 char **p_argv;
1526 char *str;
1528 if (argv[0])
1529 fprintf (stderr, "%s", argv[0]);
1530 else
1531 fprintf (stderr, "[cannot find %s]", prog);
1533 for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
1534 fprintf (stderr, " %s", str);
1536 fprintf (stderr, "\n");
1539 fflush (stdout);
1540 fflush (stderr);
1542 /* If we can't find a program we need, complain error. Do this here
1543 since we might not end up needing something that we couldn't find. */
1545 if (argv[0] == 0)
1546 fatal ("cannot find `%s'", prog);
1548 pid = vfork ();
1549 if (pid == -1)
1551 #ifdef vfork
1552 fatal_perror ("fork");
1553 #else
1554 fatal_perror ("vfork");
1555 #endif
1558 if (pid == 0) /* child context */
1560 if (redir)
1562 unlink (redir);
1563 if (freopen (redir, "a", stdout) == NULL)
1564 fatal_perror ("redirecting stdout");
1565 if (freopen (redir, "a", stderr) == NULL)
1566 fatal_perror ("redirecting stderr");
1569 execvp (argv[0], argv);
1570 fatal_perror ("executing %s", prog);
1574 static void
1575 fork_execute (prog, argv)
1576 char *prog;
1577 char **argv;
1579 collect_execute (prog, argv, NULL);
1580 do_wait (prog);
1583 /* Unlink a file unless we are debugging. */
1585 static void
1586 maybe_unlink (file)
1587 char *file;
1589 if (!debug)
1590 unlink (file);
1591 else
1592 fprintf (stderr, "[Leaving %s]\n", file);
1596 /* Add a name to a linked list. */
1598 static void
1599 add_to_list (head_ptr, name)
1600 struct head *head_ptr;
1601 char *name;
1603 struct id *newid
1604 = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
1605 struct id *p;
1606 static long sequence_number = 0;
1607 strcpy (newid->name, name);
1609 if (head_ptr->first)
1610 head_ptr->last->next = newid;
1611 else
1612 head_ptr->first = newid;
1614 /* Check for duplicate symbols. */
1615 for (p = head_ptr->first;
1616 strcmp (name, p->name) != 0;
1617 p = p->next)
1619 if (p != newid)
1621 head_ptr->last->next = 0;
1622 free (newid);
1623 return;
1626 newid->sequence = ++sequence_number;
1627 head_ptr->last = newid;
1628 head_ptr->number++;
1631 /* Write: `prefix', the names on list LIST, `suffix'. */
1633 static void
1634 write_list (stream, prefix, list)
1635 FILE *stream;
1636 char *prefix;
1637 struct id *list;
1639 while (list)
1641 fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1642 list = list->next;
1646 static void
1647 write_list_with_asm (stream, prefix, list)
1648 FILE *stream;
1649 char *prefix;
1650 struct id *list;
1652 while (list)
1654 fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1655 prefix, list->sequence, list->name);
1656 list = list->next;
1660 /* Write out the constructor and destructor tables statically (for a shared
1661 object), along with the functions to execute them. */
1663 static void
1664 write_c_file_stat (stream, name)
1665 FILE *stream;
1666 char *name;
1668 char *prefix, *p, *q;
1670 /* Figure out name of output_file, stripping off .so version. */
1671 p = rindex (output_file, '/');
1672 if (p == 0)
1673 p = (char *) output_file;
1674 else
1675 p++;
1676 q = p;
1677 while (q)
1679 q = index (q,'.');
1680 if (q == 0)
1682 q = p + strlen (p);
1683 break;
1685 else
1687 if (strncmp (q, ".so", 3) == 0)
1689 q += 3;
1690 break;
1692 else
1693 q++;
1696 /* q points to null at end of the string (or . of the .so version) */
1697 prefix = xmalloc (q - p + 1);
1698 strncpy (prefix, p, q - p);
1699 prefix[q - p] = 0;
1700 for (q = prefix; *q; q++)
1701 if (!isalnum (*q))
1702 *q = '_';
1703 if (debug)
1704 fprintf (stderr, "\nwrite_c_file - output name is %s, prefix is %s\n",
1705 output_file, prefix);
1707 #define INIT_NAME_FORMAT "_GLOBAL__FI_%s"
1708 initname = xmalloc (strlen (prefix) + sizeof (INIT_NAME_FORMAT) - 2);
1709 sprintf (initname, INIT_NAME_FORMAT, prefix);
1711 #define FINI_NAME_FORMAT "_GLOBAL__FD_%s"
1712 fininame = xmalloc (strlen (prefix) + sizeof (FINI_NAME_FORMAT) - 2);
1713 sprintf (fininame, FINI_NAME_FORMAT, prefix);
1715 free (prefix);
1717 /* Write the tables as C code */
1719 fprintf (stream, "static int count;\n");
1720 fprintf (stream, "typedef void entry_pt();\n");
1721 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1722 fprintf (stream, "void %s() {\n", initname);
1723 if (constructors.number > 0)
1725 fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
1726 write_list (stream, "\t\t", constructors.first);
1727 fprintf (stream, "\t};\n");
1728 fprintf (stream, "\tentry_pt **p;\n");
1729 fprintf (stream, "\tif (count++ != 0) return;\n");
1730 fprintf (stream, "\tp = ctors + %d;\n", constructors.number);
1731 fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
1733 else
1734 fprintf (stream, "\t++count;\n");
1735 fprintf (stream, "}\n");
1736 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1737 fprintf (stream, "void %s() {\n", fininame);
1738 if (destructors.number > 0)
1740 fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
1741 write_list (stream, "\t\t", destructors.first);
1742 fprintf (stream, "\t};\n");
1743 fprintf (stream, "\tentry_pt **p;\n");
1744 fprintf (stream, "\tif (--count != 0) return;\n");
1745 fprintf (stream, "\tp = dtors;\n");
1746 fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
1747 destructors.number);
1749 fprintf (stream, "}\n");
1751 if (shared_obj)
1753 fprintf (stream, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname);
1754 fprintf (stream, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame);
1758 /* Write the constructor/destructor tables. */
1760 static void
1761 write_c_file_glob (stream, name)
1762 FILE *stream;
1763 char *name;
1765 /* Write the tables as C code */
1767 fprintf (stream, "typedef void entry_pt();\n\n");
1769 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1771 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
1772 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number);
1773 write_list (stream, "\t", constructors.first);
1774 fprintf (stream, "\t0\n};\n\n");
1776 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1778 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
1779 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number);
1780 write_list (stream, "\t", destructors.first);
1781 fprintf (stream, "\t0\n};\n\n");
1783 fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
1784 fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
1787 static void
1788 write_c_file (stream, name)
1789 FILE *stream;
1790 char *name;
1792 #ifndef LD_INIT_SWITCH
1793 if (! shared_obj)
1794 write_c_file_glob (stream, name);
1795 else
1796 #endif
1797 write_c_file_stat (stream, name);
1800 static void
1801 write_export_file (stream)
1802 FILE *stream;
1804 struct id *list = exports.first;
1805 for (; list; list = list->next)
1806 fprintf (stream, "%s\n", list->name);
1809 #ifdef OBJECT_FORMAT_NONE
1811 /* Generic version to scan the name list of the loaded program for
1812 the symbols g++ uses for static constructors and destructors.
1814 The constructor table begins at __CTOR_LIST__ and contains a count
1815 of the number of pointers (or -1 if the constructors are built in a
1816 separate section by the linker), followed by the pointers to the
1817 constructor functions, terminated with a null pointer. The
1818 destructor table has the same format, and begins at __DTOR_LIST__. */
1820 static void
1821 scan_prog_file (prog_name, which_pass)
1822 char *prog_name;
1823 enum pass which_pass;
1825 void (*int_handler) ();
1826 void (*quit_handler) ();
1827 char *nm_argv[4];
1828 int pid;
1829 int argc = 0;
1830 int pipe_fd[2];
1831 char *p, buf[1024];
1832 FILE *inf;
1834 if (which_pass == PASS_SECOND)
1835 return;
1837 /* If we don't have an `nm', complain. */
1838 if (nm_file_name == 0)
1839 fatal ("cannot find `nm'");
1841 nm_argv[argc++] = nm_file_name;
1842 if (NM_FLAGS[0] != '\0')
1843 nm_argv[argc++] = NM_FLAGS;
1845 nm_argv[argc++] = prog_name;
1846 nm_argv[argc++] = (char *) 0;
1848 if (pipe (pipe_fd) < 0)
1849 fatal_perror ("pipe");
1851 inf = fdopen (pipe_fd[0], "r");
1852 if (inf == (FILE *) 0)
1853 fatal_perror ("fdopen");
1855 /* Trace if needed. */
1856 if (vflag)
1858 char **p_argv;
1859 char *str;
1861 for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
1862 fprintf (stderr, " %s", str);
1864 fprintf (stderr, "\n");
1867 fflush (stdout);
1868 fflush (stderr);
1870 /* Spawn child nm on pipe */
1871 pid = vfork ();
1872 if (pid == -1)
1874 #ifdef vfork
1875 fatal_perror ("fork");
1876 #else
1877 fatal_perror ("vfork");
1878 #endif
1881 if (pid == 0) /* child context */
1883 /* setup stdout */
1884 if (dup2 (pipe_fd[1], 1) < 0)
1885 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
1887 if (close (pipe_fd[0]) < 0)
1888 fatal_perror ("close (%d)", pipe_fd[0]);
1890 if (close (pipe_fd[1]) < 0)
1891 fatal_perror ("close (%d)", pipe_fd[1]);
1893 execv (nm_file_name, nm_argv);
1894 fatal_perror ("executing %s", nm_file_name);
1897 /* Parent context from here on. */
1898 int_handler = (void (*) ())signal (SIGINT, SIG_IGN);
1899 #ifdef SIGQUIT
1900 quit_handler = (void (*) ())signal (SIGQUIT, SIG_IGN);
1901 #endif
1903 if (close (pipe_fd[1]) < 0)
1904 fatal_perror ("close (%d)", pipe_fd[1]);
1906 if (debug)
1907 fprintf (stderr, "\nnm output with constructors/destructors.\n");
1909 /* Read each line of nm output. */
1910 while (fgets (buf, sizeof buf, inf) != (char *) 0)
1912 int ch, ch2;
1913 char *name, *end;
1915 /* If it contains a constructor or destructor name, add the name
1916 to the appropriate list. */
1918 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
1919 if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
1920 break;
1922 if (ch != '_')
1923 continue;
1925 name = p;
1926 /* Find the end of the symbol name.
1927 Don't include `|', because Encore nm can tack that on the end. */
1928 for (end = p; (ch2 = *end) != '\0' && !isspace (ch2) && ch2 != '|';
1929 end++)
1930 continue;
1933 *end = '\0';
1934 switch (is_ctor_dtor (name))
1936 case 1:
1937 if (which_pass != PASS_LIB)
1938 add_to_list (&constructors, name);
1939 break;
1941 case 2:
1942 if (which_pass != PASS_LIB)
1943 add_to_list (&destructors, name);
1944 break;
1946 case 3:
1947 if (which_pass != PASS_LIB)
1948 fatal ("init function found in object %s", prog_name);
1949 #ifndef LD_INIT_SWITCH
1950 add_to_list (&constructors, name);
1951 #endif
1952 break;
1954 case 4:
1955 if (which_pass != PASS_LIB)
1956 fatal ("fini function found in object %s", prog_name);
1957 #ifndef LD_FINI_SWITCH
1958 add_to_list (&destructors, name);
1959 #endif
1960 break;
1962 default: /* not a constructor or destructor */
1963 continue;
1966 if (debug)
1967 fprintf (stderr, "\t%s\n", buf);
1970 if (debug)
1971 fprintf (stderr, "\n");
1973 if (fclose (inf) != 0)
1974 fatal_perror ("fclose of pipe");
1976 do_wait (nm_file_name);
1978 signal (SIGINT, int_handler);
1979 #ifdef SIGQUIT
1980 signal (SIGQUIT, quit_handler);
1981 #endif
1984 #if SUNOS4_SHARED_LIBRARIES
1986 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
1987 that the output file depends upon and their initialization/finalization
1988 routines, if any. */
1990 #include <a.out.h>
1991 #include <fcntl.h>
1992 #include <link.h>
1993 #include <sys/mman.h>
1994 #include <sys/param.h>
1995 #include <unistd.h>
1996 #include <sys/dir.h>
1998 /* pointers to the object file */
1999 unsigned object; /* address of memory mapped file */
2000 unsigned objsize; /* size of memory mapped to file */
2001 char * code; /* pointer to code segment */
2002 char * data; /* pointer to data segment */
2003 struct nlist *symtab; /* pointer to symbol table */
2004 struct link_dynamic *ld;
2005 struct link_dynamic_2 *ld_2;
2006 struct head libraries;
2008 /* Map the file indicated by NAME into memory and store its address. */
2010 static void
2011 mapfile (name)
2012 char *name;
2014 int fp;
2015 struct stat s;
2016 if ((fp = open (name, O_RDONLY)) == -1)
2017 fatal ("unable to open file '%s'", name);
2018 if (fstat (fp, &s) == -1)
2019 fatal ("unable to stat file '%s'", name);
2021 objsize = s.st_size;
2022 object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE,
2023 fp, 0);
2024 if (object == -1)
2025 fatal ("unable to mmap file '%s'", name);
2027 close (fp);
2030 /* Helpers for locatelib. */
2032 static char *libname;
2034 static int
2035 libselect (d)
2036 struct direct *d;
2038 return (strncmp (libname, d->d_name, strlen (libname)) == 0);
2041 /* If one file has an additional numeric extension past LIBNAME, then put
2042 that one first in the sort. If both files have additional numeric
2043 extensions, then put the one with the higher number first in the sort.
2045 We must verify that the extension is numeric, because Sun saves the
2046 original versions of patched libraries with a .FCS extension. Files with
2047 invalid extensions must go last in the sort, so that they won't be used. */
2049 static int
2050 libcompare (d1, d2)
2051 struct direct **d1, **d2;
2053 int i1, i2 = strlen (libname);
2054 char *e1 = (*d1)->d_name + i2;
2055 char *e2 = (*d2)->d_name + i2;
2057 while (*e1 && *e2 && *e1 == '.' && *e2 == '.'
2058 && e1[1] && isdigit (e1[1]) && e2[1] && isdigit (e2[1]))
2060 ++e1;
2061 ++e2;
2062 i1 = strtol (e1, &e1, 10);
2063 i2 = strtol (e2, &e2, 10);
2064 if (i1 != i2)
2065 return i1 - i2;
2068 if (*e1)
2070 /* It has a valid numeric extension, prefer this one. */
2071 if (*e1 == '.' && e1[1] && isdigit (e1[1]))
2072 return 1;
2073 /* It has a invalid numeric extension, must prefer the other one. */
2074 else
2075 return -1;
2077 else if (*e2)
2079 /* It has a valid numeric extension, prefer this one. */
2080 if (*e2 == '.' && e2[1] && isdigit (e2[1]))
2081 return -1;
2082 /* It has a invalid numeric extension, must prefer the other one. */
2083 else
2084 return 1;
2086 else
2087 return 0;
2090 /* Given the name NAME of a dynamic dependency, find its pathname and add
2091 it to the list of libraries. */
2093 static void
2094 locatelib (name)
2095 char *name;
2097 static char **l;
2098 static int cnt;
2099 char buf[MAXPATHLEN];
2100 char *p, *q;
2101 char **pp;
2103 if (l == 0)
2105 char *ld_rules;
2106 char *ldr = 0;
2107 /* counting elements in array, need 1 extra for null */
2108 cnt = 1;
2109 ld_rules = (char *) (ld_2->ld_rules + code);
2110 if (ld_rules)
2112 cnt++;
2113 for (; *ld_rules != 0; ld_rules++)
2114 if (*ld_rules == ':')
2115 cnt++;
2116 ld_rules = (char *) (ld_2->ld_rules + code);
2117 ldr = (char *) malloc (strlen (ld_rules) + 1);
2118 strcpy (ldr, ld_rules);
2120 p = getenv ("LD_LIBRARY_PATH");
2121 q = 0;
2122 if (p)
2124 cnt++;
2125 for (q = p ; *q != 0; q++)
2126 if (*q == ':')
2127 cnt++;
2128 q = (char *) malloc (strlen (p) + 1);
2129 strcpy (q, p);
2131 l = (char **) malloc ((cnt + 3) * sizeof (char *));
2132 pp = l;
2133 if (ldr)
2135 *pp++ = ldr;
2136 for (; *ldr != 0; ldr++)
2137 if (*ldr == ':')
2139 *ldr++ = 0;
2140 *pp++ = ldr;
2143 if (q)
2145 *pp++ = q;
2146 for (; *q != 0; q++)
2147 if (*q == ':')
2149 *q++ = 0;
2150 *pp++ = q;
2153 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2154 *pp++ = "/lib";
2155 *pp++ = "/usr/lib";
2156 *pp++ = "/usr/local/lib";
2157 *pp = 0;
2159 libname = name;
2160 for (pp = l; *pp != 0 ; pp++)
2162 struct direct **namelist;
2163 int entries;
2164 if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0)
2166 sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name);
2167 add_to_list (&libraries, buf);
2168 if (debug)
2169 fprintf (stderr, "%s\n", buf);
2170 break;
2173 if (*pp == 0)
2175 if (debug)
2176 fprintf (stderr, "not found\n");
2177 else
2178 fatal ("dynamic dependency %s not found", name);
2182 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2183 that it depends upon and any constructors or destructors they contain. */
2185 static void
2186 scan_libraries (prog_name)
2187 char *prog_name;
2189 struct exec *header;
2190 char *base;
2191 struct link_object *lo;
2192 char buff[MAXPATHLEN];
2193 struct id *list;
2195 mapfile (prog_name);
2196 header = (struct exec *)object;
2197 if (N_BADMAG (*header))
2198 fatal ("bad magic number in file '%s'", prog_name);
2199 if (header->a_dynamic == 0)
2200 return;
2202 code = (char *) (N_TXTOFF (*header) + (long) header);
2203 data = (char *) (N_DATOFF (*header) + (long) header);
2204 symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header);
2206 if (header->a_magic == ZMAGIC && header->a_entry == 0x20)
2208 /* shared object */
2209 ld = (struct link_dynamic *) (symtab->n_value + code);
2210 base = code;
2212 else
2214 /* executable */
2215 ld = (struct link_dynamic *) data;
2216 base = code-PAGSIZ;
2219 if (debug)
2220 fprintf (stderr, "dynamic dependencies.\n");
2222 ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);
2223 for (lo = (struct link_object *) ld_2->ld_need; lo;
2224 lo = (struct link_object *) lo->lo_next)
2226 char *name;
2227 lo = (struct link_object *) ((long) lo + code);
2228 name = (char *) (code + lo->lo_name);
2229 if (lo->lo_library)
2231 if (debug)
2232 fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major);
2233 sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor);
2234 locatelib (buff);
2236 else
2238 if (debug)
2239 fprintf (stderr, "\t%s\n", name);
2240 add_to_list (&libraries, name);
2244 if (debug)
2245 fprintf (stderr, "\n");
2247 /* now iterate through the library list adding their symbols to
2248 the list. */
2249 for (list = libraries.first; list; list = list->next)
2250 scan_prog_file (list->name, PASS_LIB);
2253 #else /* SUNOS4_SHARED_LIBRARIES */
2254 #ifdef LDD_SUFFIX
2256 /* Use the List Dynamic Dependencies program to find shared libraries that
2257 the output file depends upon and their initialization/finalization
2258 routines, if any. */
2260 static void
2261 scan_libraries (prog_name)
2262 char *prog_name;
2264 static struct head libraries; /* list of shared libraries found */
2265 struct id *list;
2266 void (*int_handler) ();
2267 void (*quit_handler) ();
2268 char *ldd_argv[4];
2269 int pid;
2270 int argc = 0;
2271 int pipe_fd[2];
2272 char buf[1024];
2273 FILE *inf;
2275 /* If we don't have an `ldd', complain. */
2276 if (ldd_file_name == 0)
2278 error ("cannot find `ldd'");
2279 return;
2282 ldd_argv[argc++] = ldd_file_name;
2283 ldd_argv[argc++] = prog_name;
2284 ldd_argv[argc++] = (char *) 0;
2286 if (pipe (pipe_fd) < 0)
2287 fatal_perror ("pipe");
2289 inf = fdopen (pipe_fd[0], "r");
2290 if (inf == (FILE *) 0)
2291 fatal_perror ("fdopen");
2293 /* Trace if needed. */
2294 if (vflag)
2296 char **p_argv;
2297 char *str;
2299 for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2300 fprintf (stderr, " %s", str);
2302 fprintf (stderr, "\n");
2305 fflush (stdout);
2306 fflush (stderr);
2308 /* Spawn child ldd on pipe */
2309 pid = vfork ();
2310 if (pid == -1)
2312 #ifdef vfork
2313 fatal_perror ("fork");
2314 #else
2315 fatal_perror ("vfork");
2316 #endif
2319 if (pid == 0) /* child context */
2321 /* setup stdout */
2322 if (dup2 (pipe_fd[1], 1) < 0)
2323 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
2325 if (close (pipe_fd[0]) < 0)
2326 fatal_perror ("close (%d)", pipe_fd[0]);
2328 if (close (pipe_fd[1]) < 0)
2329 fatal_perror ("close (%d)", pipe_fd[1]);
2331 execv (ldd_file_name, ldd_argv);
2332 fatal_perror ("executing %s", ldd_file_name);
2335 /* Parent context from here on. */
2336 int_handler = (void (*) ()) signal (SIGINT, SIG_IGN);
2337 #ifdef SIGQUIT
2338 quit_handler = (void (*) ()) signal (SIGQUIT, SIG_IGN);
2339 #endif
2341 if (close (pipe_fd[1]) < 0)
2342 fatal_perror ("close (%d)", pipe_fd[1]);
2344 if (debug)
2345 fprintf (stderr, "\nldd output with constructors/destructors.\n");
2347 /* Read each line of ldd output. */
2348 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2350 int ch, ch2;
2351 char *name, *end, *p = buf;
2353 /* Extract names of libraries and add to list. */
2354 PARSE_LDD_OUTPUT (p);
2355 if (p == 0)
2356 continue;
2358 name = p;
2359 if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
2360 fatal ("dynamic dependency %s not found", buf);
2362 /* Find the end of the symbol name. */
2363 for (end = p;
2364 (ch2 = *end) != '\0' && ch2 != '\n' && !isspace (ch2) && ch2 != '|';
2365 end++)
2366 continue;
2367 *end = '\0';
2369 if (access (name, R_OK) == 0)
2370 add_to_list (&libraries, name);
2371 else
2372 fatal ("unable to open dynamic dependency '%s'", buf);
2374 if (debug)
2375 fprintf (stderr, "\t%s\n", buf);
2377 if (debug)
2378 fprintf (stderr, "\n");
2380 if (fclose (inf) != 0)
2381 fatal_perror ("fclose of pipe");
2383 do_wait (ldd_file_name);
2385 signal (SIGINT, int_handler);
2386 #ifdef SIGQUIT
2387 signal (SIGQUIT, quit_handler);
2388 #endif
2390 /* now iterate through the library list adding their symbols to
2391 the list. */
2392 for (list = libraries.first; list; list = list->next)
2393 scan_prog_file (list->name, PASS_LIB);
2396 #endif /* LDD_SUFFIX */
2397 #endif /* SUNOS4_SHARED_LIBRARIES */
2399 #endif /* OBJECT_FORMAT_NONE */
2403 * COFF specific stuff.
2406 #ifdef OBJECT_FORMAT_COFF
2408 #if defined(EXTENDED_COFF)
2409 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2410 # define GCC_SYMENT SYMR
2411 # define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
2412 # define GCC_SYMINC(X) (1)
2413 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2414 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2415 #else
2416 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2417 # define GCC_SYMENT SYMENT
2418 # define GCC_OK_SYMBOL(X) \
2419 (((X).n_sclass == C_EXT) && \
2420 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
2421 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
2422 # define GCC_SYMINC(X) ((X).n_numaux+1)
2423 # define GCC_SYMZERO(X) 0
2424 # define GCC_CHECK_HDR(X) (1)
2425 #endif
2427 extern char *ldgetname ();
2429 /* COFF version to scan the name list of the loaded program for
2430 the symbols g++ uses for static constructors and destructors.
2432 The constructor table begins at __CTOR_LIST__ and contains a count
2433 of the number of pointers (or -1 if the constructors are built in a
2434 separate section by the linker), followed by the pointers to the
2435 constructor functions, terminated with a null pointer. The
2436 destructor table has the same format, and begins at __DTOR_LIST__. */
2438 static void
2439 scan_prog_file (prog_name, which_pass)
2440 char *prog_name;
2441 enum pass which_pass;
2443 LDFILE *ldptr = NULL;
2444 int sym_index, sym_count;
2446 if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2447 return;
2449 if ((ldptr = ldopen (prog_name, ldptr)) == NULL)
2450 fatal ("%s: can't open as COFF file", prog_name);
2452 if (!MY_ISCOFF (HEADER (ldptr).f_magic))
2453 fatal ("%s: not a COFF file", prog_name);
2455 if (GCC_CHECK_HDR (ldptr))
2457 sym_count = GCC_SYMBOLS (ldptr);
2458 sym_index = GCC_SYMZERO (ldptr);
2459 while (sym_index < sym_count)
2461 GCC_SYMENT symbol;
2463 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2464 break;
2465 sym_index += GCC_SYMINC (symbol);
2467 if (GCC_OK_SYMBOL (symbol))
2469 char *name;
2471 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2472 continue; /* should never happen */
2474 #ifdef XCOFF_DEBUGGING_INFO
2475 /* All AIX function names have a duplicate entry beginning
2476 with a dot. */
2477 if (*name == '.')
2478 ++name;
2479 #endif
2481 switch (is_ctor_dtor (name))
2483 case 1:
2484 add_to_list (&constructors, name);
2485 if (which_pass == PASS_OBJ)
2486 add_to_list (&exports, name);
2487 break;
2489 case 2:
2490 add_to_list (&destructors, name);
2491 if (which_pass == PASS_OBJ)
2492 add_to_list (&exports, name);
2493 break;
2495 default: /* not a constructor or destructor */
2496 continue;
2499 #if !defined(EXTENDED_COFF)
2500 if (debug)
2501 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
2502 symbol.n_scnum, symbol.n_sclass,
2503 (symbol.n_type ? "0" : ""), symbol.n_type,
2504 name);
2505 #else
2506 if (debug)
2507 fprintf (stderr, "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
2508 symbol.iss, symbol.value, symbol.index, name);
2509 #endif
2514 (void) ldclose(ldptr);
2517 #ifdef XCOFF_SCAN_LIBS
2518 /* Scan imported AIX libraries for GCC static ctors and dtors.
2519 FIXME: it is possible to link an executable without the actual import
2520 library by using an "import file" - a text file listing symbols
2521 exported by a library. To support this, we would have to scan
2522 import files as well as actual shared binaries to find GCC ctors.
2523 TODO: use memory mapping instead of 'ld' routines, files are already
2524 memory mapped, but we could eliminate the extra in-memory copies.
2525 Is it worth the effort? */
2527 static void
2528 scan_libraries (prog_name)
2529 char *prog_name;
2531 LDFILE *ldptr;
2532 SCNHDR ldsh;
2533 static struct path_prefix libpath; /* we should only do this once */
2535 if ((ldptr = ldopen (prog_name, ldptr)) == NULL)
2536 fatal ("%s: can't open as COFF file", prog_name);
2538 if (!MY_ISCOFF (HEADER (ldptr).f_magic))
2539 fatal ("%s: not a COFF file", prog_name);
2541 /* find and read loader section */
2542 if (ldnshread (ldptr, _LOADER, &ldsh))
2544 LDHDR ldh;
2545 char *impbuf;
2546 int entry;
2548 FSEEK (ldptr, ldsh.s_scnptr, BEGINNING);
2549 FREAD (&ldh, sizeof (ldh), 1, ldptr);
2550 /* read import library list */
2551 impbuf = alloca (ldh.l_istlen);
2552 FSEEK (ldptr, ldh.l_impoff + ldsh.s_scnptr, BEGINNING);
2553 FREAD (impbuf, ldh.l_istlen, 1, ldptr);
2555 if (debug)
2556 fprintf (stderr, "LIBPATH=%s\n", impbuf);
2557 prefix_from_string (impbuf, &libpath);
2559 /* skip LIBPATH and empty base and member fields */
2560 impbuf += strlen (impbuf) + 3;
2561 for (entry = 1; entry < ldh.l_nimpid; ++entry)
2563 char *impath = impbuf;
2564 char *implib = impath + strlen (impath) + 1;
2565 char *impmem = implib + strlen (implib) + 1;
2566 char *soname = NULL;
2567 char *trial;
2568 int pathlen;
2569 LDFILE *libptr = NULL;
2570 struct prefix_list *pl;
2571 ARCHDR ah;
2573 impbuf = impmem + strlen (impmem) + 1;
2574 if (debug)
2575 fprintf (stderr, "PATH+BASE=%s%s\n", impath, implib);
2576 /* Skip AIX kernel exports */
2577 if (*impath == '/' && *(impath+1) == '\0'
2578 && strcmp (implib, "unix") == 0)
2579 continue;
2580 pathlen = strlen (impath);
2581 trial = alloca (MAX (pathlen + 1, libpath.max_len)
2582 + strlen (implib) + 1);
2583 if (*impath)
2585 strcpy (trial, impath);
2586 if (impath[pathlen - 1] != '/')
2587 trial[pathlen++] = '/';
2588 strcpy (trial + pathlen, implib);
2589 if (access (trial, R_OK) == 0)
2590 soname = trial;
2592 else
2593 for (pl = libpath.plist; pl; pl = pl->next)
2595 strcpy (trial, pl->prefix);
2596 strcat (trial, implib);
2597 if (access (trial, R_OK) == 0)
2599 soname = trial;
2600 break;
2604 if (! soname)
2605 fatal ("%s: library not found", implib);
2606 if (debug)
2607 if (*impmem)
2608 fprintf (stderr, "%s (%s)\n", soname, impmem);
2609 else
2610 fprintf (stderr, "%s\n", soname);
2614 /* scan imported shared objects for GCC GLOBAL ctors */
2615 short type;
2616 if ((libptr = ldopen (soname, libptr)) == NULL)
2617 fatal ("%s: can't open import library", soname);
2618 if (TYPE (libptr) == ARTYPE)
2620 LDFILE *memptr;
2621 if (! *impmem)
2622 fatal ("%s: no archive member specified", soname);
2623 ldahread (libptr, &ah);
2624 if (strcmp (ah.ar_name, impmem))
2625 continue;
2627 type = HEADER (libptr).f_magic;
2628 if (HEADER (libptr).f_flags & F_SHROBJ)
2630 SCNHDR soldsh;
2631 LDHDR soldh;
2632 long symcnt, i;
2633 char *ldstrings;
2634 LDSYM *lsyms;
2635 if (!ldnshread (libptr, _LOADER, &soldsh))
2636 fatal ("%s: not an import library", soname);
2637 FSEEK (libptr, soldsh.s_scnptr, BEGINNING);
2638 if (FREAD (&soldh, sizeof (soldh), 1, libptr) != 1)
2639 fatal ("%s: can't read loader section", soname);
2640 /*fprintf (stderr, "\tscanning %s\n", soname);*/
2641 symcnt = soldh.l_nsyms;
2642 lsyms = (LDSYM *) alloca (symcnt * sizeof (*lsyms));
2643 symcnt = FREAD (lsyms, sizeof (*lsyms), symcnt, libptr);
2644 ldstrings = alloca (soldh.l_stlen);
2645 FSEEK (libptr, soldsh.s_scnptr+soldh.l_stoff, BEGINNING);
2646 FREAD (ldstrings, soldh.l_stlen, 1, libptr);
2647 for (i = 0; i < symcnt; ++i)
2649 LDSYM *l = lsyms + i;
2650 if (LDR_EXPORT (*l))
2652 char *expname = 0;
2653 if (l->l_zeroes)
2654 expname = l->l_name;
2655 else if (l->l_offset < soldh.l_stlen)
2656 expname = ldstrings + l->l_offset;
2657 switch (is_ctor_dtor (expname))
2659 case 3:
2660 if (debug)
2661 fprintf (stderr, "\t%s\n", expname);
2662 add_to_list (&constructors, expname);
2663 break;
2665 case 4:
2666 add_to_list (&destructors, expname);
2667 break;
2669 default: /* not a constructor or destructor */
2670 continue;
2675 else
2676 fprintf (stderr, "%s: type = %04X flags = %04X\n",
2677 ah.ar_name, type, HEADER (libptr).f_flags);
2679 while (ldclose (libptr) == FAILURE);
2680 /* printf (stderr, "closed %s\n", soname); */
2684 #endif /* XCOFF_SCAN_LIBS */
2686 #endif /* OBJECT_FORMAT_COFF */
2690 * OSF/rose specific stuff.
2693 #ifdef OBJECT_FORMAT_ROSE
2695 /* Union of the various load commands */
2697 typedef union load_union
2699 ldc_header_t hdr; /* common header */
2700 load_cmd_map_command_t map; /* map indexing other load cmds */
2701 interpreter_command_t iprtr; /* interpreter pathname */
2702 strings_command_t str; /* load commands strings section */
2703 region_command_t region; /* region load command */
2704 reloc_command_t reloc; /* relocation section */
2705 package_command_t pkg; /* package load command */
2706 symbols_command_t sym; /* symbol sections */
2707 entry_command_t ent; /* program start section */
2708 gen_info_command_t info; /* object information */
2709 func_table_command_t func; /* function constructors/destructors */
2710 } load_union_t;
2712 /* Structure to point to load command and data section in memory. */
2714 typedef struct load_all
2716 load_union_t *load; /* load command */
2717 char *section; /* pointer to section */
2718 } load_all_t;
2720 /* Structure to contain information about a file mapped into memory. */
2722 struct file_info
2724 char *start; /* start of map */
2725 char *name; /* filename */
2726 long size; /* size of the file */
2727 long rounded_size; /* size rounded to page boundary */
2728 int fd; /* file descriptor */
2729 int rw; /* != 0 if opened read/write */
2730 int use_mmap; /* != 0 if mmap'ed */
2733 extern int decode_mach_o_hdr ();
2734 extern int encode_mach_o_hdr ();
2736 static void add_func_table PROTO((mo_header_t *, load_all_t *,
2737 symbol_info_t *, int));
2738 static void print_header PROTO((mo_header_t *));
2739 static void print_load_command PROTO((load_union_t *, size_t, int));
2740 static void bad_header PROTO((int));
2741 static struct file_info *read_file PROTO((char *, int, int));
2742 static void end_file PROTO((struct file_info *));
2744 /* OSF/rose specific version to scan the name list of the loaded
2745 program for the symbols g++ uses for static constructors and
2746 destructors.
2748 The constructor table begins at __CTOR_LIST__ and contains a count
2749 of the number of pointers (or -1 if the constructors are built in a
2750 separate section by the linker), followed by the pointers to the
2751 constructor functions, terminated with a null pointer. The
2752 destructor table has the same format, and begins at __DTOR_LIST__. */
2754 static void
2755 scan_prog_file (prog_name, which_pass)
2756 char *prog_name;
2757 enum pass which_pass;
2759 char *obj;
2760 mo_header_t hdr;
2761 load_all_t *load_array;
2762 load_all_t *load_end;
2763 load_all_t *load_cmd;
2764 int symbol_load_cmds;
2765 off_t offset;
2766 int i;
2767 int num_syms;
2768 int status;
2769 char *str_sect;
2770 struct file_info *obj_file;
2771 int prog_fd;
2772 mo_lcid_t cmd_strings = -1;
2773 symbol_info_t *main_sym = 0;
2774 int rw = (which_pass != PASS_FIRST);
2776 prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
2777 if (prog_fd < 0)
2778 fatal_perror ("can't read %s", prog_name);
2780 obj_file = read_file (prog_name, prog_fd, rw);
2781 obj = obj_file->start;
2783 status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);
2784 if (status != MO_HDR_CONV_SUCCESS)
2785 bad_header (status);
2788 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
2789 since the hardware will automatically swap bytes for us on loading little endian
2790 integers. */
2792 #ifndef CROSS_COMPILE
2793 if (hdr.moh_magic != MOH_MAGIC_MSB
2794 || hdr.moh_header_version != MOH_HEADER_VERSION
2795 || hdr.moh_byte_order != OUR_BYTE_ORDER
2796 || hdr.moh_data_rep_id != OUR_DATA_REP_ID
2797 || hdr.moh_cpu_type != OUR_CPU_TYPE
2798 || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE
2799 || hdr.moh_vendor_type != OUR_VENDOR_TYPE)
2801 fatal ("incompatibilities between object file & expected values");
2803 #endif
2805 if (debug)
2806 print_header (&hdr);
2808 offset = hdr.moh_first_cmd_off;
2809 load_end = load_array
2810 = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);
2812 /* Build array of load commands, calculating the offsets */
2813 for (i = 0; i < hdr.moh_n_load_cmds; i++)
2815 load_union_t *load_hdr; /* load command header */
2817 load_cmd = load_end++;
2818 load_hdr = (load_union_t *) (obj + offset);
2820 /* If modifying the program file, copy the header. */
2821 if (rw)
2823 load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
2824 bcopy ((char *)load_hdr, (char *)ptr, load_hdr->hdr.ldci_cmd_size);
2825 load_hdr = ptr;
2827 /* null out old command map, because we will rewrite at the end. */
2828 if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
2830 cmd_strings = ptr->map.lcm_ld_cmd_strings;
2831 ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
2835 load_cmd->load = load_hdr;
2836 if (load_hdr->hdr.ldci_section_off > 0)
2837 load_cmd->section = obj + load_hdr->hdr.ldci_section_off;
2839 if (debug)
2840 print_load_command (load_hdr, offset, i);
2842 offset += load_hdr->hdr.ldci_cmd_size;
2845 /* If the last command is the load command map and is not undefined,
2846 decrement the count of load commands. */
2847 if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)
2849 load_end--;
2850 hdr.moh_n_load_cmds--;
2853 /* Go through and process each symbol table section. */
2854 symbol_load_cmds = 0;
2855 for (load_cmd = load_array; load_cmd < load_end; load_cmd++)
2857 load_union_t *load_hdr = load_cmd->load;
2859 if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
2861 symbol_load_cmds++;
2863 if (debug)
2865 char *kind = "unknown";
2867 switch (load_hdr->sym.symc_kind)
2869 case SYMC_IMPORTS: kind = "imports"; break;
2870 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
2871 case SYMC_STABS: kind = "stabs"; break;
2874 fprintf (stderr, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
2875 symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
2878 if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
2879 continue;
2881 str_sect = load_array[load_hdr->sym.symc_strings_section].section;
2882 if (str_sect == (char *) 0)
2883 fatal ("string section missing");
2885 if (load_cmd->section == (char *) 0)
2886 fatal ("section pointer missing");
2888 num_syms = load_hdr->sym.symc_nentries;
2889 for (i = 0; i < num_syms; i++)
2891 symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
2892 char *name = sym->si_name.symbol_name + str_sect;
2894 if (name[0] != '_')
2895 continue;
2897 if (rw)
2899 char *n = name + strlen (name) - strlen (NAME__MAIN);
2901 if ((n - name) < 0 || strcmp (n, NAME__MAIN))
2902 continue;
2903 while (n != name)
2904 if (*--n != '_')
2905 continue;
2907 main_sym = sym;
2909 else
2911 switch (is_ctor_dtor (name))
2913 case 1:
2914 add_to_list (&constructors, name);
2915 break;
2917 case 2:
2918 add_to_list (&destructors, name);
2919 break;
2921 default: /* not a constructor or destructor */
2922 continue;
2926 if (debug)
2927 fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
2928 sym->si_type, sym->si_sc_type, sym->si_flags, name);
2933 if (symbol_load_cmds == 0)
2934 fatal ("no symbol table found");
2936 /* Update the program file now, rewrite header and load commands. At present,
2937 we assume that there is enough space after the last load command to insert
2938 one more. Since the first section written out is page aligned, and the
2939 number of load commands is small, this is ok for the present. */
2941 if (rw)
2943 load_union_t *load_map;
2944 size_t size;
2946 if (cmd_strings == -1)
2947 fatal ("no cmd_strings found");
2949 /* Add __main to initializer list.
2950 If we are building a program instead of a shared library, don't
2951 do anything, since in the current version, you cannot do mallocs
2952 and such in the constructors. */
2954 if (main_sym != (symbol_info_t *) 0
2955 && ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
2956 add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
2958 if (debug)
2959 fprintf (stderr, "\nUpdating header and load commands.\n\n");
2961 hdr.moh_n_load_cmds++;
2962 size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
2964 /* Create new load command map. */
2965 if (debug)
2966 fprintf (stderr, "load command map, %d cmds, new size %ld.\n",
2967 (int)hdr.moh_n_load_cmds, (long)size);
2969 load_map = (load_union_t *) xcalloc (1, size);
2970 load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
2971 load_map->map.ldc_header.ldci_cmd_size = size;
2972 load_map->map.lcm_ld_cmd_strings = cmd_strings;
2973 load_map->map.lcm_nentries = hdr.moh_n_load_cmds;
2974 load_array[hdr.moh_n_load_cmds-1].load = load_map;
2976 offset = hdr.moh_first_cmd_off;
2977 for (i = 0; i < hdr.moh_n_load_cmds; i++)
2979 load_map->map.lcm_map[i] = offset;
2980 if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)
2981 hdr.moh_load_map_cmd_off = offset;
2983 offset += load_array[i].load->hdr.ldci_cmd_size;
2986 hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
2988 if (debug)
2989 print_header (&hdr);
2991 /* Write header */
2992 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
2993 if (status != MO_HDR_CONV_SUCCESS)
2994 bad_header (status);
2996 if (debug)
2997 fprintf (stderr, "writing load commands.\n\n");
2999 /* Write load commands */
3000 offset = hdr.moh_first_cmd_off;
3001 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3003 load_union_t *load_hdr = load_array[i].load;
3004 size_t size = load_hdr->hdr.ldci_cmd_size;
3006 if (debug)
3007 print_load_command (load_hdr, offset, i);
3009 bcopy ((char *) load_hdr, (char *) (obj + offset), size);
3010 offset += size;
3014 end_file (obj_file);
3016 if (close (prog_fd))
3017 fatal_perror ("closing %s", prog_name);
3019 if (debug)
3020 fprintf (stderr, "\n");
3024 /* Add a function table to the load commands to call a function
3025 on initiation or termination of the process. */
3027 static void
3028 add_func_table (hdr_p, load_array, sym, type)
3029 mo_header_t *hdr_p; /* pointer to global header */
3030 load_all_t *load_array; /* array of ptrs to load cmds */
3031 symbol_info_t *sym; /* pointer to symbol entry */
3032 int type; /* fntc_type value */
3034 /* Add a new load command. */
3035 int num_cmds = ++hdr_p->moh_n_load_cmds;
3036 int load_index = num_cmds - 1;
3037 size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);
3038 load_union_t *ptr = xcalloc (1, size);
3039 load_all_t *load_cmd;
3040 int i;
3042 /* Set the unresolved address bit in the header to force the loader to be
3043 used, since kernel exec does not call the initialization functions. */
3044 hdr_p->moh_flags |= MOH_UNRESOLVED_F;
3046 load_cmd = &load_array[load_index];
3047 load_cmd->load = ptr;
3048 load_cmd->section = (char *) 0;
3050 /* Fill in func table load command. */
3051 ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
3052 ptr->func.ldc_header.ldci_cmd_size = size;
3053 ptr->func.ldc_header.ldci_section_off = 0;
3054 ptr->func.ldc_header.ldci_section_len = 0;
3055 ptr->func.fntc_type = type;
3056 ptr->func.fntc_nentries = 1;
3058 /* copy address, turn it from abs. address to (region,offset) if necessary. */
3059 /* Is the symbol already expressed as (region, offset)? */
3060 if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)
3062 ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;
3063 ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;
3066 /* If not, figure out which region it's in. */
3067 else
3069 mo_vm_addr_t addr = sym->si_value.abs_val;
3070 int found = 0;
3072 for (i = 0; i < load_index; i++)
3074 if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
3076 region_command_t *region_ptr = &load_array[i].load->region;
3078 if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0
3079 && addr >= region_ptr->regc_addr.vm_addr
3080 && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)
3082 ptr->func.fntc_entry_loc[0].adr_lcid = i;
3083 ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;
3084 found++;
3085 break;
3090 if (!found)
3091 fatal ("could not convert 0x%l.8x into a region", addr);
3094 if (debug)
3095 fprintf (stderr,
3096 "%s function, region %d, offset = %ld (0x%.8lx)\n",
3097 (type == FNTC_INITIALIZATION) ? "init" : "term",
3098 (int)ptr->func.fntc_entry_loc[i].adr_lcid,
3099 (long)ptr->func.fntc_entry_loc[i].adr_sctoff,
3100 (long)ptr->func.fntc_entry_loc[i].adr_sctoff);
3105 /* Print the global header for an OSF/rose object. */
3107 static void
3108 print_header (hdr_ptr)
3109 mo_header_t *hdr_ptr;
3111 fprintf (stderr, "\nglobal header:\n");
3112 fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic);
3113 fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version);
3114 fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version);
3115 fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version);
3116 fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size);
3117 fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order);
3118 fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id);
3119 fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type);
3120 fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype);
3121 fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type);
3122 fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);
3123 fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off);
3124 fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds);
3125 fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds);
3126 fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags);
3128 if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
3129 fprintf (stderr, ", relocatable");
3131 if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
3132 fprintf (stderr, ", linkable");
3134 if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
3135 fprintf (stderr, ", execable");
3137 if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
3138 fprintf (stderr, ", executable");
3140 if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
3141 fprintf (stderr, ", unresolved");
3143 fprintf (stderr, "\n\n");
3144 return;
3148 /* Print a short summary of a load command. */
3150 static void
3151 print_load_command (load_hdr, offset, number)
3152 load_union_t *load_hdr;
3153 size_t offset;
3154 int number;
3156 mo_long_t type = load_hdr->hdr.ldci_cmd_type;
3157 char *type_str = (char *) 0;
3159 switch (type)
3161 case LDC_UNDEFINED: type_str = "UNDEFINED"; break;
3162 case LDC_CMD_MAP: type_str = "CMD_MAP"; break;
3163 case LDC_INTERPRETER: type_str = "INTERPRETER"; break;
3164 case LDC_STRINGS: type_str = "STRINGS"; break;
3165 case LDC_REGION: type_str = "REGION"; break;
3166 case LDC_RELOC: type_str = "RELOC"; break;
3167 case LDC_PACKAGE: type_str = "PACKAGE"; break;
3168 case LDC_SYMBOLS: type_str = "SYMBOLS"; break;
3169 case LDC_ENTRY: type_str = "ENTRY"; break;
3170 case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break;
3171 case LDC_GEN_INFO: type_str = "GEN_INFO"; break;
3174 fprintf (stderr,
3175 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3176 number,
3177 (long) load_hdr->hdr.ldci_cmd_size,
3178 (long) offset,
3179 (long) load_hdr->hdr.ldci_section_off,
3180 (long) load_hdr->hdr.ldci_section_len);
3182 if (type_str == (char *) 0)
3183 fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
3185 else if (type != LDC_REGION)
3186 fprintf (stderr, ", ty: %s\n", type_str);
3188 else
3190 char *region = "";
3191 switch (load_hdr->region.regc_usage_type)
3193 case REG_TEXT_T: region = ", .text"; break;
3194 case REG_DATA_T: region = ", .data"; break;
3195 case REG_BSS_T: region = ", .bss"; break;
3196 case REG_GLUE_T: region = ", .glue"; break;
3197 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3198 case REG_RDATA_T: region = ", .rdata"; break;
3199 case REG_SDATA_T: region = ", .sdata"; break;
3200 case REG_SBSS_T: region = ", .sbss"; break;
3201 #endif
3204 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3205 type_str,
3206 (long) load_hdr->region.regc_vm_addr,
3207 (long) load_hdr->region.regc_vm_size,
3208 region);
3211 return;
3215 /* Fatal error when {en,de}code_mach_o_header fails. */
3217 static void
3218 bad_header (status)
3219 int status;
3221 char *msg = (char *) 0;
3223 switch (status)
3225 case MO_ERROR_BAD_MAGIC: msg = "bad magic number"; break;
3226 case MO_ERROR_BAD_HDR_VERS: msg = "bad header version"; break;
3227 case MO_ERROR_BAD_RAW_HDR_VERS: msg = "bad raw header version"; break;
3228 case MO_ERROR_BUF2SML: msg = "raw header buffer too small"; break;
3229 case MO_ERROR_OLD_RAW_HDR_FILE: msg = "old raw header file"; break;
3230 case MO_ERROR_UNSUPPORTED_VERS: msg = "unsupported version"; break;
3233 if (msg == (char *) 0)
3234 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
3235 else
3236 fatal ("%s", msg);
3240 /* Read a file into a memory buffer. */
3242 static struct file_info *
3243 read_file (name, fd, rw)
3244 char *name; /* filename */
3245 int fd; /* file descriptor */
3246 int rw; /* read/write */
3248 struct stat stat_pkt;
3249 struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
3250 #ifdef USE_MMAP
3251 static int page_size;
3252 #endif
3254 if (fstat (fd, &stat_pkt) < 0)
3255 fatal_perror ("fstat %s", name);
3257 p->name = name;
3258 p->size = stat_pkt.st_size;
3259 p->rounded_size = stat_pkt.st_size;
3260 p->fd = fd;
3261 p->rw = rw;
3263 #ifdef USE_MMAP
3264 if (debug)
3265 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
3267 if (page_size == 0)
3268 page_size = sysconf (_SC_PAGE_SIZE);
3270 p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
3271 p->start = mmap ((caddr_t) 0,
3272 (rw) ? p->rounded_size : p->size,
3273 (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
3274 MAP_FILE | MAP_VARIABLE | MAP_SHARED,
3276 0L);
3278 if (p->start != (char *) 0 && p->start != (char *) -1)
3279 p->use_mmap = 1;
3281 else
3282 #endif /* USE_MMAP */
3284 long len;
3286 if (debug)
3287 fprintf (stderr, "read %s\n", name);
3289 p->use_mmap = 0;
3290 p->start = xmalloc (p->size);
3291 if (lseek (fd, 0L, SEEK_SET) < 0)
3292 fatal_perror ("lseek to 0 on %s", name);
3294 len = read (fd, p->start, p->size);
3295 if (len < 0)
3296 fatal_perror ("read %s", name);
3298 if (len != p->size)
3299 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
3302 return p;
3305 /* Do anything necessary to write a file back from memory. */
3307 static void
3308 end_file (ptr)
3309 struct file_info *ptr; /* file information block */
3311 #ifdef USE_MMAP
3312 if (ptr->use_mmap)
3314 if (ptr->rw)
3316 if (debug)
3317 fprintf (stderr, "msync %s\n", ptr->name);
3319 if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
3320 fatal_perror ("msync %s", ptr->name);
3323 if (debug)
3324 fprintf (stderr, "munmap %s\n", ptr->name);
3326 if (munmap (ptr->start, ptr->size))
3327 fatal_perror ("munmap %s", ptr->name);
3329 else
3330 #endif /* USE_MMAP */
3332 if (ptr->rw)
3334 long len;
3336 if (debug)
3337 fprintf (stderr, "write %s\n", ptr->name);
3339 if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
3340 fatal_perror ("lseek to 0 on %s", ptr->name);
3342 len = write (ptr->fd, ptr->start, ptr->size);
3343 if (len < 0)
3344 fatal_perror ("write %s", ptr->name);
3346 if (len != ptr->size)
3347 fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
3350 free (ptr->start);
3353 free (ptr);
3356 #endif /* OBJECT_FORMAT_ROSE */