Remove some out of date comments.
[official-gcc.git] / gcc / collect2.c
blob341c70ea045f0027a1d2371e83efd9c72f73b790
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 fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
1793 #ifndef LD_INIT_SWITCH
1794 if (! shared_obj)
1795 write_c_file_glob (stream, name);
1796 else
1797 #endif
1798 write_c_file_stat (stream, name);
1799 fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
1802 static void
1803 write_export_file (stream)
1804 FILE *stream;
1806 struct id *list = exports.first;
1807 for (; list; list = list->next)
1808 fprintf (stream, "%s\n", list->name);
1811 #ifdef OBJECT_FORMAT_NONE
1813 /* Generic version to scan the name list of the loaded program for
1814 the symbols g++ uses for static constructors and destructors.
1816 The constructor table begins at __CTOR_LIST__ and contains a count
1817 of the number of pointers (or -1 if the constructors are built in a
1818 separate section by the linker), followed by the pointers to the
1819 constructor functions, terminated with a null pointer. The
1820 destructor table has the same format, and begins at __DTOR_LIST__. */
1822 static void
1823 scan_prog_file (prog_name, which_pass)
1824 char *prog_name;
1825 enum pass which_pass;
1827 void (*int_handler) ();
1828 void (*quit_handler) ();
1829 char *nm_argv[4];
1830 int pid;
1831 int argc = 0;
1832 int pipe_fd[2];
1833 char *p, buf[1024];
1834 FILE *inf;
1836 if (which_pass == PASS_SECOND)
1837 return;
1839 /* If we don't have an `nm', complain. */
1840 if (nm_file_name == 0)
1841 fatal ("cannot find `nm'");
1843 nm_argv[argc++] = nm_file_name;
1844 if (NM_FLAGS[0] != '\0')
1845 nm_argv[argc++] = NM_FLAGS;
1847 nm_argv[argc++] = prog_name;
1848 nm_argv[argc++] = (char *) 0;
1850 if (pipe (pipe_fd) < 0)
1851 fatal_perror ("pipe");
1853 inf = fdopen (pipe_fd[0], "r");
1854 if (inf == (FILE *) 0)
1855 fatal_perror ("fdopen");
1857 /* Trace if needed. */
1858 if (vflag)
1860 char **p_argv;
1861 char *str;
1863 for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
1864 fprintf (stderr, " %s", str);
1866 fprintf (stderr, "\n");
1869 fflush (stdout);
1870 fflush (stderr);
1872 /* Spawn child nm on pipe */
1873 pid = vfork ();
1874 if (pid == -1)
1876 #ifdef vfork
1877 fatal_perror ("fork");
1878 #else
1879 fatal_perror ("vfork");
1880 #endif
1883 if (pid == 0) /* child context */
1885 /* setup stdout */
1886 if (dup2 (pipe_fd[1], 1) < 0)
1887 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
1889 if (close (pipe_fd[0]) < 0)
1890 fatal_perror ("close (%d)", pipe_fd[0]);
1892 if (close (pipe_fd[1]) < 0)
1893 fatal_perror ("close (%d)", pipe_fd[1]);
1895 execv (nm_file_name, nm_argv);
1896 fatal_perror ("executing %s", nm_file_name);
1899 /* Parent context from here on. */
1900 int_handler = (void (*) ())signal (SIGINT, SIG_IGN);
1901 #ifdef SIGQUIT
1902 quit_handler = (void (*) ())signal (SIGQUIT, SIG_IGN);
1903 #endif
1905 if (close (pipe_fd[1]) < 0)
1906 fatal_perror ("close (%d)", pipe_fd[1]);
1908 if (debug)
1909 fprintf (stderr, "\nnm output with constructors/destructors.\n");
1911 /* Read each line of nm output. */
1912 while (fgets (buf, sizeof buf, inf) != (char *) 0)
1914 int ch, ch2;
1915 char *name, *end;
1917 /* If it contains a constructor or destructor name, add the name
1918 to the appropriate list. */
1920 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
1921 if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
1922 break;
1924 if (ch != '_')
1925 continue;
1927 name = p;
1928 /* Find the end of the symbol name.
1929 Don't include `|', because Encore nm can tack that on the end. */
1930 for (end = p; (ch2 = *end) != '\0' && !isspace (ch2) && ch2 != '|';
1931 end++)
1932 continue;
1935 *end = '\0';
1936 switch (is_ctor_dtor (name))
1938 case 1:
1939 if (which_pass != PASS_LIB)
1940 add_to_list (&constructors, name);
1941 break;
1943 case 2:
1944 if (which_pass != PASS_LIB)
1945 add_to_list (&destructors, name);
1946 break;
1948 case 3:
1949 if (which_pass != PASS_LIB)
1950 fatal ("init function found in object %s", prog_name);
1951 #ifndef LD_INIT_SWITCH
1952 add_to_list (&constructors, name);
1953 #endif
1954 break;
1956 case 4:
1957 if (which_pass != PASS_LIB)
1958 fatal ("fini function found in object %s", prog_name);
1959 #ifndef LD_FINI_SWITCH
1960 add_to_list (&destructors, name);
1961 #endif
1962 break;
1964 default: /* not a constructor or destructor */
1965 continue;
1968 if (debug)
1969 fprintf (stderr, "\t%s\n", buf);
1972 if (debug)
1973 fprintf (stderr, "\n");
1975 if (fclose (inf) != 0)
1976 fatal_perror ("fclose of pipe");
1978 do_wait (nm_file_name);
1980 signal (SIGINT, int_handler);
1981 #ifdef SIGQUIT
1982 signal (SIGQUIT, quit_handler);
1983 #endif
1986 #if SUNOS4_SHARED_LIBRARIES
1988 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
1989 that the output file depends upon and their initialization/finalization
1990 routines, if any. */
1992 #include <a.out.h>
1993 #include <fcntl.h>
1994 #include <link.h>
1995 #include <sys/mman.h>
1996 #include <sys/param.h>
1997 #include <unistd.h>
1998 #include <sys/dir.h>
2000 /* pointers to the object file */
2001 unsigned object; /* address of memory mapped file */
2002 unsigned objsize; /* size of memory mapped to file */
2003 char * code; /* pointer to code segment */
2004 char * data; /* pointer to data segment */
2005 struct nlist *symtab; /* pointer to symbol table */
2006 struct link_dynamic *ld;
2007 struct link_dynamic_2 *ld_2;
2008 struct head libraries;
2010 /* Map the file indicated by NAME into memory and store its address. */
2012 static void
2013 mapfile (name)
2014 char *name;
2016 int fp;
2017 struct stat s;
2018 if ((fp = open (name, O_RDONLY)) == -1)
2019 fatal ("unable to open file '%s'", name);
2020 if (fstat (fp, &s) == -1)
2021 fatal ("unable to stat file '%s'", name);
2023 objsize = s.st_size;
2024 object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE,
2025 fp, 0);
2026 if (object == -1)
2027 fatal ("unable to mmap file '%s'", name);
2029 close (fp);
2032 /* Helpers for locatelib. */
2034 static char *libname;
2036 static int
2037 libselect (d)
2038 struct direct *d;
2040 return (strncmp (libname, d->d_name, strlen (libname)) == 0);
2043 /* If one file has an additional numeric extension past LIBNAME, then put
2044 that one first in the sort. If both files have additional numeric
2045 extensions, then put the one with the higher number first in the sort.
2047 We must verify that the extension is numeric, because Sun saves the
2048 original versions of patched libraries with a .FCS extension. Files with
2049 invalid extensions must go last in the sort, so that they won't be used. */
2051 static int
2052 libcompare (d1, d2)
2053 struct direct **d1, **d2;
2055 int i1, i2 = strlen (libname);
2056 char *e1 = (*d1)->d_name + i2;
2057 char *e2 = (*d2)->d_name + i2;
2059 while (*e1 && *e2 && *e1 == '.' && *e2 == '.'
2060 && e1[1] && isdigit (e1[1]) && e2[1] && isdigit (e2[1]))
2062 ++e1;
2063 ++e2;
2064 i1 = strtol (e1, &e1, 10);
2065 i2 = strtol (e2, &e2, 10);
2066 if (i1 != i2)
2067 return i1 - i2;
2070 if (*e1)
2072 /* It has a valid numeric extension, prefer this one. */
2073 if (*e1 == '.' && e1[1] && isdigit (e1[1]))
2074 return 1;
2075 /* It has a invalid numeric extension, must prefer the other one. */
2076 else
2077 return -1;
2079 else if (*e2)
2081 /* It has a valid numeric extension, prefer this one. */
2082 if (*e2 == '.' && e2[1] && isdigit (e2[1]))
2083 return -1;
2084 /* It has a invalid numeric extension, must prefer the other one. */
2085 else
2086 return 1;
2088 else
2089 return 0;
2092 /* Given the name NAME of a dynamic dependency, find its pathname and add
2093 it to the list of libraries. */
2095 static void
2096 locatelib (name)
2097 char *name;
2099 static char **l;
2100 static int cnt;
2101 char buf[MAXPATHLEN];
2102 char *p, *q;
2103 char **pp;
2105 if (l == 0)
2107 char *ld_rules;
2108 char *ldr = 0;
2109 /* counting elements in array, need 1 extra for null */
2110 cnt = 1;
2111 ld_rules = (char *) (ld_2->ld_rules + code);
2112 if (ld_rules)
2114 cnt++;
2115 for (; *ld_rules != 0; ld_rules++)
2116 if (*ld_rules == ':')
2117 cnt++;
2118 ld_rules = (char *) (ld_2->ld_rules + code);
2119 ldr = (char *) malloc (strlen (ld_rules) + 1);
2120 strcpy (ldr, ld_rules);
2122 p = getenv ("LD_LIBRARY_PATH");
2123 q = 0;
2124 if (p)
2126 cnt++;
2127 for (q = p ; *q != 0; q++)
2128 if (*q == ':')
2129 cnt++;
2130 q = (char *) malloc (strlen (p) + 1);
2131 strcpy (q, p);
2133 l = (char **) malloc ((cnt + 3) * sizeof (char *));
2134 pp = l;
2135 if (ldr)
2137 *pp++ = ldr;
2138 for (; *ldr != 0; ldr++)
2139 if (*ldr == ':')
2141 *ldr++ = 0;
2142 *pp++ = ldr;
2145 if (q)
2147 *pp++ = q;
2148 for (; *q != 0; q++)
2149 if (*q == ':')
2151 *q++ = 0;
2152 *pp++ = q;
2155 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2156 *pp++ = "/lib";
2157 *pp++ = "/usr/lib";
2158 *pp++ = "/usr/local/lib";
2159 *pp = 0;
2161 libname = name;
2162 for (pp = l; *pp != 0 ; pp++)
2164 struct direct **namelist;
2165 int entries;
2166 if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0)
2168 sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name);
2169 add_to_list (&libraries, buf);
2170 if (debug)
2171 fprintf (stderr, "%s\n", buf);
2172 break;
2175 if (*pp == 0)
2177 if (debug)
2178 fprintf (stderr, "not found\n");
2179 else
2180 fatal ("dynamic dependency %s not found", name);
2184 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2185 that it depends upon and any constructors or destructors they contain. */
2187 static void
2188 scan_libraries (prog_name)
2189 char *prog_name;
2191 struct exec *header;
2192 char *base;
2193 struct link_object *lo;
2194 char buff[MAXPATHLEN];
2195 struct id *list;
2197 mapfile (prog_name);
2198 header = (struct exec *)object;
2199 if (N_BADMAG (*header))
2200 fatal ("bad magic number in file '%s'", prog_name);
2201 if (header->a_dynamic == 0)
2202 return;
2204 code = (char *) (N_TXTOFF (*header) + (long) header);
2205 data = (char *) (N_DATOFF (*header) + (long) header);
2206 symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header);
2208 if (header->a_magic == ZMAGIC && header->a_entry == 0x20)
2210 /* shared object */
2211 ld = (struct link_dynamic *) (symtab->n_value + code);
2212 base = code;
2214 else
2216 /* executable */
2217 ld = (struct link_dynamic *) data;
2218 base = code-PAGSIZ;
2221 if (debug)
2222 fprintf (stderr, "dynamic dependencies.\n");
2224 ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);
2225 for (lo = (struct link_object *) ld_2->ld_need; lo;
2226 lo = (struct link_object *) lo->lo_next)
2228 char *name;
2229 lo = (struct link_object *) ((long) lo + code);
2230 name = (char *) (code + lo->lo_name);
2231 if (lo->lo_library)
2233 if (debug)
2234 fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major);
2235 sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor);
2236 locatelib (buff);
2238 else
2240 if (debug)
2241 fprintf (stderr, "\t%s\n", name);
2242 add_to_list (&libraries, name);
2246 if (debug)
2247 fprintf (stderr, "\n");
2249 /* now iterate through the library list adding their symbols to
2250 the list. */
2251 for (list = libraries.first; list; list = list->next)
2252 scan_prog_file (list->name, PASS_LIB);
2255 #else /* SUNOS4_SHARED_LIBRARIES */
2256 #ifdef LDD_SUFFIX
2258 /* Use the List Dynamic Dependencies program to find shared libraries that
2259 the output file depends upon and their initialization/finalization
2260 routines, if any. */
2262 static void
2263 scan_libraries (prog_name)
2264 char *prog_name;
2266 static struct head libraries; /* list of shared libraries found */
2267 struct id *list;
2268 void (*int_handler) ();
2269 void (*quit_handler) ();
2270 char *ldd_argv[4];
2271 int pid;
2272 int argc = 0;
2273 int pipe_fd[2];
2274 char buf[1024];
2275 FILE *inf;
2277 /* If we don't have an `ldd', complain. */
2278 if (ldd_file_name == 0)
2280 error ("cannot find `ldd'");
2281 return;
2284 ldd_argv[argc++] = ldd_file_name;
2285 ldd_argv[argc++] = prog_name;
2286 ldd_argv[argc++] = (char *) 0;
2288 if (pipe (pipe_fd) < 0)
2289 fatal_perror ("pipe");
2291 inf = fdopen (pipe_fd[0], "r");
2292 if (inf == (FILE *) 0)
2293 fatal_perror ("fdopen");
2295 /* Trace if needed. */
2296 if (vflag)
2298 char **p_argv;
2299 char *str;
2301 for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2302 fprintf (stderr, " %s", str);
2304 fprintf (stderr, "\n");
2307 fflush (stdout);
2308 fflush (stderr);
2310 /* Spawn child ldd on pipe */
2311 pid = vfork ();
2312 if (pid == -1)
2314 #ifdef vfork
2315 fatal_perror ("fork");
2316 #else
2317 fatal_perror ("vfork");
2318 #endif
2321 if (pid == 0) /* child context */
2323 /* setup stdout */
2324 if (dup2 (pipe_fd[1], 1) < 0)
2325 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
2327 if (close (pipe_fd[0]) < 0)
2328 fatal_perror ("close (%d)", pipe_fd[0]);
2330 if (close (pipe_fd[1]) < 0)
2331 fatal_perror ("close (%d)", pipe_fd[1]);
2333 execv (ldd_file_name, ldd_argv);
2334 fatal_perror ("executing %s", ldd_file_name);
2337 /* Parent context from here on. */
2338 int_handler = (void (*) ()) signal (SIGINT, SIG_IGN);
2339 #ifdef SIGQUIT
2340 quit_handler = (void (*) ()) signal (SIGQUIT, SIG_IGN);
2341 #endif
2343 if (close (pipe_fd[1]) < 0)
2344 fatal_perror ("close (%d)", pipe_fd[1]);
2346 if (debug)
2347 fprintf (stderr, "\nldd output with constructors/destructors.\n");
2349 /* Read each line of ldd output. */
2350 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2352 int ch, ch2;
2353 char *name, *end, *p = buf;
2355 /* Extract names of libraries and add to list. */
2356 PARSE_LDD_OUTPUT (p);
2357 if (p == 0)
2358 continue;
2360 name = p;
2361 if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
2362 fatal ("dynamic dependency %s not found", buf);
2364 /* Find the end of the symbol name. */
2365 for (end = p;
2366 (ch2 = *end) != '\0' && ch2 != '\n' && !isspace (ch2) && ch2 != '|';
2367 end++)
2368 continue;
2369 *end = '\0';
2371 if (access (name, R_OK) == 0)
2372 add_to_list (&libraries, name);
2373 else
2374 fatal ("unable to open dynamic dependency '%s'", buf);
2376 if (debug)
2377 fprintf (stderr, "\t%s\n", buf);
2379 if (debug)
2380 fprintf (stderr, "\n");
2382 if (fclose (inf) != 0)
2383 fatal_perror ("fclose of pipe");
2385 do_wait (ldd_file_name);
2387 signal (SIGINT, int_handler);
2388 #ifdef SIGQUIT
2389 signal (SIGQUIT, quit_handler);
2390 #endif
2392 /* now iterate through the library list adding their symbols to
2393 the list. */
2394 for (list = libraries.first; list; list = list->next)
2395 scan_prog_file (list->name, PASS_LIB);
2398 #endif /* LDD_SUFFIX */
2399 #endif /* SUNOS4_SHARED_LIBRARIES */
2401 #endif /* OBJECT_FORMAT_NONE */
2405 * COFF specific stuff.
2408 #ifdef OBJECT_FORMAT_COFF
2410 #if defined(EXTENDED_COFF)
2411 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2412 # define GCC_SYMENT SYMR
2413 # define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
2414 # define GCC_SYMINC(X) (1)
2415 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2416 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2417 #else
2418 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2419 # define GCC_SYMENT SYMENT
2420 # define GCC_OK_SYMBOL(X) \
2421 (((X).n_sclass == C_EXT) && \
2422 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
2423 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
2424 # define GCC_SYMINC(X) ((X).n_numaux+1)
2425 # define GCC_SYMZERO(X) 0
2426 # define GCC_CHECK_HDR(X) (1)
2427 #endif
2429 extern char *ldgetname ();
2431 /* COFF version to scan the name list of the loaded program for
2432 the symbols g++ uses for static constructors and destructors.
2434 The constructor table begins at __CTOR_LIST__ and contains a count
2435 of the number of pointers (or -1 if the constructors are built in a
2436 separate section by the linker), followed by the pointers to the
2437 constructor functions, terminated with a null pointer. The
2438 destructor table has the same format, and begins at __DTOR_LIST__. */
2440 static void
2441 scan_prog_file (prog_name, which_pass)
2442 char *prog_name;
2443 enum pass which_pass;
2445 LDFILE *ldptr = NULL;
2446 int sym_index, sym_count;
2448 if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2449 return;
2451 if ((ldptr = ldopen (prog_name, ldptr)) == NULL)
2452 fatal ("%s: can't open as COFF file", prog_name);
2454 if (!MY_ISCOFF (HEADER (ldptr).f_magic))
2455 fatal ("%s: not a COFF file", prog_name);
2457 if (GCC_CHECK_HDR (ldptr))
2459 sym_count = GCC_SYMBOLS (ldptr);
2460 sym_index = GCC_SYMZERO (ldptr);
2461 while (sym_index < sym_count)
2463 GCC_SYMENT symbol;
2465 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2466 break;
2467 sym_index += GCC_SYMINC (symbol);
2469 if (GCC_OK_SYMBOL (symbol))
2471 char *name;
2473 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2474 continue; /* should never happen */
2476 #ifdef XCOFF_DEBUGGING_INFO
2477 /* All AIX function names have a duplicate entry beginning
2478 with a dot. */
2479 if (*name == '.')
2480 ++name;
2481 #endif
2483 switch (is_ctor_dtor (name))
2485 case 1:
2486 add_to_list (&constructors, name);
2487 if (which_pass == PASS_OBJ)
2488 add_to_list (&exports, name);
2489 break;
2491 case 2:
2492 add_to_list (&destructors, name);
2493 if (which_pass == PASS_OBJ)
2494 add_to_list (&exports, name);
2495 break;
2497 default: /* not a constructor or destructor */
2498 continue;
2501 #if !defined(EXTENDED_COFF)
2502 if (debug)
2503 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
2504 symbol.n_scnum, symbol.n_sclass,
2505 (symbol.n_type ? "0" : ""), symbol.n_type,
2506 name);
2507 #else
2508 if (debug)
2509 fprintf (stderr, "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
2510 symbol.iss, symbol.value, symbol.index, name);
2511 #endif
2516 (void) ldclose(ldptr);
2519 #ifdef XCOFF_SCAN_LIBS
2520 /* Scan imported AIX libraries for GCC static ctors and dtors.
2521 FIXME: it is possible to link an executable without the actual import
2522 library by using an "import file" - a text file listing symbols
2523 exported by a library. To support this, we would have to scan
2524 import files as well as actual shared binaries to find GCC ctors.
2525 TODO: use memory mapping instead of 'ld' routines, files are already
2526 memory mapped, but we could eliminate the extra in-memory copies.
2527 Is it worth the effort? */
2529 static void
2530 scan_libraries (prog_name)
2531 char *prog_name;
2533 LDFILE *ldptr;
2534 SCNHDR ldsh;
2535 static struct path_prefix libpath; /* we should only do this once */
2537 if ((ldptr = ldopen (prog_name, ldptr)) == NULL)
2538 fatal ("%s: can't open as COFF file", prog_name);
2540 if (!MY_ISCOFF (HEADER (ldptr).f_magic))
2541 fatal ("%s: not a COFF file", prog_name);
2543 /* find and read loader section */
2544 if (ldnshread (ldptr, _LOADER, &ldsh))
2546 LDHDR ldh;
2547 char *impbuf;
2548 int entry;
2550 FSEEK (ldptr, ldsh.s_scnptr, BEGINNING);
2551 FREAD (&ldh, sizeof (ldh), 1, ldptr);
2552 /* read import library list */
2553 impbuf = alloca (ldh.l_istlen);
2554 FSEEK (ldptr, ldh.l_impoff + ldsh.s_scnptr, BEGINNING);
2555 FREAD (impbuf, ldh.l_istlen, 1, ldptr);
2557 if (debug)
2558 fprintf (stderr, "LIBPATH=%s\n", impbuf);
2559 prefix_from_string (impbuf, &libpath);
2561 /* skip LIBPATH and empty base and member fields */
2562 impbuf += strlen (impbuf) + 3;
2563 for (entry = 1; entry < ldh.l_nimpid; ++entry)
2565 char *impath = impbuf;
2566 char *implib = impath + strlen (impath) + 1;
2567 char *impmem = implib + strlen (implib) + 1;
2568 char *soname = NULL;
2569 char *trial;
2570 int pathlen;
2571 LDFILE *libptr = NULL;
2572 struct prefix_list *pl;
2573 ARCHDR ah;
2575 impbuf = impmem + strlen (impmem) + 1;
2576 if (debug)
2577 fprintf (stderr, "PATH+BASE=%s%s\n", impath, implib);
2578 /* Skip AIX kernel exports */
2579 if (*impath == '/' && *(impath+1) == '\0'
2580 && strcmp (implib, "unix") == 0)
2581 continue;
2582 pathlen = strlen (impath);
2583 trial = alloca (MAX (pathlen + 1, libpath.max_len)
2584 + strlen (implib) + 1);
2585 if (*impath)
2587 strcpy (trial, impath);
2588 if (impath[pathlen - 1] != '/')
2589 trial[pathlen++] = '/';
2590 strcpy (trial + pathlen, implib);
2591 if (access (trial, R_OK) == 0)
2592 soname = trial;
2594 else
2595 for (pl = libpath.plist; pl; pl = pl->next)
2597 strcpy (trial, pl->prefix);
2598 strcat (trial, implib);
2599 if (access (trial, R_OK) == 0)
2601 soname = trial;
2602 break;
2606 if (! soname)
2607 fatal ("%s: library not found", implib);
2608 if (debug)
2609 if (*impmem)
2610 fprintf (stderr, "%s (%s)\n", soname, impmem);
2611 else
2612 fprintf (stderr, "%s\n", soname);
2616 /* scan imported shared objects for GCC GLOBAL ctors */
2617 short type;
2618 if ((libptr = ldopen (soname, libptr)) == NULL)
2619 fatal ("%s: can't open import library", soname);
2620 if (TYPE (libptr) == ARTYPE)
2622 LDFILE *memptr;
2623 if (! *impmem)
2624 fatal ("%s: no archive member specified", soname);
2625 ldahread (libptr, &ah);
2626 if (strcmp (ah.ar_name, impmem))
2627 continue;
2629 type = HEADER (libptr).f_magic;
2630 if (HEADER (libptr).f_flags & F_SHROBJ)
2632 SCNHDR soldsh;
2633 LDHDR soldh;
2634 long symcnt, i;
2635 char *ldstrings;
2636 LDSYM *lsyms;
2637 if (!ldnshread (libptr, _LOADER, &soldsh))
2638 fatal ("%s: not an import library", soname);
2639 FSEEK (libptr, soldsh.s_scnptr, BEGINNING);
2640 if (FREAD (&soldh, sizeof (soldh), 1, libptr) != 1)
2641 fatal ("%s: can't read loader section", soname);
2642 /*fprintf (stderr, "\tscanning %s\n", soname);*/
2643 symcnt = soldh.l_nsyms;
2644 lsyms = (LDSYM *) alloca (symcnt * sizeof (*lsyms));
2645 symcnt = FREAD (lsyms, sizeof (*lsyms), symcnt, libptr);
2646 ldstrings = alloca (soldh.l_stlen);
2647 FSEEK (libptr, soldsh.s_scnptr+soldh.l_stoff, BEGINNING);
2648 FREAD (ldstrings, soldh.l_stlen, 1, libptr);
2649 for (i = 0; i < symcnt; ++i)
2651 LDSYM *l = lsyms + i;
2652 if (LDR_EXPORT (*l))
2654 char *expname = 0;
2655 if (l->l_zeroes)
2656 expname = l->l_name;
2657 else if (l->l_offset < soldh.l_stlen)
2658 expname = ldstrings + l->l_offset;
2659 switch (is_ctor_dtor (expname))
2661 case 3:
2662 if (debug)
2663 fprintf (stderr, "\t%s\n", expname);
2664 add_to_list (&constructors, expname);
2665 break;
2667 case 4:
2668 add_to_list (&destructors, expname);
2669 break;
2671 default: /* not a constructor or destructor */
2672 continue;
2677 else
2678 fprintf (stderr, "%s: type = %04X flags = %04X\n",
2679 ah.ar_name, type, HEADER (libptr).f_flags);
2681 while (ldclose (libptr) == FAILURE);
2682 /* printf (stderr, "closed %s\n", soname); */
2686 #endif /* XCOFF_SCAN_LIBS */
2688 #endif /* OBJECT_FORMAT_COFF */
2692 * OSF/rose specific stuff.
2695 #ifdef OBJECT_FORMAT_ROSE
2697 /* Union of the various load commands */
2699 typedef union load_union
2701 ldc_header_t hdr; /* common header */
2702 load_cmd_map_command_t map; /* map indexing other load cmds */
2703 interpreter_command_t iprtr; /* interpreter pathname */
2704 strings_command_t str; /* load commands strings section */
2705 region_command_t region; /* region load command */
2706 reloc_command_t reloc; /* relocation section */
2707 package_command_t pkg; /* package load command */
2708 symbols_command_t sym; /* symbol sections */
2709 entry_command_t ent; /* program start section */
2710 gen_info_command_t info; /* object information */
2711 func_table_command_t func; /* function constructors/destructors */
2712 } load_union_t;
2714 /* Structure to point to load command and data section in memory. */
2716 typedef struct load_all
2718 load_union_t *load; /* load command */
2719 char *section; /* pointer to section */
2720 } load_all_t;
2722 /* Structure to contain information about a file mapped into memory. */
2724 struct file_info
2726 char *start; /* start of map */
2727 char *name; /* filename */
2728 long size; /* size of the file */
2729 long rounded_size; /* size rounded to page boundary */
2730 int fd; /* file descriptor */
2731 int rw; /* != 0 if opened read/write */
2732 int use_mmap; /* != 0 if mmap'ed */
2735 extern int decode_mach_o_hdr ();
2736 extern int encode_mach_o_hdr ();
2738 static void add_func_table PROTO((mo_header_t *, load_all_t *,
2739 symbol_info_t *, int));
2740 static void print_header PROTO((mo_header_t *));
2741 static void print_load_command PROTO((load_union_t *, size_t, int));
2742 static void bad_header PROTO((int));
2743 static struct file_info *read_file PROTO((char *, int, int));
2744 static void end_file PROTO((struct file_info *));
2746 /* OSF/rose specific version to scan the name list of the loaded
2747 program for the symbols g++ uses for static constructors and
2748 destructors.
2750 The constructor table begins at __CTOR_LIST__ and contains a count
2751 of the number of pointers (or -1 if the constructors are built in a
2752 separate section by the linker), followed by the pointers to the
2753 constructor functions, terminated with a null pointer. The
2754 destructor table has the same format, and begins at __DTOR_LIST__. */
2756 static void
2757 scan_prog_file (prog_name, which_pass)
2758 char *prog_name;
2759 enum pass which_pass;
2761 char *obj;
2762 mo_header_t hdr;
2763 load_all_t *load_array;
2764 load_all_t *load_end;
2765 load_all_t *load_cmd;
2766 int symbol_load_cmds;
2767 off_t offset;
2768 int i;
2769 int num_syms;
2770 int status;
2771 char *str_sect;
2772 struct file_info *obj_file;
2773 int prog_fd;
2774 mo_lcid_t cmd_strings = -1;
2775 symbol_info_t *main_sym = 0;
2776 int rw = (which_pass != PASS_FIRST);
2778 prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
2779 if (prog_fd < 0)
2780 fatal_perror ("can't read %s", prog_name);
2782 obj_file = read_file (prog_name, prog_fd, rw);
2783 obj = obj_file->start;
2785 status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);
2786 if (status != MO_HDR_CONV_SUCCESS)
2787 bad_header (status);
2790 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
2791 since the hardware will automatically swap bytes for us on loading little endian
2792 integers. */
2794 #ifndef CROSS_COMPILE
2795 if (hdr.moh_magic != MOH_MAGIC_MSB
2796 || hdr.moh_header_version != MOH_HEADER_VERSION
2797 || hdr.moh_byte_order != OUR_BYTE_ORDER
2798 || hdr.moh_data_rep_id != OUR_DATA_REP_ID
2799 || hdr.moh_cpu_type != OUR_CPU_TYPE
2800 || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE
2801 || hdr.moh_vendor_type != OUR_VENDOR_TYPE)
2803 fatal ("incompatibilities between object file & expected values");
2805 #endif
2807 if (debug)
2808 print_header (&hdr);
2810 offset = hdr.moh_first_cmd_off;
2811 load_end = load_array
2812 = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);
2814 /* Build array of load commands, calculating the offsets */
2815 for (i = 0; i < hdr.moh_n_load_cmds; i++)
2817 load_union_t *load_hdr; /* load command header */
2819 load_cmd = load_end++;
2820 load_hdr = (load_union_t *) (obj + offset);
2822 /* If modifying the program file, copy the header. */
2823 if (rw)
2825 load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
2826 bcopy ((char *)load_hdr, (char *)ptr, load_hdr->hdr.ldci_cmd_size);
2827 load_hdr = ptr;
2829 /* null out old command map, because we will rewrite at the end. */
2830 if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
2832 cmd_strings = ptr->map.lcm_ld_cmd_strings;
2833 ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
2837 load_cmd->load = load_hdr;
2838 if (load_hdr->hdr.ldci_section_off > 0)
2839 load_cmd->section = obj + load_hdr->hdr.ldci_section_off;
2841 if (debug)
2842 print_load_command (load_hdr, offset, i);
2844 offset += load_hdr->hdr.ldci_cmd_size;
2847 /* If the last command is the load command map and is not undefined,
2848 decrement the count of load commands. */
2849 if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)
2851 load_end--;
2852 hdr.moh_n_load_cmds--;
2855 /* Go through and process each symbol table section. */
2856 symbol_load_cmds = 0;
2857 for (load_cmd = load_array; load_cmd < load_end; load_cmd++)
2859 load_union_t *load_hdr = load_cmd->load;
2861 if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
2863 symbol_load_cmds++;
2865 if (debug)
2867 char *kind = "unknown";
2869 switch (load_hdr->sym.symc_kind)
2871 case SYMC_IMPORTS: kind = "imports"; break;
2872 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
2873 case SYMC_STABS: kind = "stabs"; break;
2876 fprintf (stderr, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
2877 symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
2880 if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
2881 continue;
2883 str_sect = load_array[load_hdr->sym.symc_strings_section].section;
2884 if (str_sect == (char *) 0)
2885 fatal ("string section missing");
2887 if (load_cmd->section == (char *) 0)
2888 fatal ("section pointer missing");
2890 num_syms = load_hdr->sym.symc_nentries;
2891 for (i = 0; i < num_syms; i++)
2893 symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
2894 char *name = sym->si_name.symbol_name + str_sect;
2896 if (name[0] != '_')
2897 continue;
2899 if (rw)
2901 char *n = name + strlen (name) - strlen (NAME__MAIN);
2903 if ((n - name) < 0 || strcmp (n, NAME__MAIN))
2904 continue;
2905 while (n != name)
2906 if (*--n != '_')
2907 continue;
2909 main_sym = sym;
2911 else
2913 switch (is_ctor_dtor (name))
2915 case 1:
2916 add_to_list (&constructors, name);
2917 break;
2919 case 2:
2920 add_to_list (&destructors, name);
2921 break;
2923 default: /* not a constructor or destructor */
2924 continue;
2928 if (debug)
2929 fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
2930 sym->si_type, sym->si_sc_type, sym->si_flags, name);
2935 if (symbol_load_cmds == 0)
2936 fatal ("no symbol table found");
2938 /* Update the program file now, rewrite header and load commands. At present,
2939 we assume that there is enough space after the last load command to insert
2940 one more. Since the first section written out is page aligned, and the
2941 number of load commands is small, this is ok for the present. */
2943 if (rw)
2945 load_union_t *load_map;
2946 size_t size;
2948 if (cmd_strings == -1)
2949 fatal ("no cmd_strings found");
2951 /* Add __main to initializer list.
2952 If we are building a program instead of a shared library, don't
2953 do anything, since in the current version, you cannot do mallocs
2954 and such in the constructors. */
2956 if (main_sym != (symbol_info_t *) 0
2957 && ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
2958 add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
2960 if (debug)
2961 fprintf (stderr, "\nUpdating header and load commands.\n\n");
2963 hdr.moh_n_load_cmds++;
2964 size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
2966 /* Create new load command map. */
2967 if (debug)
2968 fprintf (stderr, "load command map, %d cmds, new size %ld.\n",
2969 (int)hdr.moh_n_load_cmds, (long)size);
2971 load_map = (load_union_t *) xcalloc (1, size);
2972 load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
2973 load_map->map.ldc_header.ldci_cmd_size = size;
2974 load_map->map.lcm_ld_cmd_strings = cmd_strings;
2975 load_map->map.lcm_nentries = hdr.moh_n_load_cmds;
2976 load_array[hdr.moh_n_load_cmds-1].load = load_map;
2978 offset = hdr.moh_first_cmd_off;
2979 for (i = 0; i < hdr.moh_n_load_cmds; i++)
2981 load_map->map.lcm_map[i] = offset;
2982 if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)
2983 hdr.moh_load_map_cmd_off = offset;
2985 offset += load_array[i].load->hdr.ldci_cmd_size;
2988 hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
2990 if (debug)
2991 print_header (&hdr);
2993 /* Write header */
2994 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
2995 if (status != MO_HDR_CONV_SUCCESS)
2996 bad_header (status);
2998 if (debug)
2999 fprintf (stderr, "writing load commands.\n\n");
3001 /* Write load commands */
3002 offset = hdr.moh_first_cmd_off;
3003 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3005 load_union_t *load_hdr = load_array[i].load;
3006 size_t size = load_hdr->hdr.ldci_cmd_size;
3008 if (debug)
3009 print_load_command (load_hdr, offset, i);
3011 bcopy ((char *) load_hdr, (char *) (obj + offset), size);
3012 offset += size;
3016 end_file (obj_file);
3018 if (close (prog_fd))
3019 fatal_perror ("closing %s", prog_name);
3021 if (debug)
3022 fprintf (stderr, "\n");
3026 /* Add a function table to the load commands to call a function
3027 on initiation or termination of the process. */
3029 static void
3030 add_func_table (hdr_p, load_array, sym, type)
3031 mo_header_t *hdr_p; /* pointer to global header */
3032 load_all_t *load_array; /* array of ptrs to load cmds */
3033 symbol_info_t *sym; /* pointer to symbol entry */
3034 int type; /* fntc_type value */
3036 /* Add a new load command. */
3037 int num_cmds = ++hdr_p->moh_n_load_cmds;
3038 int load_index = num_cmds - 1;
3039 size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);
3040 load_union_t *ptr = xcalloc (1, size);
3041 load_all_t *load_cmd;
3042 int i;
3044 /* Set the unresolved address bit in the header to force the loader to be
3045 used, since kernel exec does not call the initialization functions. */
3046 hdr_p->moh_flags |= MOH_UNRESOLVED_F;
3048 load_cmd = &load_array[load_index];
3049 load_cmd->load = ptr;
3050 load_cmd->section = (char *) 0;
3052 /* Fill in func table load command. */
3053 ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
3054 ptr->func.ldc_header.ldci_cmd_size = size;
3055 ptr->func.ldc_header.ldci_section_off = 0;
3056 ptr->func.ldc_header.ldci_section_len = 0;
3057 ptr->func.fntc_type = type;
3058 ptr->func.fntc_nentries = 1;
3060 /* copy address, turn it from abs. address to (region,offset) if necessary. */
3061 /* Is the symbol already expressed as (region, offset)? */
3062 if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)
3064 ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;
3065 ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;
3068 /* If not, figure out which region it's in. */
3069 else
3071 mo_vm_addr_t addr = sym->si_value.abs_val;
3072 int found = 0;
3074 for (i = 0; i < load_index; i++)
3076 if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
3078 region_command_t *region_ptr = &load_array[i].load->region;
3080 if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0
3081 && addr >= region_ptr->regc_addr.vm_addr
3082 && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)
3084 ptr->func.fntc_entry_loc[0].adr_lcid = i;
3085 ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;
3086 found++;
3087 break;
3092 if (!found)
3093 fatal ("could not convert 0x%l.8x into a region", addr);
3096 if (debug)
3097 fprintf (stderr,
3098 "%s function, region %d, offset = %ld (0x%.8lx)\n",
3099 (type == FNTC_INITIALIZATION) ? "init" : "term",
3100 (int)ptr->func.fntc_entry_loc[i].adr_lcid,
3101 (long)ptr->func.fntc_entry_loc[i].adr_sctoff,
3102 (long)ptr->func.fntc_entry_loc[i].adr_sctoff);
3107 /* Print the global header for an OSF/rose object. */
3109 static void
3110 print_header (hdr_ptr)
3111 mo_header_t *hdr_ptr;
3113 fprintf (stderr, "\nglobal header:\n");
3114 fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic);
3115 fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version);
3116 fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version);
3117 fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version);
3118 fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size);
3119 fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order);
3120 fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id);
3121 fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type);
3122 fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype);
3123 fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type);
3124 fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);
3125 fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off);
3126 fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds);
3127 fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds);
3128 fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags);
3130 if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
3131 fprintf (stderr, ", relocatable");
3133 if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
3134 fprintf (stderr, ", linkable");
3136 if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
3137 fprintf (stderr, ", execable");
3139 if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
3140 fprintf (stderr, ", executable");
3142 if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
3143 fprintf (stderr, ", unresolved");
3145 fprintf (stderr, "\n\n");
3146 return;
3150 /* Print a short summary of a load command. */
3152 static void
3153 print_load_command (load_hdr, offset, number)
3154 load_union_t *load_hdr;
3155 size_t offset;
3156 int number;
3158 mo_long_t type = load_hdr->hdr.ldci_cmd_type;
3159 char *type_str = (char *) 0;
3161 switch (type)
3163 case LDC_UNDEFINED: type_str = "UNDEFINED"; break;
3164 case LDC_CMD_MAP: type_str = "CMD_MAP"; break;
3165 case LDC_INTERPRETER: type_str = "INTERPRETER"; break;
3166 case LDC_STRINGS: type_str = "STRINGS"; break;
3167 case LDC_REGION: type_str = "REGION"; break;
3168 case LDC_RELOC: type_str = "RELOC"; break;
3169 case LDC_PACKAGE: type_str = "PACKAGE"; break;
3170 case LDC_SYMBOLS: type_str = "SYMBOLS"; break;
3171 case LDC_ENTRY: type_str = "ENTRY"; break;
3172 case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break;
3173 case LDC_GEN_INFO: type_str = "GEN_INFO"; break;
3176 fprintf (stderr,
3177 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3178 number,
3179 (long) load_hdr->hdr.ldci_cmd_size,
3180 (long) offset,
3181 (long) load_hdr->hdr.ldci_section_off,
3182 (long) load_hdr->hdr.ldci_section_len);
3184 if (type_str == (char *) 0)
3185 fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
3187 else if (type != LDC_REGION)
3188 fprintf (stderr, ", ty: %s\n", type_str);
3190 else
3192 char *region = "";
3193 switch (load_hdr->region.regc_usage_type)
3195 case REG_TEXT_T: region = ", .text"; break;
3196 case REG_DATA_T: region = ", .data"; break;
3197 case REG_BSS_T: region = ", .bss"; break;
3198 case REG_GLUE_T: region = ", .glue"; break;
3199 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3200 case REG_RDATA_T: region = ", .rdata"; break;
3201 case REG_SDATA_T: region = ", .sdata"; break;
3202 case REG_SBSS_T: region = ", .sbss"; break;
3203 #endif
3206 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3207 type_str,
3208 (long) load_hdr->region.regc_vm_addr,
3209 (long) load_hdr->region.regc_vm_size,
3210 region);
3213 return;
3217 /* Fatal error when {en,de}code_mach_o_header fails. */
3219 static void
3220 bad_header (status)
3221 int status;
3223 char *msg = (char *) 0;
3225 switch (status)
3227 case MO_ERROR_BAD_MAGIC: msg = "bad magic number"; break;
3228 case MO_ERROR_BAD_HDR_VERS: msg = "bad header version"; break;
3229 case MO_ERROR_BAD_RAW_HDR_VERS: msg = "bad raw header version"; break;
3230 case MO_ERROR_BUF2SML: msg = "raw header buffer too small"; break;
3231 case MO_ERROR_OLD_RAW_HDR_FILE: msg = "old raw header file"; break;
3232 case MO_ERROR_UNSUPPORTED_VERS: msg = "unsupported version"; break;
3235 if (msg == (char *) 0)
3236 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
3237 else
3238 fatal ("%s", msg);
3242 /* Read a file into a memory buffer. */
3244 static struct file_info *
3245 read_file (name, fd, rw)
3246 char *name; /* filename */
3247 int fd; /* file descriptor */
3248 int rw; /* read/write */
3250 struct stat stat_pkt;
3251 struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
3252 #ifdef USE_MMAP
3253 static int page_size;
3254 #endif
3256 if (fstat (fd, &stat_pkt) < 0)
3257 fatal_perror ("fstat %s", name);
3259 p->name = name;
3260 p->size = stat_pkt.st_size;
3261 p->rounded_size = stat_pkt.st_size;
3262 p->fd = fd;
3263 p->rw = rw;
3265 #ifdef USE_MMAP
3266 if (debug)
3267 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
3269 if (page_size == 0)
3270 page_size = sysconf (_SC_PAGE_SIZE);
3272 p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
3273 p->start = mmap ((caddr_t) 0,
3274 (rw) ? p->rounded_size : p->size,
3275 (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
3276 MAP_FILE | MAP_VARIABLE | MAP_SHARED,
3278 0L);
3280 if (p->start != (char *) 0 && p->start != (char *) -1)
3281 p->use_mmap = 1;
3283 else
3284 #endif /* USE_MMAP */
3286 long len;
3288 if (debug)
3289 fprintf (stderr, "read %s\n", name);
3291 p->use_mmap = 0;
3292 p->start = xmalloc (p->size);
3293 if (lseek (fd, 0L, SEEK_SET) < 0)
3294 fatal_perror ("lseek to 0 on %s", name);
3296 len = read (fd, p->start, p->size);
3297 if (len < 0)
3298 fatal_perror ("read %s", name);
3300 if (len != p->size)
3301 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
3304 return p;
3307 /* Do anything necessary to write a file back from memory. */
3309 static void
3310 end_file (ptr)
3311 struct file_info *ptr; /* file information block */
3313 #ifdef USE_MMAP
3314 if (ptr->use_mmap)
3316 if (ptr->rw)
3318 if (debug)
3319 fprintf (stderr, "msync %s\n", ptr->name);
3321 if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
3322 fatal_perror ("msync %s", ptr->name);
3325 if (debug)
3326 fprintf (stderr, "munmap %s\n", ptr->name);
3328 if (munmap (ptr->start, ptr->size))
3329 fatal_perror ("munmap %s", ptr->name);
3331 else
3332 #endif /* USE_MMAP */
3334 if (ptr->rw)
3336 long len;
3338 if (debug)
3339 fprintf (stderr, "write %s\n", ptr->name);
3341 if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
3342 fatal_perror ("lseek to 0 on %s", ptr->name);
3344 len = write (ptr->fd, ptr->start, ptr->size);
3345 if (len < 0)
3346 fatal_perror ("write %s", ptr->name);
3348 if (len != ptr->size)
3349 fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
3352 free (ptr->start);
3355 free (ptr);
3358 #endif /* OBJECT_FORMAT_ROSE */