1 /* Collect static initialization info into data structures that can be
2 traversed by C++ initialization and finalization routines.
3 Copyright (C) 1992, 93-97, 1998 Free Software Foundation, Inc.
4 Contributed by Chris Smith (csmith@convex.com).
5 Heavily modified by Michael Meissner (meissner@cygnus.com),
6 Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
8 This file is part of GNU CC.
10 GNU CC is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
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. */
29 #include <sys/types.h>
57 #include "gansidecl.h"
64 extern char *sys_errlist
[];
70 /* Obstack allocation and deallocation routines. */
71 #define obstack_chunk_alloc xmalloc
72 #define obstack_chunk_free free
85 #define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
88 #define WTERMSIG(S) ((S) & 0x7f)
91 #define WIFEXITED(S) (((S) & 0xff) == 0)
94 #define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
97 extern char *choose_temp_base ();
99 /* On certain systems, we have code that works by scanning the object file
100 directly. But this code uses system-specific header files and library
101 functions, so turn it off in a cross-compiler. Likewise, the names of
102 the utilities are not correct for a cross-compiler; we have to hope that
103 cross-versions are in the proper directories. */
106 #undef SUNOS4_SHARED_LIBRARIES
107 #undef OBJECT_FORMAT_COFF
108 #undef OBJECT_FORMAT_ROSE
109 #undef MD_EXEC_PREFIX
110 #undef REAL_LD_FILE_NAME
111 #undef REAL_NM_FILE_NAME
112 #undef REAL_STRIP_FILE_NAME
115 /* If we cannot use a special method, use the ordinary one:
116 run nm to find what symbols are present.
117 In a cross-compiler, this means you need a cross nm,
118 but that is not quite as unpleasant as special headers. */
120 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
121 #define OBJECT_FORMAT_NONE
124 #ifdef OBJECT_FORMAT_COFF
133 /* Many versions of ldfcn.h define these. */
141 /* Some systems have an ISCOFF macro, but others do not. In some cases
142 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
143 that either do not have an ISCOFF macro in /usr/include or for those
144 where it is wrong. */
147 #define MY_ISCOFF(X) ISCOFF (X)
150 #endif /* OBJECT_FORMAT_COFF */
152 #ifdef OBJECT_FORMAT_ROSE
159 #include <sys/mman.h>
163 #include <mach_o_format.h>
164 #include <mach_o_header.h>
165 #include <mach_o_vals.h>
166 #include <mach_o_types.h>
168 #endif /* OBJECT_FORMAT_ROSE */
170 #ifdef OBJECT_FORMAT_NONE
172 /* Default flags to pass to nm. */
174 #define NM_FLAGS "-p"
177 #endif /* OBJECT_FORMAT_NONE */
179 /* Some systems use __main in a way incompatible with its use in gcc, in these
180 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
181 give the same symbol without quotes for an alternative entry point. You
182 must define both, or neither. */
184 #define NAME__MAIN "__main"
185 #define SYMBOL__MAIN __main
188 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
189 #define SCAN_LIBRARIES
193 int do_collecting
= 1;
195 int do_collecting
= 0;
198 /* Linked lists of constructor and destructor names. */
214 /* Enumeration giving which pass this is for scanning the program file. */
217 PASS_FIRST
, /* without constructors */
218 PASS_OBJ
, /* individual objects */
219 PASS_LIB
, /* looking for shared libraries */
220 PASS_SECOND
/* with constructors linked in */
223 #ifndef NO_SYS_SIGLIST
224 #ifndef SYS_SIGLIST_DECLARED
225 extern char *sys_siglist
[];
228 extern char *version_string
;
230 int vflag
; /* true if -v */
231 static int rflag
; /* true if -r */
232 static int strip_flag
; /* true if -s */
233 #ifdef COLLECT_EXPORT_LIST
234 static int export_flag
; /* true if -bE */
237 int debug
; /* true if -debug */
239 static int shared_obj
; /* true if -shared */
241 static int temp_filename_length
; /* Length of temp_filename */
242 static char *temp_filename
; /* Base of temp filenames */
243 static char *c_file
; /* <xxx>.c for constructor/destructor list. */
244 static char *o_file
; /* <xxx>.o for constructor/destructor list. */
245 #ifdef COLLECT_EXPORT_LIST
246 static char *export_file
; /* <xxx>.x for AIX export list. */
247 static char *import_file
; /* <xxx>.p for AIX import list. */
249 char *ldout
; /* File for ld errors. */
250 static char *output_file
; /* Output file for ld. */
251 static char *nm_file_name
; /* pathname of nm */
252 static char *ldd_file_name
; /* pathname of ldd (or equivalent) */
253 static char *strip_file_name
; /* pathname of strip */
254 char *c_file_name
; /* pathname of gcc */
255 static char *initname
, *fininame
; /* names of init and fini funcs */
257 static struct head constructors
; /* list of constructors found */
258 static struct head destructors
; /* list of destructors found */
259 #ifdef COLLECT_EXPORT_LIST
260 static struct head exports
; /* list of exported symbols */
261 static struct head imports
; /* list of imported symbols */
262 static struct head undefined
; /* list of undefined symbols */
264 static struct head frame_tables
; /* list of frame unwind info tables */
266 struct obstack temporary_obstack
;
267 struct obstack permanent_obstack
;
268 char * temporary_firstobj
;
270 /* Defined in the automatically-generated underscore.c. */
271 extern int prepends_underscore
;
273 extern char *getenv ();
274 extern char *mktemp ();
275 extern FILE *fdopen ();
277 /* Structure to hold all the directories in which to search for files to
282 char *prefix
; /* String to prepend to the path. */
283 struct prefix_list
*next
; /* Next in linked list. */
288 struct prefix_list
*plist
; /* List of prefixes to try */
289 int max_len
; /* Max length of a prefix in PLIST */
290 char *name
; /* Name of this list (used in config stuff) */
293 #ifdef COLLECT_EXPORT_LIST
294 /* Lists to keep libraries to be scanned for global constructors/destructors. */
295 static struct head libs
; /* list of libraries */
296 static struct path_prefix cmdline_lib_dirs
; /* directories specified with -L */
297 static struct path_prefix libpath_lib_dirs
; /* directories in LIBPATH */
298 static struct path_prefix
*libpaths
[3] = {&cmdline_lib_dirs
,
299 &libpath_lib_dirs
, NULL
};
300 static char *libexts
[3] = {"a", "so", NULL
}; /* possible library extentions */
303 void collect_exit
PROTO((int));
304 void collect_execute
PROTO((char *, char **, char *));
305 void dump_file
PROTO((char *));
306 static void handler
PROTO((int));
307 static int is_ctor_dtor
PROTO((char *));
308 static int is_in_prefix_list
PROTO((struct path_prefix
*, char *, int));
309 static char *find_a_file
PROTO((struct path_prefix
*, char *));
310 static void add_prefix
PROTO((struct path_prefix
*, char *));
311 static void prefix_from_env
PROTO((char *, struct path_prefix
*));
312 static void prefix_from_string
PROTO((char *, struct path_prefix
*));
313 static void do_wait
PROTO((char *));
314 static void fork_execute
PROTO((char *, char **));
315 static void maybe_unlink
PROTO((char *));
316 static void add_to_list
PROTO((struct head
*, char *));
317 static void write_list
PROTO((FILE *, char *, struct id
*));
318 static void dump_list
PROTO((FILE *, char *, struct id
*));
319 static void dump_prefix_list
PROTO((FILE *, char *, struct prefix_list
*));
320 static int is_in_list
PROTO((char *, struct id
*));
321 static void write_list_with_asm
PROTO((FILE *, char *, struct id
*));
322 static void write_c_file
PROTO((FILE *, char *));
323 static void scan_prog_file
PROTO((char *, enum pass
));
324 #ifdef SCAN_LIBRARIES
325 static void scan_libraries
PROTO((char *));
327 #ifdef COLLECT_EXPORT_LIST
328 static void write_export_file
PROTO((FILE *));
329 static void write_import_file
PROTO((FILE *));
330 static char *resolve_lib_name
PROTO((char *));
331 static int use_import_list
PROTO((char *));
332 static int ignore_library
PROTO((char *));
338 #ifdef NEED_DECLARATION_INDEX
339 extern char *index ();
342 #ifdef NEED_DECLARATION_RINDEX
343 extern char *rindex ();
346 #ifdef NEED_DECLARATION_FREE
363 while ((fd
= dup (oldfd
)) != newfd
&& fd
>= 0) /* good enough for low fd's */
366 close (fdtmp
[--fdx
]);
382 static char buffer
[30];
386 if (e
> 0 && e
< sys_nerr
)
387 return sys_errlist
[e
];
389 sprintf (buffer
, "Unknown error %d", e
);
394 /* Delete tempfiles and exit function. */
397 collect_exit (status
)
400 if (c_file
!= 0 && c_file
[0])
401 maybe_unlink (c_file
);
403 if (o_file
!= 0 && o_file
[0])
404 maybe_unlink (o_file
);
406 #ifdef COLLECT_EXPORT_LIST
407 if (export_file
!= 0 && export_file
[0])
408 maybe_unlink (export_file
);
410 if (import_file
!= 0 && import_file
[0])
411 maybe_unlink (import_file
);
414 if (ldout
!= 0 && ldout
[0])
417 maybe_unlink (ldout
);
420 if (status
!= 0 && output_file
!= 0 && output_file
[0])
421 maybe_unlink (output_file
);
427 /* Die when sys call fails. */
430 fatal_perror (string
, arg1
, arg2
, arg3
)
431 char *string
, *arg1
, *arg2
, *arg3
;
435 fprintf (stderr
, "collect2: ");
436 fprintf (stderr
, string
, arg1
, arg2
, arg3
);
437 fprintf (stderr
, ": %s\n", my_strerror (e
));
438 collect_exit (FATAL_EXIT_CODE
);
444 fatal (string
, arg1
, arg2
, arg3
)
445 char *string
, *arg1
, *arg2
, *arg3
;
447 fprintf (stderr
, "collect2: ");
448 fprintf (stderr
, string
, arg1
, arg2
, arg3
);
449 fprintf (stderr
, "\n");
450 collect_exit (FATAL_EXIT_CODE
);
453 /* Write error message. */
456 error (string
, arg1
, arg2
, arg3
, arg4
)
457 char *string
, *arg1
, *arg2
, *arg3
, *arg4
;
459 fprintf (stderr
, "collect2: ");
460 fprintf (stderr
, string
, arg1
, arg2
, arg3
, arg4
);
461 fprintf (stderr
, "\n");
464 /* In case obstack is linked in, and abort is defined to fancy_abort,
465 provide a default entry. */
470 fatal ("internal error");
478 if (c_file
!= 0 && c_file
[0])
479 maybe_unlink (c_file
);
481 if (o_file
!= 0 && o_file
[0])
482 maybe_unlink (o_file
);
484 if (ldout
!= 0 && ldout
[0])
485 maybe_unlink (ldout
);
487 #ifdef COLLECT_EXPORT_LIST
488 if (export_file
!= 0 && export_file
[0])
489 maybe_unlink (export_file
);
491 if (import_file
!= 0 && import_file
[0])
492 maybe_unlink (import_file
);
495 signal (signo
, SIG_DFL
);
496 kill (getpid (), signo
);
501 xcalloc (size1
, size2
)
504 char *ptr
= (char *) calloc (size1
, size2
);
508 fatal ("out of memory");
516 char *ptr
= (char *) malloc (size
);
520 fatal ("out of memory");
529 register char *value
= (char *) realloc (ptr
, size
);
531 fatal ("virtual memory exhausted");
539 return access (name
, R_OK
) == 0;
542 /* Make a copy of a string INPUT with size SIZE. */
545 savestring (input
, size
)
549 char *output
= (char *) xmalloc (size
+ 1);
550 bcopy (input
, output
, size
);
555 /* Parse a reasonable subset of shell quoting syntax. */
572 obstack_1grow (&temporary_obstack
, c
);
573 else if (! inside
&& c
== ' ')
575 else if (! inside
&& c
== '\\')
580 obstack_1grow (&temporary_obstack
, c
);
583 obstack_1grow (&temporary_obstack
, '\0');
585 return obstack_finish (&temporary_obstack
);
592 FILE *stream
= fopen (name
, "r");
593 int no_demangle
= !! getenv ("COLLECT_NO_DEMANGLE");
600 while (c
= getc (stream
),
601 c
!= EOF
&& (isalnum (c
) || c
== '_' || c
== '$' || c
== '.'))
602 obstack_1grow (&temporary_obstack
, c
);
603 if (obstack_object_size (&temporary_obstack
) > 0)
605 char *word
, *p
, *result
;
606 obstack_1grow (&temporary_obstack
, '\0');
607 word
= obstack_finish (&temporary_obstack
);
610 ++word
, putc ('.', stderr
);
612 if (*p
== '_' && prepends_underscore
)
618 result
= cplus_demangle (p
, DMGL_PARAMS
| DMGL_ANSI
);
623 fputs (result
, stderr
);
625 diff
= strlen (word
) - strlen (result
);
627 --diff
, putc (' ', stderr
);
628 while (diff
< 0 && c
== ' ')
629 ++diff
, c
= getc (stream
);
634 fputs (word
, stderr
);
637 obstack_free (&temporary_obstack
, temporary_firstobj
);
646 /* Decide whether the given symbol is:
647 a constructor (1), a destructor (2), or neither (0). */
653 struct names
{ char *name
; int len
; int ret
; int two_underscores
; };
655 register struct names
*p
;
657 register char *orig_s
= s
;
659 static struct names special
[] = {
660 #ifdef NO_DOLLAR_IN_LABEL
661 #ifdef NO_DOT_IN_LABEL
662 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
663 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
664 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
666 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
667 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
668 { "GLOBAL_.F.", sizeof ("GLOBAL_.F.")-1, 5, 0 },
671 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
672 { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },
673 { "GLOBAL_$F$", sizeof ("GLOBAL_$F$")-1, 5, 0 },
675 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
676 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
677 #ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions.
678 cfront has its own linker procedure to collect them;
679 if collect2 gets them too, they get collected twice
680 when the cfront procedure is run and the compiler used
681 for linking happens to be GCC. */
682 { "sti__", sizeof ("sti__")-1, 1, 1 },
683 { "std__", sizeof ("std__")-1, 2, 1 },
684 #endif /* CFRONT_LOSSAGE */
688 while ((ch
= *s
) == '_')
694 for (p
= &special
[0]; p
->len
> 0; p
++)
697 && (!p
->two_underscores
|| ((s
- orig_s
) >= 2))
698 && strncmp(s
, p
->name
, p
->len
) == 0)
706 /* Routine to add variables to the environment. */
714 #ifndef VMS /* nor about VMS */
716 extern char **environ
;
717 char **old_environ
= environ
;
724 while ((ch
= *p
++) != '\0' && ch
!= '=')
730 /* Search for replacing an existing environment variable, and
731 count the number of total environment variables. */
732 for (envp
= old_environ
; *envp
; envp
++)
735 if (!strncmp (str
, *envp
, name_len
))
742 /* Add a new environment variable */
743 environ
= (char **) xmalloc (sizeof (char *) * (num_envs
+2));
745 bcopy ((char *) old_environ
, (char *) (environ
+ 1),
746 sizeof (char *) * (num_envs
+1));
752 #endif /* HAVE_PUTENV */
754 /* By default, colon separates directories in a path. */
755 #ifndef PATH_SEPARATOR
756 #define PATH_SEPARATOR ':'
759 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
760 and one from the PATH variable. */
762 static struct path_prefix cpath
, path
;
765 /* This is the name of the target machine. We use it to form the name
766 of the files to execute. */
768 static char *target_machine
= TARGET_MACHINE
;
771 /* Names under which we were executed. Never return one of those files in our
774 static struct path_prefix our_file_names
;
776 /* Determine if STRING is in PPREFIX.
778 This utility is currently only used to look up file names. Prefix lists
779 record directory names. This matters to us because the latter has a
780 trailing slash, so I've added a flag to handle both. */
783 is_in_prefix_list (pprefix
, string
, filep
)
784 struct path_prefix
*pprefix
;
788 struct prefix_list
*pl
;
792 int len
= strlen (string
);
794 for (pl
= pprefix
->plist
; pl
; pl
= pl
->next
)
796 if (strncmp (pl
->prefix
, string
, len
) == 0
797 && strcmp (pl
->prefix
+ len
, "/") == 0)
803 for (pl
= pprefix
->plist
; pl
; pl
= pl
->next
)
805 if (strcmp (pl
->prefix
, string
) == 0)
813 /* Search for NAME using prefix list PPREFIX. We only look for executable
816 Return 0 if not found, otherwise return its name, allocated with malloc. */
819 find_a_file (pprefix
, name
)
820 struct path_prefix
*pprefix
;
824 struct prefix_list
*pl
;
825 int len
= pprefix
->max_len
+ strlen (name
) + 1;
827 #ifdef EXECUTABLE_SUFFIX
828 len
+= strlen (EXECUTABLE_SUFFIX
);
831 temp
= xmalloc (len
);
833 /* Determine the filename to execute (special case for absolute paths). */
837 if (access (name
, X_OK
) == 0)
844 for (pl
= pprefix
->plist
; pl
; pl
= pl
->next
)
846 strcpy (temp
, pl
->prefix
);
848 if (! is_in_prefix_list (&our_file_names
, temp
, 1)
849 /* This is a kludge, but there seems no way around it. */
850 && strcmp (temp
, "./ld") != 0
851 && access (temp
, X_OK
) == 0)
854 #ifdef EXECUTABLE_SUFFIX
855 /* Some systems have a suffix for executable files.
856 So try appending that. */
857 strcat (temp
, EXECUTABLE_SUFFIX
);
858 if (! is_in_prefix_list (&our_file_names
, temp
, 1)
859 && access (temp
, X_OK
) == 0)
868 /* Add an entry for PREFIX to prefix list PPREFIX. */
871 add_prefix (pprefix
, prefix
)
872 struct path_prefix
*pprefix
;
875 struct prefix_list
*pl
, **prev
;
880 for (pl
= pprefix
->plist
; pl
->next
; pl
= pl
->next
)
885 prev
= &pprefix
->plist
;
887 /* Keep track of the longest prefix */
889 len
= strlen (prefix
);
890 if (len
> pprefix
->max_len
)
891 pprefix
->max_len
= len
;
893 pl
= (struct prefix_list
*) xmalloc (sizeof (struct prefix_list
));
894 pl
->prefix
= savestring (prefix
, len
);
899 pl
->next
= (struct prefix_list
*) 0;
903 /* Take the value of the environment variable ENV, break it into a path, and
904 add of the entries to PPREFIX. */
907 prefix_from_env (env
, pprefix
)
909 struct path_prefix
*pprefix
;
911 char *p
= getenv (env
);
914 prefix_from_string (p
, pprefix
);
918 prefix_from_string (p
, pprefix
)
920 struct path_prefix
*pprefix
;
923 char *nstore
= (char *) xmalloc (strlen (p
) + 3);
928 if (*endp
== PATH_SEPARATOR
|| *endp
== 0)
930 strncpy (nstore
, startp
, endp
-startp
);
933 strcpy (nstore
, "./");
935 else if (endp
[-1] != '/')
937 nstore
[endp
-startp
] = '/';
938 nstore
[endp
-startp
+1] = 0;
941 nstore
[endp
-startp
] = 0;
943 add_prefix (pprefix
, nstore
);
946 endp
= startp
= endp
+ 1;
960 char *ld_suffix
= "ld";
961 char *full_ld_suffix
= ld_suffix
;
962 char *real_ld_suffix
= "real-ld";
964 char *full_real_ld_suffix
= real_ld_suffix
;
966 char *collect_ld_suffix
= "collect-ld";
967 char *nm_suffix
= "nm";
968 char *full_nm_suffix
= nm_suffix
;
969 char *gnm_suffix
= "gnm";
970 char *full_gnm_suffix
= gnm_suffix
;
972 char *ldd_suffix
= LDD_SUFFIX
;
973 char *full_ldd_suffix
= ldd_suffix
;
975 char *strip_suffix
= "strip";
976 char *full_strip_suffix
= strip_suffix
;
977 char *gstrip_suffix
= "gstrip";
978 char *full_gstrip_suffix
= gstrip_suffix
;
981 #ifdef COLLECT_EXPORT_LIST
991 char **ld1_argv
= (char **) xcalloc (sizeof (char *), argc
+3);
992 char **ld1
= ld1_argv
;
993 char **ld2_argv
= (char **) xcalloc (sizeof (char *), argc
+6);
994 char **ld2
= ld2_argv
;
995 char **object_lst
= (char **) xcalloc (sizeof (char *), argc
);
996 char **object
= object_lst
;
998 int num_c_args
= argc
+7;
1005 #ifndef DEFAULT_A_OUT_NAME
1006 output_file
= "a.out";
1008 output_file
= DEFAULT_A_OUT_NAME
;
1011 obstack_begin (&temporary_obstack
, 0);
1012 obstack_begin (&permanent_obstack
, 0);
1013 temporary_firstobj
= (char *) obstack_alloc (&temporary_obstack
, 0);
1014 current_demangling_style
= gnu_demangling
;
1016 /* We must check that we do not call ourselves in an infinite
1017 recursion loop. We append the name used for us to the COLLECT_NAMES
1018 environment variable.
1020 In practice, collect will rarely invoke itself. This can happen now
1021 that we are no longer called gld. A perfect example is when running
1022 gcc in a build directory that has been installed. When looking for
1023 ld, we will find our installed version and believe that's the real ld. */
1025 /* We must also append COLLECT_NAME to COLLECT_NAMES to watch for the
1026 previous version of collect (the one that used COLLECT_NAME and only
1027 handled two levels of recursion). If we do not we may mutually recurse
1028 forever. This can happen (I think) when bootstrapping the old version
1029 and a new one is installed (rare, but we should handle it).
1030 ??? Hopefully references to COLLECT_NAME can be removed at some point. */
1032 collect_name
= (char *) getenv ("COLLECT_NAME");
1033 collect_names
= (char *) getenv ("COLLECT_NAMES");
1035 p
= (char *) xmalloc (strlen ("COLLECT_NAMES=")
1036 + (collect_name
? strlen (collect_name
) + 1 : 0)
1037 + (collect_names
? strlen (collect_names
) + 1 : 0)
1038 + strlen (argv
[0]) + 1);
1039 strcpy (p
, "COLLECT_NAMES=");
1040 if (collect_name
!= 0)
1041 sprintf (p
+ strlen (p
), "%s%c", collect_name
, PATH_SEPARATOR
);
1042 if (collect_names
!= 0)
1043 sprintf (p
+ strlen (p
), "%s%c", collect_names
, PATH_SEPARATOR
);
1044 strcat (p
, argv
[0]);
1047 prefix_from_env ("COLLECT_NAMES", &our_file_names
);
1049 /* Set environment variable COLLECT_NAME to our name so the previous version
1050 of collect will not find us. If it does we will mutually recurse forever.
1051 This can happen when bootstrapping the new version and an old version is
1053 ??? Hopefully this bit of code can be removed at some point. */
1055 p
= xmalloc (strlen ("COLLECT_NAME=") + strlen (argv
[0]) + 1);
1056 sprintf (p
, "COLLECT_NAME=%s", argv
[0]);
1059 p
= (char *) getenv ("COLLECT_GCC_OPTIONS");
1062 char *q
= extract_string (&p
);
1063 if (*q
== '-' && (q
[1] == 'm' || q
[1] == 'f'))
1066 obstack_free (&temporary_obstack
, temporary_firstobj
);
1069 c_ptr
= c_argv
= (char **) xcalloc (sizeof (char *), num_c_args
);
1072 fatal ("no arguments");
1075 if (signal (SIGQUIT
, SIG_IGN
) != SIG_IGN
)
1076 signal (SIGQUIT
, handler
);
1078 if (signal (SIGINT
, SIG_IGN
) != SIG_IGN
)
1079 signal (SIGINT
, handler
);
1081 if (signal (SIGALRM
, SIG_IGN
) != SIG_IGN
)
1082 signal (SIGALRM
, handler
);
1085 if (signal (SIGHUP
, SIG_IGN
) != SIG_IGN
)
1086 signal (SIGHUP
, handler
);
1088 if (signal (SIGSEGV
, SIG_IGN
) != SIG_IGN
)
1089 signal (SIGSEGV
, handler
);
1091 if (signal (SIGBUS
, SIG_IGN
) != SIG_IGN
)
1092 signal (SIGBUS
, handler
);
1095 /* Extract COMPILER_PATH and PATH into our prefix list. */
1096 prefix_from_env ("COMPILER_PATH", &cpath
);
1097 prefix_from_env ("PATH", &path
);
1099 #ifdef CROSS_COMPILE
1100 /* If we look for a program in the compiler directories, we just use
1101 the short name, since these directories are already system-specific.
1102 But it we look for a took in the system directories, we need to
1103 qualify the program name with the target machine. */
1106 = xcalloc (strlen (ld_suffix
) + strlen (target_machine
) + 2, 1);
1107 strcpy (full_ld_suffix
, target_machine
);
1108 strcat (full_ld_suffix
, "-");
1109 strcat (full_ld_suffix
, ld_suffix
);
1112 = xcalloc (strlen (real_ld_suffix
) + strlen (target_machine
) + 2, 1);
1113 strcpy (full_real_ld_suffix
, target_machine
);
1114 strcat (full_real_ld_suffix
, "-");
1115 strcat (full_real_ld_suffix
, real_ld_suffix
);
1119 = xcalloc (strlen (gld_suffix
) + strlen (target_machine
) + 2, 1);
1120 strcpy (full_gld_suffix
, target_machine
);
1121 strcat (full_gld_suffix
, "-");
1122 strcat (full_gld_suffix
, gld_suffix
);
1126 = xcalloc (strlen (nm_suffix
) + strlen (target_machine
) + 2, 1);
1127 strcpy (full_nm_suffix
, target_machine
);
1128 strcat (full_nm_suffix
, "-");
1129 strcat (full_nm_suffix
, nm_suffix
);
1132 = xcalloc (strlen (gnm_suffix
) + strlen (target_machine
) + 2, 1);
1133 strcpy (full_gnm_suffix
, target_machine
);
1134 strcat (full_gnm_suffix
, "-");
1135 strcat (full_gnm_suffix
, gnm_suffix
);
1139 = xcalloc (strlen (ldd_suffix
) + strlen (target_machine
) + 2, 1);
1140 strcpy (full_ldd_suffix
, target_machine
);
1141 strcat (full_ldd_suffix
, "-");
1142 strcat (full_ldd_suffix
, ldd_suffix
);
1146 = xcalloc (strlen (strip_suffix
) + strlen (target_machine
) + 2, 1);
1147 strcpy (full_strip_suffix
, target_machine
);
1148 strcat (full_strip_suffix
, "-");
1149 strcat (full_strip_suffix
, strip_suffix
);
1152 = xcalloc (strlen (gstrip_suffix
) + strlen (target_machine
) + 2, 1);
1153 strcpy (full_gstrip_suffix
, target_machine
);
1154 strcat (full_gstrip_suffix
, "-");
1155 strcat (full_gstrip_suffix
, gstrip_suffix
);
1156 #endif /* CROSS_COMPILE */
1158 /* Try to discover a valid linker/nm/strip to use. */
1160 /* Maybe we know the right file to use (if not cross). */
1161 #ifdef REAL_LD_FILE_NAME
1162 ld_file_name
= find_a_file (&path
, REAL_LD_FILE_NAME
);
1163 if (ld_file_name
== 0)
1165 /* Search the (target-specific) compiler dirs for ld'. */
1166 ld_file_name
= find_a_file (&cpath
, real_ld_suffix
);
1167 /* Likewise for `collect-ld'. */
1168 if (ld_file_name
== 0)
1169 ld_file_name
= find_a_file (&cpath
, collect_ld_suffix
);
1170 /* Search the compiler directories for `ld'. We have protection against
1171 recursive calls in find_a_file. */
1172 if (ld_file_name
== 0)
1173 ld_file_name
= find_a_file (&cpath
, ld_suffix
);
1174 /* Search the ordinary system bin directories
1175 for `ld' (if native linking) or `TARGET-ld' (if cross). */
1176 if (ld_file_name
== 0)
1177 ld_file_name
= find_a_file (&path
, full_ld_suffix
);
1179 /* If we've invoked ourselves, try again with LD_FILE_NAME. */
1181 if (collect_names
!= 0)
1183 if (ld_file_name
!= 0)
1185 argv
[0] = ld_file_name
;
1186 execvp (argv
[0], argv
);
1188 fatal ("cannot find `ld'");
1191 #ifdef REAL_NM_FILE_NAME
1192 nm_file_name
= find_a_file (&path
, REAL_NM_FILE_NAME
);
1193 if (nm_file_name
== 0)
1195 nm_file_name
= find_a_file (&cpath
, gnm_suffix
);
1196 if (nm_file_name
== 0)
1197 nm_file_name
= find_a_file (&path
, full_gnm_suffix
);
1198 if (nm_file_name
== 0)
1199 nm_file_name
= find_a_file (&cpath
, nm_suffix
);
1200 if (nm_file_name
== 0)
1201 nm_file_name
= find_a_file (&path
, full_nm_suffix
);
1204 ldd_file_name
= find_a_file (&cpath
, ldd_suffix
);
1205 if (ldd_file_name
== 0)
1206 ldd_file_name
= find_a_file (&path
, full_ldd_suffix
);
1209 #ifdef REAL_STRIP_FILE_NAME
1210 strip_file_name
= find_a_file (&path
, REAL_STRIP_FILE_NAME
);
1211 if (strip_file_name
== 0)
1213 strip_file_name
= find_a_file (&cpath
, gstrip_suffix
);
1214 if (strip_file_name
== 0)
1215 strip_file_name
= find_a_file (&path
, full_gstrip_suffix
);
1216 if (strip_file_name
== 0)
1217 strip_file_name
= find_a_file (&cpath
, strip_suffix
);
1218 if (strip_file_name
== 0)
1219 strip_file_name
= find_a_file (&path
, full_strip_suffix
);
1221 /* Determine the full path name of the C compiler to use. */
1222 c_file_name
= getenv ("COLLECT_GCC");
1223 if (c_file_name
== 0)
1225 #ifdef CROSS_COMPILE
1226 c_file_name
= xcalloc (sizeof ("gcc-") + strlen (target_machine
) + 1, 1);
1227 strcpy (c_file_name
, target_machine
);
1228 strcat (c_file_name
, "-gcc");
1230 c_file_name
= "gcc";
1234 p
= find_a_file (&cpath
, c_file_name
);
1236 /* Here it should be safe to use the system search path since we should have
1237 already qualified the name of the compiler when it is needed. */
1239 p
= find_a_file (&path
, c_file_name
);
1244 *ld1
++ = *ld2
++ = ld_file_name
;
1246 /* Make temp file names. */
1247 temp_filename
= choose_temp_base ();
1248 temp_filename_length
= strlen (temp_filename
);
1249 c_file
= xcalloc (temp_filename_length
+ sizeof (".c"), 1);
1250 o_file
= xcalloc (temp_filename_length
+ sizeof (".o"), 1);
1251 #ifdef COLLECT_EXPORT_LIST
1252 export_file
= xmalloc (temp_filename_length
+ sizeof (".x"));
1253 import_file
= xmalloc (temp_filename_length
+ sizeof (".p"));
1255 ldout
= xmalloc (temp_filename_length
+ sizeof (".ld"));
1256 sprintf (ldout
, "%s.ld", temp_filename
);
1257 sprintf (c_file
, "%s.c", temp_filename
);
1258 sprintf (o_file
, "%s.o", temp_filename
);
1259 #ifdef COLLECT_EXPORT_LIST
1260 sprintf (export_file
, "%s.x", temp_filename
);
1261 sprintf (import_file
, "%s.p", temp_filename
);
1263 *c_ptr
++ = c_file_name
;
1268 #ifdef COLLECT_EXPORT_LIST
1269 /* Generate a list of directories from LIBPATH. */
1270 prefix_from_env ("LIBPATH", &libpath_lib_dirs
);
1271 /* Add to this list also two standard directories where
1272 AIX loader always searches for libraries. */
1273 add_prefix (&libpath_lib_dirs
, "/lib");
1274 add_prefix (&libpath_lib_dirs
, "/usr/lib");
1277 /* Get any options that the upper GCC wants to pass to the sub-GCC.
1279 AIX support needs to know if -shared has been specified before
1280 parsing commandline arguments. */
1282 p
= (char *) getenv ("COLLECT_GCC_OPTIONS");
1285 char *q
= extract_string (&p
);
1286 if (*q
== '-' && (q
[1] == 'm' || q
[1] == 'f'))
1287 *c_ptr
++ = obstack_copy0 (&permanent_obstack
, q
, strlen (q
));
1288 if (strncmp (q
, "-shared", sizeof ("-shared") - 1) == 0)
1291 obstack_free (&temporary_obstack
, temporary_firstobj
);
1292 *c_ptr
++ = "-fno-exceptions";
1294 /* !!! When GCC calls collect2,
1295 it does not know whether it is calling collect2 or ld.
1296 So collect2 cannot meaningfully understand any options
1297 except those ld understands.
1298 If you propose to make GCC pass some other option,
1299 just imagine what will happen if ld is really ld!!! */
1301 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1302 /* After the first file, put in the c++ rt0. */
1305 while ((arg
= *++argv
) != (char *) 0)
1307 *ld1
++ = *ld2
++ = arg
;
1313 #ifdef COLLECT_EXPORT_LIST
1314 /* We want to disable automatic exports on AIX when user
1315 explicitly puts an export list in command line */
1317 if (arg
[2] == 'E' || strncmp (&arg
[2], "export", 6) == 0)
1323 if (!strcmp (arg
, "-debug"))
1335 /* place o_file BEFORE this argument! */
1341 #ifdef COLLECT_EXPORT_LIST
1343 /* Resolving full library name. */
1344 char *s
= resolve_lib_name (arg
+2);
1346 /* If we will use an import list for this library,
1347 we should exclude it from ld args. */
1348 if (use_import_list (s
))
1354 /* Saving a full library name. */
1355 add_to_list (&libs
, s
);
1360 #ifdef COLLECT_EXPORT_LIST
1361 /* Saving directories where to search for libraries. */
1363 add_prefix (&cmdline_lib_dirs
, arg
+2);
1369 output_file
= *ld1
++ = *ld2
++ = *++argv
;
1371 output_file
= &arg
[2];
1380 if (arg
[2] == '\0' && do_collecting
)
1382 /* We must strip after the nm run, otherwise C++ linking
1383 will not work. Thus we strip in the second ld run, or
1384 else with strip if there is no second ld run. */
1396 else if ((p
= rindex (arg
, '.')) != (char *) 0
1397 && (strcmp (p
, ".o") == 0 || strcmp (p
, ".a") == 0
1398 || strcmp (p
, ".so") == 0))
1407 /* place o_file BEFORE this argument! */
1415 #ifdef COLLECT_EXPORT_LIST
1416 /* libraries can be specified directly, i.e. without -l flag. */
1419 /* If we will use an import list for this library,
1420 we should exclude it from ld args. */
1421 if (use_import_list (arg
))
1427 /* Saving a full library name. */
1428 add_to_list (&libs
, arg
);
1434 #ifdef COLLECT_EXPORT_LIST
1435 /* This is added only for debugging purposes. */
1438 fprintf (stderr
, "List of libraries:\n");
1439 dump_list (stderr
, "\t", libs
.first
);
1442 /* The AIX linker will discard static constructors in object files if
1443 nothing else in the file is referenced, so look at them first. */
1445 char **export_object_lst
= object_lst
;
1446 while (export_object_lst
< object
)
1447 scan_prog_file (*export_object_lst
++, PASS_OBJ
);
1450 struct id
*list
= libs
.first
;
1451 for (; list
; list
= list
->next
)
1452 scan_prog_file (list
->name
, PASS_FIRST
);
1455 char *buf1
= alloca (strlen (export_file
) + 5);
1456 char *buf2
= alloca (strlen (import_file
) + 5);
1457 sprintf (buf1
, "-bE:%s", export_file
);
1458 sprintf (buf2
, "-bI:%s", import_file
);
1463 exportf
= fopen (export_file
, "w");
1464 if (exportf
== (FILE *) 0)
1465 fatal_perror ("%s", export_file
);
1466 write_export_file (exportf
);
1467 if (fclose (exportf
))
1468 fatal_perror ("closing %s", export_file
);
1469 importf
= fopen (import_file
, "w");
1470 if (importf
== (FILE *) 0)
1471 fatal_perror ("%s", import_file
);
1472 write_import_file (importf
);
1473 if (fclose (importf
))
1474 fatal_perror ("closing %s", import_file
);
1479 *object
= *c_ptr
= *ld1
= (char *) 0;
1483 fprintf (stderr
, "collect2 version %s", version_string
);
1484 #ifdef TARGET_VERSION
1487 fprintf (stderr
, "\n");
1493 fprintf (stderr
, "ld_file_name = %s\n",
1494 (ld_file_name
? ld_file_name
: "not found"));
1495 fprintf (stderr
, "c_file_name = %s\n",
1496 (c_file_name
? c_file_name
: "not found"));
1497 fprintf (stderr
, "nm_file_name = %s\n",
1498 (nm_file_name
? nm_file_name
: "not found"));
1500 fprintf (stderr
, "ldd_file_name = %s\n",
1501 (ldd_file_name
? ldd_file_name
: "not found"));
1503 fprintf (stderr
, "strip_file_name = %s\n",
1504 (strip_file_name
? strip_file_name
: "not found"));
1505 fprintf (stderr
, "c_file = %s\n",
1506 (c_file
? c_file
: "not found"));
1507 fprintf (stderr
, "o_file = %s\n",
1508 (o_file
? o_file
: "not found"));
1510 ptr
= getenv ("COLLECT_NAMES");
1512 fprintf (stderr
, "COLLECT_NAMES = %s\n", ptr
);
1514 ptr
= getenv ("COLLECT_GCC_OPTIONS");
1516 fprintf (stderr
, "COLLECT_GCC_OPTIONS = %s\n", ptr
);
1518 ptr
= getenv ("COLLECT_GCC");
1520 fprintf (stderr
, "COLLECT_GCC = %s\n", ptr
);
1522 ptr
= getenv ("COMPILER_PATH");
1524 fprintf (stderr
, "COMPILER_PATH = %s\n", ptr
);
1526 ptr
= getenv ("LIBRARY_PATH");
1528 fprintf (stderr
, "LIBRARY_PATH = %s\n", ptr
);
1530 fprintf (stderr
, "\n");
1533 /* Load the program, searching all libraries and attempting to provide
1534 undefined symbols from repository information. */
1536 /* On AIX we do this later. */
1537 #ifndef COLLECT_EXPORT_LIST
1538 do_tlink (ld1_argv
, object_lst
);
1541 /* If -r or they will be run via some other method, do not build the
1542 constructor or destructor list, just return now. */
1543 if (rflag
|| ! do_collecting
)
1545 /* But make sure we delete the export file we may have created. */
1546 if (export_file
!= 0 && export_file
[0])
1547 maybe_unlink (export_file
);
1548 if (import_file
!= 0 && import_file
[0])
1549 maybe_unlink (import_file
);
1553 /* Examine the namelist with nm and search it for static constructors
1554 and destructors to call.
1555 Write the constructor and destructor tables to a .s file and reload. */
1557 /* On AIX we already done scanning for global constructors/destructors. */
1558 #ifndef COLLECT_EXPORT_LIST
1559 scan_prog_file (output_file
, PASS_FIRST
);
1562 #ifdef SCAN_LIBRARIES
1563 scan_libraries (output_file
);
1568 fprintf (stderr
, "%d constructor(s) found\n", constructors
.number
);
1569 fprintf (stderr
, "%d destructor(s) found\n", destructors
.number
);
1572 if (constructors
.number
== 0 && destructors
.number
== 0
1573 && frame_tables
.number
== 0
1574 #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1575 /* If we will be running these functions ourselves, we want to emit
1576 stubs into the shared library so that we do not have to relink
1577 dependent programs when we add static objects. */
1582 #ifdef COLLECT_EXPORT_LIST
1583 /* Doing tlink without additional code generation */
1584 do_tlink (ld1_argv
, object_lst
);
1586 /* Strip now if it was requested on the command line. */
1589 char **strip_argv
= (char **) xcalloc (sizeof (char *), 3);
1590 strip_argv
[0] = strip_file_name
;
1591 strip_argv
[1] = output_file
;
1592 strip_argv
[2] = (char *) 0;
1593 fork_execute ("strip", strip_argv
);
1596 #ifdef COLLECT_EXPORT_LIST
1597 maybe_unlink (export_file
);
1598 maybe_unlink (import_file
);
1603 maybe_unlink(output_file
);
1604 outf
= fopen (c_file
, "w");
1605 if (outf
== (FILE *) 0)
1606 fatal_perror ("%s", c_file
);
1608 write_c_file (outf
, c_file
);
1611 fatal_perror ("closing %s", c_file
);
1613 /* Tell the linker that we have initializer and finalizer functions. */
1614 #ifdef LD_INIT_SWITCH
1615 *ld2
++ = LD_INIT_SWITCH
;
1617 *ld2
++ = LD_FINI_SWITCH
;
1622 #ifdef COLLECT_EXPORT_LIST
1625 add_to_list (&exports
, initname
);
1626 add_to_list (&exports
, fininame
);
1627 add_to_list (&exports
, "_GLOBAL__DI");
1628 add_to_list (&exports
, "_GLOBAL__DD");
1629 exportf
= fopen (export_file
, "w");
1630 if (exportf
== (FILE *) 0)
1631 fatal_perror ("%s", export_file
);
1632 write_export_file (exportf
);
1633 if (fclose (exportf
))
1634 fatal_perror ("closing %s", export_file
);
1640 fprintf (stderr
, "\n========== output_file = %s, c_file = %s\n",
1641 output_file
, c_file
);
1642 write_c_file (stderr
, "stderr");
1643 fprintf (stderr
, "========== end of c_file\n\n");
1644 #ifdef COLLECT_EXPORT_LIST
1645 fprintf (stderr
, "\n========== export_file = %s\n", export_file
);
1646 write_export_file (stderr
);
1647 fprintf (stderr
, "========== end of export_file\n\n");
1651 /* Assemble the constructor and destructor tables.
1652 Link the tables in with the rest of the program. */
1654 fork_execute ("gcc", c_argv
);
1655 #ifdef COLLECT_EXPORT_LIST
1656 /* On AIX we must call tlink because of possible templates resolution */
1657 do_tlink (ld2_argv
, object_lst
);
1659 /* Otherwise, simply call ld because tlink is already done */
1660 fork_execute ("ld", ld2_argv
);
1662 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1663 constructors/destructors in shared libraries. */
1664 scan_prog_file (output_file
, PASS_SECOND
);
1667 maybe_unlink (c_file
);
1668 maybe_unlink (o_file
);
1670 #ifdef COLLECT_EXPORT_LIST
1671 maybe_unlink (export_file
);
1672 maybe_unlink (import_file
);
1679 /* Wait for a process to finish, and exit if a non-zero status is found. */
1690 if (WIFSIGNALED (status
))
1692 int sig
= WTERMSIG (status
);
1693 #ifdef NO_SYS_SIGLIST
1694 error ("%s terminated with signal %d %s",
1697 (status
& 0200) ? ", core dumped" : "");
1699 error ("%s terminated with signal %d [%s]%s",
1703 (status
& 0200) ? ", core dumped" : "");
1706 collect_exit (FATAL_EXIT_CODE
);
1709 if (WIFEXITED (status
))
1710 return WEXITSTATUS (status
);
1719 int ret
= collect_wait (prog
);
1722 error ("%s returned %d exit status", prog
, ret
);
1728 /* Fork and execute a program, and wait for the reply. */
1731 collect_execute (prog
, argv
, redir
)
1744 fprintf (stderr
, "%s", argv
[0]);
1746 fprintf (stderr
, "[cannot find %s]", prog
);
1748 for (p_argv
= &argv
[1]; (str
= *p_argv
) != (char *) 0; p_argv
++)
1749 fprintf (stderr
, " %s", str
);
1751 fprintf (stderr
, "\n");
1757 /* If we cannot find a program we need, complain error. Do this here
1758 since we might not end up needing something that we could not find. */
1761 fatal ("cannot find `%s'", prog
);
1767 fatal_perror ("fork");
1769 fatal_perror ("vfork");
1773 if (pid
== 0) /* child context */
1778 if (freopen (redir
, "a", stdout
) == NULL
)
1779 fatal_perror ("redirecting stdout: %s", redir
);
1780 if (freopen (redir
, "a", stderr
) == NULL
)
1781 fatal_perror ("redirecting stderr: %s", redir
);
1784 execvp (argv
[0], argv
);
1785 fatal_perror ("executing %s", prog
);
1790 fork_execute (prog
, argv
)
1794 collect_execute (prog
, argv
, NULL
);
1798 /* Unlink a file unless we are debugging. */
1807 fprintf (stderr
, "[Leaving %s]\n", file
);
1811 /* Add a name to a linked list. */
1814 add_to_list (head_ptr
, name
)
1815 struct head
*head_ptr
;
1819 = (struct id
*) xcalloc (sizeof (struct id
) + strlen (name
), 1);
1821 static long sequence_number
= 0;
1822 strcpy (newid
->name
, name
);
1824 if (head_ptr
->first
)
1825 head_ptr
->last
->next
= newid
;
1827 head_ptr
->first
= newid
;
1829 /* Check for duplicate symbols. */
1830 for (p
= head_ptr
->first
;
1831 strcmp (name
, p
->name
) != 0;
1836 head_ptr
->last
->next
= 0;
1841 newid
->sequence
= ++sequence_number
;
1842 head_ptr
->last
= newid
;
1846 /* Write: `prefix', the names on list LIST, `suffix'. */
1849 write_list (stream
, prefix
, list
)
1856 fprintf (stream
, "%sx%d,\n", prefix
, list
->sequence
);
1861 /* This function is really used only on AIX, but may be useful. */
1863 is_in_list (prefix
, list
)
1869 if (!strcmp (prefix
, list
->name
)) return 1;
1875 /* Added for debugging purpose. */
1877 dump_list (stream
, prefix
, list
)
1884 fprintf (stream
, "%s%s,\n", prefix
, list
->name
);
1890 dump_prefix_list (stream
, prefix
, list
)
1893 struct prefix_list
*list
;
1897 fprintf (stream
, "%s%s,\n", prefix
, list
->prefix
);
1903 write_list_with_asm (stream
, prefix
, list
)
1910 fprintf (stream
, "%sx%d __asm__ (\"%s\");\n",
1911 prefix
, list
->sequence
, list
->name
);
1916 /* Write out the constructor and destructor tables statically (for a shared
1917 object), along with the functions to execute them. */
1920 write_c_file_stat (stream
, name
)
1924 char *prefix
, *p
, *q
;
1925 int frames
= (frame_tables
.number
> 0);
1927 /* Figure out name of output_file, stripping off .so version. */
1928 p
= rindex (output_file
, '/');
1930 p
= (char *) output_file
;
1944 if (strncmp (q
, ".so", 3) == 0)
1953 /* q points to null at end of the string (or . of the .so version) */
1954 prefix
= xmalloc (q
- p
+ 1);
1955 strncpy (prefix
, p
, q
- p
);
1957 for (q
= prefix
; *q
; q
++)
1961 fprintf (stderr
, "\nwrite_c_file - output name is %s, prefix is %s\n",
1962 output_file
, prefix
);
1964 #define INIT_NAME_FORMAT "_GLOBAL__FI_%s"
1965 initname
= xmalloc (strlen (prefix
) + sizeof (INIT_NAME_FORMAT
) - 2);
1966 sprintf (initname
, INIT_NAME_FORMAT
, prefix
);
1968 #define FINI_NAME_FORMAT "_GLOBAL__FD_%s"
1969 fininame
= xmalloc (strlen (prefix
) + sizeof (FINI_NAME_FORMAT
) - 2);
1970 sprintf (fininame
, FINI_NAME_FORMAT
, prefix
);
1974 /* Write the tables as C code */
1976 fprintf (stream
, "static int count;\n");
1977 fprintf (stream
, "typedef void entry_pt();\n");
1978 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
1982 write_list_with_asm (stream
, "extern void *", frame_tables
.first
);
1984 fprintf (stream
, "\tstatic void *frame_table[] = {\n");
1985 write_list (stream
, "\t\t&", frame_tables
.first
);
1986 fprintf (stream
, "\t0\n};\n");
1988 /* This must match what's in frame.h. */
1989 fprintf (stream
, "struct object {\n");
1990 fprintf (stream
, " void *pc_begin;\n");
1991 fprintf (stream
, " void *pc_end;\n");
1992 fprintf (stream
, " void *fde_begin;\n");
1993 fprintf (stream
, " void *fde_array;\n");
1994 fprintf (stream
, " __SIZE_TYPE__ count;\n");
1995 fprintf (stream
, " struct object *next;\n");
1996 fprintf (stream
, "};\n");
1998 fprintf (stream
, "extern void __register_frame_info_table (void *, struct object *);\n");
1999 fprintf (stream
, "extern void *__deregister_frame_info (void *);\n");
2001 fprintf (stream
, "static void reg_frame () {\n");
2002 fprintf (stream
, "\tstatic struct object ob;\n");
2003 fprintf (stream
, "\t__register_frame_info_table (frame_table, &ob);\n");
2004 fprintf (stream
, "\t}\n");
2006 fprintf (stream
, "static void dereg_frame () {\n");
2007 fprintf (stream
, "\t__deregister_frame_info (frame_table);\n");
2008 fprintf (stream
, "\t}\n");
2011 fprintf (stream
, "void %s() {\n", initname
);
2012 if (constructors
.number
> 0 || frames
)
2014 fprintf (stream
, "\tstatic entry_pt *ctors[] = {\n");
2015 write_list (stream
, "\t\t", constructors
.first
);
2017 fprintf (stream
, "\treg_frame,\n");
2018 fprintf (stream
, "\t};\n");
2019 fprintf (stream
, "\tentry_pt **p;\n");
2020 fprintf (stream
, "\tif (count++ != 0) return;\n");
2021 fprintf (stream
, "\tp = ctors + %d;\n", constructors
.number
+ frames
);
2022 fprintf (stream
, "\twhile (p > ctors) (*--p)();\n");
2025 fprintf (stream
, "\t++count;\n");
2026 fprintf (stream
, "}\n");
2027 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
2028 fprintf (stream
, "void %s() {\n", fininame
);
2029 if (destructors
.number
> 0 || frames
)
2031 fprintf (stream
, "\tstatic entry_pt *dtors[] = {\n");
2032 write_list (stream
, "\t\t", destructors
.first
);
2034 fprintf (stream
, "\tdereg_frame,\n");
2035 fprintf (stream
, "\t};\n");
2036 fprintf (stream
, "\tentry_pt **p;\n");
2037 fprintf (stream
, "\tif (--count != 0) return;\n");
2038 fprintf (stream
, "\tp = dtors;\n");
2039 fprintf (stream
, "\twhile (p < dtors + %d) (*p++)();\n",
2040 destructors
.number
+ frames
);
2042 fprintf (stream
, "}\n");
2046 fprintf (stream
, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname
);
2047 fprintf (stream
, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame
);
2051 /* Write the constructor/destructor tables. */
2054 write_c_file_glob (stream
, name
)
2058 /* Write the tables as C code */
2060 int frames
= (frame_tables
.number
> 0);
2062 fprintf (stream
, "typedef void entry_pt();\n\n");
2064 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
2068 write_list_with_asm (stream
, "extern void *", frame_tables
.first
);
2070 fprintf (stream
, "\tstatic void *frame_table[] = {\n");
2071 write_list (stream
, "\t\t&", frame_tables
.first
);
2072 fprintf (stream
, "\t0\n};\n");
2074 /* This must match what's in frame.h. */
2075 fprintf (stream
, "struct object {\n");
2076 fprintf (stream
, " void *pc_begin;\n");
2077 fprintf (stream
, " void *pc_end;\n");
2078 fprintf (stream
, " void *fde_begin;\n");
2079 fprintf (stream
, " void *fde_array;\n");
2080 fprintf (stream
, " __SIZE_TYPE__ count;\n");
2081 fprintf (stream
, " struct object *next;\n");
2082 fprintf (stream
, "};\n");
2084 fprintf (stream
, "extern void __register_frame_info_table (void *, struct object *);\n");
2085 fprintf (stream
, "extern void *__deregister_frame_info (void *);\n");
2087 fprintf (stream
, "static void reg_frame () {\n");
2088 fprintf (stream
, "\tstatic struct object ob;\n");
2089 fprintf (stream
, "\t__register_frame_info_table (frame_table, &ob);\n");
2090 fprintf (stream
, "\t}\n");
2092 fprintf (stream
, "static void dereg_frame () {\n");
2093 fprintf (stream
, "\t__deregister_frame_info (frame_table);\n");
2094 fprintf (stream
, "\t}\n");
2097 fprintf (stream
, "\nentry_pt * __CTOR_LIST__[] = {\n");
2098 fprintf (stream
, "\t(entry_pt *) %d,\n", constructors
.number
+ frames
);
2099 write_list (stream
, "\t", constructors
.first
);
2101 fprintf (stream
, "\treg_frame,\n");
2102 fprintf (stream
, "\t0\n};\n\n");
2104 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
2106 fprintf (stream
, "\nentry_pt * __DTOR_LIST__[] = {\n");
2107 fprintf (stream
, "\t(entry_pt *) %d,\n", destructors
.number
+ frames
);
2108 write_list (stream
, "\t", destructors
.first
);
2110 fprintf (stream
, "\tdereg_frame,\n");
2111 fprintf (stream
, "\t0\n};\n\n");
2113 fprintf (stream
, "extern entry_pt %s;\n", NAME__MAIN
);
2114 fprintf (stream
, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN
);
2118 write_c_file (stream
, name
)
2122 fprintf (stream
, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
2123 #ifndef LD_INIT_SWITCH
2125 write_c_file_glob (stream
, name
);
2128 write_c_file_stat (stream
, name
);
2129 fprintf (stream
, "#ifdef __cplusplus\n}\n#endif\n");
2132 #ifdef COLLECT_EXPORT_LIST
2134 write_export_file (stream
)
2137 struct id
*list
= exports
.first
;
2138 for (; list
; list
= list
->next
)
2139 fprintf (stream
, "%s\n", list
->name
);
2143 write_import_file (stream
)
2146 struct id
*list
= imports
.first
;
2147 fprintf (stream
, "%s\n", "#! .");
2148 for (; list
; list
= list
->next
)
2149 fprintf (stream
, "%s\n", list
->name
);
2153 #ifdef OBJECT_FORMAT_NONE
2155 /* Generic version to scan the name list of the loaded program for
2156 the symbols g++ uses for static constructors and destructors.
2158 The constructor table begins at __CTOR_LIST__ and contains a count
2159 of the number of pointers (or -1 if the constructors are built in a
2160 separate section by the linker), followed by the pointers to the
2161 constructor functions, terminated with a null pointer. The
2162 destructor table has the same format, and begins at __DTOR_LIST__. */
2165 scan_prog_file (prog_name
, which_pass
)
2167 enum pass which_pass
;
2169 void (*int_handler
) ();
2170 void (*quit_handler
) ();
2178 if (which_pass
== PASS_SECOND
)
2181 /* If we do not have an `nm', complain. */
2182 if (nm_file_name
== 0)
2183 fatal ("cannot find `nm'");
2185 nm_argv
[argc
++] = nm_file_name
;
2186 if (NM_FLAGS
[0] != '\0')
2187 nm_argv
[argc
++] = NM_FLAGS
;
2189 nm_argv
[argc
++] = prog_name
;
2190 nm_argv
[argc
++] = (char *) 0;
2192 if (pipe (pipe_fd
) < 0)
2193 fatal_perror ("pipe");
2195 inf
= fdopen (pipe_fd
[0], "r");
2196 if (inf
== (FILE *) 0)
2197 fatal_perror ("fdopen");
2199 /* Trace if needed. */
2205 for (p_argv
= &nm_argv
[0]; (str
= *p_argv
) != (char *) 0; p_argv
++)
2206 fprintf (stderr
, " %s", str
);
2208 fprintf (stderr
, "\n");
2214 /* Spawn child nm on pipe */
2219 fatal_perror ("fork");
2221 fatal_perror ("vfork");
2225 if (pid
== 0) /* child context */
2228 if (dup2 (pipe_fd
[1], 1) < 0)
2229 fatal_perror ("dup2 (%d, 1)", pipe_fd
[1]);
2231 if (close (pipe_fd
[0]) < 0)
2232 fatal_perror ("close (%d)", pipe_fd
[0]);
2234 if (close (pipe_fd
[1]) < 0)
2235 fatal_perror ("close (%d)", pipe_fd
[1]);
2237 execv (nm_file_name
, nm_argv
);
2238 fatal_perror ("executing %s", nm_file_name
);
2241 /* Parent context from here on. */
2242 int_handler
= (void (*) ())signal (SIGINT
, SIG_IGN
);
2244 quit_handler
= (void (*) ())signal (SIGQUIT
, SIG_IGN
);
2247 if (close (pipe_fd
[1]) < 0)
2248 fatal_perror ("close (%d)", pipe_fd
[1]);
2251 fprintf (stderr
, "\nnm output with constructors/destructors.\n");
2253 /* Read each line of nm output. */
2254 while (fgets (buf
, sizeof buf
, inf
) != (char *) 0)
2259 /* If it contains a constructor or destructor name, add the name
2260 to the appropriate list. */
2262 for (p
= buf
; (ch
= *p
) != '\0' && ch
!= '\n' && ch
!= '_'; p
++)
2263 if (ch
== ' ' && p
[1] == 'U' && p
[2] == ' ')
2270 /* Find the end of the symbol name.
2271 Do not include `|', because Encore nm can tack that on the end. */
2272 for (end
= p
; (ch2
= *end
) != '\0' && !isspace (ch2
) && ch2
!= '|';
2278 switch (is_ctor_dtor (name
))
2281 if (which_pass
!= PASS_LIB
)
2282 add_to_list (&constructors
, name
);
2286 if (which_pass
!= PASS_LIB
)
2287 add_to_list (&destructors
, name
);
2291 if (which_pass
!= PASS_LIB
)
2292 fatal ("init function found in object %s", prog_name
);
2293 #ifndef LD_INIT_SWITCH
2294 add_to_list (&constructors
, name
);
2299 if (which_pass
!= PASS_LIB
)
2300 fatal ("fini function found in object %s", prog_name
);
2301 #ifndef LD_FINI_SWITCH
2302 add_to_list (&destructors
, name
);
2307 if (which_pass
!= PASS_LIB
)
2308 add_to_list (&frame_tables
, name
);
2310 default: /* not a constructor or destructor */
2315 fprintf (stderr
, "\t%s\n", buf
);
2319 fprintf (stderr
, "\n");
2321 if (fclose (inf
) != 0)
2322 fatal_perror ("fclose of pipe");
2324 do_wait (nm_file_name
);
2326 signal (SIGINT
, int_handler
);
2328 signal (SIGQUIT
, quit_handler
);
2332 #if SUNOS4_SHARED_LIBRARIES
2334 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2335 that the output file depends upon and their initialization/finalization
2336 routines, if any. */
2341 #include <sys/mman.h>
2342 #include <sys/param.h>
2344 #include <sys/dir.h>
2346 /* pointers to the object file */
2347 unsigned object
; /* address of memory mapped file */
2348 unsigned objsize
; /* size of memory mapped to file */
2349 char * code
; /* pointer to code segment */
2350 char * data
; /* pointer to data segment */
2351 struct nlist
*symtab
; /* pointer to symbol table */
2352 struct link_dynamic
*ld
;
2353 struct link_dynamic_2
*ld_2
;
2354 struct head libraries
;
2356 /* Map the file indicated by NAME into memory and store its address. */
2364 if ((fp
= open (name
, O_RDONLY
)) == -1)
2365 fatal ("unable to open file '%s'", name
);
2366 if (fstat (fp
, &s
) == -1)
2367 fatal ("unable to stat file '%s'", name
);
2369 objsize
= s
.st_size
;
2370 object
= (unsigned) mmap (0, objsize
, PROT_READ
|PROT_WRITE
, MAP_PRIVATE
,
2373 fatal ("unable to mmap file '%s'", name
);
2378 /* Helpers for locatelib. */
2380 static char *libname
;
2386 return (strncmp (libname
, d
->d_name
, strlen (libname
)) == 0);
2389 /* If one file has an additional numeric extension past LIBNAME, then put
2390 that one first in the sort. If both files have additional numeric
2391 extensions, then put the one with the higher number first in the sort.
2393 We must verify that the extension is numeric, because Sun saves the
2394 original versions of patched libraries with a .FCS extension. Files with
2395 invalid extensions must go last in the sort, so that they will not be used. */
2399 struct direct
**d1
, **d2
;
2401 int i1
, i2
= strlen (libname
);
2402 char *e1
= (*d1
)->d_name
+ i2
;
2403 char *e2
= (*d2
)->d_name
+ i2
;
2405 while (*e1
&& *e2
&& *e1
== '.' && *e2
== '.'
2406 && e1
[1] && isdigit (e1
[1]) && e2
[1] && isdigit (e2
[1]))
2410 i1
= strtol (e1
, &e1
, 10);
2411 i2
= strtol (e2
, &e2
, 10);
2418 /* It has a valid numeric extension, prefer this one. */
2419 if (*e1
== '.' && e1
[1] && isdigit (e1
[1]))
2421 /* It has a invalid numeric extension, must prefer the other one. */
2427 /* It has a valid numeric extension, prefer this one. */
2428 if (*e2
== '.' && e2
[1] && isdigit (e2
[1]))
2430 /* It has a invalid numeric extension, must prefer the other one. */
2438 /* Given the name NAME of a dynamic dependency, find its pathname and add
2439 it to the list of libraries. */
2447 char buf
[MAXPATHLEN
];
2455 /* counting elements in array, need 1 extra for null */
2457 ld_rules
= (char *) (ld_2
->ld_rules
+ code
);
2461 for (; *ld_rules
!= 0; ld_rules
++)
2462 if (*ld_rules
== ':')
2464 ld_rules
= (char *) (ld_2
->ld_rules
+ code
);
2465 ldr
= (char *) malloc (strlen (ld_rules
) + 1);
2466 strcpy (ldr
, ld_rules
);
2468 p
= getenv ("LD_LIBRARY_PATH");
2473 for (q
= p
; *q
!= 0; q
++)
2476 q
= (char *) malloc (strlen (p
) + 1);
2479 l
= (char **) malloc ((cnt
+ 3) * sizeof (char *));
2484 for (; *ldr
!= 0; ldr
++)
2494 for (; *q
!= 0; q
++)
2501 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2504 *pp
++ = "/usr/local/lib";
2508 for (pp
= l
; *pp
!= 0 ; pp
++)
2510 struct direct
**namelist
;
2512 if ((entries
= scandir (*pp
, &namelist
, libselect
, libcompare
)) > 0)
2514 sprintf (buf
, "%s/%s", *pp
, namelist
[entries
- 1]->d_name
);
2515 add_to_list (&libraries
, buf
);
2517 fprintf (stderr
, "%s\n", buf
);
2524 fprintf (stderr
, "not found\n");
2526 fatal ("dynamic dependency %s not found", name
);
2530 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2531 that it depends upon and any constructors or destructors they contain. */
2534 scan_libraries (prog_name
)
2537 struct exec
*header
;
2539 struct link_object
*lo
;
2540 char buff
[MAXPATHLEN
];
2543 mapfile (prog_name
);
2544 header
= (struct exec
*)object
;
2545 if (N_BADMAG (*header
))
2546 fatal ("bad magic number in file '%s'", prog_name
);
2547 if (header
->a_dynamic
== 0)
2550 code
= (char *) (N_TXTOFF (*header
) + (long) header
);
2551 data
= (char *) (N_DATOFF (*header
) + (long) header
);
2552 symtab
= (struct nlist
*) (N_SYMOFF (*header
) + (long) header
);
2554 if (header
->a_magic
== ZMAGIC
&& header
->a_entry
== 0x20)
2557 ld
= (struct link_dynamic
*) (symtab
->n_value
+ code
);
2563 ld
= (struct link_dynamic
*) data
;
2568 fprintf (stderr
, "dynamic dependencies.\n");
2570 ld_2
= (struct link_dynamic_2
*) ((long) ld
->ld_un
.ld_2
+ (long)base
);
2571 for (lo
= (struct link_object
*) ld_2
->ld_need
; lo
;
2572 lo
= (struct link_object
*) lo
->lo_next
)
2575 lo
= (struct link_object
*) ((long) lo
+ code
);
2576 name
= (char *) (code
+ lo
->lo_name
);
2580 fprintf (stderr
, "\t-l%s.%d => ", name
, lo
->lo_major
);
2581 sprintf (buff
, "lib%s.so.%d.%d", name
, lo
->lo_major
, lo
->lo_minor
);
2587 fprintf (stderr
, "\t%s\n", name
);
2588 add_to_list (&libraries
, name
);
2593 fprintf (stderr
, "\n");
2595 /* now iterate through the library list adding their symbols to
2597 for (list
= libraries
.first
; list
; list
= list
->next
)
2598 scan_prog_file (list
->name
, PASS_LIB
);
2601 #else /* SUNOS4_SHARED_LIBRARIES */
2604 /* Use the List Dynamic Dependencies program to find shared libraries that
2605 the output file depends upon and their initialization/finalization
2606 routines, if any. */
2609 scan_libraries (prog_name
)
2612 static struct head libraries
; /* list of shared libraries found */
2614 void (*int_handler
) ();
2615 void (*quit_handler
) ();
2623 /* If we do not have an `ldd', complain. */
2624 if (ldd_file_name
== 0)
2626 error ("cannot find `ldd'");
2630 ldd_argv
[argc
++] = ldd_file_name
;
2631 ldd_argv
[argc
++] = prog_name
;
2632 ldd_argv
[argc
++] = (char *) 0;
2634 if (pipe (pipe_fd
) < 0)
2635 fatal_perror ("pipe");
2637 inf
= fdopen (pipe_fd
[0], "r");
2638 if (inf
== (FILE *) 0)
2639 fatal_perror ("fdopen");
2641 /* Trace if needed. */
2647 for (p_argv
= &ldd_argv
[0]; (str
= *p_argv
) != (char *) 0; p_argv
++)
2648 fprintf (stderr
, " %s", str
);
2650 fprintf (stderr
, "\n");
2656 /* Spawn child ldd on pipe */
2661 fatal_perror ("fork");
2663 fatal_perror ("vfork");
2667 if (pid
== 0) /* child context */
2670 if (dup2 (pipe_fd
[1], 1) < 0)
2671 fatal_perror ("dup2 (%d, 1)", pipe_fd
[1]);
2673 if (close (pipe_fd
[0]) < 0)
2674 fatal_perror ("close (%d)", pipe_fd
[0]);
2676 if (close (pipe_fd
[1]) < 0)
2677 fatal_perror ("close (%d)", pipe_fd
[1]);
2679 execv (ldd_file_name
, ldd_argv
);
2680 fatal_perror ("executing %s", ldd_file_name
);
2683 /* Parent context from here on. */
2684 int_handler
= (void (*) ()) signal (SIGINT
, SIG_IGN
);
2686 quit_handler
= (void (*) ()) signal (SIGQUIT
, SIG_IGN
);
2689 if (close (pipe_fd
[1]) < 0)
2690 fatal_perror ("close (%d)", pipe_fd
[1]);
2693 fprintf (stderr
, "\nldd output with constructors/destructors.\n");
2695 /* Read each line of ldd output. */
2696 while (fgets (buf
, sizeof buf
, inf
) != (char *) 0)
2699 char *name
, *end
, *p
= buf
;
2701 /* Extract names of libraries and add to list. */
2702 PARSE_LDD_OUTPUT (p
);
2707 if (strncmp (name
, "not found", sizeof ("not found") - 1) == 0)
2708 fatal ("dynamic dependency %s not found", buf
);
2710 /* Find the end of the symbol name. */
2712 (ch2
= *end
) != '\0' && ch2
!= '\n' && !isspace (ch2
) && ch2
!= '|';
2717 if (access (name
, R_OK
) == 0)
2718 add_to_list (&libraries
, name
);
2720 fatal ("unable to open dynamic dependency '%s'", buf
);
2723 fprintf (stderr
, "\t%s\n", buf
);
2726 fprintf (stderr
, "\n");
2728 if (fclose (inf
) != 0)
2729 fatal_perror ("fclose of pipe");
2731 do_wait (ldd_file_name
);
2733 signal (SIGINT
, int_handler
);
2735 signal (SIGQUIT
, quit_handler
);
2738 /* now iterate through the library list adding their symbols to
2740 for (list
= libraries
.first
; list
; list
= list
->next
)
2741 scan_prog_file (list
->name
, PASS_LIB
);
2744 #endif /* LDD_SUFFIX */
2745 #endif /* SUNOS4_SHARED_LIBRARIES */
2747 #endif /* OBJECT_FORMAT_NONE */
2751 * COFF specific stuff.
2754 #ifdef OBJECT_FORMAT_COFF
2756 #if defined(EXTENDED_COFF)
2757 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2758 # define GCC_SYMENT SYMR
2759 # define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
2760 # define GCC_SYMINC(X) (1)
2761 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2762 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2764 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2765 # define GCC_SYMENT SYMENT
2766 # define GCC_OK_SYMBOL(X) \
2767 (((X).n_sclass == C_EXT) && \
2768 ((X).n_scnum > N_UNDEF) && \
2769 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
2770 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
2771 # define GCC_UNDEF_SYMBOL(X) \
2772 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2773 # define GCC_SYMINC(X) ((X).n_numaux+1)
2774 # define GCC_SYMZERO(X) 0
2775 # define GCC_CHECK_HDR(X) (1)
2778 extern char *ldgetname ();
2780 /* COFF version to scan the name list of the loaded program for
2781 the symbols g++ uses for static constructors and destructors.
2783 The constructor table begins at __CTOR_LIST__ and contains a count
2784 of the number of pointers (or -1 if the constructors are built in a
2785 separate section by the linker), followed by the pointers to the
2786 constructor functions, terminated with a null pointer. The
2787 destructor table has the same format, and begins at __DTOR_LIST__. */
2790 scan_prog_file (prog_name
, which_pass
)
2792 enum pass which_pass
;
2794 LDFILE
*ldptr
= NULL
;
2795 int sym_index
, sym_count
;
2797 #ifdef COLLECT_EXPORT_LIST
2798 /* Should we generate an import list for given prog_name? */
2799 int import_flag
= (which_pass
== PASS_OBJ
? 0 : use_import_list (prog_name
));
2802 if (which_pass
!= PASS_FIRST
&& which_pass
!= PASS_OBJ
)
2805 #ifdef COLLECT_EXPORT_LIST
2806 /* We do not need scanning for some standard C libraries. */
2807 if (which_pass
== PASS_FIRST
&& ignore_library (prog_name
))
2810 /* On AIX we have a loop, because there is not much difference
2811 between an object and an archive. This trick allows us to
2812 eliminate scan_libraries() function. */
2816 if ((ldptr
= ldopen (prog_name
, ldptr
)) != NULL
)
2819 if (!MY_ISCOFF (HEADER (ldptr
).f_magic
))
2820 fatal ("%s: not a COFF file", prog_name
);
2822 #ifdef COLLECT_EXPORT_LIST
2823 /* Is current archive member a shared object? */
2824 is_shared
= HEADER (ldptr
).f_flags
& F_SHROBJ
;
2826 if (GCC_CHECK_HDR (ldptr
))
2828 sym_count
= GCC_SYMBOLS (ldptr
);
2829 sym_index
= GCC_SYMZERO (ldptr
);
2830 while (sym_index
< sym_count
)
2834 if (ldtbread (ldptr
, sym_index
, &symbol
) <= 0)
2836 sym_index
+= GCC_SYMINC (symbol
);
2838 if (GCC_OK_SYMBOL (symbol
))
2842 if ((name
= ldgetname (ldptr
, &symbol
)) == NULL
)
2843 continue; /* should never happen */
2845 #ifdef XCOFF_DEBUGGING_INFO
2846 /* All AIX function names have a duplicate entry
2847 beginning with a dot. */
2852 switch (is_ctor_dtor (name
))
2855 if (! is_shared
) add_to_list (&constructors
, name
);
2856 if (which_pass
== PASS_OBJ
)
2857 add_to_list (&exports
, name
);
2858 #ifdef COLLECT_EXPORT_LIST
2859 /* If this symbol was undefined and we are building
2860 an import list, we should add a symbol to this
2864 && is_in_list (name
, undefined
.first
))
2865 add_to_list (&imports
, name
);
2870 if (! is_shared
) add_to_list (&destructors
, name
);
2871 if (which_pass
== PASS_OBJ
)
2872 add_to_list (&exports
, name
);
2873 #ifdef COLLECT_EXPORT_LIST
2874 /* If this symbol was undefined and we are building
2875 an import list, we should add a symbol to this
2879 && is_in_list (name
, undefined
.first
))
2880 add_to_list (&imports
, name
);
2884 #ifdef COLLECT_EXPORT_LIST
2887 add_to_list (&constructors
, name
);
2892 add_to_list (&destructors
, name
);
2896 default: /* not a constructor or destructor */
2897 #ifdef COLLECT_EXPORT_LIST
2898 /* If we are building a shared object on AIX we need
2899 to explicitly export all global symbols or add
2900 them to import list. */
2902 if (which_pass
== PASS_OBJ
&& (! export_flag
))
2903 add_to_list (&exports
, name
);
2904 else if (! is_shared
&& which_pass
== PASS_FIRST
2906 && is_in_list(name
, undefined
.first
))
2907 add_to_list (&imports
, name
);
2912 #if !defined(EXTENDED_COFF)
2914 fprintf (stderr
, "\tsec=%d class=%d type=%s%o %s\n",
2915 symbol
.n_scnum
, symbol
.n_sclass
,
2916 (symbol
.n_type
? "0" : ""), symbol
.n_type
,
2921 "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
2922 symbol
.iss
, symbol
.value
, symbol
.index
, name
);
2925 #ifdef COLLECT_EXPORT_LIST
2926 /* If we are building a shared object we should collect
2927 information about undefined symbols for later
2928 import list generation. */
2929 else if (shared_obj
&& GCC_UNDEF_SYMBOL (symbol
))
2933 if ((name
= ldgetname (ldptr
, &symbol
)) == NULL
)
2934 continue; /* should never happen */
2936 /* All AIX function names have a duplicate entry
2937 beginning with a dot. */
2940 add_to_list (&undefined
, name
);
2948 fatal ("%s: cannot open as COFF file", prog_name
);
2950 #ifdef COLLECT_EXPORT_LIST
2951 /* On AIX loop continues while there are more members in archive. */
2953 while (ldclose (ldptr
) == FAILURE
);
2955 /* Otherwise we simply close ldptr. */
2956 (void) ldclose(ldptr
);
2961 #ifdef COLLECT_EXPORT_LIST
2963 /* This new function is used to decide whether we should
2964 generate import list for an object or to use it directly. */
2966 use_import_list (prog_name
)
2971 /* If we do not build a shared object then import list should not be used. */
2972 if (! shared_obj
) return 0;
2974 /* Currently we check only for libgcc, but this can be changed in future. */
2975 p
= strstr (prog_name
, "libgcc.a");
2976 if (p
!= 0 && (strlen (p
) == sizeof ("libgcc.a") - 1))
2981 /* Given a library name without "lib" prefix, this function
2982 returns a full library name including a path. */
2984 resolve_lib_name (name
)
2990 for (i
= 0; libpaths
[i
]; i
++)
2991 if (libpaths
[i
]->max_len
> l
)
2992 l
= libpaths
[i
]->max_len
;
2994 lib_buf
= xmalloc (l
+ strlen(name
) + 10);
2996 for (i
= 0; libpaths
[i
]; i
++)
2998 struct prefix_list
*list
= libpaths
[i
]->plist
;
2999 for (; list
; list
= list
->next
)
3001 for (j
= 0; libexts
[j
]; j
++)
3003 /* The following lines are needed because path_prefix list
3004 may contain directories both with trailing '/' and
3007 if (list
->prefix
[strlen(list
->prefix
)-1] != '/')
3009 sprintf (lib_buf
, "%s%slib%s.%s",
3010 list
->prefix
, p
, name
, libexts
[j
]);
3011 if (debug
) fprintf (stderr
, "searching for: %s\n", lib_buf
);
3012 if (file_exists (lib_buf
))
3014 if (debug
) fprintf (stderr
, "found: %s\n", lib_buf
);
3021 fprintf (stderr
, "not found\n");
3023 fatal ("Library lib%s not found", name
);
3027 /* Array of standard AIX libraries which should not
3028 be scanned for ctors/dtors. */
3029 static char* aix_std_libs
[] = {
3034 "/usr/lib/libc_r.a",
3035 "/usr/lib/threads/libc.a",
3036 "/usr/ccs/lib/libc.a",
3037 "/usr/ccs/lib/libc_r.a",
3041 /* This function checks the filename and returns 1
3042 if this name matches the location of a standard AIX library. */
3044 ignore_library (name
)
3047 char **p
= &aix_std_libs
[0];
3048 while (*p
++ != NULL
)
3049 if (! strcmp (name
, *p
)) return 1;
3055 #endif /* OBJECT_FORMAT_COFF */
3059 * OSF/rose specific stuff.
3062 #ifdef OBJECT_FORMAT_ROSE
3064 /* Union of the various load commands */
3066 typedef union load_union
3068 ldc_header_t hdr
; /* common header */
3069 load_cmd_map_command_t map
; /* map indexing other load cmds */
3070 interpreter_command_t iprtr
; /* interpreter pathname */
3071 strings_command_t str
; /* load commands strings section */
3072 region_command_t region
; /* region load command */
3073 reloc_command_t reloc
; /* relocation section */
3074 package_command_t pkg
; /* package load command */
3075 symbols_command_t sym
; /* symbol sections */
3076 entry_command_t ent
; /* program start section */
3077 gen_info_command_t info
; /* object information */
3078 func_table_command_t func
; /* function constructors/destructors */
3081 /* Structure to point to load command and data section in memory. */
3083 typedef struct load_all
3085 load_union_t
*load
; /* load command */
3086 char *section
; /* pointer to section */
3089 /* Structure to contain information about a file mapped into memory. */
3093 char *start
; /* start of map */
3094 char *name
; /* filename */
3095 long size
; /* size of the file */
3096 long rounded_size
; /* size rounded to page boundary */
3097 int fd
; /* file descriptor */
3098 int rw
; /* != 0 if opened read/write */
3099 int use_mmap
; /* != 0 if mmap'ed */
3102 extern int decode_mach_o_hdr ();
3103 extern int encode_mach_o_hdr ();
3105 static void add_func_table
PROTO((mo_header_t
*, load_all_t
*,
3106 symbol_info_t
*, int));
3107 static void print_header
PROTO((mo_header_t
*));
3108 static void print_load_command
PROTO((load_union_t
*, size_t, int));
3109 static void bad_header
PROTO((int));
3110 static struct file_info
*read_file
PROTO((char *, int, int));
3111 static void end_file
PROTO((struct file_info
*));
3113 /* OSF/rose specific version to scan the name list of the loaded
3114 program for the symbols g++ uses for static constructors and
3117 The constructor table begins at __CTOR_LIST__ and contains a count
3118 of the number of pointers (or -1 if the constructors are built in a
3119 separate section by the linker), followed by the pointers to the
3120 constructor functions, terminated with a null pointer. The
3121 destructor table has the same format, and begins at __DTOR_LIST__. */
3124 scan_prog_file (prog_name
, which_pass
)
3126 enum pass which_pass
;
3130 load_all_t
*load_array
;
3131 load_all_t
*load_end
;
3132 load_all_t
*load_cmd
;
3133 int symbol_load_cmds
;
3139 struct file_info
*obj_file
;
3141 mo_lcid_t cmd_strings
= -1;
3142 symbol_info_t
*main_sym
= 0;
3143 int rw
= (which_pass
!= PASS_FIRST
);
3145 prog_fd
= open (prog_name
, (rw
) ? O_RDWR
: O_RDONLY
);
3147 fatal_perror ("cannot read %s", prog_name
);
3149 obj_file
= read_file (prog_name
, prog_fd
, rw
);
3150 obj
= obj_file
->start
;
3152 status
= decode_mach_o_hdr (obj
, MO_SIZEOF_RAW_HDR
, MOH_HEADER_VERSION
, &hdr
);
3153 if (status
!= MO_HDR_CONV_SUCCESS
)
3154 bad_header (status
);
3157 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
3158 since the hardware will automatically swap bytes for us on loading little endian
3161 #ifndef CROSS_COMPILE
3162 if (hdr
.moh_magic
!= MOH_MAGIC_MSB
3163 || hdr
.moh_header_version
!= MOH_HEADER_VERSION
3164 || hdr
.moh_byte_order
!= OUR_BYTE_ORDER
3165 || hdr
.moh_data_rep_id
!= OUR_DATA_REP_ID
3166 || hdr
.moh_cpu_type
!= OUR_CPU_TYPE
3167 || hdr
.moh_cpu_subtype
!= OUR_CPU_SUBTYPE
3168 || hdr
.moh_vendor_type
!= OUR_VENDOR_TYPE
)
3170 fatal ("incompatibilities between object file & expected values");
3175 print_header (&hdr
);
3177 offset
= hdr
.moh_first_cmd_off
;
3178 load_end
= load_array
3179 = (load_all_t
*) xcalloc (sizeof (load_all_t
), hdr
.moh_n_load_cmds
+ 2);
3181 /* Build array of load commands, calculating the offsets */
3182 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
3184 load_union_t
*load_hdr
; /* load command header */
3186 load_cmd
= load_end
++;
3187 load_hdr
= (load_union_t
*) (obj
+ offset
);
3189 /* If modifying the program file, copy the header. */
3192 load_union_t
*ptr
= (load_union_t
*) xmalloc (load_hdr
->hdr
.ldci_cmd_size
);
3193 bcopy ((char *)load_hdr
, (char *)ptr
, load_hdr
->hdr
.ldci_cmd_size
);
3196 /* null out old command map, because we will rewrite at the end. */
3197 if (ptr
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
3199 cmd_strings
= ptr
->map
.lcm_ld_cmd_strings
;
3200 ptr
->hdr
.ldci_cmd_type
= LDC_UNDEFINED
;
3204 load_cmd
->load
= load_hdr
;
3205 if (load_hdr
->hdr
.ldci_section_off
> 0)
3206 load_cmd
->section
= obj
+ load_hdr
->hdr
.ldci_section_off
;
3209 print_load_command (load_hdr
, offset
, i
);
3211 offset
+= load_hdr
->hdr
.ldci_cmd_size
;
3214 /* If the last command is the load command map and is not undefined,
3215 decrement the count of load commands. */
3216 if (rw
&& load_end
[-1].load
->hdr
.ldci_cmd_type
== LDC_UNDEFINED
)
3219 hdr
.moh_n_load_cmds
--;
3222 /* Go through and process each symbol table section. */
3223 symbol_load_cmds
= 0;
3224 for (load_cmd
= load_array
; load_cmd
< load_end
; load_cmd
++)
3226 load_union_t
*load_hdr
= load_cmd
->load
;
3228 if (load_hdr
->hdr
.ldci_cmd_type
== LDC_SYMBOLS
)
3234 char *kind
= "unknown";
3236 switch (load_hdr
->sym
.symc_kind
)
3238 case SYMC_IMPORTS
: kind
= "imports"; break;
3239 case SYMC_DEFINED_SYMBOLS
: kind
= "defined"; break;
3240 case SYMC_STABS
: kind
= "stabs"; break;
3243 fprintf (stderr
, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
3244 symbol_load_cmds
, load_hdr
->hdr
.ldci_section_off
, kind
);
3247 if (load_hdr
->sym
.symc_kind
!= SYMC_DEFINED_SYMBOLS
)
3250 str_sect
= load_array
[load_hdr
->sym
.symc_strings_section
].section
;
3251 if (str_sect
== (char *) 0)
3252 fatal ("string section missing");
3254 if (load_cmd
->section
== (char *) 0)
3255 fatal ("section pointer missing");
3257 num_syms
= load_hdr
->sym
.symc_nentries
;
3258 for (i
= 0; i
< num_syms
; i
++)
3260 symbol_info_t
*sym
= ((symbol_info_t
*) load_cmd
->section
) + i
;
3261 char *name
= sym
->si_name
.symbol_name
+ str_sect
;
3268 char *n
= name
+ strlen (name
) - strlen (NAME__MAIN
);
3270 if ((n
- name
) < 0 || strcmp (n
, NAME__MAIN
))
3280 switch (is_ctor_dtor (name
))
3283 add_to_list (&constructors
, name
);
3287 add_to_list (&destructors
, name
);
3290 default: /* not a constructor or destructor */
3296 fprintf (stderr
, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
3297 sym
->si_type
, sym
->si_sc_type
, sym
->si_flags
, name
);
3302 if (symbol_load_cmds
== 0)
3303 fatal ("no symbol table found");
3305 /* Update the program file now, rewrite header and load commands. At present,
3306 we assume that there is enough space after the last load command to insert
3307 one more. Since the first section written out is page aligned, and the
3308 number of load commands is small, this is ok for the present. */
3312 load_union_t
*load_map
;
3315 if (cmd_strings
== -1)
3316 fatal ("no cmd_strings found");
3318 /* Add __main to initializer list.
3319 If we are building a program instead of a shared library, do not
3320 do anything, since in the current version, you cannot do mallocs
3321 and such in the constructors. */
3323 if (main_sym
!= (symbol_info_t
*) 0
3324 && ((hdr
.moh_flags
& MOH_EXECABLE_F
) == 0))
3325 add_func_table (&hdr
, load_array
, main_sym
, FNTC_INITIALIZATION
);
3328 fprintf (stderr
, "\nUpdating header and load commands.\n\n");
3330 hdr
.moh_n_load_cmds
++;
3331 size
= sizeof (load_cmd_map_command_t
) + (sizeof (mo_offset_t
) * (hdr
.moh_n_load_cmds
- 1));
3333 /* Create new load command map. */
3335 fprintf (stderr
, "load command map, %d cmds, new size %ld.\n",
3336 (int)hdr
.moh_n_load_cmds
, (long)size
);
3338 load_map
= (load_union_t
*) xcalloc (1, size
);
3339 load_map
->map
.ldc_header
.ldci_cmd_type
= LDC_CMD_MAP
;
3340 load_map
->map
.ldc_header
.ldci_cmd_size
= size
;
3341 load_map
->map
.lcm_ld_cmd_strings
= cmd_strings
;
3342 load_map
->map
.lcm_nentries
= hdr
.moh_n_load_cmds
;
3343 load_array
[hdr
.moh_n_load_cmds
-1].load
= load_map
;
3345 offset
= hdr
.moh_first_cmd_off
;
3346 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
3348 load_map
->map
.lcm_map
[i
] = offset
;
3349 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
3350 hdr
.moh_load_map_cmd_off
= offset
;
3352 offset
+= load_array
[i
].load
->hdr
.ldci_cmd_size
;
3355 hdr
.moh_sizeofcmds
= offset
- MO_SIZEOF_RAW_HDR
;
3358 print_header (&hdr
);
3361 status
= encode_mach_o_hdr (&hdr
, obj
, MO_SIZEOF_RAW_HDR
);
3362 if (status
!= MO_HDR_CONV_SUCCESS
)
3363 bad_header (status
);
3366 fprintf (stderr
, "writing load commands.\n\n");
3368 /* Write load commands */
3369 offset
= hdr
.moh_first_cmd_off
;
3370 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
3372 load_union_t
*load_hdr
= load_array
[i
].load
;
3373 size_t size
= load_hdr
->hdr
.ldci_cmd_size
;
3376 print_load_command (load_hdr
, offset
, i
);
3378 bcopy ((char *) load_hdr
, (char *) (obj
+ offset
), size
);
3383 end_file (obj_file
);
3385 if (close (prog_fd
))
3386 fatal_perror ("closing %s", prog_name
);
3389 fprintf (stderr
, "\n");
3393 /* Add a function table to the load commands to call a function
3394 on initiation or termination of the process. */
3397 add_func_table (hdr_p
, load_array
, sym
, type
)
3398 mo_header_t
*hdr_p
; /* pointer to global header */
3399 load_all_t
*load_array
; /* array of ptrs to load cmds */
3400 symbol_info_t
*sym
; /* pointer to symbol entry */
3401 int type
; /* fntc_type value */
3403 /* Add a new load command. */
3404 int num_cmds
= ++hdr_p
->moh_n_load_cmds
;
3405 int load_index
= num_cmds
- 1;
3406 size_t size
= sizeof (func_table_command_t
) + sizeof (mo_addr_t
);
3407 load_union_t
*ptr
= xcalloc (1, size
);
3408 load_all_t
*load_cmd
;
3411 /* Set the unresolved address bit in the header to force the loader to be
3412 used, since kernel exec does not call the initialization functions. */
3413 hdr_p
->moh_flags
|= MOH_UNRESOLVED_F
;
3415 load_cmd
= &load_array
[load_index
];
3416 load_cmd
->load
= ptr
;
3417 load_cmd
->section
= (char *) 0;
3419 /* Fill in func table load command. */
3420 ptr
->func
.ldc_header
.ldci_cmd_type
= LDC_FUNC_TABLE
;
3421 ptr
->func
.ldc_header
.ldci_cmd_size
= size
;
3422 ptr
->func
.ldc_header
.ldci_section_off
= 0;
3423 ptr
->func
.ldc_header
.ldci_section_len
= 0;
3424 ptr
->func
.fntc_type
= type
;
3425 ptr
->func
.fntc_nentries
= 1;
3427 /* copy address, turn it from abs. address to (region,offset) if necessary. */
3428 /* Is the symbol already expressed as (region, offset)? */
3429 if ((sym
->si_flags
& SI_ABSOLUTE_VALUE_F
) == 0)
3431 ptr
->func
.fntc_entry_loc
[i
].adr_lcid
= sym
->si_value
.def_val
.adr_lcid
;
3432 ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
= sym
->si_value
.def_val
.adr_sctoff
;
3435 /* If not, figure out which region it's in. */
3438 mo_vm_addr_t addr
= sym
->si_value
.abs_val
;
3441 for (i
= 0; i
< load_index
; i
++)
3443 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_REGION
)
3445 region_command_t
*region_ptr
= &load_array
[i
].load
->region
;
3447 if ((region_ptr
->regc_flags
& REG_ABS_ADDR_F
) != 0
3448 && addr
>= region_ptr
->regc_addr
.vm_addr
3449 && addr
<= region_ptr
->regc_addr
.vm_addr
+ region_ptr
->regc_vm_size
)
3451 ptr
->func
.fntc_entry_loc
[0].adr_lcid
= i
;
3452 ptr
->func
.fntc_entry_loc
[0].adr_sctoff
= addr
- region_ptr
->regc_addr
.vm_addr
;
3460 fatal ("could not convert 0x%l.8x into a region", addr
);
3465 "%s function, region %d, offset = %ld (0x%.8lx)\n",
3466 (type
== FNTC_INITIALIZATION
) ? "init" : "term",
3467 (int)ptr
->func
.fntc_entry_loc
[i
].adr_lcid
,
3468 (long)ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
,
3469 (long)ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
);
3474 /* Print the global header for an OSF/rose object. */
3477 print_header (hdr_ptr
)
3478 mo_header_t
*hdr_ptr
;
3480 fprintf (stderr
, "\nglobal header:\n");
3481 fprintf (stderr
, "\tmoh_magic = 0x%.8lx\n", hdr_ptr
->moh_magic
);
3482 fprintf (stderr
, "\tmoh_major_version = %d\n", (int)hdr_ptr
->moh_major_version
);
3483 fprintf (stderr
, "\tmoh_minor_version = %d\n", (int)hdr_ptr
->moh_minor_version
);
3484 fprintf (stderr
, "\tmoh_header_version = %d\n", (int)hdr_ptr
->moh_header_version
);
3485 fprintf (stderr
, "\tmoh_max_page_size = %d\n", (int)hdr_ptr
->moh_max_page_size
);
3486 fprintf (stderr
, "\tmoh_byte_order = %d\n", (int)hdr_ptr
->moh_byte_order
);
3487 fprintf (stderr
, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr
->moh_data_rep_id
);
3488 fprintf (stderr
, "\tmoh_cpu_type = %d\n", (int)hdr_ptr
->moh_cpu_type
);
3489 fprintf (stderr
, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr
->moh_cpu_subtype
);
3490 fprintf (stderr
, "\tmoh_vendor_type = %d\n", (int)hdr_ptr
->moh_vendor_type
);
3491 fprintf (stderr
, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr
->moh_load_map_cmd_off
);
3492 fprintf (stderr
, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr
->moh_first_cmd_off
);
3493 fprintf (stderr
, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr
->moh_sizeofcmds
);
3494 fprintf (stderr
, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr
->moh_n_load_cmds
);
3495 fprintf (stderr
, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr
->moh_flags
);
3497 if (hdr_ptr
->moh_flags
& MOH_RELOCATABLE_F
)
3498 fprintf (stderr
, ", relocatable");
3500 if (hdr_ptr
->moh_flags
& MOH_LINKABLE_F
)
3501 fprintf (stderr
, ", linkable");
3503 if (hdr_ptr
->moh_flags
& MOH_EXECABLE_F
)
3504 fprintf (stderr
, ", execable");
3506 if (hdr_ptr
->moh_flags
& MOH_EXECUTABLE_F
)
3507 fprintf (stderr
, ", executable");
3509 if (hdr_ptr
->moh_flags
& MOH_UNRESOLVED_F
)
3510 fprintf (stderr
, ", unresolved");
3512 fprintf (stderr
, "\n\n");
3517 /* Print a short summary of a load command. */
3520 print_load_command (load_hdr
, offset
, number
)
3521 load_union_t
*load_hdr
;
3525 mo_long_t type
= load_hdr
->hdr
.ldci_cmd_type
;
3526 char *type_str
= (char *) 0;
3530 case LDC_UNDEFINED
: type_str
= "UNDEFINED"; break;
3531 case LDC_CMD_MAP
: type_str
= "CMD_MAP"; break;
3532 case LDC_INTERPRETER
: type_str
= "INTERPRETER"; break;
3533 case LDC_STRINGS
: type_str
= "STRINGS"; break;
3534 case LDC_REGION
: type_str
= "REGION"; break;
3535 case LDC_RELOC
: type_str
= "RELOC"; break;
3536 case LDC_PACKAGE
: type_str
= "PACKAGE"; break;
3537 case LDC_SYMBOLS
: type_str
= "SYMBOLS"; break;
3538 case LDC_ENTRY
: type_str
= "ENTRY"; break;
3539 case LDC_FUNC_TABLE
: type_str
= "FUNC_TABLE"; break;
3540 case LDC_GEN_INFO
: type_str
= "GEN_INFO"; break;
3544 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3546 (long) load_hdr
->hdr
.ldci_cmd_size
,
3548 (long) load_hdr
->hdr
.ldci_section_off
,
3549 (long) load_hdr
->hdr
.ldci_section_len
);
3551 if (type_str
== (char *) 0)
3552 fprintf (stderr
, ", ty: unknown (%ld)\n", (long) type
);
3554 else if (type
!= LDC_REGION
)
3555 fprintf (stderr
, ", ty: %s\n", type_str
);
3560 switch (load_hdr
->region
.regc_usage_type
)
3562 case REG_TEXT_T
: region
= ", .text"; break;
3563 case REG_DATA_T
: region
= ", .data"; break;
3564 case REG_BSS_T
: region
= ", .bss"; break;
3565 case REG_GLUE_T
: region
= ", .glue"; break;
3566 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3567 case REG_RDATA_T
: region
= ", .rdata"; break;
3568 case REG_SDATA_T
: region
= ", .sdata"; break;
3569 case REG_SBSS_T
: region
= ", .sbss"; break;
3573 fprintf (stderr
, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3575 (long) load_hdr
->region
.regc_vm_addr
,
3576 (long) load_hdr
->region
.regc_vm_size
,
3584 /* Fatal error when {en,de}code_mach_o_header fails. */
3590 char *msg
= (char *) 0;
3594 case MO_ERROR_BAD_MAGIC
: msg
= "bad magic number"; break;
3595 case MO_ERROR_BAD_HDR_VERS
: msg
= "bad header version"; break;
3596 case MO_ERROR_BAD_RAW_HDR_VERS
: msg
= "bad raw header version"; break;
3597 case MO_ERROR_BUF2SML
: msg
= "raw header buffer too small"; break;
3598 case MO_ERROR_OLD_RAW_HDR_FILE
: msg
= "old raw header file"; break;
3599 case MO_ERROR_UNSUPPORTED_VERS
: msg
= "unsupported version"; break;
3602 if (msg
== (char *) 0)
3603 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status
);
3609 /* Read a file into a memory buffer. */
3611 static struct file_info
*
3612 read_file (name
, fd
, rw
)
3613 char *name
; /* filename */
3614 int fd
; /* file descriptor */
3615 int rw
; /* read/write */
3617 struct stat stat_pkt
;
3618 struct file_info
*p
= (struct file_info
*) xcalloc (sizeof (struct file_info
), 1);
3620 static int page_size
;
3623 if (fstat (fd
, &stat_pkt
) < 0)
3624 fatal_perror ("fstat %s", name
);
3627 p
->size
= stat_pkt
.st_size
;
3628 p
->rounded_size
= stat_pkt
.st_size
;
3634 fprintf (stderr
, "mmap %s, %s\n", name
, (rw
) ? "read/write" : "read-only");
3637 page_size
= sysconf (_SC_PAGE_SIZE
);
3639 p
->rounded_size
= ((p
->size
+ page_size
- 1) / page_size
) * page_size
;
3640 p
->start
= mmap ((caddr_t
) 0,
3641 (rw
) ? p
->rounded_size
: p
->size
,
3642 (rw
) ? (PROT_READ
| PROT_WRITE
) : PROT_READ
,
3643 MAP_FILE
| MAP_VARIABLE
| MAP_SHARED
,
3647 if (p
->start
!= (char *) 0 && p
->start
!= (char *) -1)
3651 #endif /* USE_MMAP */
3656 fprintf (stderr
, "read %s\n", name
);
3659 p
->start
= xmalloc (p
->size
);
3660 if (lseek (fd
, 0L, SEEK_SET
) < 0)
3661 fatal_perror ("lseek to 0 on %s", name
);
3663 len
= read (fd
, p
->start
, p
->size
);
3665 fatal_perror ("read %s", name
);
3668 fatal ("read %ld bytes, expected %ld, from %s", len
, p
->size
, name
);
3674 /* Do anything necessary to write a file back from memory. */
3678 struct file_info
*ptr
; /* file information block */
3686 fprintf (stderr
, "msync %s\n", ptr
->name
);
3688 if (msync (ptr
->start
, ptr
->rounded_size
, MS_ASYNC
))
3689 fatal_perror ("msync %s", ptr
->name
);
3693 fprintf (stderr
, "munmap %s\n", ptr
->name
);
3695 if (munmap (ptr
->start
, ptr
->size
))
3696 fatal_perror ("munmap %s", ptr
->name
);
3699 #endif /* USE_MMAP */
3706 fprintf (stderr
, "write %s\n", ptr
->name
);
3708 if (lseek (ptr
->fd
, 0L, SEEK_SET
) < 0)
3709 fatal_perror ("lseek to 0 on %s", ptr
->name
);
3711 len
= write (ptr
->fd
, ptr
->start
, ptr
->size
);
3713 fatal_perror ("write %s", ptr
->name
);
3715 if (len
!= ptr
->size
)
3716 fatal ("wrote %ld bytes, expected %ld, to %s", len
, ptr
->size
, ptr
->name
);
3725 #endif /* OBJECT_FORMAT_ROSE */