1 /* Collect static initialization info into data structures
2 that can be traversed by C++ initialization and finalization
5 Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
6 Contributed by Chris Smith (csmith@convex.com).
7 Heavily modified by Michael Meissner (meissner@osf.org),
8 Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
10 This file is part of GNU CC.
12 GNU CC is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2, or (at your option)
17 GNU CC is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with GNU CC; see the file COPYING. If not, write to
24 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
27 /* Build tables of static constructors and destructors and run ld. */
29 #include <sys/types.h>
44 #if defined(bsd4_4) || defined(__NetBSD__)
45 extern const char *const sys_errlist
[];
47 extern char *sys_errlist
[];
67 /* Add prototype support. */
69 #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
70 #define PROTO(ARGS) ARGS
72 #define PROTO(ARGS) ()
82 /* On MSDOS, write temp files in current dir
83 because there's no place else we can expect to use. */
90 /* On certain systems, we have code that works by scanning the object file
91 directly. But this code uses system-specific header files and library
92 functions, so turn it off in a cross-compiler. Likewise, the names of
93 the utilities aren't correct for a cross-compiler; we have to hope that
94 cross-versions are in the proper directories. */
97 #undef OBJECT_FORMAT_COFF
98 #undef OBJECT_FORMAT_ROSE
100 #undef REAL_LD_FILE_NAME
101 #undef REAL_NM_FILE_NAME
102 #undef REAL_STRIP_FILE_NAME
105 /* If we can't use a special method, use the ordinary one:
106 run nm to find what symbols are present.
107 In a cross-compiler, this means you need a cross nm,
108 but that isn't quite as unpleasant as special headers. */
110 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
111 #define OBJECT_FORMAT_NONE
114 #ifdef OBJECT_FORMAT_COFF
123 /* Many versions of ldfcn.h define these. */
131 /* Some systems have an ISCOFF macro, but others do not. In some cases
132 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
133 that either do not have an ISCOFF macro in /usr/include or for those
134 where it is wrong. */
137 #define MY_ISCOFF(X) ISCOFF (X)
140 #endif /* OBJECT_FORMAT_COFF */
142 #ifdef OBJECT_FORMAT_ROSE
149 #include <sys/mman.h>
153 #include <mach_o_format.h>
154 #include <mach_o_header.h>
155 #include <mach_o_vals.h>
156 #include <mach_o_types.h>
158 #endif /* OBJECT_FORMAT_ROSE */
160 #ifdef OBJECT_FORMAT_NONE
162 /* Default flags to pass to nm. */
164 #define NM_FLAGS "-p"
167 #endif /* OBJECT_FORMAT_NONE */
169 /* Some systems use __main in a way incompatible with its use in gcc, in these
170 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
171 give the same symbol without quotes for an alternative entry point. You
172 must define both, or niether. */
174 #define NAME__MAIN "__main"
175 #define SYMBOL__MAIN __main
179 /* Linked lists of constructor and destructor names. */
195 /* Enumeration giving which pass this is for scanning the program file. */
198 PASS_FIRST
, /* without constructors */
199 PASS_SECOND
/* with constructors linked in */
202 #ifndef NO_SYS_SIGLIST
203 #ifndef DONT_DECLARE_SYS_SIGLIST
204 extern char *sys_siglist
[];
207 extern char *version_string
;
209 static int vflag
; /* true if -v */
210 static int rflag
; /* true if -r */
211 static int strip_flag
; /* true if -s */
213 static int debug
; /* true if -debug */
215 static int temp_filename_length
; /* Length of temp_filename */
216 static char *temp_filename
; /* Base of temp filenames */
217 static char *c_file
; /* <xxx>.c for constructor/destructor list. */
218 static char *o_file
; /* <xxx>.o for constructor/destructor list. */
219 static char *output_file
; /* Output file for ld. */
220 static char *nm_file_name
; /* pathname of nm */
221 static char *strip_file_name
; /* pathname of strip */
223 static struct head constructors
; /* list of constructors found */
224 static struct head destructors
; /* list of destructors found */
226 extern char *getenv ();
227 extern char *mktemp ();
228 extern FILE *fdopen ();
230 /* Structure to hold all the directories in which to search for files to
235 char *prefix
; /* String to prepend to the path. */
236 struct prefix_list
*next
; /* Next in linked list. */
241 struct prefix_list
*plist
; /* List of prefixes to try */
242 int max_len
; /* Max length of a prefix in PLIST */
243 char *name
; /* Name of this list (used in config stuff) */
246 static void my_exit
PROTO((int));
247 static void handler
PROTO((int));
248 static int is_ctor_dtor
PROTO((char *));
249 static void choose_temp_base
PROTO((void));
250 static int is_in_prefix_list
PROTO((struct path_prefix
*, char *, int));
251 static char *find_a_file
PROTO((struct path_prefix
*, char *));
252 static void add_prefix
PROTO((struct path_prefix
*, char *));
253 static void prefix_from_env
PROTO((char *, struct path_prefix
*));
254 static void do_wait
PROTO((char *));
255 static void fork_execute
PROTO((char *, char **));
256 static void maybe_unlink
PROTO((char *));
257 static void add_to_list
PROTO((struct head
*, char *));
258 static void write_list
PROTO((FILE *, char *, struct id
*));
259 static void write_list_with_asm
PROTO((FILE *, char *, struct id
*));
260 static void write_c_file
PROTO((FILE *, char *));
261 static void scan_prog_file
PROTO((char *, enum pass
));
266 extern char *index ();
267 extern char *rindex ();
282 while ((fd
= dup (oldfd
)) != newfd
&& fd
>= 0) /* good enough for low fd's */
285 close (fdtmp
[--fdx
]);
295 static char buffer
[30];
300 if (e
> 0 && e
< sys_nerr
)
301 return sys_errlist
[e
];
303 sprintf (buffer
, "Unknown error %d", e
);
307 /* Delete tempfiles and exit function. */
313 if (c_file
!= 0 && c_file
[0])
314 maybe_unlink (c_file
);
316 if (o_file
!= 0 && o_file
[0])
317 maybe_unlink (o_file
);
319 if (status
!= 0 && output_file
!= 0 && output_file
[0])
320 maybe_unlink (output_file
);
326 /* Die when sys call fails. */
329 fatal_perror (string
, arg1
, arg2
, arg3
)
330 char *string
, *arg1
, *arg2
, *arg3
;
334 fprintf (stderr
, "collect2: ");
335 fprintf (stderr
, string
, arg1
, arg2
, arg3
);
336 fprintf (stderr
, ": %s\n", my_strerror (e
));
343 fatal (string
, arg1
, arg2
, arg3
)
344 char *string
, *arg1
, *arg2
, *arg3
;
346 fprintf (stderr
, "collect2: ");
347 fprintf (stderr
, string
, arg1
, arg2
, arg3
);
348 fprintf (stderr
, "\n");
352 /* Write error message. */
355 error (string
, arg1
, arg2
, arg3
, arg4
)
356 char *string
, *arg1
, *arg2
, *arg3
, *arg4
;
358 fprintf (stderr
, "collect2: ");
359 fprintf (stderr
, string
, arg1
, arg2
, arg3
, arg4
);
360 fprintf (stderr
, "\n");
363 /* In case obstack is linked in, and abort is defined to fancy_abort,
364 provide a default entry. */
369 fatal ("internal error");
377 if (c_file
!= 0 && c_file
[0])
378 maybe_unlink (c_file
);
380 if (o_file
!= 0 && o_file
[0])
381 maybe_unlink (o_file
);
383 signal (signo
, SIG_DFL
);
384 kill (getpid (), signo
);
389 xcalloc (size1
, size2
)
392 generic
*ptr
= (generic
*) calloc (size1
, size2
);
396 fatal ("out of memory");
404 generic
*ptr
= (generic
*) malloc (size
);
408 fatal ("out of memory");
412 /* Make a copy of a string INPUT with size SIZE. */
415 savestring (input
, size
)
419 char *output
= (char *) xmalloc (size
+ 1);
420 bcopy (input
, output
, size
);
425 /* Decide whether the given symbol is:
426 a constructor (1), a destructor (2), or neither (0). */
432 struct names
{ char *name
; int len
; int ret
; int two_underscores
; };
434 register struct names
*p
;
436 register char *orig_s
= s
;
438 static struct names special
[] = {
439 #ifdef NO_DOLLAR_IN_LABEL
440 #ifdef NO_DOT_IN_LABEL
441 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
442 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
444 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
445 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
448 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
449 { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },
451 #ifdef CFRONT_LOSSAGE /* Don't collect cfront initialization functions.
452 cfront has its own linker procedure to collect them;
453 if collect2 gets them too, they get collected twice
454 when the cfront procedure is run and the compiler used
455 for linking happens to be GCC. */
456 { "sti__", sizeof ("sti__")-1, 1, 1 },
457 { "std__", sizeof ("std__")-1, 2, 1 },
458 #endif /* CFRONT_LOSSAGE */
462 while ((ch
= *s
) == '_')
468 for (p
= &special
[0]; p
->len
> 0; p
++)
471 && (!p
->two_underscores
|| ((s
- orig_s
) >= 2))
472 && strncmp(s
, p
->name
, p
->len
) == 0)
481 /* Compute a string to use as the base of all temporary file names.
482 It is substituted for %g. */
487 char *base
= getenv ("TMPDIR");
490 if (base
== (char *)0)
493 if (access (P_tmpdir
, R_OK
| W_OK
) == 0)
496 if (base
== (char *)0)
498 if (access ("/usr/tmp", R_OK
| W_OK
) == 0)
506 temp_filename
= xmalloc (len
+ sizeof("/ccXXXXXX") + 1);
507 strcpy (temp_filename
, base
);
508 if (len
> 0 && temp_filename
[len
-1] != '/')
509 temp_filename
[len
++] = '/';
510 strcpy (temp_filename
+ len
, "ccXXXXXX");
512 mktemp (temp_filename
);
513 temp_filename_length
= strlen (temp_filename
);
516 /* Routine to add variables to the environment. */
524 #ifndef VMS /* nor about VMS */
526 extern char **environ
;
527 char **old_environ
= environ
;
534 while ((ch
= *p
++) != '\0' && ch
!= '=')
540 /* Search for replacing an existing environment variable, and
541 count the number of total environment variables. */
542 for (envp
= old_environ
; *envp
; envp
++)
545 if (!strncmp (str
, *envp
, name_len
))
552 /* Add a new environment variable */
553 environ
= (char **) xmalloc (sizeof (char *) * (num_envs
+2));
555 bcopy ((char *) old_environ
, (char *) (environ
+ 1),
556 sizeof (char *) * (num_envs
+1));
562 #endif /* HAVE_PUTENV */
564 /* By default, colon separates directories in a path. */
565 #ifndef PATH_SEPARATOR
566 #define PATH_SEPARATOR ':'
569 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
570 and one from the PATH variable. */
572 static struct path_prefix cpath
, path
;
575 /* This is the name of the target machine. We use it to form the name
576 of the files to execute. */
578 static char *target_machine
= TARGET_MACHINE
;
581 /* Names under which we were executed. Never return one of those files in our
584 static struct path_prefix our_file_names
;
586 /* Determine if STRING is in PPREFIX.
588 This utility is currently only used to look up file names. Prefix lists
589 record directory names. This matters to us because the latter has a
590 trailing slash, so I've added a flag to handle both. */
593 is_in_prefix_list (pprefix
, string
, filep
)
594 struct path_prefix
*pprefix
;
598 struct prefix_list
*pl
;
602 int len
= strlen (string
);
604 for (pl
= pprefix
->plist
; pl
; pl
= pl
->next
)
606 if (strncmp (pl
->prefix
, string
, len
) == 0
607 && strcmp (pl
->prefix
+ len
, "/") == 0)
613 for (pl
= pprefix
->plist
; pl
; pl
= pl
->next
)
615 if (strcmp (pl
->prefix
, string
) == 0)
623 /* Search for NAME using prefix list PPREFIX. We only look for executable
626 Return 0 if not found, otherwise return its name, allocated with malloc. */
629 find_a_file (pprefix
, name
)
630 struct path_prefix
*pprefix
;
634 struct prefix_list
*pl
;
635 int len
= pprefix
->max_len
+ strlen (name
) + 1;
637 #ifdef EXECUTABLE_SUFFIX
638 len
+= strlen (EXECUTABLE_SUFFIX
);
641 temp
= xmalloc (len
);
643 /* Determine the filename to execute (special case for absolute paths). */
647 if (access (name
, X_OK
) == 0)
654 for (pl
= pprefix
->plist
; pl
; pl
= pl
->next
)
656 strcpy (temp
, pl
->prefix
);
658 if (! is_in_prefix_list (&our_file_names
, temp
, 1)
659 /* This is a kludge, but there seems no way around it. */
660 && strcmp (temp
, "./ld") != 0
661 && access (temp
, X_OK
) == 0)
664 #ifdef EXECUTABLE_SUFFIX
665 /* Some systems have a suffix for executable files.
666 So try appending that. */
667 strcat (temp
, EXECUTABLE_SUFFIX
);
668 if (! is_in_prefix_list (&our_file_names
, temp
, 1)
669 && access (temp
, X_OK
) == 0)
678 /* Add an entry for PREFIX to prefix list PPREFIX. */
681 add_prefix (pprefix
, prefix
)
682 struct path_prefix
*pprefix
;
685 struct prefix_list
*pl
, **prev
;
690 for (pl
= pprefix
->plist
; pl
->next
; pl
= pl
->next
)
695 prev
= &pprefix
->plist
;
697 /* Keep track of the longest prefix */
699 len
= strlen (prefix
);
700 if (len
> pprefix
->max_len
)
701 pprefix
->max_len
= len
;
703 pl
= (struct prefix_list
*) xmalloc (sizeof (struct prefix_list
));
704 pl
->prefix
= savestring (prefix
, len
);
709 pl
->next
= (struct prefix_list
*) 0;
713 /* Take the value of the environment variable ENV, break it into a path, and
714 add of the entries to PPREFIX. */
717 prefix_from_env (env
, pprefix
)
719 struct path_prefix
*pprefix
;
721 char *p
= getenv (env
);
726 char *nstore
= (char *) xmalloc (strlen (p
) + 3);
731 if (*endp
== PATH_SEPARATOR
|| *endp
== 0)
733 strncpy (nstore
, startp
, endp
-startp
);
736 strcpy (nstore
, "./");
738 else if (endp
[-1] != '/')
740 nstore
[endp
-startp
] = '/';
741 nstore
[endp
-startp
+1] = 0;
744 nstore
[endp
-startp
] = 0;
746 add_prefix (pprefix
, nstore
);
749 endp
= startp
= endp
+ 1;
764 char *ld_suffix
= "ld";
765 char *full_ld_suffix
= ld_suffix
;
766 char *real_ld_suffix
= "real-ld";
767 char *full_real_ld_suffix
= real_ld_suffix
;
769 char *gld_suffix
= "gld";
770 char *full_gld_suffix
= gld_suffix
;
772 char *nm_suffix
= "nm";
773 char *full_nm_suffix
= nm_suffix
;
774 char *gnm_suffix
= "gnm";
775 char *full_gnm_suffix
= gnm_suffix
;
776 char *strip_suffix
= "strip";
777 char *full_strip_suffix
= strip_suffix
;
778 char *gstrip_suffix
= "gstrip";
779 char *full_gstrip_suffix
= gstrip_suffix
;
789 char **ld1_argv
= (char **) xcalloc (sizeof (char *), argc
+2);
790 char **ld1
= ld1_argv
;
791 char **ld2_argv
= (char **) xcalloc (sizeof (char *), argc
+5);
792 char **ld2
= ld2_argv
;
794 int num_c_args
= argc
+7;
801 output_file
= "a.out";
803 /* We must check that we do not call ourselves in an infinite
804 recursion loop. We append the name used for us to the COLLECT_NAMES
805 environment variable.
807 In practice, collect will rarely invoke itself. This can happen now
808 that we are no longer called gld. A perfect example is when running
809 gcc in a build directory that has been installed. When looking for
810 ld's, we'll find our installed version and believe that's the real ld. */
812 /* We must also append COLLECT_NAME to COLLECT_NAMES to watch for the
813 previous version of collect (the one that used COLLECT_NAME and only
814 handled two levels of recursion). If we don't we may mutually recurse
815 forever. This can happen (I think) when bootstrapping the old version
816 and a new one is installed (rare, but we should handle it).
817 ??? Hopefully references to COLLECT_NAME can be removed at some point. */
819 collect_name
= (char *) getenv ("COLLECT_NAME");
820 collect_names
= (char *) getenv ("COLLECT_NAMES");
822 p
= (char *) xmalloc (strlen ("COLLECT_NAMES=")
823 + (collect_name
? strlen (collect_name
) + 1 : 0)
824 + (collect_names
? strlen (collect_names
) + 1 : 0)
825 + strlen (argv
[0]) + 1);
826 strcpy (p
, "COLLECT_NAMES=");
827 if (collect_name
!= 0)
828 sprintf (p
+ strlen (p
), "%s%c", collect_name
, PATH_SEPARATOR
);
829 if (collect_names
!= 0)
830 sprintf (p
+ strlen (p
), "%s%c", collect_names
, PATH_SEPARATOR
);
834 prefix_from_env ("COLLECT_NAMES", &our_file_names
);
836 /* Set environment variable COLLECT_NAME to our name so the previous version
837 of collect won't find us. If it does we'll mutually recurse forever.
838 This can happen when bootstrapping the new version and an old version is
840 ??? Hopefully this bit of code can be removed at some point. */
842 p
= xmalloc (strlen ("COLLECT_NAME=") + strlen (argv
[0]) + 1);
843 sprintf (p
, "COLLECT_NAME=%s", argv
[0]);
846 p
= (char *) getenv ("COLLECT_GCC_OPTIONS");
851 while (*q
&& *q
!= ' ') q
++;
852 if (*p
== '-' && p
[1] == 'm')
859 c_ptr
= c_argv
= (char **) xcalloc (sizeof (char *), num_c_args
);
862 fatal ("no arguments");
865 if (signal (SIGQUIT
, SIG_IGN
) != SIG_IGN
)
866 signal (SIGQUIT
, handler
);
868 if (signal (SIGINT
, SIG_IGN
) != SIG_IGN
)
869 signal (SIGINT
, handler
);
871 if (signal (SIGALRM
, SIG_IGN
) != SIG_IGN
)
872 signal (SIGALRM
, handler
);
875 if (signal (SIGHUP
, SIG_IGN
) != SIG_IGN
)
876 signal (SIGHUP
, handler
);
878 if (signal (SIGSEGV
, SIG_IGN
) != SIG_IGN
)
879 signal (SIGSEGV
, handler
);
881 if (signal (SIGBUS
, SIG_IGN
) != SIG_IGN
)
882 signal (SIGBUS
, handler
);
885 /* Extract COMPILER_PATH and PATH into our prefix list. */
886 prefix_from_env ("COMPILER_PATH", &cpath
);
887 prefix_from_env ("PATH", &path
);
890 /* If we look for a program in the compiler directories, we just use
891 the short name, since these directories are already system-specific.
892 But it we look for a took in the system directories, we need to
893 qualify the program name with the target machine. */
896 = xcalloc (strlen (ld_suffix
) + strlen (target_machine
) + 2, 1);
897 strcpy (full_ld_suffix
, target_machine
);
898 strcat (full_ld_suffix
, "-");
899 strcat (full_ld_suffix
, ld_suffix
);
902 = xcalloc (strlen (real_ld_suffix
) + strlen (target_machine
) + 2, 1);
903 strcpy (full_real_ld_suffix
, target_machine
);
904 strcat (full_real_ld_suffix
, "-");
905 strcat (full_real_ld_suffix
, real_ld_suffix
);
909 = xcalloc (strlen (gld_suffix
) + strlen (target_machine
) + 2, 1);
910 strcpy (full_gld_suffix
, target_machine
);
911 strcat (full_gld_suffix
, "-");
912 strcat (full_gld_suffix
, gld_suffix
);
916 = xcalloc (strlen (nm_suffix
) + strlen (target_machine
) + 2, 1);
917 strcpy (full_nm_suffix
, target_machine
);
918 strcat (full_nm_suffix
, "-");
919 strcat (full_nm_suffix
, nm_suffix
);
922 = xcalloc (strlen (gnm_suffix
) + strlen (target_machine
) + 2, 1);
923 strcpy (full_gnm_suffix
, target_machine
);
924 strcat (full_gnm_suffix
, "-");
925 strcat (full_gnm_suffix
, gnm_suffix
);
928 = xcalloc (strlen (strip_suffix
) + strlen (target_machine
) + 2, 1);
929 strcpy (full_strip_suffix
, target_machine
);
930 strcat (full_strip_suffix
, "-");
931 strcat (full_strip_suffix
, strip_suffix
);
934 = xcalloc (strlen (gstrip_suffix
) + strlen (target_machine
) + 2, 1);
935 strcpy (full_gstrip_suffix
, target_machine
);
936 strcat (full_gstrip_suffix
, "-");
937 strcat (full_gstrip_suffix
, gstrip_suffix
);
938 #endif /* CROSS_COMPILE */
940 /* Try to discover a valid linker/nm/strip to use. */
943 /* Search the (target-specific) compiler dirs for `gld'. */
944 ld_file_name
= find_a_file (&cpath
, gld_suffix
);
945 /* Search the ordinary system bin directories
946 for `gld' (if native linking) or `TARGET-gld' (if cross). */
947 if (ld_file_name
== 0)
948 ld_file_name
= find_a_file (&path
, full_gld_suffix
);
952 /* Likewise for `real-ld'. */
953 if (ld_file_name
== 0)
954 ld_file_name
= find_a_file (&cpath
, real_ld_suffix
);
955 if (ld_file_name
== 0)
956 ld_file_name
= find_a_file (&path
, full_real_ld_suffix
);
957 /* Maybe we know the right file to use (if not cross). */
958 #ifdef REAL_LD_FILE_NAME
959 if (ld_file_name
== 0)
960 ld_file_name
= find_a_file (&path
, REAL_LD_FILE_NAME
);
962 /* Search the compiler directories for `ld'. We have protection against
963 recursive calls in find_a_file. */
964 if (ld_file_name
== 0)
965 ld_file_name
= find_a_file (&cpath
, ld_suffix
);
966 /* Search the ordinary system bin directories
967 for `ld' (if native linking) or `TARGET-ld' (if cross). */
968 if (ld_file_name
== 0)
969 ld_file_name
= find_a_file (&path
, full_ld_suffix
);
971 /* If we've invoked ourselves, try again with LD_FILE_NAME. */
973 if (collect_names
!= 0)
975 if (ld_file_name
!= 0)
977 argv
[0] = ld_file_name
;
978 execvp (argv
[0], argv
);
980 fatal ("cannot find `ld'");
983 nm_file_name
= find_a_file (&cpath
, gnm_suffix
);
984 if (nm_file_name
== 0)
985 nm_file_name
= find_a_file (&path
, full_gnm_suffix
);
986 if (nm_file_name
== 0)
987 nm_file_name
= find_a_file (&cpath
, nm_suffix
);
988 #ifdef REAL_NM_FILE_NAME
989 if (nm_file_name
== 0)
990 nm_file_name
= find_a_file (&path
, REAL_NM_FILE_NAME
);
992 if (nm_file_name
== 0)
993 nm_file_name
= find_a_file (&path
, full_nm_suffix
);
995 strip_file_name
= find_a_file (&cpath
, gstrip_suffix
);
996 if (strip_file_name
== 0)
997 strip_file_name
= find_a_file (&path
, full_gstrip_suffix
);
998 if (strip_file_name
== 0)
999 strip_file_name
= find_a_file (&cpath
, strip_suffix
);
1000 #ifdef REAL_STRIP_FILE_NAME
1001 if (strip_file_name
== 0)
1002 strip_file_name
= find_a_file (&path
, REAL_STRIP_FILE_NAME
);
1004 if (strip_file_name
== 0)
1005 strip_file_name
= find_a_file (&path
, full_strip_suffix
);
1007 /* Determine the full path name of the C compiler to use. */
1008 c_file_name
= getenv ("COLLECT_GCC");
1009 if (c_file_name
== 0)
1011 #ifdef CROSS_COMPILE
1012 c_file_name
= xcalloc (sizeof ("gcc-") + strlen (target_machine
) + 1, 1);
1013 strcpy (c_file_name
, target_machine
);
1014 strcat (c_file_name
, "-gcc");
1016 c_file_name
= "gcc";
1020 p
= find_a_file (&cpath
, c_file_name
);
1022 /* Here it should be safe to use the system search path since we should have
1023 already qualified the name of the compiler when it is needed. */
1025 p
= find_a_file (&path
, c_file_name
);
1030 *ld1
++ = *ld2
++ = ld_file_name
;
1032 /* Make temp file names. */
1033 choose_temp_base ();
1034 c_file
= xcalloc (temp_filename_length
+ sizeof (".c"), 1);
1035 o_file
= xcalloc (temp_filename_length
+ sizeof (".o"), 1);
1036 sprintf (c_file
, "%s.c", temp_filename
);
1037 sprintf (o_file
, "%s.o", temp_filename
);
1038 *c_ptr
++ = c_file_name
;
1043 /* !!! When GCC calls collect2,
1044 it does not know whether it is calling collect2 or ld.
1045 So collect2 cannot meaningfully understand any options
1046 except those ld understands.
1047 If you propose to make GCC pass some other option,
1048 just imagine what will happen if ld is really ld!!! */
1050 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1051 /* After the first file, put in the c++ rt0. */
1054 while ((arg
= *++argv
) != (char *)0)
1056 *ld1
++ = *ld2
++ = arg
;
1062 if (!strcmp (arg
, "-debug"))
1072 output_file
= (arg
[2] == '\0') ? argv
[1] : &arg
[2];
1083 /* We must strip after the nm run, otherwise C++ linking
1084 won't work. Thus we strip in the second ld run, or
1085 else with strip if there is no second ld run. */
1098 && (p
= rindex (arg
, '.')) != (char *)0
1099 && strcmp (p
, ".o") == 0)
1106 /* Get any options that the upper GCC wants to pass to the sub-GCC. */
1107 p
= (char *) getenv ("COLLECT_GCC_OPTIONS");
1112 while (*q
&& *q
!= ' ') q
++;
1113 if (*p
== '-' && (p
[1] == 'm' || p
[1] == 'f'))
1114 *c_ptr
++ = savestring (p
, q
- p
);
1121 *c_ptr
= *ld1
= *ld2
= (char *)0;
1125 fprintf (stderr
, "collect2 version %s", version_string
);
1126 #ifdef TARGET_VERSION
1129 fprintf (stderr
, "\n");
1135 fprintf (stderr
, "ld_file_name = %s\n",
1136 (ld_file_name
? ld_file_name
: "not found"));
1137 fprintf (stderr
, "c_file_name = %s\n",
1138 (c_file_name
? c_file_name
: "not found"));
1139 fprintf (stderr
, "nm_file_name = %s\n",
1140 (nm_file_name
? nm_file_name
: "not found"));
1141 fprintf (stderr
, "strip_file_name = %s\n",
1142 (strip_file_name
? strip_file_name
: "not found"));
1143 fprintf (stderr
, "c_file = %s\n",
1144 (c_file
? c_file
: "not found"));
1145 fprintf (stderr
, "o_file = %s\n",
1146 (o_file
? o_file
: "not found"));
1148 ptr
= getenv ("COLLECT_NAMES");
1150 fprintf (stderr
, "COLLECT_NAMES = %s\n", ptr
);
1152 ptr
= getenv ("COLLECT_GCC_OPTIONS");
1154 fprintf (stderr
, "COLLECT_GCC_OPTIONS = %s\n", ptr
);
1156 ptr
= getenv ("COLLECT_GCC");
1158 fprintf (stderr
, "COLLECT_GCC = %s\n", ptr
);
1160 ptr
= getenv ("COMPILER_PATH");
1162 fprintf (stderr
, "COMPILER_PATH = %s\n", ptr
);
1164 ptr
= getenv ("LIBRARY_PATH");
1166 fprintf (stderr
, "LIBRARY_PATH = %s\n", ptr
);
1168 fprintf (stderr
, "\n");
1171 /* Load the program, searching all libraries.
1172 Examine the namelist with nm and search it for static constructors
1173 and destructors to call.
1174 Write the constructor and destructor tables to a .s file and reload. */
1176 fork_execute ("ld", ld1_argv
);
1178 /* If -r, don't build the constructor or destructor list, just return now. */
1182 scan_prog_file (output_file
, PASS_FIRST
);
1186 fprintf (stderr
, "%d constructor(s) found\n", constructors
.number
);
1187 fprintf (stderr
, "%d destructor(s) found\n", destructors
.number
);
1190 if (constructors
.number
== 0 && destructors
.number
== 0)
1192 /* Strip now if it was requested on the command line. */
1195 char **strip_argv
= (char **) xcalloc (sizeof (char *), 3);
1196 strip_argv
[0] = strip_file_name
;
1197 strip_argv
[1] = output_file
;
1198 strip_argv
[2] = (char *) 0;
1199 fork_execute ("strip", strip_argv
);
1204 outf
= fopen (c_file
, "w");
1205 if (outf
== (FILE *)0)
1206 fatal_perror ("%s", c_file
);
1208 write_c_file (outf
, c_file
);
1211 fatal_perror ("closing %s", c_file
);
1215 fprintf (stderr
, "\n========== output_file = %s, c_file = %s\n",
1216 output_file
, c_file
);
1217 write_c_file (stderr
, "stderr");
1218 fprintf (stderr
, "========== end of c_file\n\n");
1221 /* Assemble the constructor and destructor tables.
1222 Link the tables in with the rest of the program. */
1224 fork_execute ("gcc", c_argv
);
1225 fork_execute ("ld", ld2_argv
);
1227 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1228 constructors/destructors in shared libraries. */
1229 scan_prog_file (output_file
, PASS_SECOND
);
1231 maybe_unlink (c_file
);
1232 maybe_unlink (o_file
);
1237 /* Wait for a process to finish, and exit if a non-zero status is found. */
1248 int sig
= status
& 0x7F;
1251 if (sig
!= -1 && sig
!= 0)
1253 #ifdef NO_SYS_SIGLIST
1254 error ("%s terminated with signal %d %s",
1257 (status
& 0200) ? ", core dumped" : "");
1259 error ("%s terminated with signal %d [%s]%s",
1263 (status
& 0200) ? ", core dumped" : "");
1269 ret
= ((status
& 0xFF00) >> 8);
1270 if (ret
!= -1 && ret
!= 0)
1272 error ("%s returned %d exit status", prog
, ret
);
1279 /* Fork and execute a program, and wait for the reply. */
1282 fork_execute (prog
, argv
)
1294 fprintf (stderr
, "%s", argv
[0]);
1296 fprintf (stderr
, "[cannot find %s]", prog
);
1298 for (p_argv
= &argv
[1]; (str
= *p_argv
) != (char *)0; p_argv
++)
1299 fprintf (stderr
, " %s", str
);
1301 fprintf (stderr
, "\n");
1307 /* If we can't find a program we need, complain error. Do this here
1308 since we might not end up needing something that we couldn't find. */
1311 fatal ("cannot find `%s'", prog
);
1317 fatal_perror ("fork");
1319 fatal_perror ("vfork");
1323 if (pid
== 0) /* child context */
1325 execvp (argv
[0], argv
);
1326 fatal_perror ("executing %s", prog
);
1333 /* Unlink a file unless we are debugging. */
1342 fprintf (stderr
, "[Leaving %s]\n", file
);
1346 /* Add a name to a linked list. */
1349 add_to_list (head_ptr
, name
)
1350 struct head
*head_ptr
;
1353 struct id
*newid
= (struct id
*) xcalloc (sizeof (*newid
) + strlen (name
), 1);
1354 static long sequence_number
= 0;
1355 newid
->sequence
= ++sequence_number
;
1356 strcpy (newid
->name
, name
);
1358 if (head_ptr
->first
)
1359 head_ptr
->last
->next
= newid
;
1361 head_ptr
->first
= newid
;
1363 head_ptr
->last
= newid
;
1367 /* Write: `prefix', the names on list LIST, `suffix'. */
1370 write_list (stream
, prefix
, list
)
1377 fprintf (stream
, "%sx%d,\n", prefix
, list
->sequence
);
1383 write_list_with_asm (stream
, prefix
, list
)
1390 fprintf (stream
, "%sx%d __asm__ (\"%s\");\n",
1391 prefix
, list
->sequence
, list
->name
);
1396 /* Write the constructor/destructor tables. */
1399 write_c_file (stream
, name
)
1403 /* Write the tables as C code */
1405 fprintf (stream
, "typedef void entry_pt();\n\n");
1407 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
1409 fprintf (stream
, "\nentry_pt * __CTOR_LIST__[] = {\n");
1410 fprintf (stream
, "\t(entry_pt *) %d,\n", constructors
.number
);
1411 write_list (stream
, "\t", constructors
.first
);
1412 fprintf (stream
, "\t0\n};\n\n");
1414 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
1416 fprintf (stream
, "\nentry_pt * __DTOR_LIST__[] = {\n");
1417 fprintf (stream
, "\t(entry_pt *) %d,\n", destructors
.number
);
1418 write_list (stream
, "\t", destructors
.first
);
1419 fprintf (stream
, "\t0\n};\n\n");
1421 fprintf (stream
, "extern entry_pt %s;\n", NAME__MAIN
);
1422 fprintf (stream
, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN
);
1426 #ifdef OBJECT_FORMAT_NONE
1428 /* Generic version to scan the name list of the loaded program for
1429 the symbols g++ uses for static constructors and destructors.
1431 The constructor table begins at __CTOR_LIST__ and contains a count
1432 of the number of pointers (or -1 if the constructors are built in a
1433 separate section by the linker), followed by the pointers to the
1434 constructor functions, terminated with a null pointer. The
1435 destructor table has the same format, and begins at __DTOR_LIST__. */
1438 scan_prog_file (prog_name
, which_pass
)
1440 enum pass which_pass
;
1442 void (*int_handler
) ();
1443 void (*quit_handler
) ();
1451 if (which_pass
!= PASS_FIRST
)
1454 /* If we don't have an `nm', complain. */
1455 if (nm_file_name
== 0)
1456 fatal ("cannot find `nm'");
1458 nm_argv
[argc
++] = "nm";
1459 if (NM_FLAGS
[0] != '\0')
1460 nm_argv
[argc
++] = NM_FLAGS
;
1462 nm_argv
[argc
++] = prog_name
;
1463 nm_argv
[argc
++] = (char *)0;
1465 if (pipe (pipe_fd
) < 0)
1466 fatal_perror ("pipe");
1468 inf
= fdopen (pipe_fd
[0], "r");
1469 if (inf
== (FILE *)0)
1470 fatal_perror ("fdopen");
1472 /* Trace if needed. */
1478 fprintf (stderr
, "%s", nm_file_name
);
1479 for (p_argv
= &nm_argv
[1]; (str
= *p_argv
) != (char *)0; p_argv
++)
1480 fprintf (stderr
, " %s", str
);
1482 fprintf (stderr
, "\n");
1488 /* Spawn child nm on pipe */
1493 fatal_perror ("fork");
1495 fatal_perror ("vfork");
1499 if (pid
== 0) /* child context */
1502 if (dup2 (pipe_fd
[1], 1) < 0)
1503 fatal_perror ("dup2 (%d, 1)", pipe_fd
[1]);
1505 if (close (pipe_fd
[0]) < 0)
1506 fatal_perror ("close (%d)", pipe_fd
[0]);
1508 if (close (pipe_fd
[1]) < 0)
1509 fatal_perror ("close (%d)", pipe_fd
[1]);
1511 execv (nm_file_name
, nm_argv
);
1512 fatal_perror ("executing %s", nm_file_name
);
1515 /* Parent context from here on. */
1516 int_handler
= (void (*) ())signal (SIGINT
, SIG_IGN
);
1518 quit_handler
= (void (*) ())signal (SIGQUIT
, SIG_IGN
);
1521 if (close (pipe_fd
[1]) < 0)
1522 fatal_perror ("close (%d)", pipe_fd
[1]);
1525 fprintf (stderr
, "\nnm output with constructors/destructors.\n");
1527 /* Read each line of nm output. */
1528 while (fgets (buf
, sizeof buf
, inf
) != (char *)0)
1533 /* If it contains a constructor or destructor name, add the name
1534 to the appropriate list. */
1536 for (p
= buf
; (ch
= *p
) != '\0' && ch
!= '\n' && ch
!= '_'; p
++)
1539 if (ch
== '\0' || ch
== '\n')
1543 /* Find the end of the symbol name.
1544 Don't include `|', because Encore nm can tack that on the end. */
1545 for (end
= p
; (ch2
= *end
) != '\0' && !isspace (ch2
) && ch2
!= '|';
1550 switch (is_ctor_dtor (name
))
1553 add_to_list (&constructors
, name
);
1557 add_to_list (&destructors
, name
);
1560 default: /* not a constructor or destructor */
1565 fprintf (stderr
, "\t%s\n", buf
);
1569 fprintf (stderr
, "\n");
1571 if (fclose (inf
) != 0)
1572 fatal_perror ("fclose of pipe");
1574 do_wait (nm_file_name
);
1576 signal (SIGINT
, int_handler
);
1578 signal (SIGQUIT
, quit_handler
);
1582 #endif /* OBJECT_FORMAT_NONE */
1586 * COFF specific stuff.
1589 #ifdef OBJECT_FORMAT_COFF
1591 #if defined(EXTENDED_COFF)
1592 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
1593 # define GCC_SYMENT SYMR
1594 # define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
1595 # define GCC_SYMINC(X) (1)
1596 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
1597 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
1599 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
1600 # define GCC_SYMENT SYMENT
1601 # define GCC_OK_SYMBOL(X) \
1602 (((X).n_sclass == C_EXT) && \
1603 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
1604 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
1605 # define GCC_SYMINC(X) ((X).n_numaux+1)
1606 # define GCC_SYMZERO(X) 0
1607 # define GCC_CHECK_HDR(X) (1)
1610 extern char *ldgetname ();
1612 /* COFF version to scan the name list of the loaded program for
1613 the symbols g++ uses for static constructors and destructors.
1615 The constructor table begins at __CTOR_LIST__ and contains a count
1616 of the number of pointers (or -1 if the constructors are built in a
1617 separate section by the linker), followed by the pointers to the
1618 constructor functions, terminated with a null pointer. The
1619 destructor table has the same format, and begins at __DTOR_LIST__. */
1622 scan_prog_file (prog_name
, which_pass
)
1624 enum pass which_pass
;
1626 LDFILE
*ldptr
= NULL
;
1627 int sym_index
, sym_count
;
1629 if (which_pass
!= PASS_FIRST
)
1632 if ((ldptr
= ldopen (prog_name
, ldptr
)) == NULL
)
1633 fatal ("%s: can't open as COFF file", prog_name
);
1635 if (!MY_ISCOFF (HEADER (ldptr
).f_magic
))
1636 fatal ("%s: not a COFF file", prog_name
);
1638 if (GCC_CHECK_HDR (ldptr
))
1640 sym_count
= GCC_SYMBOLS (ldptr
);
1641 sym_index
= GCC_SYMZERO (ldptr
);
1642 while (sym_index
< sym_count
)
1646 if (ldtbread (ldptr
, sym_index
, &symbol
) <= 0)
1648 sym_index
+= GCC_SYMINC (symbol
);
1650 if (GCC_OK_SYMBOL (symbol
))
1654 if ((name
= ldgetname (ldptr
, &symbol
)) == NULL
)
1655 continue; /* should never happen */
1658 /* All AIX function names begin with a dot. */
1663 switch (is_ctor_dtor (name
))
1666 add_to_list (&constructors
, name
);
1670 add_to_list (&destructors
, name
);
1673 default: /* not a constructor or destructor */
1677 #if !defined(EXTENDED_COFF)
1679 fprintf (stderr
, "\tsec=%d class=%d type=%s%o %s\n",
1680 symbol
.n_scnum
, symbol
.n_sclass
,
1681 (symbol
.n_type
? "0" : ""), symbol
.n_type
,
1685 fprintf (stderr
, "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
1686 symbol
.iss
, symbol
.value
, symbol
.index
, name
);
1692 (void) ldclose(ldptr
);
1695 #endif /* OBJECT_FORMAT_COFF */
1699 * OSF/rose specific stuff.
1702 #ifdef OBJECT_FORMAT_ROSE
1704 /* Union of the various load commands */
1706 typedef union load_union
1708 ldc_header_t hdr
; /* common header */
1709 load_cmd_map_command_t map
; /* map indexing other load cmds */
1710 interpreter_command_t iprtr
; /* interpreter pathname */
1711 strings_command_t str
; /* load commands strings section */
1712 region_command_t region
; /* region load command */
1713 reloc_command_t reloc
; /* relocation section */
1714 package_command_t pkg
; /* package load command */
1715 symbols_command_t sym
; /* symbol sections */
1716 entry_command_t ent
; /* program start section */
1717 gen_info_command_t info
; /* object information */
1718 func_table_command_t func
; /* function constructors/destructors */
1721 /* Structure to point to load command and data section in memory. */
1723 typedef struct load_all
1725 load_union_t
*load
; /* load command */
1726 char *section
; /* pointer to section */
1729 /* Structure to contain information about a file mapped into memory. */
1733 char *start
; /* start of map */
1734 char *name
; /* filename */
1735 long size
; /* size of the file */
1736 long rounded_size
; /* size rounded to page boundary */
1737 int fd
; /* file descriptor */
1738 int rw
; /* != 0 if opened read/write */
1739 int use_mmap
; /* != 0 if mmap'ed */
1742 extern int decode_mach_o_hdr ();
1743 extern int encode_mach_o_hdr ();
1745 static void add_func_table
PROTO((mo_header_t
*, load_all_t
*,
1746 symbol_info_t
*, int));
1747 static void print_header
PROTO((mo_header_t
*));
1748 static void print_load_command
PROTO((load_union_t
*, size_t, int));
1749 static void bad_header
PROTO((int));
1750 static struct file_info
*read_file
PROTO((char *, int, int));
1751 static void end_file
PROTO((struct file_info
*));
1753 /* OSF/rose specific version to scan the name list of the loaded
1754 program for the symbols g++ uses for static constructors and
1757 The constructor table begins at __CTOR_LIST__ and contains a count
1758 of the number of pointers (or -1 if the constructors are built in a
1759 separate section by the linker), followed by the pointers to the
1760 constructor functions, terminated with a null pointer. The
1761 destructor table has the same format, and begins at __DTOR_LIST__. */
1764 scan_prog_file (prog_name
, which_pass
)
1766 enum pass which_pass
;
1770 load_all_t
*load_array
;
1771 load_all_t
*load_end
;
1772 load_all_t
*load_cmd
;
1773 int symbol_load_cmds
;
1779 struct file_info
*obj_file
;
1781 mo_lcid_t cmd_strings
= -1;
1782 symbol_info_t
*main_sym
= 0;
1783 int rw
= (which_pass
!= PASS_FIRST
);
1785 prog_fd
= open (prog_name
, (rw
) ? O_RDWR
: O_RDONLY
);
1787 fatal_perror ("can't read %s", prog_name
);
1789 obj_file
= read_file (prog_name
, prog_fd
, rw
);
1790 obj
= obj_file
->start
;
1792 status
= decode_mach_o_hdr (obj
, MO_SIZEOF_RAW_HDR
, MOH_HEADER_VERSION
, &hdr
);
1793 if (status
!= MO_HDR_CONV_SUCCESS
)
1794 bad_header (status
);
1797 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
1798 since the hardware will automatically swap bytes for us on loading little endian
1801 #ifndef CROSS_COMPILE
1802 if (hdr
.moh_magic
!= MOH_MAGIC_MSB
1803 || hdr
.moh_header_version
!= MOH_HEADER_VERSION
1804 || hdr
.moh_byte_order
!= OUR_BYTE_ORDER
1805 || hdr
.moh_data_rep_id
!= OUR_DATA_REP_ID
1806 || hdr
.moh_cpu_type
!= OUR_CPU_TYPE
1807 || hdr
.moh_cpu_subtype
!= OUR_CPU_SUBTYPE
1808 || hdr
.moh_vendor_type
!= OUR_VENDOR_TYPE
)
1810 fatal ("incompatibilities between object file & expected values");
1815 print_header (&hdr
);
1817 offset
= hdr
.moh_first_cmd_off
;
1818 load_end
= load_array
1819 = (load_all_t
*) xcalloc (sizeof (load_all_t
), hdr
.moh_n_load_cmds
+ 2);
1821 /* Build array of load commands, calculating the offsets */
1822 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
1824 load_union_t
*load_hdr
; /* load command header */
1826 load_cmd
= load_end
++;
1827 load_hdr
= (load_union_t
*) (obj
+ offset
);
1829 /* If modifying the program file, copy the header. */
1832 load_union_t
*ptr
= (load_union_t
*) xmalloc (load_hdr
->hdr
.ldci_cmd_size
);
1833 bcopy ((char *)load_hdr
, (char *)ptr
, load_hdr
->hdr
.ldci_cmd_size
);
1836 /* null out old command map, because we will rewrite at the end. */
1837 if (ptr
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
1839 cmd_strings
= ptr
->map
.lcm_ld_cmd_strings
;
1840 ptr
->hdr
.ldci_cmd_type
= LDC_UNDEFINED
;
1844 load_cmd
->load
= load_hdr
;
1845 if (load_hdr
->hdr
.ldci_section_off
> 0)
1846 load_cmd
->section
= obj
+ load_hdr
->hdr
.ldci_section_off
;
1849 print_load_command (load_hdr
, offset
, i
);
1851 offset
+= load_hdr
->hdr
.ldci_cmd_size
;
1854 /* If the last command is the load command map and is not undefined,
1855 decrement the count of load commands. */
1856 if (rw
&& load_end
[-1].load
->hdr
.ldci_cmd_type
== LDC_UNDEFINED
)
1859 hdr
.moh_n_load_cmds
--;
1862 /* Go through and process each symbol table section. */
1863 symbol_load_cmds
= 0;
1864 for (load_cmd
= load_array
; load_cmd
< load_end
; load_cmd
++)
1866 load_union_t
*load_hdr
= load_cmd
->load
;
1868 if (load_hdr
->hdr
.ldci_cmd_type
== LDC_SYMBOLS
)
1874 char *kind
= "unknown";
1876 switch (load_hdr
->sym
.symc_kind
)
1878 case SYMC_IMPORTS
: kind
= "imports"; break;
1879 case SYMC_DEFINED_SYMBOLS
: kind
= "defined"; break;
1880 case SYMC_STABS
: kind
= "stabs"; break;
1883 fprintf (stderr
, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
1884 symbol_load_cmds
, load_hdr
->hdr
.ldci_section_off
, kind
);
1887 if (load_hdr
->sym
.symc_kind
!= SYMC_DEFINED_SYMBOLS
)
1890 str_sect
= load_array
[load_hdr
->sym
.symc_strings_section
].section
;
1891 if (str_sect
== (char *)0)
1892 fatal ("string section missing");
1894 if (load_cmd
->section
== (char *)0)
1895 fatal ("section pointer missing");
1897 num_syms
= load_hdr
->sym
.symc_nentries
;
1898 for (i
= 0; i
< num_syms
; i
++)
1900 symbol_info_t
*sym
= ((symbol_info_t
*) load_cmd
->section
) + i
;
1901 char *name
= sym
->si_name
.symbol_name
+ str_sect
;
1908 char *n
= name
+ strlen (name
) - strlen (NAME__MAIN
);
1910 if ((n
- name
) < 0 || strcmp (n
, NAME__MAIN
))
1920 switch (is_ctor_dtor (name
))
1923 add_to_list (&constructors
, name
);
1927 add_to_list (&destructors
, name
);
1930 default: /* not a constructor or destructor */
1936 fprintf (stderr
, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
1937 sym
->si_type
, sym
->si_sc_type
, sym
->si_flags
, name
);
1942 if (symbol_load_cmds
== 0)
1943 fatal ("no symbol table found");
1945 /* Update the program file now, rewrite header and load commands. At present,
1946 we assume that there is enough space after the last load command to insert
1947 one more. Since the first section written out is page aligned, and the
1948 number of load commands is small, this is ok for the present. */
1952 load_union_t
*load_map
;
1955 if (cmd_strings
== -1)
1956 fatal ("no cmd_strings found");
1958 /* Add __main to initializer list.
1959 If we are building a program instead of a shared library, don't
1960 do anything, since in the current version, you cannot do mallocs
1961 and such in the constructors. */
1963 if (main_sym
!= (symbol_info_t
*)0
1964 && ((hdr
.moh_flags
& MOH_EXECABLE_F
) == 0))
1965 add_func_table (&hdr
, load_array
, main_sym
, FNTC_INITIALIZATION
);
1968 fprintf (stderr
, "\nUpdating header and load commands.\n\n");
1970 hdr
.moh_n_load_cmds
++;
1971 size
= sizeof (load_cmd_map_command_t
) + (sizeof (mo_offset_t
) * (hdr
.moh_n_load_cmds
- 1));
1973 /* Create new load command map. */
1975 fprintf (stderr
, "load command map, %d cmds, new size %ld.\n",
1976 (int)hdr
.moh_n_load_cmds
, (long)size
);
1978 load_map
= (load_union_t
*) xcalloc (1, size
);
1979 load_map
->map
.ldc_header
.ldci_cmd_type
= LDC_CMD_MAP
;
1980 load_map
->map
.ldc_header
.ldci_cmd_size
= size
;
1981 load_map
->map
.lcm_ld_cmd_strings
= cmd_strings
;
1982 load_map
->map
.lcm_nentries
= hdr
.moh_n_load_cmds
;
1983 load_array
[hdr
.moh_n_load_cmds
-1].load
= load_map
;
1985 offset
= hdr
.moh_first_cmd_off
;
1986 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
1988 load_map
->map
.lcm_map
[i
] = offset
;
1989 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
1990 hdr
.moh_load_map_cmd_off
= offset
;
1992 offset
+= load_array
[i
].load
->hdr
.ldci_cmd_size
;
1995 hdr
.moh_sizeofcmds
= offset
- MO_SIZEOF_RAW_HDR
;
1998 print_header (&hdr
);
2001 status
= encode_mach_o_hdr (&hdr
, obj
, MO_SIZEOF_RAW_HDR
);
2002 if (status
!= MO_HDR_CONV_SUCCESS
)
2003 bad_header (status
);
2006 fprintf (stderr
, "writing load commands.\n\n");
2008 /* Write load commands */
2009 offset
= hdr
.moh_first_cmd_off
;
2010 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
2012 load_union_t
*load_hdr
= load_array
[i
].load
;
2013 size_t size
= load_hdr
->hdr
.ldci_cmd_size
;
2016 print_load_command (load_hdr
, offset
, i
);
2018 bcopy ((char *)load_hdr
, (char *)(obj
+ offset
), size
);
2023 end_file (obj_file
);
2025 if (close (prog_fd
))
2026 fatal_perror ("closing %s", prog_name
);
2029 fprintf (stderr
, "\n");
2033 /* Add a function table to the load commands to call a function
2034 on initiation or termination of the process. */
2037 add_func_table (hdr_p
, load_array
, sym
, type
)
2038 mo_header_t
*hdr_p
; /* pointer to global header */
2039 load_all_t
*load_array
; /* array of ptrs to load cmds */
2040 symbol_info_t
*sym
; /* pointer to symbol entry */
2041 int type
; /* fntc_type value */
2043 /* Add a new load command. */
2044 int num_cmds
= ++hdr_p
->moh_n_load_cmds
;
2045 int load_index
= num_cmds
- 1;
2046 size_t size
= sizeof (func_table_command_t
) + sizeof (mo_addr_t
);
2047 load_union_t
*ptr
= xcalloc (1, size
);
2048 load_all_t
*load_cmd
;
2051 /* Set the unresolved address bit in the header to force the loader to be
2052 used, since kernel exec does not call the initialization functions. */
2053 hdr_p
->moh_flags
|= MOH_UNRESOLVED_F
;
2055 load_cmd
= &load_array
[load_index
];
2056 load_cmd
->load
= ptr
;
2057 load_cmd
->section
= (char *)0;
2059 /* Fill in func table load command. */
2060 ptr
->func
.ldc_header
.ldci_cmd_type
= LDC_FUNC_TABLE
;
2061 ptr
->func
.ldc_header
.ldci_cmd_size
= size
;
2062 ptr
->func
.ldc_header
.ldci_section_off
= 0;
2063 ptr
->func
.ldc_header
.ldci_section_len
= 0;
2064 ptr
->func
.fntc_type
= type
;
2065 ptr
->func
.fntc_nentries
= 1;
2067 /* copy address, turn it from abs. address to (region,offset) if necessary. */
2068 /* Is the symbol already expressed as (region, offset)? */
2069 if ((sym
->si_flags
& SI_ABSOLUTE_VALUE_F
) == 0)
2071 ptr
->func
.fntc_entry_loc
[i
].adr_lcid
= sym
->si_value
.def_val
.adr_lcid
;
2072 ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
= sym
->si_value
.def_val
.adr_sctoff
;
2075 /* If not, figure out which region it's in. */
2078 mo_vm_addr_t addr
= sym
->si_value
.abs_val
;
2081 for (i
= 0; i
< load_index
; i
++)
2083 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_REGION
)
2085 region_command_t
*region_ptr
= &load_array
[i
].load
->region
;
2087 if ((region_ptr
->regc_flags
& REG_ABS_ADDR_F
) != 0
2088 && addr
>= region_ptr
->regc_addr
.vm_addr
2089 && addr
<= region_ptr
->regc_addr
.vm_addr
+ region_ptr
->regc_vm_size
)
2091 ptr
->func
.fntc_entry_loc
[0].adr_lcid
= i
;
2092 ptr
->func
.fntc_entry_loc
[0].adr_sctoff
= addr
- region_ptr
->regc_addr
.vm_addr
;
2100 fatal ("could not convert 0x%l.8x into a region", addr
);
2105 "%s function, region %d, offset = %ld (0x%.8lx)\n",
2106 (type
== FNTC_INITIALIZATION
) ? "init" : "term",
2107 (int)ptr
->func
.fntc_entry_loc
[i
].adr_lcid
,
2108 (long)ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
,
2109 (long)ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
);
2114 /* Print the global header for an OSF/rose object. */
2117 print_header (hdr_ptr
)
2118 mo_header_t
*hdr_ptr
;
2120 fprintf (stderr
, "\nglobal header:\n");
2121 fprintf (stderr
, "\tmoh_magic = 0x%.8lx\n", hdr_ptr
->moh_magic
);
2122 fprintf (stderr
, "\tmoh_major_version = %d\n", (int)hdr_ptr
->moh_major_version
);
2123 fprintf (stderr
, "\tmoh_minor_version = %d\n", (int)hdr_ptr
->moh_minor_version
);
2124 fprintf (stderr
, "\tmoh_header_version = %d\n", (int)hdr_ptr
->moh_header_version
);
2125 fprintf (stderr
, "\tmoh_max_page_size = %d\n", (int)hdr_ptr
->moh_max_page_size
);
2126 fprintf (stderr
, "\tmoh_byte_order = %d\n", (int)hdr_ptr
->moh_byte_order
);
2127 fprintf (stderr
, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr
->moh_data_rep_id
);
2128 fprintf (stderr
, "\tmoh_cpu_type = %d\n", (int)hdr_ptr
->moh_cpu_type
);
2129 fprintf (stderr
, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr
->moh_cpu_subtype
);
2130 fprintf (stderr
, "\tmoh_vendor_type = %d\n", (int)hdr_ptr
->moh_vendor_type
);
2131 fprintf (stderr
, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr
->moh_load_map_cmd_off
);
2132 fprintf (stderr
, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr
->moh_first_cmd_off
);
2133 fprintf (stderr
, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr
->moh_sizeofcmds
);
2134 fprintf (stderr
, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr
->moh_n_load_cmds
);
2135 fprintf (stderr
, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr
->moh_flags
);
2137 if (hdr_ptr
->moh_flags
& MOH_RELOCATABLE_F
)
2138 fprintf (stderr
, ", relocatable");
2140 if (hdr_ptr
->moh_flags
& MOH_LINKABLE_F
)
2141 fprintf (stderr
, ", linkable");
2143 if (hdr_ptr
->moh_flags
& MOH_EXECABLE_F
)
2144 fprintf (stderr
, ", execable");
2146 if (hdr_ptr
->moh_flags
& MOH_EXECUTABLE_F
)
2147 fprintf (stderr
, ", executable");
2149 if (hdr_ptr
->moh_flags
& MOH_UNRESOLVED_F
)
2150 fprintf (stderr
, ", unresolved");
2152 fprintf (stderr
, "\n\n");
2157 /* Print a short summary of a load command. */
2160 print_load_command (load_hdr
, offset
, number
)
2161 load_union_t
*load_hdr
;
2165 mo_long_t type
= load_hdr
->hdr
.ldci_cmd_type
;
2166 char *type_str
= (char *)0;
2170 case LDC_UNDEFINED
: type_str
= "UNDEFINED"; break;
2171 case LDC_CMD_MAP
: type_str
= "CMD_MAP"; break;
2172 case LDC_INTERPRETER
: type_str
= "INTERPRETER"; break;
2173 case LDC_STRINGS
: type_str
= "STRINGS"; break;
2174 case LDC_REGION
: type_str
= "REGION"; break;
2175 case LDC_RELOC
: type_str
= "RELOC"; break;
2176 case LDC_PACKAGE
: type_str
= "PACKAGE"; break;
2177 case LDC_SYMBOLS
: type_str
= "SYMBOLS"; break;
2178 case LDC_ENTRY
: type_str
= "ENTRY"; break;
2179 case LDC_FUNC_TABLE
: type_str
= "FUNC_TABLE"; break;
2180 case LDC_GEN_INFO
: type_str
= "GEN_INFO"; break;
2184 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
2186 (long) load_hdr
->hdr
.ldci_cmd_size
,
2188 (long) load_hdr
->hdr
.ldci_section_off
,
2189 (long) load_hdr
->hdr
.ldci_section_len
);
2191 if (type_str
== (char *)0)
2192 fprintf (stderr
, ", ty: unknown (%ld)\n", (long) type
);
2194 else if (type
!= LDC_REGION
)
2195 fprintf (stderr
, ", ty: %s\n", type_str
);
2200 switch (load_hdr
->region
.regc_usage_type
)
2202 case REG_TEXT_T
: region
= ", .text"; break;
2203 case REG_DATA_T
: region
= ", .data"; break;
2204 case REG_BSS_T
: region
= ", .bss"; break;
2205 case REG_GLUE_T
: region
= ", .glue"; break;
2206 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
2207 case REG_RDATA_T
: region
= ", .rdata"; break;
2208 case REG_SDATA_T
: region
= ", .sdata"; break;
2209 case REG_SBSS_T
: region
= ", .sbss"; break;
2213 fprintf (stderr
, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
2215 (long) load_hdr
->region
.regc_vm_addr
,
2216 (long) load_hdr
->region
.regc_vm_size
,
2224 /* Fatal error when {en,de}code_mach_o_header fails. */
2230 char *msg
= (char *)0;
2234 case MO_ERROR_BAD_MAGIC
: msg
= "bad magic number"; break;
2235 case MO_ERROR_BAD_HDR_VERS
: msg
= "bad header version"; break;
2236 case MO_ERROR_BAD_RAW_HDR_VERS
: msg
= "bad raw header version"; break;
2237 case MO_ERROR_BUF2SML
: msg
= "raw header buffer too small"; break;
2238 case MO_ERROR_OLD_RAW_HDR_FILE
: msg
= "old raw header file"; break;
2239 case MO_ERROR_UNSUPPORTED_VERS
: msg
= "unsupported version"; break;
2242 if (msg
== (char *)0)
2243 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status
);
2249 /* Read a file into a memory buffer. */
2251 static struct file_info
*
2252 read_file (name
, fd
, rw
)
2253 char *name
; /* filename */
2254 int fd
; /* file descriptor */
2255 int rw
; /* read/write */
2257 struct stat stat_pkt
;
2258 struct file_info
*p
= (struct file_info
*) xcalloc (sizeof (struct file_info
), 1);
2260 static int page_size
;
2263 if (fstat (fd
, &stat_pkt
) < 0)
2264 fatal_perror ("fstat %s", name
);
2267 p
->size
= stat_pkt
.st_size
;
2268 p
->rounded_size
= stat_pkt
.st_size
;
2274 fprintf (stderr
, "mmap %s, %s\n", name
, (rw
) ? "read/write" : "read-only");
2277 page_size
= sysconf (_SC_PAGE_SIZE
);
2279 p
->rounded_size
= ((p
->size
+ page_size
- 1) / page_size
) * page_size
;
2280 p
->start
= mmap ((caddr_t
)0,
2281 (rw
) ? p
->rounded_size
: p
->size
,
2282 (rw
) ? (PROT_READ
| PROT_WRITE
) : PROT_READ
,
2283 MAP_FILE
| MAP_VARIABLE
| MAP_SHARED
,
2287 if (p
->start
!= (char *)0 && p
->start
!= (char *)-1)
2291 #endif /* USE_MMAP */
2296 fprintf (stderr
, "read %s\n", name
);
2299 p
->start
= xmalloc (p
->size
);
2300 if (lseek (fd
, 0L, SEEK_SET
) < 0)
2301 fatal_perror ("lseek to 0 on %s", name
);
2303 len
= read (fd
, p
->start
, p
->size
);
2305 fatal_perror ("read %s", name
);
2308 fatal ("read %ld bytes, expected %ld, from %s", len
, p
->size
, name
);
2314 /* Do anything necessary to write a file back from memory. */
2318 struct file_info
*ptr
; /* file information block */
2326 fprintf (stderr
, "msync %s\n", ptr
->name
);
2328 if (msync (ptr
->start
, ptr
->rounded_size
, MS_ASYNC
))
2329 fatal_perror ("msync %s", ptr
->name
);
2333 fprintf (stderr
, "munmap %s\n", ptr
->name
);
2335 if (munmap (ptr
->start
, ptr
->size
))
2336 fatal_perror ("munmap %s", ptr
->name
);
2339 #endif /* USE_MMAP */
2346 fprintf (stderr
, "write %s\n", ptr
->name
);
2348 if (lseek (ptr
->fd
, 0L, SEEK_SET
) < 0)
2349 fatal_perror ("lseek to 0 on %s", ptr
->name
);
2351 len
= write (ptr
->fd
, ptr
->start
, ptr
->size
);
2353 fatal_perror ("read %s", ptr
->name
);
2355 if (len
!= ptr
->size
)
2356 fatal ("wrote %ld bytes, expected %ld, to %s", len
, ptr
->size
, ptr
->name
);
2359 free ((generic
*)ptr
->start
);
2362 free ((generic
*)ptr
);
2365 #endif /* OBJECT_FORMAT_ROSE */